Merge "MetadataRetriever: Use RGBA_8888 as default color format based on a flag" into main
diff --git a/Android.bp b/Android.bp
index e8f6264..1fb50b6 100644
--- a/Android.bp
+++ b/Android.bp
@@ -603,19 +603,6 @@
     ],
 }
 
-packages_to_document = [
-    "android",
-    "dalvik",
-    "java",
-    "javax",
-    "junit",
-    "org.apache.http",
-    "org.json",
-    "org.w3c.dom",
-    "org.xml.sax",
-    "org.xmlpull",
-]
-
 filegroup {
     name: "android-non-updatable-stub-sources",
     srcs: [
@@ -630,144 +617,6 @@
     visibility: ["//frameworks/base/api"],
 }
 
-// Defaults for all stubs that include the non-updatable framework. These defaults do not include
-// module symbols, so will not compile correctly on their own. Users must add module APIs to the
-// classpath (or sources) somehow.
-stubs_defaults {
-    name: "android-non-updatable-stubs-defaults",
-    srcs: [":android-non-updatable-stub-sources"],
-    sdk_version: "none",
-    system_modules: "none",
-    java_version: "1.8",
-    arg_files: [":frameworks-base-core-AndroidManifest.xml"],
-    aidl: {
-        include_dirs: [
-            "frameworks/av/aidl",
-            "frameworks/base/media/aidl",
-            "frameworks/base/telephony/java",
-            "frameworks/native/libs/permission/aidl",
-            "packages/modules/Bluetooth/framework/aidl-export",
-            "packages/modules/Connectivity/framework/aidl-export",
-            "packages/modules/Media/apex/aidl/stable",
-            "hardware/interfaces/biometrics/common/aidl",
-            "hardware/interfaces/biometrics/fingerprint/aidl",
-            "hardware/interfaces/graphics/common/aidl",
-            "hardware/interfaces/keymaster/aidl",
-            "system/hardware/interfaces/media/aidl",
-        ],
-    },
-    // These are libs from framework-internal-utils that are required (i.e. being referenced)
-    // from framework-non-updatable-sources. Add more here when there's a need.
-    // DO NOT add the entire framework-internal-utils. It might cause unnecessary circular
-    // dependencies gets bigger.
-    libs: [
-        "android.hardware.cas-V1.2-java",
-        "android.hardware.health-V1.0-java-constants",
-        "android.hardware.radio-V1.5-java",
-        "android.hardware.radio-V1.6-java",
-        "android.hardware.thermal-V1.0-java-constants",
-        "android.hardware.thermal-V2.0-java",
-        "android.hardware.tv.input-V1.0-java-constants",
-        "android.hardware.usb-V1.0-java-constants",
-        "android.hardware.usb-V1.1-java-constants",
-        "android.hardware.usb.gadget-V1.0-java",
-        "android.hardware.vibrator-V1.3-java",
-        "framework-protos",
-    ],
-    flags: [
-        "--api-lint-ignore-prefix android.icu.",
-        "--api-lint-ignore-prefix java.",
-        "--api-lint-ignore-prefix junit.",
-        "--api-lint-ignore-prefix org.",
-        "--error NoSettingsProvider",
-        "--error UnhiddenSystemApi",
-        "--error UnflaggedApi",
-        "--force-convert-to-warning-nullability-annotations +*:-android.*:+android.icu.*:-dalvik.*",
-        "--hide BroadcastBehavior",
-        "--hide CallbackInterface",
-        "--hide DeprecationMismatch",
-        "--hide HiddenSuperclass",
-        "--hide MissingPermission",
-        "--hide RequiresPermission",
-        "--hide SdkConstant",
-        "--hide Todo",
-        "--hide-package android.audio.policy.configuration.V7_0",
-        "--hide-package com.android.server",
-        "--manifest $(location :frameworks-base-core-AndroidManifest.xml)",
-    ],
-    filter_packages: packages_to_document,
-    high_mem: true, // Lots of sources => high memory use, see b/170701554
-    installable: false,
-    annotations_enabled: true,
-    previous_api: ":android.api.public.latest",
-    merge_annotations_dirs: ["metalava-manual"],
-    defaults_visibility: ["//frameworks/base/api"],
-    visibility: ["//frameworks/base/api"],
-}
-
-// Defaults with module APIs in the classpath (mostly from prebuilts).
-// Suitable for compiling android-non-updatable.
-stubs_defaults {
-    name: "module-classpath-stubs-defaults",
-    aidl: {
-        include_dirs: [
-            "packages/modules/Bluetooth/framework/aidl-export",
-            "packages/modules/Connectivity/framework/aidl-export",
-            "packages/modules/Media/apex/aidl/stable",
-        ],
-    },
-    libs: [
-        "art.module.public.api",
-        "sdk_module-lib_current_framework-tethering",
-        "sdk_module-lib_current_framework-connectivity-t",
-        "sdk_public_current_framework-bluetooth",
-        // There are a few classes from modules used by the core that
-        // need to be resolved by metalava. We use a prebuilt stub of the
-        // full sdk to ensure we can resolve them. If a new class gets added,
-        // the prebuilts/sdk/current needs to be updated.
-        "sdk_system_current_android",
-        // NOTE: The below can be removed once the prebuilt stub contains IKE.
-        "sdk_system_current_android.net.ipsec.ike",
-    ],
-}
-
-// Defaults for the java_sdk_libraries of unbundled jars from framework.
-// java_sdk_libraries using these defaults should also add themselves to the
-// non_updatable_modules list in frameworks/base/api/api.go
-java_defaults {
-    name: "framework-non-updatable-unbundled-defaults",
-    defaults: [
-        "framework-non-updatable-lint-defaults",
-        "non-updatable-framework-module-defaults",
-    ],
-    public: {
-        libs: ["android_module_lib_stubs_current"],
-    },
-    system: {
-        libs: ["android_module_lib_stubs_current"],
-    },
-    module_lib: {
-        libs: ["android_module_lib_stubs_current"],
-    },
-    test: {
-        libs: ["android_test_frameworks_core_stubs_current"],
-    },
-    sdk_version: "core_platform",
-    stub_only_libs: ["framework-protos"],
-    impl_only_libs: ["framework-minus-apex-headers"], // the framework, including hidden API
-    impl_library_visibility: ["//frameworks/base"],
-    defaults_visibility: ["//frameworks/base/location"],
-    plugins: ["error_prone_android_framework"],
-    errorprone: {
-        javacflags: [
-            "-Xep:AndroidFrameworkCompatChange:ERROR",
-            "-Xep:AndroidFrameworkUid:ERROR",
-        ],
-    },
-    // Include manual annotations in API txt files
-    merge_annotations_dirs: ["metalava-manual"],
-}
-
 build = [
     "AconfigFlags.bp",
     "ProtoLibraries.bp",
diff --git a/api/Android.bp b/api/Android.bp
index 6986ac0..d2e0849 100644
--- a/api/Android.bp
+++ b/api/Android.bp
@@ -262,6 +262,157 @@
     cmd: "cat $(in) | md5sum | cut -d' ' -f1 > $(out)",
 }
 
+packages_to_document = [
+    "android",
+    "dalvik",
+    "java",
+    "javax",
+    "junit",
+    "org.apache.http",
+    "org.json",
+    "org.w3c.dom",
+    "org.xml.sax",
+    "org.xmlpull",
+]
+
+// Defaults for all stubs that include the non-updatable framework. These defaults do not include
+// module symbols, so will not compile correctly on their own. Users must add module APIs to the
+// classpath (or sources) somehow.
+stubs_defaults {
+    name: "android-non-updatable-stubs-defaults",
+    srcs: [":android-non-updatable-stub-sources"],
+    sdk_version: "none",
+    system_modules: "none",
+    java_version: "1.8",
+    arg_files: [":frameworks-base-core-AndroidManifest.xml"],
+    aidl: {
+        include_dirs: [
+            "frameworks/av/aidl",
+            "frameworks/base/media/aidl",
+            "frameworks/base/telephony/java",
+            "frameworks/native/libs/permission/aidl",
+            "packages/modules/Bluetooth/framework/aidl-export",
+            "packages/modules/Connectivity/framework/aidl-export",
+            "packages/modules/Media/apex/aidl/stable",
+            "hardware/interfaces/biometrics/common/aidl",
+            "hardware/interfaces/biometrics/fingerprint/aidl",
+            "hardware/interfaces/graphics/common/aidl",
+            "hardware/interfaces/keymaster/aidl",
+            "system/hardware/interfaces/media/aidl",
+        ],
+    },
+    // These are libs from framework-internal-utils that are required (i.e. being referenced)
+    // from framework-non-updatable-sources. Add more here when there's a need.
+    // DO NOT add the entire framework-internal-utils. It might cause unnecessary circular
+    // dependencies gets bigger.
+    libs: [
+        "android.hardware.cas-V1.2-java",
+        "android.hardware.health-V1.0-java-constants",
+        "android.hardware.radio-V1.5-java",
+        "android.hardware.radio-V1.6-java",
+        "android.hardware.thermal-V1.0-java-constants",
+        "android.hardware.thermal-V2.0-java",
+        "android.hardware.tv.input-V1.0-java-constants",
+        "android.hardware.usb-V1.0-java-constants",
+        "android.hardware.usb-V1.1-java-constants",
+        "android.hardware.usb.gadget-V1.0-java",
+        "android.hardware.vibrator-V1.3-java",
+        "framework-protos",
+    ],
+    flags: [
+        "--api-lint-ignore-prefix android.icu.",
+        "--api-lint-ignore-prefix java.",
+        "--api-lint-ignore-prefix junit.",
+        "--api-lint-ignore-prefix org.",
+        "--error NoSettingsProvider",
+        "--error UnhiddenSystemApi",
+        "--error UnflaggedApi",
+        "--force-convert-to-warning-nullability-annotations +*:-android.*:+android.icu.*:-dalvik.*",
+        "--hide BroadcastBehavior",
+        "--hide CallbackInterface",
+        "--hide DeprecationMismatch",
+        "--hide HiddenSuperclass",
+        "--hide MissingPermission",
+        "--hide RequiresPermission",
+        "--hide SdkConstant",
+        "--hide Todo",
+        "--hide-package android.audio.policy.configuration.V7_0",
+        "--hide-package com.android.server",
+        "--manifest $(location :frameworks-base-core-AndroidManifest.xml)",
+    ],
+    filter_packages: packages_to_document,
+    high_mem: true, // Lots of sources => high memory use, see b/170701554
+    installable: false,
+    annotations_enabled: true,
+    previous_api: ":android.api.public.latest",
+    merge_annotations_dirs: ["metalava-manual"],
+    defaults_visibility: ["//frameworks/base/api"],
+    visibility: ["//frameworks/base/api"],
+}
+
+// Defaults with module APIs in the classpath (mostly from prebuilts).
+// Suitable for compiling android-non-updatable.
+stubs_defaults {
+    name: "module-classpath-stubs-defaults",
+    aidl: {
+        include_dirs: [
+            "packages/modules/Bluetooth/framework/aidl-export",
+            "packages/modules/Connectivity/framework/aidl-export",
+            "packages/modules/Media/apex/aidl/stable",
+        ],
+    },
+    libs: [
+        "art.module.public.api",
+        "sdk_module-lib_current_framework-tethering",
+        "sdk_module-lib_current_framework-connectivity-t",
+        "sdk_public_current_framework-bluetooth",
+        // There are a few classes from modules used by the core that
+        // need to be resolved by metalava. We use a prebuilt stub of the
+        // full sdk to ensure we can resolve them. If a new class gets added,
+        // the prebuilts/sdk/current needs to be updated.
+        "sdk_system_current_android",
+        // NOTE: The below can be removed once the prebuilt stub contains IKE.
+        "sdk_system_current_android.net.ipsec.ike",
+    ],
+}
+
+// Defaults for the java_sdk_libraries of unbundled jars from framework.
+// java_sdk_libraries using these defaults should also add themselves to the
+// non_updatable_modules list in frameworks/base/api/api.go
+java_defaults {
+    name: "framework-non-updatable-unbundled-defaults",
+    defaults: [
+        "framework-non-updatable-lint-defaults",
+        "non-updatable-framework-module-defaults",
+    ],
+    public: {
+        libs: ["android_module_lib_stubs_current"],
+    },
+    system: {
+        libs: ["android_module_lib_stubs_current"],
+    },
+    module_lib: {
+        libs: ["android_module_lib_stubs_current"],
+    },
+    test: {
+        libs: ["android_test_frameworks_core_stubs_current"],
+    },
+    sdk_version: "core_platform",
+    stub_only_libs: ["framework-protos"],
+    impl_only_libs: ["framework-minus-apex-headers"], // the framework, including hidden API
+    impl_library_visibility: ["//frameworks/base"],
+    defaults_visibility: ["//frameworks/base/location"],
+    plugins: ["error_prone_android_framework"],
+    errorprone: {
+        javacflags: [
+            "-Xep:AndroidFrameworkCompatChange:ERROR",
+            "-Xep:AndroidFrameworkUid:ERROR",
+        ],
+    },
+    // Include manual annotations in API txt files
+    merge_annotations_dirs: ["metalava-manual"],
+}
+
 build = [
     "ApiDocs.bp",
     "StubLibraries.bp",
diff --git a/core/java/android/app/OWNERS b/core/java/android/app/OWNERS
index e1c45d9..164bdbe 100644
--- a/core/java/android/app/OWNERS
+++ b/core/java/android/app/OWNERS
@@ -36,6 +36,7 @@
 per-file GameState* = file:/GAME_MANAGER_OWNERS
 per-file IGameManager* = file:/GAME_MANAGER_OWNERS
 per-file IGameMode* = file:/GAME_MANAGER_OWNERS
+per-file BackgroundStartPrivileges.java = file:/BAL_OWNERS
 
 # ActivityThread
 per-file ActivityThread.java = file:/services/core/java/com/android/server/am/OWNERS
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index c3fd744..0fd0e15 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -1161,6 +1161,11 @@
      * numbers.  Applications can <strong>dial</strong> emergency numbers using
      * {@link #ACTION_DIAL}, however.
      *
+     * <p>Note: This Intent can only be used to dial call forwarding MMI codes if the application
+     * using this intent is set as the default or system dialer. The system will treat any other
+     * application using this Intent for the purpose of dialing call forwarding MMI codes as if the
+     * {@link #ACTION_DIAL} Intent was used instead.
+     *
      * <p>Note: An app filling the {@link android.app.role.RoleManager#ROLE_DIALER} role should use
      * {@link android.telecom.TelecomManager#placeCall(Uri, Bundle)} to place calls rather than
      * relying on this intent.
diff --git a/core/java/android/window/flags/OWNERS b/core/java/android/window/flags/OWNERS
new file mode 100644
index 0000000..fa81ee3
--- /dev/null
+++ b/core/java/android/window/flags/OWNERS
@@ -0,0 +1 @@
+per-file responsible_apis.aconfig = file:/BAL_OWNERS
\ No newline at end of file
diff --git a/keystore/java/android/security/keystore/KeyGenParameterSpec.java b/keystore/java/android/security/keystore/KeyGenParameterSpec.java
index 1ba41b1..b714035 100644
--- a/keystore/java/android/security/keystore/KeyGenParameterSpec.java
+++ b/keystore/java/android/security/keystore/KeyGenParameterSpec.java
@@ -1596,6 +1596,8 @@
          * {@link #getAttestationChallenge()} returns non-null and the spec is used to generate a
          * symmetric (AES or HMAC) key, {@link javax.crypto.KeyGenerator#generateKey()} will throw
          * {@link java.security.InvalidAlgorithmParameterException}.
+         *
+         * <p>The challenge may be up to 128 bytes.
          */
         @NonNull
         public Builder setAttestationChallenge(byte[] attestationChallenge) {
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index 9a0e47d..eba9bf6 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -1637,8 +1637,8 @@
             return false;
         }
 
-        if (!StorageManager.isUserKeyUnlocked(mCurrentUser)) {
-            // Can't launch home on secondary display areas if device is still locked.
+        if (!StorageManager.isCeStorageUnlocked(mCurrentUser)) {
+            // Can't launch home on secondary display areas if CE storage is still locked.
             return false;
         }
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
index 3bc6450..b92cc64 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
@@ -870,7 +870,7 @@
                 new TestDisplayContent.Builder(mAtm, 1000, 1500)
                         .setSystemDecorations(true).build();
 
-        // Use invalid user id to let StorageManager.isUserKeyUnlocked() return false.
+        // Use invalid user id to let StorageManager.isCeStorageUnlocked() return false.
         final int currentUser = mRootWindowContainer.mCurrentUser;
         mRootWindowContainer.mCurrentUser = -1;
 
diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java
index a72f780..89ef523 100644
--- a/telecomm/java/android/telecom/TelecomManager.java
+++ b/telecomm/java/android/telecom/TelecomManager.java
@@ -2352,6 +2352,11 @@
      * <p>
      * <b>Note</b>: {@link android.app.Notification.CallStyle} notifications should be posted after
      * the call is placed in order for the notification to be non-dismissible.
+     * <p><b>Note</b>: Call Forwarding MMI codes can only be dialed by applications that are
+     * configured as the user defined default dialer or system dialer role. If a call containing a
+     * call forwarding MMI code is placed by an application that is not in one of these roles, the
+     * dialer will be launched with a UI showing the MMI code already populated so that the user can
+     * confirm the action before the call is placed.
      * @param address The address to make the call to.
      * @param extras Bundle of extras to use with the call.
      */
diff --git a/tools/lint/global/checks/src/main/java/com/google/android/lint/AndroidGlobalIssueRegistry.kt b/tools/lint/global/checks/src/main/java/com/google/android/lint/AndroidGlobalIssueRegistry.kt
index a20266a..28eab8f 100644
--- a/tools/lint/global/checks/src/main/java/com/google/android/lint/AndroidGlobalIssueRegistry.kt
+++ b/tools/lint/global/checks/src/main/java/com/google/android/lint/AndroidGlobalIssueRegistry.kt
@@ -20,7 +20,6 @@
 import com.android.tools.lint.client.api.Vendor
 import com.android.tools.lint.detector.api.CURRENT_API
 import com.google.android.lint.aidl.EnforcePermissionDetector
-import com.google.android.lint.aidl.EnforcePermissionHelperDetector
 import com.google.android.lint.aidl.SimpleManualPermissionEnforcementDetector
 import com.google.auto.service.AutoService
 
@@ -30,7 +29,8 @@
     override val issues = listOf(
             EnforcePermissionDetector.ISSUE_MISSING_ENFORCE_PERMISSION,
             EnforcePermissionDetector.ISSUE_MISMATCHING_ENFORCE_PERMISSION,
-            EnforcePermissionHelperDetector.ISSUE_ENFORCE_PERMISSION_HELPER,
+            EnforcePermissionDetector.ISSUE_ENFORCE_PERMISSION_HELPER,
+            EnforcePermissionDetector.ISSUE_MISUSING_ENFORCE_PERMISSION,
             SimpleManualPermissionEnforcementDetector.ISSUE_SIMPLE_MANUAL_PERMISSION_ENFORCEMENT,
     )
 
@@ -45,4 +45,4 @@
             feedbackUrl = "http://b/issues/new?component=315013",
             contact = "repsonsible-apis@google.com"
     )
-}
\ No newline at end of file
+}
diff --git a/tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/EnforcePermissionDetector.kt b/tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/EnforcePermissionDetector.kt
index 0baac2c..a74400d 100644
--- a/tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/EnforcePermissionDetector.kt
+++ b/tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/EnforcePermissionDetector.kt
@@ -30,29 +30,34 @@
 import com.android.tools.lint.detector.api.Scope
 import com.android.tools.lint.detector.api.Severity
 import com.android.tools.lint.detector.api.SourceCodeScanner
+import com.google.android.lint.findCallExpression
 import com.intellij.psi.PsiAnnotation
 import com.intellij.psi.PsiArrayInitializerMemberValue
 import com.intellij.psi.PsiClass
 import com.intellij.psi.PsiElement
 import com.intellij.psi.PsiMethod
-import org.jetbrains.uast.UAnnotation
+import org.jetbrains.uast.UBlockExpression
+import org.jetbrains.uast.UDeclarationsExpression
 import org.jetbrains.uast.UElement
+import org.jetbrains.uast.UExpression
 import org.jetbrains.uast.UMethod
-import org.jetbrains.uast.toUElement
+import org.jetbrains.uast.skipParenthesizedExprDown
+
+import java.util.EnumSet
 
 /**
- * Lint Detector that ensures that any method overriding a method annotated
- * with @EnforcePermission is also annotated with the exact same annotation.
- * The intent is to surface the effective permission checks to the service
- * implementations.
+ * Lint Detector that ensures consistency when using the @EnforcePermission
+ * annotation. Multiple verifications are implemented:
  *
- * This is done with 2 mechanisms:
  *  1. Visit any annotation usage, to ensure that any derived class will have
- *     the correct annotation on each methods. This is for the top to bottom
- *     propagation.
- *  2. Visit any annotation, to ensure that if a method is annotated, it has
+ *     the correct annotation on each methods. Even if the subclass does not
+ *     have the annotation, visitAnnotationUsage will be called which allows us
+ *     to capture the issue.
+ *  2. Visit any method, to ensure that if a method is annotated, it has
  *     its ancestor also annotated. This is to avoid having an annotation on a
  *     Java method without the corresponding annotation on the AIDL interface.
+ *  3. When annotated, ensures that the first instruction is to call the helper
+ *     method (or the parent helper).
  */
 class EnforcePermissionDetector : Detector(), SourceCodeScanner {
 
@@ -60,9 +65,8 @@
         return listOf(ANNOTATION_ENFORCE_PERMISSION)
     }
 
-    override fun getApplicableUastTypes(): List<Class<out UElement>> {
-        return listOf(UAnnotation::class.java)
-    }
+    override fun getApplicableUastTypes(): List<Class<out UElement?>> =
+            listOf(UMethod::class.java)
 
     private fun annotationValueGetChildren(elem: PsiElement): Array<PsiElement> {
         if (elem is PsiArrayInitializerMemberValue)
@@ -121,11 +125,6 @@
         overriddenMethod: PsiMethod,
         checkEquivalence: Boolean = true
     ) {
-        // If method is not from a Stub subclass, this method shouldn't use @EP at all.
-        // This is handled by EnforcePermissionHelperDetector.
-        if (!isContainedInSubclassOfStub(context, overridingMethod.toUElement() as? UMethod)) {
-            return
-        }
         val overridingAnnotation = overridingMethod.getAnnotation(ANNOTATION_ENFORCE_PERMISSION)
         val overriddenAnnotation = overriddenMethod.getAnnotation(ANNOTATION_ENFORCE_PERMISSION)
         val location = context.getLocation(element)
@@ -161,40 +160,102 @@
     ) {
         if (usageInfo.type == AnnotationUsageType.METHOD_OVERRIDE &&
             annotationInfo.origin == AnnotationOrigin.METHOD) {
+            /* Ignore implementations that are not a sub-class of Stub (i.e., Proxy). */
+            val uMethod = element as? UMethod ?: return
+            if (!isContainedInSubclassOfStub(context, uMethod)) {
+                return
+            }
             val overridingMethod = element.sourcePsi as PsiMethod
             val overriddenMethod = usageInfo.referenced as PsiMethod
             compareMethods(context, element, overridingMethod, overriddenMethod)
         }
     }
 
-    override fun createUastHandler(context: JavaContext): UElementHandler {
-        return object : UElementHandler() {
-            override fun visitAnnotation(node: UAnnotation) {
-                if (node.qualifiedName != ANNOTATION_ENFORCE_PERMISSION) {
-                    return
-                }
-                val method = node.uastParent as? UMethod ?: return
-                val overridingMethod = method as PsiMethod
-                val parents = overridingMethod.findSuperMethods()
-                for (overriddenMethod in parents) {
-                    // The equivalence check can be skipped, if both methods are
-                    // annotated, it will be verified by visitAnnotationUsage.
-                    compareMethods(context, method, overridingMethod,
-                        overriddenMethod, checkEquivalence = false)
-                }
+    override fun createUastHandler(context: JavaContext): UElementHandler = AidlStubHandler(context)
+
+    private inner class AidlStubHandler(val context: JavaContext) : UElementHandler() {
+        override fun visitMethod(node: UMethod) {
+            if (context.evaluator.isAbstract(node)) return
+            if (!node.hasAnnotation(ANNOTATION_ENFORCE_PERMISSION)) return
+
+            if (!isContainedInSubclassOfStub(context, node)) {
+                context.report(
+                    ISSUE_MISUSING_ENFORCE_PERMISSION,
+                    node,
+                    context.getLocation(node),
+                    "The class of ${node.name} does not inherit from an AIDL generated Stub class"
+                )
+                return
+            }
+
+            /* Check that we are connected to the super class */
+            val overridingMethod = node as PsiMethod
+            val parents = overridingMethod.findSuperMethods()
+            for (overriddenMethod in parents) {
+                // The equivalence check can be skipped, if both methods are
+                // annotated, it will be verified by visitAnnotationUsage.
+                compareMethods(context, node, overridingMethod,
+                    overriddenMethod, checkEquivalence = false)
+            }
+
+            /* Check that the helper is called as a first instruction */
+            val targetExpression = getHelperMethodCallSourceString(node)
+            val message =
+                "Method must start with $targetExpression or super.${node.name}(), if applicable"
+
+            val firstExpression = (node.uastBody as? UBlockExpression)
+                    ?.expressions?.firstOrNull()
+
+            if (firstExpression == null) {
+                context.report(
+                    ISSUE_ENFORCE_PERMISSION_HELPER,
+                    context.getLocation(node),
+                    message,
+                )
+                return
+            }
+
+            val firstExpressionSource = firstExpression.skipParenthesizedExprDown()
+              .asSourceString()
+              .filterNot(Char::isWhitespace)
+
+            if (firstExpressionSource != targetExpression &&
+                  firstExpressionSource != "super.$targetExpression") {
+                // calling super.<methodName>() is also legal
+                val directSuper = context.evaluator.getSuperMethod(node)
+                val firstCall = findCallExpression(firstExpression)?.resolve()
+                if (directSuper != null && firstCall == directSuper) return
+
+                val locationTarget = getLocationTarget(firstExpression)
+                val expressionLocation = context.getLocation(locationTarget)
+
+                context.report(
+                    ISSUE_ENFORCE_PERMISSION_HELPER,
+                    context.getLocation(node),
+                    message,
+                    getHelperMethodFix(node, expressionLocation),
+                )
             }
         }
     }
 
     companion object {
+
+        private const val HELPER_SUFFIX = "_enforcePermission"
+
         val EXPLANATION = """
-            The @EnforcePermission annotation is used to indicate that the underlying binder code
-            has already verified the caller's permissions before calling the appropriate method. The
-            verification code is usually generated by the AIDL compiler, which also takes care of
-            annotating the generated Java code.
+            The @EnforcePermission annotation is used to delegate the verification of the caller's
+            permissions to a generated AIDL method.
 
             In order to surface that information to platform developers, the same annotation must be
             used on the implementation class or methods.
+
+            The @EnforcePermission annotation can only be used on methods whose class extends from
+            the Stub class generated by the AIDL compiler. When @EnforcePermission is applied, the
+            AIDL compiler generates a Stub method to do the permission check called yourMethodName$HELPER_SUFFIX.
+
+            yourMethodName$HELPER_SUFFIX must be executed before any other operation. To do that, you can
+            either call it directly, or call it indirectly via super.yourMethodName().
             """
 
         val ISSUE_MISSING_ENFORCE_PERMISSION: Issue = Issue.create(
@@ -206,7 +267,7 @@
             severity = Severity.ERROR,
             implementation = Implementation(
                     EnforcePermissionDetector::class.java,
-                    Scope.JAVA_FILE_SCOPE
+                    EnumSet.of(Scope.JAVA_FILE, Scope.TEST_SOURCES)
             )
         )
 
@@ -219,8 +280,47 @@
             severity = Severity.ERROR,
             implementation = Implementation(
                     EnforcePermissionDetector::class.java,
-                    Scope.JAVA_FILE_SCOPE
+                    EnumSet.of(Scope.JAVA_FILE, Scope.TEST_SOURCES)
             )
         )
+
+        val ISSUE_ENFORCE_PERMISSION_HELPER: Issue = Issue.create(
+            id = "MissingEnforcePermissionHelper",
+            briefDescription = """Missing permission-enforcing method call in AIDL method
+                |annotated with @EnforcePermission""".trimMargin(),
+            explanation = EXPLANATION,
+            category = Category.SECURITY,
+            priority = 6,
+            severity = Severity.ERROR,
+            implementation = Implementation(
+                    EnforcePermissionDetector::class.java,
+                    EnumSet.of(Scope.JAVA_FILE, Scope.TEST_SOURCES)
+            )
+        )
+
+        val ISSUE_MISUSING_ENFORCE_PERMISSION: Issue = Issue.create(
+            id = "MisusingEnforcePermissionAnnotation",
+            briefDescription = "@EnforcePermission cannot be used here",
+            explanation = EXPLANATION,
+            category = Category.SECURITY,
+            priority = 6,
+            severity = Severity.ERROR,
+            implementation = Implementation(
+                    EnforcePermissionDetector::class.java,
+                    EnumSet.of(Scope.JAVA_FILE, Scope.TEST_SOURCES)
+            )
+        )
+
+        /**
+         * handles an edge case with UDeclarationsExpression, where sourcePsi is null,
+         * resulting in an incorrect Location if used directly
+         */
+        private fun getLocationTarget(firstExpression: UExpression): PsiElement? {
+            if (firstExpression.sourcePsi != null) return firstExpression.sourcePsi
+            if (firstExpression is UDeclarationsExpression) {
+                return firstExpression.declarations.firstOrNull()?.sourcePsi
+            }
+            return null
+        }
     }
 }
diff --git a/tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/EnforcePermissionHelperDetector.kt b/tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/EnforcePermissionHelperDetector.kt
deleted file mode 100644
index df13af5..0000000
--- a/tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/EnforcePermissionHelperDetector.kt
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.android.lint.aidl
-
-import com.android.tools.lint.client.api.UElementHandler
-import com.android.tools.lint.detector.api.Category
-import com.android.tools.lint.detector.api.Detector
-import com.android.tools.lint.detector.api.Implementation
-import com.android.tools.lint.detector.api.Issue
-import com.android.tools.lint.detector.api.JavaContext
-import com.android.tools.lint.detector.api.Scope
-import com.android.tools.lint.detector.api.Severity
-import com.android.tools.lint.detector.api.SourceCodeScanner
-import com.google.android.lint.findCallExpression
-import com.intellij.psi.PsiElement
-import org.jetbrains.uast.UBlockExpression
-import org.jetbrains.uast.UDeclarationsExpression
-import org.jetbrains.uast.UElement
-import org.jetbrains.uast.UExpression
-import org.jetbrains.uast.UMethod
-import org.jetbrains.uast.skipParenthesizedExprDown
-
-class EnforcePermissionHelperDetector : Detector(), SourceCodeScanner {
-    override fun getApplicableUastTypes(): List<Class<out UElement?>> =
-            listOf(UMethod::class.java)
-
-    override fun createUastHandler(context: JavaContext): UElementHandler = AidlStubHandler(context)
-
-    private inner class AidlStubHandler(val context: JavaContext) : UElementHandler() {
-        override fun visitMethod(node: UMethod) {
-            if (context.evaluator.isAbstract(node)) return
-            if (!node.hasAnnotation(ANNOTATION_ENFORCE_PERMISSION)) return
-
-            if (!isContainedInSubclassOfStub(context, node)) {
-                context.report(
-                    ISSUE_MISUSING_ENFORCE_PERMISSION,
-                    node,
-                    context.getLocation(node),
-                    "The class of ${node.name} does not inherit from an AIDL generated Stub class"
-                )
-                return
-            }
-
-            val targetExpression = getHelperMethodCallSourceString(node)
-            val message =
-                "Method must start with $targetExpression or super.${node.name}(), if applicable"
-
-            val firstExpression = (node.uastBody as? UBlockExpression)
-                    ?.expressions?.firstOrNull()
-
-            if (firstExpression == null) {
-                context.report(
-                    ISSUE_ENFORCE_PERMISSION_HELPER,
-                    context.getLocation(node),
-                    message,
-                )
-                return
-            }
-
-            val firstExpressionSource = firstExpression.skipParenthesizedExprDown()
-              .asSourceString()
-              .filterNot(Char::isWhitespace)
-
-            if (firstExpressionSource != targetExpression &&
-                  firstExpressionSource != "super.$targetExpression") {
-                // calling super.<methodName>() is also legal
-                val directSuper = context.evaluator.getSuperMethod(node)
-                val firstCall = findCallExpression(firstExpression)?.resolve()
-                if (directSuper != null && firstCall == directSuper) return
-
-                val locationTarget = getLocationTarget(firstExpression)
-                val expressionLocation = context.getLocation(locationTarget)
-
-                context.report(
-                    ISSUE_ENFORCE_PERMISSION_HELPER,
-                    context.getLocation(node),
-                    message,
-                    getHelperMethodFix(node, expressionLocation),
-                )
-            }
-        }
-    }
-
-    companion object {
-        private const val HELPER_SUFFIX = "_enforcePermission"
-
-        private const val EXPLANATION = """
-            The @EnforcePermission annotation can only be used on methods whose class extends from
-            the Stub class generated by the AIDL compiler. When @EnforcePermission is applied, the
-            AIDL compiler generates a Stub method to do the permission check called yourMethodName$HELPER_SUFFIX.
-
-            yourMethodName$HELPER_SUFFIX must be executed before any other operation. To do that, you can
-            either call it directly, or call it indirectly via super.yourMethodName().
-            """
-
-        val ISSUE_ENFORCE_PERMISSION_HELPER: Issue = Issue.create(
-                id = "MissingEnforcePermissionHelper",
-                briefDescription = """Missing permission-enforcing method call in AIDL method
-                    |annotated with @EnforcePermission""".trimMargin(),
-                explanation = EXPLANATION,
-                category = Category.SECURITY,
-                priority = 6,
-                severity = Severity.ERROR,
-                implementation = Implementation(
-                        EnforcePermissionHelperDetector::class.java,
-                        Scope.JAVA_FILE_SCOPE
-                )
-        )
-
-        val ISSUE_MISUSING_ENFORCE_PERMISSION: Issue = Issue.create(
-                id = "MisusingEnforcePermissionAnnotation",
-                briefDescription = "@EnforcePermission cannot be used here",
-                explanation = EXPLANATION,
-                category = Category.SECURITY,
-                priority = 6,
-                severity = Severity.ERROR,
-                implementation = Implementation(
-                        EnforcePermissionDetector::class.java,
-                        Scope.JAVA_FILE_SCOPE
-                )
-        )
-
-        /**
-         * handles an edge case with UDeclarationsExpression, where sourcePsi is null,
-         * resulting in an incorrect Location if used directly
-         */
-        private fun getLocationTarget(firstExpression: UExpression): PsiElement? {
-            if (firstExpression.sourcePsi != null) return firstExpression.sourcePsi
-            if (firstExpression is UDeclarationsExpression) {
-                return firstExpression.declarations.firstOrNull()?.sourcePsi
-            }
-            return null
-        }
-    }
-}
diff --git a/tools/lint/global/checks/src/test/java/com/google/android/lint/aidl/EnforcePermissionHelperDetectorCodegenTest.kt b/tools/lint/global/checks/src/test/java/com/google/android/lint/aidl/EnforcePermissionHelperDetectorCodegenTest.kt
index 5a63bb4..3ef02f8 100644
--- a/tools/lint/global/checks/src/test/java/com/google/android/lint/aidl/EnforcePermissionHelperDetectorCodegenTest.kt
+++ b/tools/lint/global/checks/src/test/java/com/google/android/lint/aidl/EnforcePermissionHelperDetectorCodegenTest.kt
@@ -25,10 +25,10 @@
 
 @Suppress("UnstableApiUsage")
 class EnforcePermissionHelperDetectorCodegenTest : LintDetectorTest() {
-    override fun getDetector(): Detector = EnforcePermissionHelperDetector()
+    override fun getDetector(): Detector = EnforcePermissionDetector()
 
     override fun getIssues(): List<Issue> = listOf(
-            EnforcePermissionHelperDetector.ISSUE_ENFORCE_PERMISSION_HELPER
+            EnforcePermissionDetector.ISSUE_ENFORCE_PERMISSION_HELPER
     )
 
     override fun lint(): TestLintTask = super.lint().allowMissingSdk(true)
diff --git a/tools/lint/global/checks/src/test/java/com/google/android/lint/aidl/EnforcePermissionHelperDetectorTest.kt b/tools/lint/global/checks/src/test/java/com/google/android/lint/aidl/EnforcePermissionHelperDetectorTest.kt
index 10a6e1d..64e2bfb 100644
--- a/tools/lint/global/checks/src/test/java/com/google/android/lint/aidl/EnforcePermissionHelperDetectorTest.kt
+++ b/tools/lint/global/checks/src/test/java/com/google/android/lint/aidl/EnforcePermissionHelperDetectorTest.kt
@@ -20,10 +20,10 @@
 import com.android.tools.lint.checks.infrastructure.TestLintTask
 
 class EnforcePermissionHelperDetectorTest : LintDetectorTest() {
-    override fun getDetector() = EnforcePermissionHelperDetector()
+    override fun getDetector() = EnforcePermissionDetector()
     override fun getIssues() = listOf(
-        EnforcePermissionHelperDetector.ISSUE_ENFORCE_PERMISSION_HELPER,
-        EnforcePermissionHelperDetector.ISSUE_MISUSING_ENFORCE_PERMISSION
+        EnforcePermissionDetector.ISSUE_ENFORCE_PERMISSION_HELPER,
+        EnforcePermissionDetector.ISSUE_MISUSING_ENFORCE_PERMISSION
     )
 
     override fun lint(): TestLintTask = super.lint().allowMissingSdk()