diff options
17 files changed, 272 insertions, 106 deletions
diff --git a/api/Android.bp b/api/Android.bp index d2e0849ed946..15b10a6a5966 100644 --- a/api/Android.bp +++ b/api/Android.bp @@ -350,6 +350,16 @@ stubs_defaults { visibility: ["//frameworks/base/api"], } +// We resolve dependencies on APIs in modules by depending on a prebuilt of the whole +// platform (sdk_system_current_android). That prebuilt does not include module-lib APIs, +// so use the prebuilt module-lib stubs for modules that export module-lib stubs that the +// non-updatable part depends on. +non_updatable_api_deps_on_modules = [ + "sdk_module-lib_current_framework-tethering", + "sdk_module-lib_current_framework-connectivity-t", + "sdk_system_current_android", +] + // Defaults with module APIs in the classpath (mostly from prebuilts). // Suitable for compiling android-non-updatable. stubs_defaults { @@ -361,19 +371,7 @@ stubs_defaults { "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", - ], + libs: non_updatable_api_deps_on_modules, } // Defaults for the java_sdk_libraries of unbundled jars from framework. diff --git a/api/StubLibraries.bp b/api/StubLibraries.bp index 5688b968db87..f6f69291ce0e 100644 --- a/api/StubLibraries.bp +++ b/api/StubLibraries.bp @@ -351,17 +351,7 @@ java_library { "android-non-updatable_from_source_defaults", ], srcs: [":module-lib-api-stubs-docs-non-updatable"], - libs: [ - // We cannot depend on all-modules-module-lib-stubs, because the module-lib stubs - // depend on this stub. We resolve dependencies on APIs in modules by depending - // on a prebuilt of the whole platform (sdk_system_current_android). - // That prebuilt does not include module-lib APIs, so use the prebuilt module-lib - // stubs for modules that export module-lib stubs that the non-updatable part - // depends on. - "sdk_module-lib_current_framework-tethering", - "sdk_module-lib_current_framework-connectivity-t", - "sdk_system_current_android", - ], + libs: non_updatable_api_deps_on_modules, dist: { dir: "apistubs/android/module-lib", }, diff --git a/core/java/android/content/AttributionSource.java b/core/java/android/content/AttributionSource.java index cd45f4df3d50..b4f4a7efad98 100644 --- a/core/java/android/content/AttributionSource.java +++ b/core/java/android/content/AttributionSource.java @@ -212,6 +212,11 @@ public final class AttributionSource implements Parcelable { } /** @hide */ + public AttributionSource withDefaultToken() { + return withToken(sDefaultToken); + } + + /** @hide */ public AttributionSource withPid(int pid) { return new AttributionSource(getUid(), pid, getPackageName(), getAttributionTag(), getToken(), mAttributionSourceState.renouncedPermissions, getNext()); @@ -520,16 +525,28 @@ public final class AttributionSource implements Parcelable { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; AttributionSource that = (AttributionSource) o; - return mAttributionSourceState.uid == that.mAttributionSourceState.uid + return equalsExceptToken(that) && Objects.equals( + mAttributionSourceState.token, that.mAttributionSourceState.token); + } + + /** + * We store trusted attribution sources without their token (the token is the key to the map) + * to avoid having a strong reference to the token. This means, when checking the equality of a + * supplied AttributionSource in PermissionManagerService.isTrustedAttributionSource, we want to + * compare everything except the token. + * + * @hide + */ + public boolean equalsExceptToken(@Nullable AttributionSource o) { + if (o == null) return false; + return mAttributionSourceState.uid == o.mAttributionSourceState.uid && Objects.equals(mAttributionSourceState.packageName, - that.mAttributionSourceState.packageName) + o.mAttributionSourceState.packageName) && Objects.equals(mAttributionSourceState.attributionTag, - that.mAttributionSourceState.attributionTag) - && Objects.equals(mAttributionSourceState.token, - that.mAttributionSourceState.token) + o.mAttributionSourceState.attributionTag) && Arrays.equals(mAttributionSourceState.renouncedPermissions, - that.mAttributionSourceState.renouncedPermissions) - && Objects.equals(getNext(), that.getNext()); + o.mAttributionSourceState.renouncedPermissions) + && Objects.equals(getNext(), o.getNext()); } @Override diff --git a/core/java/android/preference/OWNERS b/core/java/android/preference/OWNERS index 827134e8fc9d..b4cb9ec7ceda 100644 --- a/core/java/android/preference/OWNERS +++ b/core/java/android/preference/OWNERS @@ -1,3 +1,5 @@ lpf@google.com pavlis@google.com clarabayarri@google.com + +per-file SeekBarVolumizer.java = jmtrivi@google.com
\ No newline at end of file diff --git a/core/java/android/view/OWNERS b/core/java/android/view/OWNERS index 42ac74ce7353..ad326e41a146 100644 --- a/core/java/android/view/OWNERS +++ b/core/java/android/view/OWNERS @@ -11,6 +11,7 @@ jjaggi@google.com roosa@google.com jreck@google.com siyamed@google.com +mount@google.com # Autofill per-file ViewStructure.java = file:/core/java/android/service/autofill/OWNERS diff --git a/core/res/res/xml/sms_short_codes.xml b/core/res/res/xml/sms_short_codes.xml index 3a2e50aa06e8..709646b00e5c 100644 --- a/core/res/res/xml/sms_short_codes.xml +++ b/core/res/res/xml/sms_short_codes.xml @@ -34,7 +34,7 @@ http://smscoin.net/software/engine/WordPress/Paid+SMS-registration/ --> <!-- Arab Emirates --> - <shortcode country="ae" pattern="\\d{1,5}" free="1017|1355|3214" /> + <shortcode country="ae" pattern="\\d{1,5}" free="1017|1355|3214|6253" /> <!-- Albania: 5 digits, known short codes listed --> <shortcode country="al" pattern="\\d{5}" premium="15191|55[56]00" /> @@ -155,7 +155,7 @@ <shortcode country="ie" pattern="\\d{5}" premium="5[3-9]\\d{3}" free="50\\d{3}|116\\d{3}" standard="5[12]\\d{3}" /> <!-- Israel: 4 digits, known premium codes listed --> - <shortcode country="il" pattern="\\d{4}" premium="4422|4545" /> + <shortcode country="il" pattern="\\d{1,5}" premium="4422|4545" free="37477" /> <!-- Italy: 5 digits (premium=41xxx,42xxx), plus EU: https://www.itu.int/dms_pub/itu-t/oth/02/02/T020200006B0001PDFE.pdf --> @@ -198,6 +198,9 @@ <!-- Malaysia: 5 digits: http://www.skmm.gov.my/attachment/Consumer_Regulation/Mobile_Content_Services_FAQs.pdf --> <shortcode country="my" pattern="\\d{5}" premium="32298|33776" free="22099|28288|66668" /> + <!-- Namibia: 5 digits --> + <shortcode country="na" pattern="\\d{1,5}" free="40005" /> + <!-- The Netherlands, 4 digits, known premium codes listed, plus EU --> <shortcode country="nl" pattern="\\d{4}" premium="4466|5040" free="116\\d{3}|2223|6225|2223|1662" /> diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java index 297ad73e054b..c24d5236f4f7 100644 --- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java +++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java @@ -1001,7 +1001,9 @@ public class PermissionManagerService extends IPermissionManager.Stub { } synchronized (mLock) { - mAttributions.put(source.getToken(), source); + // Change the token for the AttributionSource we're storing, so that we don't store + // a strong reference to the original token inside the map itself. + mAttributions.put(source.getToken(), source.withDefaultToken()); } } @@ -1009,7 +1011,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { synchronized (mLock) { final AttributionSource cachedSource = mAttributions.get(source.getToken()); if (cachedSource != null) { - return cachedSource.equals(source); + return cachedSource.equalsExceptToken(source); } return false; } diff --git a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java index 9128974fa9d3..76ee84571b04 100644 --- a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java +++ b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java @@ -1281,12 +1281,19 @@ public class StatsPullAtomService extends SystemService { private void addBytesTransferByTagAndMeteredAtoms(@NonNull NetworkStatsExt statsExt, @NonNull List<StatsEvent> pulledData) { + // Workaround for 5G NSA mode, see {@link NetworkStatsManager#NETWORK_TYPE_5G_NSA}. + // 5G NSA mode means the primary cell is LTE with a secondary connection to an + // NR cell. To mitigate risk, NetworkStats is currently storing this state as + // a fake RAT type rather than storing the boolean separately. + final boolean is5GNsa = statsExt.ratType == NetworkStatsManager.NETWORK_TYPE_5G_NSA; + for (NetworkStats.Entry entry : statsExt.stats) { pulledData.add(FrameworkStatsLog.buildStatsEvent( FrameworkStatsLog.BYTES_TRANSFER_BY_TAG_AND_METERED, entry.getUid(), entry.getMetered() == NetworkStats.METERED_YES, entry.getTag(), entry.getRxBytes(), entry.getRxPackets(), entry.getTxBytes(), - entry.getTxPackets())); + entry.getTxPackets(), + is5GNsa ? TelephonyManager.NETWORK_TYPE_LTE : statsExt.ratType)); } } diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index 18a6254ca115..82a954d4178f 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -4214,6 +4214,9 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A Slog.v(TAG_APP, "Keeping entry during removeHistory for activity " + this); } } + if (task != null && task.mKillProcessesOnDestroyed) { + mTaskSupervisor.removeTimeoutOfKillProcessesOnProcessDied(this, task); + } // upgrade transition trigger to task if this is the last activity since it means we are // closing the task. final WindowContainer trigger = remove && task != null && task.getChildCount() == 1 diff --git a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java index b34ae1930048..ecdca93ccaaa 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java +++ b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java @@ -1891,7 +1891,7 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks { // DestroyActivityItem may be called first. final ActivityRecord top = task.getTopMostActivity(); if (top != null && top.finishing && !top.mAppStopped && top.lastVisibleTime > 0 - && !task.mKillProcessesOnDestroyed) { + && !task.mKillProcessesOnDestroyed && top.hasProcess()) { task.mKillProcessesOnDestroyed = true; mHandler.sendMessageDelayed( mHandler.obtainMessage(KILL_TASK_PROCESSES_TIMEOUT_MSG, task), @@ -1901,8 +1901,26 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks { killTaskProcessesIfPossible(task); } + void removeTimeoutOfKillProcessesOnProcessDied(@NonNull ActivityRecord r, @NonNull Task task) { + if (r.packageName.equals(task.getBasePackageName())) { + task.mKillProcessesOnDestroyed = false; + mHandler.removeMessages(KILL_TASK_PROCESSES_TIMEOUT_MSG, task); + } + } + void killTaskProcessesOnDestroyedIfNeeded(Task task) { if (task == null || !task.mKillProcessesOnDestroyed) return; + final int[] numDestroyingActivities = new int[1]; + task.forAllActivities(r -> { + if (r.finishing && r.lastVisibleTime > 0 && r.attachedToProcess()) { + numDestroyingActivities[0]++; + } + }); + if (numDestroyingActivities[0] > 1) { + // Skip if there are still destroying activities. When the last activity reports + // destroyed, the number will be 1 to proceed the kill. + return; + } mHandler.removeMessages(KILL_TASK_PROCESSES_TIMEOUT_MSG, task); killTaskProcessesIfPossible(task); } @@ -2763,7 +2781,7 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks { } break; case KILL_TASK_PROCESSES_TIMEOUT_MSG: { final Task task = (Task) msg.obj; - if (task.mKillProcessesOnDestroyed) { + if (task.mKillProcessesOnDestroyed && task.hasActivity()) { Slog.i(TAG, "Destroy timeout of remove-task, attempt to kill " + task); killTaskProcessesIfPossible(task); } diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java index 0ccb0d0b2ef5..9e0d69bfdf6e 100644 --- a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java @@ -1040,14 +1040,25 @@ public class RecentTasksTest extends WindowTestsBase { // If the task has a non-stopped activity, the removal will wait for its onDestroy. final Task task = tasks.get(0); + final ActivityRecord bottom = new ActivityBuilder(mAtm).setTask(task).build(); final ActivityRecord top = new ActivityBuilder(mAtm).setTask(task).build(); - top.lastVisibleTime = 123; + bottom.lastVisibleTime = top.lastVisibleTime = 123; top.setState(ActivityRecord.State.RESUMED, "test"); mRecentTasks.removeTasksByPackageName(task.getBasePackageName(), TEST_USER_0_ID); assertTrue(task.mKillProcessesOnDestroyed); top.setState(ActivityRecord.State.DESTROYING, "test"); + bottom.destroyed("test"); + assertTrue("Wait for all destroyed", task.mKillProcessesOnDestroyed); top.destroyed("test"); - assertFalse(task.mKillProcessesOnDestroyed); + assertFalse("Consume kill", task.mKillProcessesOnDestroyed); + + // If the process is died, the state should be cleared. + final Task lastTask = tasks.get(0); + lastTask.intent.setComponent(top.mActivityComponent); + lastTask.addChild(top); + lastTask.mKillProcessesOnDestroyed = true; + top.handleAppDied(); + assertFalse(lastTask.mKillProcessesOnDestroyed); } @Test diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java index 216f45acd5bd..d722f2f1aa0c 100644 --- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java +++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java @@ -279,6 +279,7 @@ final class VoiceInteractionSessionConnection implements ServiceConnection, mFullyBound = mContext.bindServiceAsUser(mBindIntent, mFullConnection, Context.BIND_AUTO_CREATE | Context.BIND_TREAT_LIKE_ACTIVITY | Context.BIND_SCHEDULE_LIKE_TOP_APP + | Context.BIND_TREAT_LIKE_VISIBLE_FOREGROUND_SERVICE | Context.BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS, new UserHandle(mUser)); } diff --git a/tools/fonts/update_font_metadata.py b/tools/fonts/update_font_metadata.py index c07a98a1e3d2..04a552886d42 100755 --- a/tools/fonts/update_font_metadata.py +++ b/tools/fonts/update_font_metadata.py @@ -19,7 +19,7 @@ def main(): args_parser.add_argument('--revision', help='Updated font revision. Use + to update revision based on the current revision') args = args_parser.parse_args() - font = ttLib.TTFont(args.input) + font = ttLib.TTFont(args.input, recalcTimestamp=False) update_font_revision(font, args.revision) font.save(args.output) diff --git a/tools/lint/common/src/main/java/com/google/android/lint/aidl/Constants.kt b/tools/lint/common/src/main/java/com/google/android/lint/aidl/Constants.kt index e03d92ab44a0..f1727b78f135 100644 --- a/tools/lint/common/src/main/java/com/google/android/lint/aidl/Constants.kt +++ b/tools/lint/common/src/main/java/com/google/android/lint/aidl/Constants.kt @@ -30,6 +30,7 @@ const val BINDER_CLASS = "android.os.Binder" const val IINTERFACE_INTERFACE = "android.os.IInterface" const val AIDL_PERMISSION_HELPER_SUFFIX = "_enforcePermission" +const val PERMISSION_PREFIX_LITERAL = "android.permission." /** * If a non java (e.g. c++) backend is enabled, the @EnforcePermission 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 a74400d3c0b3..83b8f163abee 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 @@ -97,7 +97,7 @@ class EnforcePermissionDetector : Detector(), SourceCodeScanner { val v1 = ConstantEvaluator.evaluate(context, value1) val v2 = ConstantEvaluator.evaluate(context, value2) if (v1 != null && v2 != null) { - if (v1 != v2) { + if (v1 != v2 && !isOneShortPermissionOfOther(v1, v2)) { return false } } else { @@ -109,7 +109,7 @@ class EnforcePermissionDetector : Detector(), SourceCodeScanner { for (j in children1.indices) { val c1 = ConstantEvaluator.evaluate(context, children1[j]) val c2 = ConstantEvaluator.evaluate(context, children2[j]) - if (c1 != c2) { + if (c1 != c2 && !isOneShortPermissionOfOther(c1, c2)) { return false } } @@ -118,6 +118,12 @@ class EnforcePermissionDetector : Detector(), SourceCodeScanner { return true } + private fun isOneShortPermissionOfOther( + permission1: Any?, + permission2: Any? + ): Boolean = permission1 == (permission2 as? String)?.removePrefix(PERMISSION_PREFIX_LITERAL) || + permission2 == (permission1 as? String)?.removePrefix(PERMISSION_PREFIX_LITERAL) + private fun compareMethods( context: JavaContext, element: UElement, @@ -191,6 +197,15 @@ class EnforcePermissionDetector : Detector(), SourceCodeScanner { /* Check that we are connected to the super class */ val overridingMethod = node as PsiMethod val parents = overridingMethod.findSuperMethods() + if (parents.isEmpty()) { + context.report( + ISSUE_MISUSING_ENFORCE_PERMISSION, + node, + context.getLocation(node), + "The method ${node.name} does not override an AIDL generated method" + ) + return + } for (overriddenMethod in parents) { // The equivalence check can be skipped, if both methods are // annotated, it will be verified by visitAnnotationUsage. diff --git a/tools/lint/global/checks/src/test/java/com/google/android/lint/aidl/EnforcePermissionDetectorTest.kt b/tools/lint/global/checks/src/test/java/com/google/android/lint/aidl/EnforcePermissionDetectorTest.kt index 75b00737a168..d8afcb977594 100644 --- a/tools/lint/global/checks/src/test/java/com/google/android/lint/aidl/EnforcePermissionDetectorTest.kt +++ b/tools/lint/global/checks/src/test/java/com/google/android/lint/aidl/EnforcePermissionDetectorTest.kt @@ -28,7 +28,9 @@ class EnforcePermissionDetectorTest : LintDetectorTest() { override fun getIssues(): List<Issue> = listOf( EnforcePermissionDetector.ISSUE_MISSING_ENFORCE_PERMISSION, - EnforcePermissionDetector.ISSUE_MISMATCHING_ENFORCE_PERMISSION + EnforcePermissionDetector.ISSUE_MISMATCHING_ENFORCE_PERMISSION, + EnforcePermissionDetector.ISSUE_ENFORCE_PERMISSION_HELPER, + EnforcePermissionDetector.ISSUE_MISUSING_ENFORCE_PERMISSION ) override fun lint(): TestLintTask = super.lint().allowMissingSdk(true) @@ -41,7 +43,9 @@ class EnforcePermissionDetectorTest : LintDetectorTest() { public class TestClass2 extends IFooMethod.Stub { @Override @EnforcePermission(android.Manifest.permission.READ_PHONE_STATE) - public void testMethod() {} + public void testMethod() { + testMethod_enforcePermission(); + } } """).indented(), *stubs @@ -58,7 +62,9 @@ class EnforcePermissionDetectorTest : LintDetectorTest() { public class TestClass11 extends IFooMethod.Stub { @Override @EnforcePermission(allOf={android.Manifest.permission.INTERNET, android.Manifest.permission.READ_PHONE_STATE}) - public void testMethodAll() {} + public void testMethodAll() { + testMethodAll_enforcePermission(); + } } """).indented(), *stubs @@ -75,7 +81,10 @@ class EnforcePermissionDetectorTest : LintDetectorTest() { public class TestClass111 extends IFooMethod.Stub { @Override @EnforcePermission(allOf={"android.permission.INTERNET", android.Manifest.permission.READ_PHONE_STATE}) - public void testMethodAllLiteral() {} + public void testMethodAllLiteral() { + testMethodAllLiteral_enforcePermission(); + + } } """).indented(), *stubs @@ -92,7 +101,9 @@ class EnforcePermissionDetectorTest : LintDetectorTest() { public class TestClass12 extends IFooMethod.Stub { @Override @EnforcePermission(anyOf={android.Manifest.permission.INTERNET, android.Manifest.permission.READ_PHONE_STATE}) - public void testMethodAny() {} + public void testMethodAny() { + testMethodAny_enforcePermission(); + } } """).indented(), *stubs @@ -109,7 +120,9 @@ class EnforcePermissionDetectorTest : LintDetectorTest() { public class TestClass121 extends IFooMethod.Stub { @Override @EnforcePermission(anyOf={"android.permission.INTERNET", android.Manifest.permission.READ_PHONE_STATE}) - public void testMethodAnyLiteral() {} + public void testMethodAnyLiteral() { + testMethodAnyLiteral_enforcePermission(); + } } """).indented(), *stubs @@ -124,7 +137,9 @@ class EnforcePermissionDetectorTest : LintDetectorTest() { package test.pkg; public class TestClass4 extends IFooMethod.Stub { @android.annotation.EnforcePermission(android.Manifest.permission.INTERNET) - public void testMethod() {} + public void testMethod() { + testMethod_enforcePermission(); + } } """).indented(), *stubs @@ -132,21 +147,44 @@ class EnforcePermissionDetectorTest : LintDetectorTest() { .run() .expect(""" src/test/pkg/TestClass4.java:4: Error: The method TestClass4.testMethod is annotated with @android.annotation.EnforcePermission(android.Manifest.permission.INTERNET) \ - which differs from the overridden method Stub.testMethod: @android.annotation.EnforcePermission(android.Manifest.permission.READ_PHONE_STATE). \ + which differs from the overridden method IFooMethod.testMethod: @android.annotation.EnforcePermission(android.Manifest.permission.READ_PHONE_STATE). \ The same annotation must be used for both methods. [MismatchingEnforcePermissionAnnotation] - public void testMethod() {} + public void testMethod() { ~~~~~~~~~~ 1 errors, 0 warnings """.addLineContinuation()) } + fun testDetectIssuesAnnotationOnNonStubMethod() { + lint().files(java( + """ + package test.pkg; + public class TestClass42 extends IFooMethod.Stub { + @android.annotation.EnforcePermission(android.Manifest.permission.INTERNET) + public void aRegularMethodNotPartOfStub() { + } + } + """).indented(), + *stubs + ) + .run() + .expect(""" + src/test/pkg/TestClass42.java:3: Error: The method aRegularMethodNotPartOfStub does not override an AIDL generated method [MisusingEnforcePermissionAnnotation] + @android.annotation.EnforcePermission(android.Manifest.permission.INTERNET) + ^ + 1 errors, 0 warnings + """.addLineContinuation()) + } + fun testDetectIssuesEmptyAnnotationOnMethod() { lint().files(java( """ package test.pkg; public class TestClass41 extends IFooMethod.Stub { @android.annotation.EnforcePermission - public void testMethod() {} + public void testMethod() { + testMethod_enforcePermission(); + } } """).indented(), *stubs @@ -154,9 +192,9 @@ class EnforcePermissionDetectorTest : LintDetectorTest() { .run() .expect(""" src/test/pkg/TestClass41.java:4: Error: The method TestClass41.testMethod is annotated with @android.annotation.EnforcePermission \ - which differs from the overridden method Stub.testMethod: @android.annotation.EnforcePermission(android.Manifest.permission.READ_PHONE_STATE). \ + which differs from the overridden method IFooMethod.testMethod: @android.annotation.EnforcePermission(android.Manifest.permission.READ_PHONE_STATE). \ The same annotation must be used for both methods. [MismatchingEnforcePermissionAnnotation] - public void testMethod() {} + public void testMethod() { ~~~~~~~~~~ 1 errors, 0 warnings """.addLineContinuation()) @@ -168,7 +206,9 @@ class EnforcePermissionDetectorTest : LintDetectorTest() { package test.pkg; public class TestClass9 extends IFooMethod.Stub { @android.annotation.EnforcePermission(anyOf={android.Manifest.permission.INTERNET, android.Manifest.permission.NFC}) - public void testMethodAny() {} + public void testMethodAny() { + testMethodAny_enforcePermission(); + } } """).indented(), *stubs @@ -177,10 +217,10 @@ class EnforcePermissionDetectorTest : LintDetectorTest() { .expect(""" src/test/pkg/TestClass9.java:4: Error: The method TestClass9.testMethodAny is annotated with \ @android.annotation.EnforcePermission(anyOf={android.Manifest.permission.INTERNET, android.Manifest.permission.NFC}) \ - which differs from the overridden method Stub.testMethodAny: \ + which differs from the overridden method IFooMethod.testMethodAny: \ @android.annotation.EnforcePermission(anyOf={android.Manifest.permission.INTERNET, android.Manifest.permission.READ_PHONE_STATE}). \ The same annotation must be used for both methods. [MismatchingEnforcePermissionAnnotation] - public void testMethodAny() {} + public void testMethodAny() { ~~~~~~~~~~~~~ 1 errors, 0 warnings """.addLineContinuation()) @@ -192,7 +232,9 @@ class EnforcePermissionDetectorTest : LintDetectorTest() { package test.pkg; public class TestClass91 extends IFooMethod.Stub { @android.annotation.EnforcePermission(anyOf={"android.permission.INTERNET", "android.permissionoopsthisisatypo.READ_PHONE_STATE"}) - public void testMethodAnyLiteral() {} + public void testMethodAnyLiteral() { + testMethodAnyLiteral_enforcePermission(); + } } """).indented(), *stubs @@ -201,10 +243,10 @@ class EnforcePermissionDetectorTest : LintDetectorTest() { .expect(""" src/test/pkg/TestClass91.java:4: Error: The method TestClass91.testMethodAnyLiteral is annotated with \ @android.annotation.EnforcePermission(anyOf={"android.permission.INTERNET", "android.permissionoopsthisisatypo.READ_PHONE_STATE"}) \ - which differs from the overridden method Stub.testMethodAnyLiteral: \ + which differs from the overridden method IFooMethod.testMethodAnyLiteral: \ @android.annotation.EnforcePermission(anyOf={android.Manifest.permission.INTERNET, "android.permission.READ_PHONE_STATE"}). \ The same annotation must be used for both methods. [MismatchingEnforcePermissionAnnotation] - public void testMethodAnyLiteral() {} + public void testMethodAnyLiteral() { ~~~~~~~~~~~~~~~~~~~~ 1 errors, 0 warnings """.addLineContinuation()) @@ -216,7 +258,9 @@ class EnforcePermissionDetectorTest : LintDetectorTest() { package test.pkg; public class TestClass10 extends IFooMethod.Stub { @android.annotation.EnforcePermission(allOf={android.Manifest.permission.INTERNET, android.Manifest.permission.NFC}) - public void testMethodAll() {} + public void testMethodAll() { + testMethodAll_enforcePermission(); + } } """).indented(), *stubs @@ -225,10 +269,10 @@ class EnforcePermissionDetectorTest : LintDetectorTest() { .expect(""" src/test/pkg/TestClass10.java:4: Error: The method TestClass10.testMethodAll is annotated with \ @android.annotation.EnforcePermission(allOf={android.Manifest.permission.INTERNET, android.Manifest.permission.NFC}) \ - which differs from the overridden method Stub.testMethodAll: \ + which differs from the overridden method IFooMethod.testMethodAll: \ @android.annotation.EnforcePermission(allOf={android.Manifest.permission.INTERNET, android.Manifest.permission.READ_PHONE_STATE}). \ The same annotation must be used for both methods. [MismatchingEnforcePermissionAnnotation] - public void testMethodAll() {} + public void testMethodAll() { ~~~~~~~~~~~~~ 1 errors, 0 warnings """.addLineContinuation()) @@ -240,7 +284,9 @@ class EnforcePermissionDetectorTest : LintDetectorTest() { package test.pkg; public class TestClass101 extends IFooMethod.Stub { @android.annotation.EnforcePermission(allOf={"android.permission.INTERNET", "android.permissionoopsthisisatypo.READ_PHONE_STATE"}) - public void testMethodAllLiteral() {} + public void testMethodAllLiteral() { + testMethodAllLiteral_enforcePermission(); + } } """).indented(), *stubs @@ -249,10 +295,10 @@ class EnforcePermissionDetectorTest : LintDetectorTest() { .expect(""" src/test/pkg/TestClass101.java:4: Error: The method TestClass101.testMethodAllLiteral is annotated with \ @android.annotation.EnforcePermission(allOf={"android.permission.INTERNET", "android.permissionoopsthisisatypo.READ_PHONE_STATE"}) \ - which differs from the overridden method Stub.testMethodAllLiteral: \ + which differs from the overridden method IFooMethod.testMethodAllLiteral: \ @android.annotation.EnforcePermission(allOf={android.Manifest.permission.INTERNET, "android.permission.READ_PHONE_STATE"}). \ The same annotation must be used for both methods. [MismatchingEnforcePermissionAnnotation] - public void testMethodAllLiteral() {} + public void testMethodAllLiteral() { ~~~~~~~~~~~~~~~~~~~~ 1 errors, 0 warnings """.addLineContinuation()) @@ -263,16 +309,18 @@ class EnforcePermissionDetectorTest : LintDetectorTest() { """ package test.pkg; public class TestClass6 extends IFooMethod.Stub { - public void testMethod() {} + public void testMethod() { + testMethod_enforcePermission(); + } } """).indented(), *stubs ) .run() .expect(""" - src/test/pkg/TestClass6.java:3: Error: The method TestClass6.testMethod overrides the method Stub.testMethod which is annotated with @EnforcePermission. \ + src/test/pkg/TestClass6.java:3: Error: The method TestClass6.testMethod overrides the method IFooMethod.testMethod which is annotated with @EnforcePermission. \ The same annotation must be used on TestClass6.testMethod [MissingEnforcePermissionAnnotation] - public void testMethod() {} + public void testMethod() { ~~~~~~~~~~ 1 errors, 0 warnings """.addLineContinuation()) @@ -284,16 +332,18 @@ class EnforcePermissionDetectorTest : LintDetectorTest() { package test.pkg; public class TestClass7 extends IBar.Stub { @android.annotation.EnforcePermission(android.Manifest.permission.INTERNET) - public void testMethod() {} + public void testMethod() { + testMethod_enforcePermission(); + } } """).indented(), *stubs ) .run() .expect(""" - src/test/pkg/TestClass7.java:4: Error: The method TestClass7.testMethod overrides the method Stub.testMethod which is not annotated with @EnforcePermission. \ - The same annotation must be used on Stub.testMethod. Did you forget to annotate the AIDL definition? [MissingEnforcePermissionAnnotation] - public void testMethod() {} + src/test/pkg/TestClass7.java:4: Error: The method TestClass7.testMethod overrides the method IBar.testMethod which is not annotated with @EnforcePermission. \ + The same annotation must be used on IBar.testMethod. Did you forget to annotate the AIDL definition? [MissingEnforcePermissionAnnotation] + public void testMethod() { ~~~~~~~~~~ 1 errors, 0 warnings """.addLineContinuation()) @@ -304,7 +354,9 @@ class EnforcePermissionDetectorTest : LintDetectorTest() { """ package test.pkg; public class Default extends IFooMethod.Stub { - public void testMethod() {} + public void testMethod() { + testMethod_enforcePermission(); + } } """).indented(), *stubs @@ -313,23 +365,74 @@ class EnforcePermissionDetectorTest : LintDetectorTest() { .expect( """ src/test/pkg/Default.java:3: Error: The method Default.testMethod \ - overrides the method Stub.testMethod which is annotated with @EnforcePermission. The same annotation must be used on Default.testMethod [MissingEnforcePermissionAnnotation] - public void testMethod() {} + overrides the method IFooMethod.testMethod which is annotated with @EnforcePermission. The same annotation must be used on Default.testMethod [MissingEnforcePermissionAnnotation] + public void testMethod() { ~~~~~~~~~~ - 1 errors, 0 warnings + 1 errors, 0 warnings """.addLineContinuation() ) } - fun testDoesDetectIssuesShortStringsNotAllowed() { + fun testDoesNotDetectIssuesShortStringsAllowedInChildAndParent() { lint().files(java( """ package test.pkg; import android.annotation.EnforcePermission; public class TestClass121 extends IFooMethod.Stub { @Override + @EnforcePermission("READ_PHONE_STATE") + public void testMethod() { + testMethod_enforcePermission(); + } + @Override + @EnforcePermission(android.Manifest.permission.READ_PHONE_STATE) + public void testMethodParentShortPermission() { + testMethodParentShortPermission_enforcePermission(); + } + @Override @EnforcePermission(anyOf={"INTERNET", "READ_PHONE_STATE"}) - public void testMethodAnyLiteral() {} + public void testMethodAnyLiteral() { + testMethodAnyLiteral_enforcePermission(); + } + @Override + @EnforcePermission(anyOf={android.Manifest.permission.INTERNET, android.Manifest.permission.READ_PHONE_STATE}) + public void testMethodAnyLiteralParentsShortPermission() { + testMethodAnyLiteralParentsShortPermission_enforcePermission(); + } + } + """).indented(), + *stubs + ) + .run() + .expectClean() + } + + fun testDoesDetectIssuesWrongShortStringsInChildAndParent() { + lint().files(java( + """ + package test.pkg; + import android.annotation.EnforcePermission; + public class TestClass121 extends IFooMethod.Stub { + @Override + @EnforcePermission("READ_WRONG_PHONE_STATE") + public void testMethod() { + testMethod_enforcePermission(); + } + @Override + @EnforcePermission(android.Manifest.permission.READ_WRONG_PHONE_STATE) + public void testMethodParentShortPermission() { + testMethodParentShortPermission_enforcePermission(); + } + @Override + @EnforcePermission(anyOf={"WRONG_INTERNET", "READ_PHONE_STATE"}) + public void testMethodAnyLiteral() { + testMethodAnyLiteral_enforcePermission(); + } + @Override + @EnforcePermission(anyOf={android.Manifest.permission.INTERNET, android.Manifest.permission.READ_WRONG_PHONE_STATE}) + public void testMethodAnyLiteralParentsShortPermission() { + testMethodAnyLiteralParentsShortPermission_enforcePermission(); + } } """).indented(), *stubs @@ -337,14 +440,19 @@ class EnforcePermissionDetectorTest : LintDetectorTest() { .run() .expect( """ - src/test/pkg/TestClass121.java:6: Error: The method \ - TestClass121.testMethodAnyLiteral is annotated with @EnforcePermission(anyOf={"INTERNET", "READ_PHONE_STATE"}) \ - which differs from the overridden method Stub.testMethodAnyLiteral: \ - @android.annotation.EnforcePermission(anyOf={android.Manifest.permission.INTERNET, "android.permission.READ_PHONE_STATE"}). \ - The same annotation must be used for both methods. [MismatchingEnforcePermissionAnnotation] - public void testMethodAnyLiteral() {} - ~~~~~~~~~~~~~~~~~~~~ - 1 errors, 0 warnings + src/test/pkg/TestClass121.java:6: Error: The method TestClass121.testMethod is annotated with @EnforcePermission("READ_WRONG_PHONE_STATE") which differs from the overridden method IFooMethod.testMethod: @android.annotation.EnforcePermission(android.Manifest.permission.READ_PHONE_STATE). The same annotation must be used for both methods. [MismatchingEnforcePermissionAnnotation] + public void testMethod() { + ~~~~~~~~~~ + src/test/pkg/TestClass121.java:11: Error: The method TestClass121.testMethodParentShortPermission is annotated with @EnforcePermission(android.Manifest.permission.READ_WRONG_PHONE_STATE) which differs from the overridden method IFooMethod.testMethodParentShortPermission: @android.annotation.EnforcePermission("READ_PHONE_STATE"). The same annotation must be used for both methods. [MismatchingEnforcePermissionAnnotation] + public void testMethodParentShortPermission() { + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + src/test/pkg/TestClass121.java:16: Error: The method TestClass121.testMethodAnyLiteral is annotated with @EnforcePermission(anyOf={"WRONG_INTERNET", "READ_PHONE_STATE"}) which differs from the overridden method IFooMethod.testMethodAnyLiteral: @android.annotation.EnforcePermission(anyOf={android.Manifest.permission.INTERNET, "android.permission.READ_PHONE_STATE"}). The same annotation must be used for both methods. [MismatchingEnforcePermissionAnnotation] + public void testMethodAnyLiteral() { + ~~~~~~~~~~~~~~~~~~~~ + src/test/pkg/TestClass121.java:21: Error: The method TestClass121.testMethodAnyLiteralParentsShortPermission is annotated with @EnforcePermission(anyOf={android.Manifest.permission.INTERNET, android.Manifest.permission.READ_WRONG_PHONE_STATE}) which differs from the overridden method IFooMethod.testMethodAnyLiteralParentsShortPermission: @android.annotation.EnforcePermission(anyOf={"INTERNET", "READ_PHONE_STATE"}). The same annotation must be used for both methods. [MismatchingEnforcePermissionAnnotation] + public void testMethodAnyLiteralParentsShortPermission() { + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + 4 errors, 0 warnings """.addLineContinuation() ) } @@ -356,28 +464,17 @@ class EnforcePermissionDetectorTest : LintDetectorTest() { """ public interface IFooMethod extends android.os.IInterface { public static abstract class Stub extends android.os.Binder implements IFooMethod { - @Override - @android.annotation.EnforcePermission(android.Manifest.permission.READ_PHONE_STATE) - public void testMethod() {} - @Override - @android.annotation.EnforcePermission(anyOf={android.Manifest.permission.INTERNET, android.Manifest.permission.READ_PHONE_STATE}) - public void testMethodAny() {} - @Override - @android.annotation.EnforcePermission(anyOf={android.Manifest.permission.INTERNET, "android.permission.READ_PHONE_STATE"}) - public void testMethodAnyLiteral() {} - @Override - @android.annotation.EnforcePermission(allOf={android.Manifest.permission.INTERNET, android.Manifest.permission.READ_PHONE_STATE}) - public void testMethodAll() {} - @Override - @android.annotation.EnforcePermission(allOf={android.Manifest.permission.INTERNET, "android.permission.READ_PHONE_STATE"}) - public void testMethodAllLiteral() {} } @android.annotation.EnforcePermission(android.Manifest.permission.READ_PHONE_STATE) public void testMethod(); + @android.annotation.EnforcePermission("READ_PHONE_STATE") + public void testMethodParentShortPermission(); @android.annotation.EnforcePermission(anyOf={android.Manifest.permission.INTERNET, android.Manifest.permission.READ_PHONE_STATE}) public void testMethodAny() {} @android.annotation.EnforcePermission(anyOf={android.Manifest.permission.INTERNET, "android.permission.READ_PHONE_STATE"}) public void testMethodAnyLiteral() {} + @android.annotation.EnforcePermission(anyOf={"INTERNET", "READ_PHONE_STATE"}) + public void testMethodAnyLiteralParentsShortPermission() {} @android.annotation.EnforcePermission(allOf={android.Manifest.permission.INTERNET, android.Manifest.permission.READ_PHONE_STATE}) public void testMethodAll() {} @android.annotation.EnforcePermission(allOf={android.Manifest.permission.INTERNET, "android.permission.READ_PHONE_STATE"}) @@ -391,8 +488,6 @@ class EnforcePermissionDetectorTest : LintDetectorTest() { """ public interface IBar extends android.os.IInterface { public static abstract class Stub extends android.os.Binder implements IBar { - @Override - public void testMethod() {} } public void testMethod(); } @@ -404,6 +499,7 @@ class EnforcePermissionDetectorTest : LintDetectorTest() { package android.Manifest; class permission { public static final String READ_PHONE_STATE = "android.permission.READ_PHONE_STATE"; + public static final String READ_WRONG_PHONE_STATE = "android.permission.READ_WRONG_PHONE_STATE"; public static final String NFC = "android.permission.NFC"; public static final String INTERNET = "android.permission.INTERNET"; } 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 3ef02f865355..a4b0bc3a7c76 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 @@ -28,7 +28,8 @@ class EnforcePermissionHelperDetectorCodegenTest : LintDetectorTest() { override fun getDetector(): Detector = EnforcePermissionDetector() override fun getIssues(): List<Issue> = listOf( - EnforcePermissionDetector.ISSUE_ENFORCE_PERMISSION_HELPER + EnforcePermissionDetector.ISSUE_ENFORCE_PERMISSION_HELPER, + EnforcePermissionDetector.ISSUE_MISUSING_ENFORCE_PERMISSION ) override fun lint(): TestLintTask = super.lint().allowMissingSdk(true) |