Merge changes from topic "am-28715fbefc2c44e5ae5a9c401bb9bb6f" into main
* changes:
[automerger skipped] Merge "Import translations. DO NOT MERGE ANYWHERE" into udc-qpr-dev am: 7daf196375 -s ours am: 85b5f93bd2 -s ours
[automerger skipped] Import translations. DO NOT MERGE ANYWHERE am: 0281c03b84 -s ours am: 0b71a5a480 -s ours
[automerger skipped] Merge "Import translations. DO NOT MERGE ANYWHERE" into udc-qpr-dev am: 97b322847a -s ours am: bc2554a8e0 -s ours
[automerger skipped] Import translations. DO NOT MERGE ANYWHERE am: f642a33f38 -s ours am: f131078199 -s ours
[automerger skipped] Merge "Import translations. DO NOT MERGE ANYWHERE" into udc-qpr-dev am: c55b27b079 -s ours am: 6765caae98 -s ours
[automerger skipped] Import translations. DO NOT MERGE ANYWHERE am: 84a6297bbd -s ours am: 43575e12c3 -s ours
[automerger skipped] Merge "Import translations. DO NOT MERGE ANYWHERE" into udc-qpr-dev am: 8afb775cbf -s ours am: 0098f592e0 -s ours
[automerger skipped] Import translations. DO NOT MERGE ANYWHERE am: 9b33a71691 -s ours am: 276c16bd28 -s ours
[automerger skipped] Merge "Import translations. DO NOT MERGE ANYWHERE" into udc-qpr-dev am: 9585783d07 -s ours am: d7d5416a8c -s ours
[automerger skipped] Import translations. DO NOT MERGE ANYWHERE am: cbc5088f91 -s ours am: 801f7423b2 -s ours
diff --git a/services/core/java/com/android/server/wm/BackgroundActivityStartController.java b/services/core/java/com/android/server/wm/BackgroundActivityStartController.java
index 055aa5b..fc3a338 100644
--- a/services/core/java/com/android/server/wm/BackgroundActivityStartController.java
+++ b/services/core/java/com/android/server/wm/BackgroundActivityStartController.java
@@ -648,8 +648,7 @@
Slog.d(TAG, "Activity start allowed by caller. "
+ state.dump());
}
- // return the realCaller result for backwards compatibility
- return allowBasedOnRealCaller(state);
+ return allowBasedOnCaller(state);
}
if (state.mBalAllowedByPiCreator.allowsBackgroundActivityStarts()) {
Slog.wtf(TAG,
@@ -658,8 +657,7 @@
+ " AND the PI sender upgrades target_sdk to 34+! "
+ state.dump());
showBalRiskToast();
- // return the realCaller result for backwards compatibility
- return allowBasedOnRealCaller(state);
+ return allowBasedOnCaller(state);
}
Slog.wtf(TAG,
"Without Android 15 BAL hardening this activity start would be allowed"
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
index ff55e95..c82f751 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
@@ -88,6 +88,7 @@
import android.app.ActivityOptions;
import android.app.AppOpsManager;
import android.app.BackgroundStartPrivileges;
+import android.app.ComponentOptions.BackgroundActivityStartMode;
import android.app.IApplicationThread;
import android.app.PictureInPictureParams;
import android.content.ComponentName;
@@ -914,31 +915,78 @@
.mockStatic(FrameworkStatsLog.class)
.strictness(Strictness.LENIENT)
.startMocking();
- doReturn(PERMISSION_GRANTED).when(() -> ActivityTaskManagerService.checkPermission(
- eq(START_ACTIVITIES_FROM_BACKGROUND),
- anyInt(), anyInt()));
- runAndVerifyBackgroundActivityStartsSubtest(
- "allowed_notAborted", false,
- UNIMPORTANT_UID, false, PROCESS_STATE_BOUND_TOP,
- UNIMPORTANT_UID2, false, PROCESS_STATE_BOUND_TOP,
- false, true, false, false, false, false, false, false);
- verify(() -> FrameworkStatsLog.write(FrameworkStatsLog.BAL_ALLOWED,
- "", // activity name
- BackgroundActivityStartController.BAL_ALLOW_PERMISSION,
- UNIMPORTANT_UID,
- UNIMPORTANT_UID2,
- BackgroundActivityStartController.BAL_ALLOW_PERMISSION,
- true, // opt in
- false, // but no explicit opt in
- BackgroundActivityStartController.BAL_BLOCK,
- true, // opt in
- false // but no explicit opt in
+ try {
+ doReturn(PERMISSION_GRANTED).when(() -> ActivityTaskManagerService.checkPermission(
+ eq(START_ACTIVITIES_FROM_BACKGROUND),
+ anyInt(), anyInt()));
+ runAndVerifyBackgroundActivityStartsSubtest(
+ "allowed_notAborted", false,
+ UNIMPORTANT_UID, false, PROCESS_STATE_BOUND_TOP,
+ UNIMPORTANT_UID2, false, PROCESS_STATE_BOUND_TOP,
+ false, true, false, false, false, false, false, false);
+ verify(() -> FrameworkStatsLog.write(FrameworkStatsLog.BAL_ALLOWED,
+ "", // activity name
+ BackgroundActivityStartController.BAL_ALLOW_PERMISSION,
+ UNIMPORTANT_UID,
+ UNIMPORTANT_UID2,
+ BackgroundActivityStartController.BAL_ALLOW_PERMISSION,
+ true, // opt in
+ false, // but no explicit opt in
+ BackgroundActivityStartController.BAL_BLOCK,
+ true, // opt in
+ false // but no explicit opt in
));
- mockingSession.finishMocking();
+ } finally {
+ mockingSession.finishMocking();
+ }
}
/**
- * This test ensures proper logging for BAL_ALLOW_PENDING_INTENT.
+ * This test ensures proper logging for BAL_ALLOW_PENDING_INTENT, when the PendingIntent sender
+ * is the only reason BAL is allowed.
+ */
+ @Test
+ public void testBackgroundActivityStartsAllowed_loggingOnlyPendingIntentAllowed() {
+ doReturn(false).when(mAtm).isBackgroundActivityStartsEnabled();
+ MockitoSession mockingSession = mockitoSession()
+ .mockStatic(ActivityTaskManagerService.class)
+ .mockStatic(FrameworkStatsLog.class)
+ .mockStatic(PendingIntentRecord.class)
+ .strictness(Strictness.LENIENT)
+ .startMocking();
+ try {
+ doReturn(PERMISSION_GRANTED).when(() -> ActivityTaskManagerService.checkPermission(
+ eq(START_ACTIVITIES_FROM_BACKGROUND),
+ anyInt(), anyInt()));
+ doReturn(BackgroundStartPrivileges.allowBackgroundActivityStarts(null)).when(
+ () -> PendingIntentRecord.getBackgroundStartPrivilegesAllowedByCaller(
+ anyObject(), anyInt(), anyObject()));
+ runAndVerifyBackgroundActivityStartsSubtest(
+ "allowed_notAborted", false,
+ UNIMPORTANT_UID, false, PROCESS_STATE_BOUND_TOP,
+ Process.SYSTEM_UID, true, PROCESS_STATE_BOUND_TOP,
+ false, true, false, false, false, false, false, false,
+ ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_DENIED);
+ verify(() -> FrameworkStatsLog.write(FrameworkStatsLog.BAL_ALLOWED,
+ DEFAULT_COMPONENT_PACKAGE_NAME + "/" + DEFAULT_COMPONENT_PACKAGE_NAME,
+ BackgroundActivityStartController.BAL_ALLOW_PENDING_INTENT,
+ UNIMPORTANT_UID,
+ Process.SYSTEM_UID,
+ BackgroundActivityStartController.BAL_ALLOW_PERMISSION,
+ false, // opt in
+ true, // explicit opt out
+ BackgroundActivityStartController.BAL_ALLOW_VISIBLE_WINDOW,
+ true, // opt in
+ false // but no explicit opt in
+ ));
+ } finally {
+ mockingSession.finishMocking();
+ }
+ }
+
+ /**
+ * This test ensures proper logging for BAL_ALLOW_PENDING_INTENT, when the PendingIntent sender
+ * is not the primary reason to allow BAL (but the creator).
*/
@Test
public void testBackgroundActivityStartsAllowed_loggingPendingIntentAllowed() {
@@ -949,30 +997,34 @@
.mockStatic(PendingIntentRecord.class)
.strictness(Strictness.LENIENT)
.startMocking();
- doReturn(PERMISSION_GRANTED).when(() -> ActivityTaskManagerService.checkPermission(
- eq(START_ACTIVITIES_FROM_BACKGROUND),
- anyInt(), anyInt()));
- doReturn(BackgroundStartPrivileges.allowBackgroundActivityStarts(null)).when(
- () -> PendingIntentRecord.getBackgroundStartPrivilegesAllowedByCaller(
- anyObject(), anyInt(), anyObject()));
- runAndVerifyBackgroundActivityStartsSubtest(
- "allowed_notAborted", false,
- UNIMPORTANT_UID, false, PROCESS_STATE_BOUND_TOP,
- Process.SYSTEM_UID, true, PROCESS_STATE_BOUND_TOP,
- false, true, false, false, false, false, false, false);
- verify(() -> FrameworkStatsLog.write(FrameworkStatsLog.BAL_ALLOWED,
- DEFAULT_COMPONENT_PACKAGE_NAME + "/" + DEFAULT_COMPONENT_PACKAGE_NAME,
- BackgroundActivityStartController.BAL_ALLOW_PENDING_INTENT,
- UNIMPORTANT_UID,
- Process.SYSTEM_UID,
- BackgroundActivityStartController.BAL_ALLOW_PERMISSION,
- true, // opt in
- false, // but no explicit opt in
- BackgroundActivityStartController.BAL_ALLOW_VISIBLE_WINDOW,
- true, // opt in
- false // but no explicit opt in
+ try {
+ doReturn(PERMISSION_GRANTED).when(() -> ActivityTaskManagerService.checkPermission(
+ eq(START_ACTIVITIES_FROM_BACKGROUND),
+ anyInt(), anyInt()));
+ doReturn(BackgroundStartPrivileges.allowBackgroundActivityStarts(null)).when(
+ () -> PendingIntentRecord.getBackgroundStartPrivilegesAllowedByCaller(
+ anyObject(), anyInt(), anyObject()));
+ runAndVerifyBackgroundActivityStartsSubtest(
+ "allowed_notAborted", false,
+ UNIMPORTANT_UID, false, PROCESS_STATE_BOUND_TOP,
+ Process.SYSTEM_UID, true, PROCESS_STATE_BOUND_TOP,
+ false, true, false, false, false, false, false, false,
+ ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED);
+ verify(() -> FrameworkStatsLog.write(FrameworkStatsLog.BAL_ALLOWED,
+ "",
+ BackgroundActivityStartController.BAL_ALLOW_PERMISSION,
+ UNIMPORTANT_UID,
+ Process.SYSTEM_UID,
+ BackgroundActivityStartController.BAL_ALLOW_PERMISSION,
+ true, // opt in
+ true, // explicit opt in
+ BackgroundActivityStartController.BAL_ALLOW_VISIBLE_WINDOW,
+ true, // opt in
+ false // but no explicit opt in
));
- mockingSession.finishMocking();
+ } finally {
+ mockingSession.finishMocking();
+ }
}
private void runAndVerifyBackgroundActivityStartsSubtest(String name, boolean shouldHaveAborted,
@@ -985,6 +1037,27 @@
boolean isCallingUidAffiliatedProfileOwner,
boolean isPinnedSingleInstance,
boolean hasSystemExemptAppOp) {
+ runAndVerifyBackgroundActivityStartsSubtest(name, shouldHaveAborted, callingUid,
+ callingUidHasVisibleWindow, callingUidProcState, realCallingUid,
+ realCallingUidHasVisibleWindow, realCallingUidProcState, hasForegroundActivities,
+ callerIsRecents, callerIsTempAllowed,
+ callerIsInstrumentingWithBackgroundActivityStartPrivileges,
+ isCallingUidDeviceOwner, isCallingUidAffiliatedProfileOwner, isPinnedSingleInstance,
+ hasSystemExemptAppOp,
+ ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_SYSTEM_DEFINED);
+ }
+
+ private void runAndVerifyBackgroundActivityStartsSubtest(String name, boolean shouldHaveAborted,
+ int callingUid, boolean callingUidHasVisibleWindow, int callingUidProcState,
+ int realCallingUid, boolean realCallingUidHasVisibleWindow, int realCallingUidProcState,
+ boolean hasForegroundActivities, boolean callerIsRecents,
+ boolean callerIsTempAllowed,
+ boolean callerIsInstrumentingWithBackgroundActivityStartPrivileges,
+ boolean isCallingUidDeviceOwner,
+ boolean isCallingUidAffiliatedProfileOwner,
+ boolean isPinnedSingleInstance,
+ boolean hasSystemExemptAppOp,
+ @BackgroundActivityStartMode int pendingIntentCreatorBackgroundActivityStartMode) {
// window visibility
doReturn(callingUidHasVisibleWindow).when(mAtm).hasActiveVisibleWindow(callingUid);
doReturn(realCallingUidHasVisibleWindow).when(mAtm).hasActiveVisibleWindow(realCallingUid);
@@ -1036,7 +1109,10 @@
launchMode = LAUNCH_SINGLE_INSTANCE;
}
- final ActivityOptions options = spy(ActivityOptions.makeBasic());
+ ActivityOptions rawOptions = ActivityOptions.makeBasic()
+ .setPendingIntentCreatorBackgroundActivityStartMode(
+ pendingIntentCreatorBackgroundActivityStartMode);
+ final ActivityOptions options = spy(rawOptions);
ActivityRecord[] outActivity = new ActivityRecord[1];
ActivityStarter starter = prepareStarter(
FLAG_ACTIVITY_NEW_TASK, true, launchMode)