Loading services/core/java/com/android/server/wm/BackgroundActivityStartController.java +31 −16 Original line number Diff line number Diff line Loading @@ -297,7 +297,8 @@ public class BackgroundActivityStartController { private final int mCallingUid; private final int mCallingPid; private final @ActivityTaskManagerService.AppSwitchState int mAppSwitchState; private final boolean mCallingUidHasAnyVisibleWindow; private final boolean mCallingUidHasVisibleActivity; private final boolean mCallingUidHasNonAppVisibleWindow; private final @ActivityManager.ProcessState int mCallingUidProcState; private final boolean mIsCallingUidPersistentSystemProcess; final BackgroundStartPrivileges mBalAllowedByPiSender; Loading @@ -306,7 +307,8 @@ public class BackgroundActivityStartController { private final String mRealCallingPackage; private final int mRealCallingUid; private final int mRealCallingPid; private final boolean mRealCallingUidHasAnyVisibleWindow; private final boolean mRealCallingUidHasVisibleActivity; private final boolean mRealCallingUidHasNonAppVisibleWindow; private final @ActivityManager.ProcessState int mRealCallingUidProcState; private final boolean mIsRealCallingUidPersistentSystemProcess; private final PendingIntentRecord mOriginatingPendingIntent; Loading Loading @@ -401,16 +403,21 @@ public class BackgroundActivityStartController { mCallingUidProcState = mService.mActiveUids.getUidState(callingUid); mIsCallingUidPersistentSystemProcess = mCallingUidProcState <= ActivityManager.PROCESS_STATE_PERSISTENT_UI; mCallingUidHasAnyVisibleWindow = mService.hasActiveVisibleWindow(callingUid); mCallingUidHasVisibleActivity = mService.mVisibleActivityProcessTracker.hasVisibleActivity(callingUid); mCallingUidHasNonAppVisibleWindow = mService.mActiveUids.hasNonAppVisibleWindow( callingUid); if (realCallingUid == NO_PROCESS_UID) { // no process provided mRealCallingUidProcState = PROCESS_STATE_NONEXISTENT; mRealCallingUidHasAnyVisibleWindow = false; mRealCallingUidHasVisibleActivity = false; mRealCallingUidHasNonAppVisibleWindow = false; mRealCallerApp = null; mIsRealCallingUidPersistentSystemProcess = false; } else if (callingUid == realCallingUid) { mRealCallingUidProcState = mCallingUidProcState; mRealCallingUidHasAnyVisibleWindow = mCallingUidHasAnyVisibleWindow; mRealCallingUidHasVisibleActivity = mCallingUidHasVisibleActivity; mRealCallingUidHasNonAppVisibleWindow = mCallingUidHasNonAppVisibleWindow; // In the PendingIntent case callerApp is not passed in, so resolve it ourselves. mRealCallerApp = callerApp == null ? mService.getProcessController(realCallingPid, realCallingUid) Loading @@ -418,8 +425,10 @@ public class BackgroundActivityStartController { mIsRealCallingUidPersistentSystemProcess = mIsCallingUidPersistentSystemProcess; } else { mRealCallingUidProcState = mService.mActiveUids.getUidState(realCallingUid); mRealCallingUidHasAnyVisibleWindow = mService.hasActiveVisibleWindow(realCallingUid); mRealCallingUidHasVisibleActivity = mService.mVisibleActivityProcessTracker.hasVisibleActivity(realCallingUid); mRealCallingUidHasNonAppVisibleWindow = mService.mActiveUids.hasNonAppVisibleWindow(realCallingUid); mRealCallerApp = mService.getProcessController(realCallingPid, realCallingUid); mIsRealCallingUidPersistentSystemProcess = mRealCallingUidProcState <= ActivityManager.PROCESS_STATE_PERSISTENT_UI; Loading Loading @@ -546,7 +555,9 @@ public class BackgroundActivityStartController { sb.append("; callingUid: ").append(mCallingUid); sb.append("; callingPid: ").append(mCallingPid); sb.append("; appSwitchState: ").append(mAppSwitchState); sb.append("; callingUidHasAnyVisibleWindow: ").append(mCallingUidHasAnyVisibleWindow); sb.append("; callingUidHasVisibleActivity: ").append(mCallingUidHasVisibleActivity); sb.append("; callingUidHasNonAppVisibleWindow: ").append( mCallingUidHasNonAppVisibleWindow); sb.append("; callingUidProcState: ").append(DebugUtils.valueToString( ActivityManager.class, "PROCESS_STATE_", mCallingUidProcState)); sb.append("; isCallingUidPersistentSystemProcess: ") Loading Loading @@ -575,8 +586,10 @@ public class BackgroundActivityStartController { .append(getTargetSdk(mRealCallingPackage)); sb.append("; realCallingUid: ").append(mRealCallingUid); sb.append("; realCallingPid: ").append(mRealCallingPid); sb.append("; realCallingUidHasAnyVisibleWindow: ") .append(mRealCallingUidHasAnyVisibleWindow); sb.append("; realCallingUidHasVisibleActivity: ") .append(mRealCallingUidHasVisibleActivity); sb.append("; realCallingUidHasNonAppVisibleWindow: ") .append(mRealCallingUidHasNonAppVisibleWindow); sb.append("; realCallingUidProcState: ").append(DebugUtils.valueToString( ActivityManager.class, "PROCESS_STATE_", mRealCallingUidProcState)); sb.append("; isRealCallingUidPersistentSystemProcess: ") Loading Loading @@ -997,11 +1010,11 @@ public class BackgroundActivityStartController { // is allowed, or apps like live wallpaper with non app visible window will be allowed. final boolean appSwitchAllowedOrFg = state.mAppSwitchState == APP_SWITCH_ALLOW || state.mAppSwitchState == APP_SWITCH_FG_ONLY; if (appSwitchAllowedOrFg && state.mCallingUidHasAnyVisibleWindow) { if (appSwitchAllowedOrFg && state.mCallingUidHasVisibleActivity) { return new BalVerdict(BAL_ALLOW_VISIBLE_WINDOW, /*background*/ false, "callingUid has visible window"); } if (mService.mActiveUids.hasNonAppVisibleWindow(state.mCallingUid)) { if (state.mCallingUidHasNonAppVisibleWindow) { return new BalVerdict(BAL_ALLOW_NON_APP_VISIBLE_WINDOW, /*background*/ false, "callingUid has non-app visible window"); } Loading Loading @@ -1123,11 +1136,11 @@ public class BackgroundActivityStartController { final boolean appSwitchAllowedOrFg = state.mAppSwitchState == APP_SWITCH_ALLOW || state.mAppSwitchState == APP_SWITCH_FG_ONLY || isHomeApp(state.mRealCallingUid, state.mRealCallingPackage); if (appSwitchAllowedOrFg && state.mRealCallingUidHasAnyVisibleWindow) { if (appSwitchAllowedOrFg && state.mRealCallingUidHasVisibleActivity) { return new BalVerdict(BAL_ALLOW_VISIBLE_WINDOW, /*background*/ false, "realCallingUid has visible window"); } if (mService.mActiveUids.hasNonAppVisibleWindow(state.mRealCallingUid)) { if (state.mRealCallingUidHasNonAppVisibleWindow) { return new BalVerdict(BAL_ALLOW_NON_APP_VISIBLE_WINDOW, /*background*/ false, "realCallingUid has non-app visible window"); } Loading Loading @@ -1872,10 +1885,12 @@ public class BackgroundActivityStartController { state.mCallingUid, state.mCallingPackage, state.mCallingUidProcState, state.mCallingUidHasAnyVisibleWindow, state.mCallingUidHasVisibleActivity || state.mCallingUidHasNonAppVisibleWindow, state.mRealCallingUid, state.mRealCallingUidProcState, state.mRealCallingUidHasAnyVisibleWindow, state.mRealCallingUidHasVisibleActivity || state.mRealCallingUidHasNonAppVisibleWindow, (state.mOriginatingPendingIntent != null)); } Loading services/tests/wmtests/src/com/android/server/wm/BackgroundActivityStartControllerExemptionTests.java +89 −4 Original line number Diff line number Diff line Loading @@ -23,11 +23,13 @@ import static android.app.ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOW_I import static com.android.server.wm.ActivityTaskManagerService.APP_SWITCH_ALLOW; import static com.android.server.wm.BackgroundActivityStartController.BAL_ALLOW_ALLOWLISTED_COMPONENT; import static com.android.server.wm.BackgroundActivityStartController.BAL_ALLOW_FOREGROUND; import static com.android.server.wm.BackgroundActivityStartController.BAL_ALLOW_NON_APP_VISIBLE_WINDOW; import static com.android.server.wm.BackgroundActivityStartController.BAL_ALLOW_PERMISSION; import static com.android.server.wm.BackgroundActivityStartController.BAL_ALLOW_SAW_PERMISSION; import static com.android.server.wm.BackgroundActivityStartController.BAL_ALLOW_VISIBLE_WINDOW; import static com.android.server.wm.BackgroundActivityStartController.BAL_BLOCK; import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertWithMessage; import static org.mockito.ArgumentMatchers.any; Loading @@ -50,6 +52,7 @@ import android.platform.test.flag.junit.CheckFlagsRule; import android.platform.test.flag.junit.DeviceFlagsValueProvider; import android.provider.DeviceConfig; import android.util.Pair; import android.view.WindowManager; import androidx.test.filters.SmallTest; Loading Loading @@ -126,6 +129,8 @@ public class BackgroundActivityStartControllerExemptionTests { AppOpsManager mAppOpsManager; MirrorActiveUids mActiveUids = new MirrorActiveUids(); WindowProcessControllerMap mProcessMap = new WindowProcessControllerMap(); @Mock VisibleActivityProcessTracker mVisibleActivityProcessTracker; @Mock ActivityTaskSupervisor mSupervisor; Loading Loading @@ -182,6 +187,8 @@ public class BackgroundActivityStartControllerExemptionTests { mService.mRootWindowContainer = mRootWindowContainer; when(mService.getAppOpsManager()).thenReturn(mAppOpsManager); setViaReflection(mService, "mProcessMap", mProcessMap); setViaReflection(mService, "mVisibleActivityProcessTracker", mVisibleActivityProcessTracker); setViaReflection(mSupervisor, "mRecentTasks", mRecentTasks); Loading Loading @@ -257,7 +264,7 @@ public class BackgroundActivityStartControllerExemptionTests { int realCallingPid = REGULAR_PID_2; // setup state when(mService.hasActiveVisibleWindow(eq(callingUid))).thenReturn(true); when(mVisibleActivityProcessTracker.hasVisibleActivity(eq(callingUid))).thenReturn(true); when(mService.getBalAppSwitchesState()).thenReturn(APP_SWITCH_ALLOW); // prepare call Loading @@ -269,6 +276,8 @@ public class BackgroundActivityStartControllerExemptionTests { callingPid, callingPackage, realCallingUid, realCallingPid, mCallerApp, originatingPendingIntent, allowBalExemptionForSystemProcess, mResultRecord, intent, checkedOptions); assertThat(balState.toString()).contains("callingUidHasVisibleActivity: true"); assertThat(balState.toString()).contains("callingUidHasNonAppVisibleWindow: false"); // call BalVerdict callerVerdict = mController.checkBackgroundActivityStartAllowedByCaller( Loading @@ -289,7 +298,8 @@ public class BackgroundActivityStartControllerExemptionTests { int realCallingPid = REGULAR_PID_2; // setup state when(mService.hasActiveVisibleWindow(eq(realCallingUid))).thenReturn(true); when(mVisibleActivityProcessTracker.hasVisibleActivity(eq(realCallingUid))).thenReturn( true); when(mService.getBalAppSwitchesState()).thenReturn(APP_SWITCH_ALLOW); // prepare call Loading @@ -301,6 +311,8 @@ public class BackgroundActivityStartControllerExemptionTests { callingPid, callingPackage, realCallingUid, realCallingPid, mCallerApp, originatingPendingIntent, allowBalExemptionForSystemProcess, mResultRecord, intent, checkedOptions); assertThat(balState.toString()).contains("realCallingUidHasVisibleActivity: true"); assertThat(balState.toString()).contains("realCallingUidHasNonAppVisibleWindow: false"); // call BalVerdict realCallerVerdict = mController.checkBackgroundActivityStartAllowedByRealCaller( Loading @@ -312,6 +324,74 @@ public class BackgroundActivityStartControllerExemptionTests { BAL_ALLOW_VISIBLE_WINDOW); } @Test public void testCaller_appHasNonAppVisibleWindow() { int callingUid = REGULAR_UID_1; int callingPid = REGULAR_PID_1; final String callingPackage = REGULAR_PACKAGE_1; int realCallingUid = REGULAR_UID_2; int realCallingPid = REGULAR_PID_2; // setup state mActiveUids.onNonAppSurfaceVisibilityChanged(callingUid, true); when(mService.getBalAppSwitchesState()).thenReturn(APP_SWITCH_ALLOW); // prepare call PendingIntentRecord originatingPendingIntent = mPendingIntentRecord; boolean allowBalExemptionForSystemProcess = false; Intent intent = TEST_INTENT; ActivityOptions checkedOptions = mCheckedOptions; BackgroundActivityStartController.BalState balState = mController.new BalState(callingUid, callingPid, callingPackage, realCallingUid, realCallingPid, mCallerApp, originatingPendingIntent, allowBalExemptionForSystemProcess, mResultRecord, intent, checkedOptions); assertThat(balState.toString()).contains("callingUidHasVisibleActivity: false"); assertThat(balState.toString()).contains("callingUidHasNonAppVisibleWindow: true"); // call BalVerdict callerVerdict = mController.checkBackgroundActivityStartAllowedByCaller( balState); balState.setResultForCaller(callerVerdict); // assertions assertWithMessage(balState.toString()).that(callerVerdict.getCode()).isEqualTo( BAL_ALLOW_NON_APP_VISIBLE_WINDOW); } @Test public void testRealCaller_appHasNonAppVisibleWindow() { int callingUid = REGULAR_UID_1; int callingPid = REGULAR_PID_1; final String callingPackage = REGULAR_PACKAGE_1; int realCallingUid = REGULAR_UID_2; int realCallingPid = REGULAR_PID_2; // setup state mActiveUids.onNonAppSurfaceVisibilityChanged(realCallingUid, true); when(mService.getBalAppSwitchesState()).thenReturn(APP_SWITCH_ALLOW); // prepare call PendingIntentRecord originatingPendingIntent = mPendingIntentRecord; boolean allowBalExemptionForSystemProcess = false; Intent intent = TEST_INTENT; ActivityOptions checkedOptions = mCheckedOptions; BackgroundActivityStartController.BalState balState = mController.new BalState(callingUid, callingPid, callingPackage, realCallingUid, realCallingPid, mCallerApp, originatingPendingIntent, allowBalExemptionForSystemProcess, mResultRecord, intent, checkedOptions); assertThat(balState.toString()).contains("realCallingUidHasVisibleActivity: false"); assertThat(balState.toString()).contains("realCallingUidHasNonAppVisibleWindow: true"); // call BalVerdict realCallerVerdict = mController.checkBackgroundActivityStartAllowedByRealCaller( balState); balState.setResultForRealCaller(realCallerVerdict); // assertions assertWithMessage(balState.toString()).that(realCallerVerdict.getCode()).isEqualTo( BAL_ALLOW_NON_APP_VISIBLE_WINDOW); } @Test @RequiresFlagsEnabled(Flags.FLAG_BAL_ADDITIONAL_START_MODES) public void testCaller_appHasVisibleWindowWithIfVisibleOptIn() { Loading @@ -322,7 +402,7 @@ public class BackgroundActivityStartControllerExemptionTests { int realCallingPid = REGULAR_PID_2; // setup state when(mService.hasActiveVisibleWindow(eq(callingUid))).thenReturn(true); when(mVisibleActivityProcessTracker.hasVisibleActivity(eq(callingUid))).thenReturn(true); when(mService.getBalAppSwitchesState()).thenReturn(APP_SWITCH_ALLOW); // prepare call Loading @@ -336,6 +416,8 @@ public class BackgroundActivityStartControllerExemptionTests { callingPid, callingPackage, realCallingUid, realCallingPid, mCallerApp, originatingPendingIntent, allowBalExemptionForSystemProcess, mResultRecord, intent, checkedOptions); assertThat(balState.toString()).contains("callingUidHasVisibleActivity: true"); assertThat(balState.toString()).contains("callingUidHasNonAppVisibleWindow: false"); // call BalVerdict callerVerdict = mController.checkBackgroundActivityStartAllowedByCaller( Loading @@ -357,7 +439,8 @@ public class BackgroundActivityStartControllerExemptionTests { int realCallingPid = REGULAR_PID_2; // setup state when(mService.hasActiveVisibleWindow(eq(realCallingUid))).thenReturn(true); when(mVisibleActivityProcessTracker.hasVisibleActivity(eq(realCallingUid))).thenReturn( true); when(mService.getBalAppSwitchesState()).thenReturn(APP_SWITCH_ALLOW); // prepare call Loading @@ -371,6 +454,8 @@ public class BackgroundActivityStartControllerExemptionTests { callingPid, callingPackage, realCallingUid, realCallingPid, mCallerApp, originatingPendingIntent, allowBalExemptionForSystemProcess, mResultRecord, intent, checkedOptions); assertThat(balState.toString()).contains("realCallingUidHasVisibleActivity: true"); assertThat(balState.toString()).contains("realCallingUidHasNonAppVisibleWindow: false"); // call BalVerdict realCallerVerdict = mController.checkBackgroundActivityStartAllowedByRealCaller( Loading services/tests/wmtests/src/com/android/server/wm/BackgroundActivityStartControllerLogTests.java +4 −0 Original line number Diff line number Diff line Loading @@ -67,12 +67,16 @@ public class BackgroundActivityStartControllerLogTests { @Mock PendingIntentRecord mPendingIntentRecord; MirrorActiveUids mActiveUids = new MirrorActiveUids(); @Mock VisibleActivityProcessTracker mVisibleActivityProcessTracker; BackgroundActivityStartController mController; BackgroundActivityStartController.BalState mState; @Before public void setup() { setViaReflection(mService, "mActiveUids", mActiveUids); setViaReflection(mService, "mVisibleActivityProcessTracker", mVisibleActivityProcessTracker); mController = new BackgroundActivityStartController(mService, mSupervisor); } Loading services/tests/wmtests/src/com/android/server/wm/BackgroundActivityStartControllerTests.java +23 −8 Original line number Diff line number Diff line Loading @@ -111,6 +111,9 @@ public class BackgroundActivityStartControllerTests { @Mock AppOpsManager mAppOpsManager; MirrorActiveUids mActiveUids = new MirrorActiveUids(); @Mock VisibleActivityProcessTracker mVisibleActivityProcessTracker; WindowProcessControllerMap mProcessMap = new WindowProcessControllerMap(); @Mock Loading Loading @@ -200,6 +203,8 @@ public class BackgroundActivityStartControllerTests { mService.mRootWindowContainer = mRootWindowContainer; Mockito.when(mService.getAppOpsManager()).thenReturn(mAppOpsManager); setViaReflection(mService, "mProcessMap", mProcessMap); setViaReflection(mService, "mVisibleActivityProcessTracker", mVisibleActivityProcessTracker); //Mockito.when(mSupervisor.getBackgroundActivityLaunchController()).thenReturn(mController); setViaReflection(mSupervisor, "mRecentTasks", mRecentTasks); Loading Loading @@ -551,13 +556,14 @@ public class BackgroundActivityStartControllerTests { assertThat(balState.callerExplicitOptInOrOut()).isFalse(); assertThat(balState.realCallerExplicitOptInOrAutoOptIn()).isTrue(); assertThat(balState.realCallerExplicitOptInOrOut()).isFalse(); assertThat(balState.toString()).startsWith( assertThat(balState.toString()).isEqualTo( "[callingPackage: package.app1; " + "callingPackageTargetSdk: -1; " + "callingUid: 10001; " + "callingPid: 11001; " + "appSwitchState: 0; " + "callingUidHasAnyVisibleWindow: false; " + "callingUidHasVisibleActivity: false; " + "callingUidHasNonAppVisibleWindow: false; " + "callingUidProcState: NONEXISTENT; " + "isCallingUidPersistentSystemProcess: false; " + "allowBalExemptionForSystemProcess: false; " Loading @@ -576,13 +582,17 @@ public class BackgroundActivityStartControllerTests { + "realCallingPackageTargetSdk: -1; " + "realCallingUid: 1; " + "realCallingPid: 1; " + "realCallingUidHasAnyVisibleWindow: false; " + "realCallingUidHasVisibleActivity: false; " + "realCallingUidHasNonAppVisibleWindow: false; " + "realCallingUidProcState: NONEXISTENT; " + "isRealCallingUidPersistentSystemProcess: false; " + "originatingPendingIntent: null; " + "realCallerApp: null; " + "balAllowedByPiSender: BSP.ALLOW_BAL; " + "resultIfPiSenderAllowsBal: null"); + "resultIfPiSenderAllowsBal: null; " + "realCallerStartMode: MODE_BACKGROUND_ACTIVITY_START_SYSTEM_DEFINED; " + "balRequireOptInByPendingIntentCreator: true; " + "balDontBringExistingBackgroundTaskStackToFg: true]"); } @Test Loading Loading @@ -651,13 +661,14 @@ public class BackgroundActivityStartControllerTests { assertThat(balState.callerExplicitOptInOrOut()).isFalse(); assertThat(balState.realCallerExplicitOptInOrAutoOptIn()).isFalse(); assertThat(balState.realCallerExplicitOptInOrOut()).isFalse(); assertThat(balState.toString()).startsWith( assertThat(balState.toString()).isEqualTo( "[callingPackage: package.app1; " + "callingPackageTargetSdk: -1; " + "callingUid: 10001; " + "callingPid: 11001; " + "appSwitchState: 0; " + "callingUidHasAnyVisibleWindow: false; " + "callingUidHasVisibleActivity: false; " + "callingUidHasNonAppVisibleWindow: false; " + "callingUidProcState: NONEXISTENT; " + "isCallingUidPersistentSystemProcess: false; " + "allowBalExemptionForSystemProcess: false; " Loading @@ -676,12 +687,16 @@ public class BackgroundActivityStartControllerTests { + "realCallingPackageTargetSdk: -1; " + "realCallingUid: 1; " + "realCallingPid: 1; " + "realCallingUidHasAnyVisibleWindow: false; " + "realCallingUidHasVisibleActivity: false; " + "realCallingUidHasNonAppVisibleWindow: false; " + "realCallingUidProcState: NONEXISTENT; " + "isRealCallingUidPersistentSystemProcess: false; " + "originatingPendingIntent: PendingIntentRecord; " + "realCallerApp: null; " + "balAllowedByPiSender: BSP.ALLOW_FGS; " + "resultIfPiSenderAllowsBal: null"); + "resultIfPiSenderAllowsBal: null; " + "realCallerStartMode: MODE_BACKGROUND_ACTIVITY_START_SYSTEM_DEFINED; " + "balRequireOptInByPendingIntentCreator: true; " + "balDontBringExistingBackgroundTaskStackToFg: true]"); } } Loading
services/core/java/com/android/server/wm/BackgroundActivityStartController.java +31 −16 Original line number Diff line number Diff line Loading @@ -297,7 +297,8 @@ public class BackgroundActivityStartController { private final int mCallingUid; private final int mCallingPid; private final @ActivityTaskManagerService.AppSwitchState int mAppSwitchState; private final boolean mCallingUidHasAnyVisibleWindow; private final boolean mCallingUidHasVisibleActivity; private final boolean mCallingUidHasNonAppVisibleWindow; private final @ActivityManager.ProcessState int mCallingUidProcState; private final boolean mIsCallingUidPersistentSystemProcess; final BackgroundStartPrivileges mBalAllowedByPiSender; Loading @@ -306,7 +307,8 @@ public class BackgroundActivityStartController { private final String mRealCallingPackage; private final int mRealCallingUid; private final int mRealCallingPid; private final boolean mRealCallingUidHasAnyVisibleWindow; private final boolean mRealCallingUidHasVisibleActivity; private final boolean mRealCallingUidHasNonAppVisibleWindow; private final @ActivityManager.ProcessState int mRealCallingUidProcState; private final boolean mIsRealCallingUidPersistentSystemProcess; private final PendingIntentRecord mOriginatingPendingIntent; Loading Loading @@ -401,16 +403,21 @@ public class BackgroundActivityStartController { mCallingUidProcState = mService.mActiveUids.getUidState(callingUid); mIsCallingUidPersistentSystemProcess = mCallingUidProcState <= ActivityManager.PROCESS_STATE_PERSISTENT_UI; mCallingUidHasAnyVisibleWindow = mService.hasActiveVisibleWindow(callingUid); mCallingUidHasVisibleActivity = mService.mVisibleActivityProcessTracker.hasVisibleActivity(callingUid); mCallingUidHasNonAppVisibleWindow = mService.mActiveUids.hasNonAppVisibleWindow( callingUid); if (realCallingUid == NO_PROCESS_UID) { // no process provided mRealCallingUidProcState = PROCESS_STATE_NONEXISTENT; mRealCallingUidHasAnyVisibleWindow = false; mRealCallingUidHasVisibleActivity = false; mRealCallingUidHasNonAppVisibleWindow = false; mRealCallerApp = null; mIsRealCallingUidPersistentSystemProcess = false; } else if (callingUid == realCallingUid) { mRealCallingUidProcState = mCallingUidProcState; mRealCallingUidHasAnyVisibleWindow = mCallingUidHasAnyVisibleWindow; mRealCallingUidHasVisibleActivity = mCallingUidHasVisibleActivity; mRealCallingUidHasNonAppVisibleWindow = mCallingUidHasNonAppVisibleWindow; // In the PendingIntent case callerApp is not passed in, so resolve it ourselves. mRealCallerApp = callerApp == null ? mService.getProcessController(realCallingPid, realCallingUid) Loading @@ -418,8 +425,10 @@ public class BackgroundActivityStartController { mIsRealCallingUidPersistentSystemProcess = mIsCallingUidPersistentSystemProcess; } else { mRealCallingUidProcState = mService.mActiveUids.getUidState(realCallingUid); mRealCallingUidHasAnyVisibleWindow = mService.hasActiveVisibleWindow(realCallingUid); mRealCallingUidHasVisibleActivity = mService.mVisibleActivityProcessTracker.hasVisibleActivity(realCallingUid); mRealCallingUidHasNonAppVisibleWindow = mService.mActiveUids.hasNonAppVisibleWindow(realCallingUid); mRealCallerApp = mService.getProcessController(realCallingPid, realCallingUid); mIsRealCallingUidPersistentSystemProcess = mRealCallingUidProcState <= ActivityManager.PROCESS_STATE_PERSISTENT_UI; Loading Loading @@ -546,7 +555,9 @@ public class BackgroundActivityStartController { sb.append("; callingUid: ").append(mCallingUid); sb.append("; callingPid: ").append(mCallingPid); sb.append("; appSwitchState: ").append(mAppSwitchState); sb.append("; callingUidHasAnyVisibleWindow: ").append(mCallingUidHasAnyVisibleWindow); sb.append("; callingUidHasVisibleActivity: ").append(mCallingUidHasVisibleActivity); sb.append("; callingUidHasNonAppVisibleWindow: ").append( mCallingUidHasNonAppVisibleWindow); sb.append("; callingUidProcState: ").append(DebugUtils.valueToString( ActivityManager.class, "PROCESS_STATE_", mCallingUidProcState)); sb.append("; isCallingUidPersistentSystemProcess: ") Loading Loading @@ -575,8 +586,10 @@ public class BackgroundActivityStartController { .append(getTargetSdk(mRealCallingPackage)); sb.append("; realCallingUid: ").append(mRealCallingUid); sb.append("; realCallingPid: ").append(mRealCallingPid); sb.append("; realCallingUidHasAnyVisibleWindow: ") .append(mRealCallingUidHasAnyVisibleWindow); sb.append("; realCallingUidHasVisibleActivity: ") .append(mRealCallingUidHasVisibleActivity); sb.append("; realCallingUidHasNonAppVisibleWindow: ") .append(mRealCallingUidHasNonAppVisibleWindow); sb.append("; realCallingUidProcState: ").append(DebugUtils.valueToString( ActivityManager.class, "PROCESS_STATE_", mRealCallingUidProcState)); sb.append("; isRealCallingUidPersistentSystemProcess: ") Loading Loading @@ -997,11 +1010,11 @@ public class BackgroundActivityStartController { // is allowed, or apps like live wallpaper with non app visible window will be allowed. final boolean appSwitchAllowedOrFg = state.mAppSwitchState == APP_SWITCH_ALLOW || state.mAppSwitchState == APP_SWITCH_FG_ONLY; if (appSwitchAllowedOrFg && state.mCallingUidHasAnyVisibleWindow) { if (appSwitchAllowedOrFg && state.mCallingUidHasVisibleActivity) { return new BalVerdict(BAL_ALLOW_VISIBLE_WINDOW, /*background*/ false, "callingUid has visible window"); } if (mService.mActiveUids.hasNonAppVisibleWindow(state.mCallingUid)) { if (state.mCallingUidHasNonAppVisibleWindow) { return new BalVerdict(BAL_ALLOW_NON_APP_VISIBLE_WINDOW, /*background*/ false, "callingUid has non-app visible window"); } Loading Loading @@ -1123,11 +1136,11 @@ public class BackgroundActivityStartController { final boolean appSwitchAllowedOrFg = state.mAppSwitchState == APP_SWITCH_ALLOW || state.mAppSwitchState == APP_SWITCH_FG_ONLY || isHomeApp(state.mRealCallingUid, state.mRealCallingPackage); if (appSwitchAllowedOrFg && state.mRealCallingUidHasAnyVisibleWindow) { if (appSwitchAllowedOrFg && state.mRealCallingUidHasVisibleActivity) { return new BalVerdict(BAL_ALLOW_VISIBLE_WINDOW, /*background*/ false, "realCallingUid has visible window"); } if (mService.mActiveUids.hasNonAppVisibleWindow(state.mRealCallingUid)) { if (state.mRealCallingUidHasNonAppVisibleWindow) { return new BalVerdict(BAL_ALLOW_NON_APP_VISIBLE_WINDOW, /*background*/ false, "realCallingUid has non-app visible window"); } Loading Loading @@ -1872,10 +1885,12 @@ public class BackgroundActivityStartController { state.mCallingUid, state.mCallingPackage, state.mCallingUidProcState, state.mCallingUidHasAnyVisibleWindow, state.mCallingUidHasVisibleActivity || state.mCallingUidHasNonAppVisibleWindow, state.mRealCallingUid, state.mRealCallingUidProcState, state.mRealCallingUidHasAnyVisibleWindow, state.mRealCallingUidHasVisibleActivity || state.mRealCallingUidHasNonAppVisibleWindow, (state.mOriginatingPendingIntent != null)); } Loading
services/tests/wmtests/src/com/android/server/wm/BackgroundActivityStartControllerExemptionTests.java +89 −4 Original line number Diff line number Diff line Loading @@ -23,11 +23,13 @@ import static android.app.ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOW_I import static com.android.server.wm.ActivityTaskManagerService.APP_SWITCH_ALLOW; import static com.android.server.wm.BackgroundActivityStartController.BAL_ALLOW_ALLOWLISTED_COMPONENT; import static com.android.server.wm.BackgroundActivityStartController.BAL_ALLOW_FOREGROUND; import static com.android.server.wm.BackgroundActivityStartController.BAL_ALLOW_NON_APP_VISIBLE_WINDOW; import static com.android.server.wm.BackgroundActivityStartController.BAL_ALLOW_PERMISSION; import static com.android.server.wm.BackgroundActivityStartController.BAL_ALLOW_SAW_PERMISSION; import static com.android.server.wm.BackgroundActivityStartController.BAL_ALLOW_VISIBLE_WINDOW; import static com.android.server.wm.BackgroundActivityStartController.BAL_BLOCK; import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertWithMessage; import static org.mockito.ArgumentMatchers.any; Loading @@ -50,6 +52,7 @@ import android.platform.test.flag.junit.CheckFlagsRule; import android.platform.test.flag.junit.DeviceFlagsValueProvider; import android.provider.DeviceConfig; import android.util.Pair; import android.view.WindowManager; import androidx.test.filters.SmallTest; Loading Loading @@ -126,6 +129,8 @@ public class BackgroundActivityStartControllerExemptionTests { AppOpsManager mAppOpsManager; MirrorActiveUids mActiveUids = new MirrorActiveUids(); WindowProcessControllerMap mProcessMap = new WindowProcessControllerMap(); @Mock VisibleActivityProcessTracker mVisibleActivityProcessTracker; @Mock ActivityTaskSupervisor mSupervisor; Loading Loading @@ -182,6 +187,8 @@ public class BackgroundActivityStartControllerExemptionTests { mService.mRootWindowContainer = mRootWindowContainer; when(mService.getAppOpsManager()).thenReturn(mAppOpsManager); setViaReflection(mService, "mProcessMap", mProcessMap); setViaReflection(mService, "mVisibleActivityProcessTracker", mVisibleActivityProcessTracker); setViaReflection(mSupervisor, "mRecentTasks", mRecentTasks); Loading Loading @@ -257,7 +264,7 @@ public class BackgroundActivityStartControllerExemptionTests { int realCallingPid = REGULAR_PID_2; // setup state when(mService.hasActiveVisibleWindow(eq(callingUid))).thenReturn(true); when(mVisibleActivityProcessTracker.hasVisibleActivity(eq(callingUid))).thenReturn(true); when(mService.getBalAppSwitchesState()).thenReturn(APP_SWITCH_ALLOW); // prepare call Loading @@ -269,6 +276,8 @@ public class BackgroundActivityStartControllerExemptionTests { callingPid, callingPackage, realCallingUid, realCallingPid, mCallerApp, originatingPendingIntent, allowBalExemptionForSystemProcess, mResultRecord, intent, checkedOptions); assertThat(balState.toString()).contains("callingUidHasVisibleActivity: true"); assertThat(balState.toString()).contains("callingUidHasNonAppVisibleWindow: false"); // call BalVerdict callerVerdict = mController.checkBackgroundActivityStartAllowedByCaller( Loading @@ -289,7 +298,8 @@ public class BackgroundActivityStartControllerExemptionTests { int realCallingPid = REGULAR_PID_2; // setup state when(mService.hasActiveVisibleWindow(eq(realCallingUid))).thenReturn(true); when(mVisibleActivityProcessTracker.hasVisibleActivity(eq(realCallingUid))).thenReturn( true); when(mService.getBalAppSwitchesState()).thenReturn(APP_SWITCH_ALLOW); // prepare call Loading @@ -301,6 +311,8 @@ public class BackgroundActivityStartControllerExemptionTests { callingPid, callingPackage, realCallingUid, realCallingPid, mCallerApp, originatingPendingIntent, allowBalExemptionForSystemProcess, mResultRecord, intent, checkedOptions); assertThat(balState.toString()).contains("realCallingUidHasVisibleActivity: true"); assertThat(balState.toString()).contains("realCallingUidHasNonAppVisibleWindow: false"); // call BalVerdict realCallerVerdict = mController.checkBackgroundActivityStartAllowedByRealCaller( Loading @@ -312,6 +324,74 @@ public class BackgroundActivityStartControllerExemptionTests { BAL_ALLOW_VISIBLE_WINDOW); } @Test public void testCaller_appHasNonAppVisibleWindow() { int callingUid = REGULAR_UID_1; int callingPid = REGULAR_PID_1; final String callingPackage = REGULAR_PACKAGE_1; int realCallingUid = REGULAR_UID_2; int realCallingPid = REGULAR_PID_2; // setup state mActiveUids.onNonAppSurfaceVisibilityChanged(callingUid, true); when(mService.getBalAppSwitchesState()).thenReturn(APP_SWITCH_ALLOW); // prepare call PendingIntentRecord originatingPendingIntent = mPendingIntentRecord; boolean allowBalExemptionForSystemProcess = false; Intent intent = TEST_INTENT; ActivityOptions checkedOptions = mCheckedOptions; BackgroundActivityStartController.BalState balState = mController.new BalState(callingUid, callingPid, callingPackage, realCallingUid, realCallingPid, mCallerApp, originatingPendingIntent, allowBalExemptionForSystemProcess, mResultRecord, intent, checkedOptions); assertThat(balState.toString()).contains("callingUidHasVisibleActivity: false"); assertThat(balState.toString()).contains("callingUidHasNonAppVisibleWindow: true"); // call BalVerdict callerVerdict = mController.checkBackgroundActivityStartAllowedByCaller( balState); balState.setResultForCaller(callerVerdict); // assertions assertWithMessage(balState.toString()).that(callerVerdict.getCode()).isEqualTo( BAL_ALLOW_NON_APP_VISIBLE_WINDOW); } @Test public void testRealCaller_appHasNonAppVisibleWindow() { int callingUid = REGULAR_UID_1; int callingPid = REGULAR_PID_1; final String callingPackage = REGULAR_PACKAGE_1; int realCallingUid = REGULAR_UID_2; int realCallingPid = REGULAR_PID_2; // setup state mActiveUids.onNonAppSurfaceVisibilityChanged(realCallingUid, true); when(mService.getBalAppSwitchesState()).thenReturn(APP_SWITCH_ALLOW); // prepare call PendingIntentRecord originatingPendingIntent = mPendingIntentRecord; boolean allowBalExemptionForSystemProcess = false; Intent intent = TEST_INTENT; ActivityOptions checkedOptions = mCheckedOptions; BackgroundActivityStartController.BalState balState = mController.new BalState(callingUid, callingPid, callingPackage, realCallingUid, realCallingPid, mCallerApp, originatingPendingIntent, allowBalExemptionForSystemProcess, mResultRecord, intent, checkedOptions); assertThat(balState.toString()).contains("realCallingUidHasVisibleActivity: false"); assertThat(balState.toString()).contains("realCallingUidHasNonAppVisibleWindow: true"); // call BalVerdict realCallerVerdict = mController.checkBackgroundActivityStartAllowedByRealCaller( balState); balState.setResultForRealCaller(realCallerVerdict); // assertions assertWithMessage(balState.toString()).that(realCallerVerdict.getCode()).isEqualTo( BAL_ALLOW_NON_APP_VISIBLE_WINDOW); } @Test @RequiresFlagsEnabled(Flags.FLAG_BAL_ADDITIONAL_START_MODES) public void testCaller_appHasVisibleWindowWithIfVisibleOptIn() { Loading @@ -322,7 +402,7 @@ public class BackgroundActivityStartControllerExemptionTests { int realCallingPid = REGULAR_PID_2; // setup state when(mService.hasActiveVisibleWindow(eq(callingUid))).thenReturn(true); when(mVisibleActivityProcessTracker.hasVisibleActivity(eq(callingUid))).thenReturn(true); when(mService.getBalAppSwitchesState()).thenReturn(APP_SWITCH_ALLOW); // prepare call Loading @@ -336,6 +416,8 @@ public class BackgroundActivityStartControllerExemptionTests { callingPid, callingPackage, realCallingUid, realCallingPid, mCallerApp, originatingPendingIntent, allowBalExemptionForSystemProcess, mResultRecord, intent, checkedOptions); assertThat(balState.toString()).contains("callingUidHasVisibleActivity: true"); assertThat(balState.toString()).contains("callingUidHasNonAppVisibleWindow: false"); // call BalVerdict callerVerdict = mController.checkBackgroundActivityStartAllowedByCaller( Loading @@ -357,7 +439,8 @@ public class BackgroundActivityStartControllerExemptionTests { int realCallingPid = REGULAR_PID_2; // setup state when(mService.hasActiveVisibleWindow(eq(realCallingUid))).thenReturn(true); when(mVisibleActivityProcessTracker.hasVisibleActivity(eq(realCallingUid))).thenReturn( true); when(mService.getBalAppSwitchesState()).thenReturn(APP_SWITCH_ALLOW); // prepare call Loading @@ -371,6 +454,8 @@ public class BackgroundActivityStartControllerExemptionTests { callingPid, callingPackage, realCallingUid, realCallingPid, mCallerApp, originatingPendingIntent, allowBalExemptionForSystemProcess, mResultRecord, intent, checkedOptions); assertThat(balState.toString()).contains("realCallingUidHasVisibleActivity: true"); assertThat(balState.toString()).contains("realCallingUidHasNonAppVisibleWindow: false"); // call BalVerdict realCallerVerdict = mController.checkBackgroundActivityStartAllowedByRealCaller( Loading
services/tests/wmtests/src/com/android/server/wm/BackgroundActivityStartControllerLogTests.java +4 −0 Original line number Diff line number Diff line Loading @@ -67,12 +67,16 @@ public class BackgroundActivityStartControllerLogTests { @Mock PendingIntentRecord mPendingIntentRecord; MirrorActiveUids mActiveUids = new MirrorActiveUids(); @Mock VisibleActivityProcessTracker mVisibleActivityProcessTracker; BackgroundActivityStartController mController; BackgroundActivityStartController.BalState mState; @Before public void setup() { setViaReflection(mService, "mActiveUids", mActiveUids); setViaReflection(mService, "mVisibleActivityProcessTracker", mVisibleActivityProcessTracker); mController = new BackgroundActivityStartController(mService, mSupervisor); } Loading
services/tests/wmtests/src/com/android/server/wm/BackgroundActivityStartControllerTests.java +23 −8 Original line number Diff line number Diff line Loading @@ -111,6 +111,9 @@ public class BackgroundActivityStartControllerTests { @Mock AppOpsManager mAppOpsManager; MirrorActiveUids mActiveUids = new MirrorActiveUids(); @Mock VisibleActivityProcessTracker mVisibleActivityProcessTracker; WindowProcessControllerMap mProcessMap = new WindowProcessControllerMap(); @Mock Loading Loading @@ -200,6 +203,8 @@ public class BackgroundActivityStartControllerTests { mService.mRootWindowContainer = mRootWindowContainer; Mockito.when(mService.getAppOpsManager()).thenReturn(mAppOpsManager); setViaReflection(mService, "mProcessMap", mProcessMap); setViaReflection(mService, "mVisibleActivityProcessTracker", mVisibleActivityProcessTracker); //Mockito.when(mSupervisor.getBackgroundActivityLaunchController()).thenReturn(mController); setViaReflection(mSupervisor, "mRecentTasks", mRecentTasks); Loading Loading @@ -551,13 +556,14 @@ public class BackgroundActivityStartControllerTests { assertThat(balState.callerExplicitOptInOrOut()).isFalse(); assertThat(balState.realCallerExplicitOptInOrAutoOptIn()).isTrue(); assertThat(balState.realCallerExplicitOptInOrOut()).isFalse(); assertThat(balState.toString()).startsWith( assertThat(balState.toString()).isEqualTo( "[callingPackage: package.app1; " + "callingPackageTargetSdk: -1; " + "callingUid: 10001; " + "callingPid: 11001; " + "appSwitchState: 0; " + "callingUidHasAnyVisibleWindow: false; " + "callingUidHasVisibleActivity: false; " + "callingUidHasNonAppVisibleWindow: false; " + "callingUidProcState: NONEXISTENT; " + "isCallingUidPersistentSystemProcess: false; " + "allowBalExemptionForSystemProcess: false; " Loading @@ -576,13 +582,17 @@ public class BackgroundActivityStartControllerTests { + "realCallingPackageTargetSdk: -1; " + "realCallingUid: 1; " + "realCallingPid: 1; " + "realCallingUidHasAnyVisibleWindow: false; " + "realCallingUidHasVisibleActivity: false; " + "realCallingUidHasNonAppVisibleWindow: false; " + "realCallingUidProcState: NONEXISTENT; " + "isRealCallingUidPersistentSystemProcess: false; " + "originatingPendingIntent: null; " + "realCallerApp: null; " + "balAllowedByPiSender: BSP.ALLOW_BAL; " + "resultIfPiSenderAllowsBal: null"); + "resultIfPiSenderAllowsBal: null; " + "realCallerStartMode: MODE_BACKGROUND_ACTIVITY_START_SYSTEM_DEFINED; " + "balRequireOptInByPendingIntentCreator: true; " + "balDontBringExistingBackgroundTaskStackToFg: true]"); } @Test Loading Loading @@ -651,13 +661,14 @@ public class BackgroundActivityStartControllerTests { assertThat(balState.callerExplicitOptInOrOut()).isFalse(); assertThat(balState.realCallerExplicitOptInOrAutoOptIn()).isFalse(); assertThat(balState.realCallerExplicitOptInOrOut()).isFalse(); assertThat(balState.toString()).startsWith( assertThat(balState.toString()).isEqualTo( "[callingPackage: package.app1; " + "callingPackageTargetSdk: -1; " + "callingUid: 10001; " + "callingPid: 11001; " + "appSwitchState: 0; " + "callingUidHasAnyVisibleWindow: false; " + "callingUidHasVisibleActivity: false; " + "callingUidHasNonAppVisibleWindow: false; " + "callingUidProcState: NONEXISTENT; " + "isCallingUidPersistentSystemProcess: false; " + "allowBalExemptionForSystemProcess: false; " Loading @@ -676,12 +687,16 @@ public class BackgroundActivityStartControllerTests { + "realCallingPackageTargetSdk: -1; " + "realCallingUid: 1; " + "realCallingPid: 1; " + "realCallingUidHasAnyVisibleWindow: false; " + "realCallingUidHasVisibleActivity: false; " + "realCallingUidHasNonAppVisibleWindow: false; " + "realCallingUidProcState: NONEXISTENT; " + "isRealCallingUidPersistentSystemProcess: false; " + "originatingPendingIntent: PendingIntentRecord; " + "realCallerApp: null; " + "balAllowedByPiSender: BSP.ALLOW_FGS; " + "resultIfPiSenderAllowsBal: null"); + "resultIfPiSenderAllowsBal: null; " + "realCallerStartMode: MODE_BACKGROUND_ACTIVITY_START_SYSTEM_DEFINED; " + "balRequireOptInByPendingIntentCreator: true; " + "balDontBringExistingBackgroundTaskStackToFg: true]"); } }