Merge spl-2020-12-05

Change-Id: I05736d5e124ec4fc4a76143941d412c1eb3dfc7b
diff --git a/Android.bp b/Android.bp
index f56ff28..439f8bb 100644
--- a/Android.bp
+++ b/Android.bp
@@ -75,6 +75,9 @@
         ":private-stub-annotations",
     ],
     sdk_version: "core_current",
+    // private-stub-annotations-jar ends up in android.jar in the SDK and should
+    // use -target 8.
+    java_version: "1.8",
 }
 
 droiddoc_exported_dir {
diff --git a/src/main/java/com/android/tools/metalava/Driver.kt b/src/main/java/com/android/tools/metalava/Driver.kt
index 1241a16..2089215 100644
--- a/src/main/java/com/android/tools/metalava/Driver.kt
+++ b/src/main/java/com/android/tools/metalava/Driver.kt
@@ -1163,7 +1163,7 @@
     file: File,
     pkg: String
 ) {
-    if (file.isDirectory) {
+    if (FileReadSandbox.isDirectory(file)) {
         if (skippableDirectory(file)) {
             return
         }
@@ -1179,7 +1179,7 @@
         if (files != null) {
             for (child in files) {
                 var subPkg =
-                    if (child.isDirectory)
+                    if (FileReadSandbox.isDirectory(child))
                         if (pkg.isEmpty())
                             child.name
                         else pkg + "." + child.name
@@ -1194,7 +1194,7 @@
                 addHiddenPackages(packageToDoc, packageToOverview, hiddenPackages, child, subPkg)
             }
         }
-    } else if (file.isFile) {
+    } else if (FileReadSandbox.isFile(file)) {
         var javadoc = false
         val map = when {
             file.name == "package.html" -> {
diff --git a/src/main/java/com/android/tools/metalava/FileReadSandbox.kt b/src/main/java/com/android/tools/metalava/FileReadSandbox.kt
index a4ebb98..2c2443b 100644
--- a/src/main/java/com/android/tools/metalava/FileReadSandbox.kt
+++ b/src/main/java/com/android/tools/metalava/FileReadSandbox.kt
@@ -188,6 +188,24 @@
         return false
     }
 
+    fun isDirectory(file: File): Boolean {
+        try {
+            temporaryExempt.set(true)
+            return file.isDirectory()
+        } finally {
+            temporaryExempt.set(false)
+        }
+    }
+
+    fun isFile(file: File): Boolean {
+        try {
+            temporaryExempt.set(true)
+            return file.isFile()
+        } finally {
+            temporaryExempt.set(false)
+        }
+    }
+
     /** Used to skip all checks on any filesystem access made within the [check] method. */
     private val temporaryExempt = ThreadLocal<Boolean>()
 
diff --git a/src/main/java/com/android/tools/metalava/Options.kt b/src/main/java/com/android/tools/metalava/Options.kt
index 1636985..16917e3 100644
--- a/src/main/java/com/android/tools/metalava/Options.kt
+++ b/src/main/java/com/android/tools/metalava/Options.kt
@@ -787,7 +787,7 @@
                                 "$arg should point to a source root directory, not a source file ($path)"
                             )
                         }
-                        mutableSourcePath.addAll(stringToExistingDirsOrJars(path))
+                        mutableSourcePath.addAll(stringToExistingDirsOrJars(path, false))
                     }
                 }
 
@@ -1944,7 +1944,7 @@
         return FileReadSandbox.allowAccess(files)
     }
 
-    private fun stringToExistingDirsOrJars(value: String): List<File> {
+    private fun stringToExistingDirsOrJars(value: String, exempt: Boolean = true): List<File> {
         val files = mutableListOf<File>()
         for (path in value.split(File.pathSeparatorChar)) {
             val file = fileForPathInner(path)
@@ -1953,7 +1953,10 @@
             }
             files.add(file)
         }
-        return FileReadSandbox.allowAccess(files)
+        if (exempt) {
+            return FileReadSandbox.allowAccess(files)
+        }
+        return files
     }
 
     private fun stringToExistingDirsOrFiles(value: String): List<File> {
@@ -2156,7 +2159,10 @@
                 "@ followed by a path to a text file containing paths to the full set of files to parse.",
 
             "$ARG_SOURCE_PATH <paths>", "One or more directories (separated by `${File.pathSeparator}`) " +
-                "containing source files (within a package hierarchy)",
+                "containing source files (within a package hierarchy). If $ARG_STRICT_INPUT_FILES, " +
+                "$ARG_STRICT_INPUT_FILES_WARN, or $ARG_STRICT_INPUT_FILES_STACK are used, files accessed under " +
+                "$ARG_SOURCE_PATH that are not explicitly specified in $ARG_SOURCE_FILES are reported as " +
+                "violations.",
 
             "$ARG_CLASS_PATH <paths>", "One or more directories or jars (separated by " +
                 "`${File.pathSeparator}`) containing classes that should be on the classpath when parsing the " +
diff --git a/src/test/java/com/android/tools/metalava/OptionsTest.kt b/src/test/java/com/android/tools/metalava/OptionsTest.kt
index 33cfc7f..371106e 100644
--- a/src/test/java/com/android/tools/metalava/OptionsTest.kt
+++ b/src/test/java/com/android/tools/metalava/OptionsTest.kt
@@ -70,7 +70,10 @@
                                              parse.
 --source-path <paths>                        
                                              One or more directories (separated by `:`) containing source files (within
-                                             a package hierarchy)
+                                             a package hierarchy). If --strict-input-files, --strict-input-files:warn,
+                                             or --strict-input-files:stack are used, files accessed under --source-path
+                                             that are not explicitly specified in --source-files are reported as
+                                             violations.
 --classpath <paths>                          
                                              One or more directories or jars (separated by `:`) containing classes that
                                              should be on the classpath when parsing the source files