Loading services/core/java/com/android/server/wm/BackgroundActivityStartController.java +28 −15 Original line number Diff line number Diff line Loading @@ -80,6 +80,8 @@ import android.util.ArraySet; import android.util.DebugUtils; import android.util.Slog; import android.util.SparseArray; import android.util.SparseIntArray; import android.view.WindowManager; import android.widget.Toast; import com.android.internal.R; Loading Loading @@ -230,6 +232,12 @@ public class BackgroundActivityStartController { static final int BAL_ALLOW_BOUND_BY_FOREGROUND = FrameworkStatsLog.BAL_ALLOWED__ALLOWED_REASON__BAL_ALLOW_BOUND_BY_FOREGROUND; static final int BAL_ALLOW_NOTIFICATION_TOKEN = FrameworkStatsLog.BAL_ALLOWED__ALLOWED_REASON__BAL_ALLOW_NOTIFICATION_TOKEN; static final int BAL_ALLOW_WALLPAPER = FrameworkStatsLog.BAL_ALLOWED__ALLOWED_REASON__BAL_ALLOW_WALLPAPER; static String balCodeToString(@BalCode int balCode) { return switch (balCode) { case BAL_ALLOW_ALLOWLISTED_COMPONENT -> "BAL_ALLOW_ALLOWLISTED_COMPONENT"; Loading @@ -245,6 +253,8 @@ public class BackgroundActivityStartController { case BAL_ALLOW_SDK_SANDBOX -> "BAL_ALLOW_SDK_SANDBOX"; case BAL_ALLOW_TOKEN -> "BAL_ALLOW_TOKEN"; case BAL_ALLOW_VISIBLE_WINDOW -> "BAL_ALLOW_VISIBLE_WINDOW"; case BAL_ALLOW_NOTIFICATION_TOKEN -> "BAL_ALLOW_NOTIFICATION_TOKEN"; case BAL_ALLOW_WALLPAPER -> "BAL_ALLOW_WALLPAPER"; case BAL_BLOCK -> "BAL_BLOCK"; default -> throw new IllegalArgumentException("Unexpected value: " + balCode); }; Loading Loading @@ -1053,14 +1063,22 @@ public class BackgroundActivityStartController { return BalVerdict.BLOCK; }; private final BalExemptionCheck mCheckCallerNonAppVisible = state -> { if (state.mCallingUidHasNonAppVisibleWindow) { private BalVerdict checkNonAppVisibleWindow(int uid, boolean hasNonAppVisibleWindow) { if (hasNonAppVisibleWindow) { SparseIntArray nonAppVisibleWindowDetails = getService().mActiveUids.getNonAppVisibleWindowDetails(uid); if (nonAppVisibleWindowDetails.size() == 1 && nonAppVisibleWindowDetails.get( WindowManager.LayoutParams.TYPE_WALLPAPER) > 0) { return new BalVerdict(BAL_ALLOW_WALLPAPER, "uid has wallpaper window"); } return new BalVerdict(BAL_ALLOW_NON_APP_VISIBLE_WINDOW, "callingUid has non-app visible window " + getService().mActiveUids.getNonAppVisibleWindowDetails(state.mCallingUid)); "uid has non-app visible window " + nonAppVisibleWindowDetails); } return BalVerdict.BLOCK; }; } private final BalExemptionCheck mCheckCallerNonAppVisible = state -> checkNonAppVisibleWindow(state.mCallingUid, state.mCallingUidHasNonAppVisibleWindow); private final BalExemptionCheck mCheckCallerIsAllowlistedUid = state -> { // don't abort for the most important UIDs Loading Loading @@ -1183,15 +1201,9 @@ public class BackgroundActivityStartController { return BalVerdict.BLOCK; }; private final BalExemptionCheck mCheckRealCallerNonAppVisible = state -> { if (state.mRealCallingUidHasNonAppVisibleWindow) { return new BalVerdict(BAL_ALLOW_NON_APP_VISIBLE_WINDOW, "realCallingUid has non-app visible window " + getService().mActiveUids.getNonAppVisibleWindowDetails( state.mRealCallingUid)); } return BalVerdict.BLOCK; }; private final BalExemptionCheck mCheckRealCallerNonAppVisible = state -> checkNonAppVisibleWindow(state.mRealCallingUid, state.mRealCallingUidHasNonAppVisibleWindow); // Don't abort if the realCallerApp or other processes of that uid are considered to be in // the foreground. Loading Loading @@ -1951,7 +1963,8 @@ public class BackgroundActivityStartController { } } logIfOnlyAllowedBy(finalVerdict, state, BAL_ALLOW_NON_APP_VISIBLE_WINDOW); logIfOnlyAllowedBy(finalVerdict, state, BAL_ALLOW_TOKEN); logIfOnlyAllowedBy(finalVerdict, state, BAL_ALLOW_NOTIFICATION_TOKEN); logIfOnlyAllowedBy(finalVerdict, state, BAL_ALLOW_WALLPAPER); if (shouldLogStats(finalVerdict, state)) { String activityName; Loading services/core/java/com/android/server/wm/BackgroundLaunchProcessController.java +2 −1 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import static com.android.server.wm.ActivityTaskManagerService.APP_SWITCH_DISALL import static com.android.server.wm.BackgroundActivityStartController.BAL_ALLOW_BOUND_BY_FOREGROUND; import static com.android.server.wm.BackgroundActivityStartController.BAL_ALLOW_FOREGROUND; import static com.android.server.wm.BackgroundActivityStartController.BAL_ALLOW_GRACE_PERIOD; import static com.android.server.wm.BackgroundActivityStartController.BAL_ALLOW_NOTIFICATION_TOKEN; import static com.android.server.wm.BackgroundActivityStartController.BAL_ALLOW_PERMISSION; import static com.android.server.wm.BackgroundActivityStartController.BAL_ALLOW_TOKEN; Loading Loading @@ -219,7 +220,7 @@ class BackgroundLaunchProcessController { return new BalVerdict(BAL_ALLOW_TOKEN, "process allowed by callback (token ignored) tokens: " + binderTokens); } return new BalVerdict(BAL_ALLOW_TOKEN, return new BalVerdict(BAL_ALLOW_NOTIFICATION_TOKEN, "process allowed by callback (token: " + activityStartAllowed.token() + ") tokens: " + binderTokens); } Loading services/tests/wmtests/src/com/android/server/wm/BackgroundActivityStartControllerExemptionTests.java +71 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ import static com.android.server.wm.BackgroundActivityStartController.BAL_ALLOW_ 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_ALLOW_WALLPAPER; import static com.android.server.wm.BackgroundActivityStartController.BAL_BLOCK; import static com.google.common.truth.Truth.assertThat; Loading Loading @@ -451,6 +452,41 @@ public class BackgroundActivityStartControllerExemptionTests { BAL_ALLOW_NON_APP_VISIBLE_WINDOW); } @Test public void testCaller_appHasVisibleWallpaper() { 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, WindowManager.LayoutParams.TYPE_WALLPAPER, 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_WALLPAPER); } @Test public void testRealCaller_appHasNonAppVisibleWindow() { int callingUid = REGULAR_UID_1; Loading Loading @@ -486,6 +522,41 @@ public class BackgroundActivityStartControllerExemptionTests { BAL_ALLOW_NON_APP_VISIBLE_WINDOW); } @Test public void testRealCaller_appHasVisibleWallpaper() { 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, WindowManager.LayoutParams.TYPE_WALLPAPER, 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_WALLPAPER); } @Test @RequiresFlagsEnabled(Flags.FLAG_BAL_ADDITIONAL_START_MODES) public void testCaller_appHasVisibleWindowWithIfVisibleOptIn() { Loading services/tests/wmtests/src/com/android/server/wm/BackgroundLaunchProcessControllerTests.java +16 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import static com.android.server.wm.ActivityTaskManagerService.APP_SWITCH_DISALL import static com.android.server.wm.BackgroundActivityStartController.BAL_ALLOW_BOUND_BY_FOREGROUND; import static com.android.server.wm.BackgroundActivityStartController.BAL_ALLOW_FOREGROUND; import static com.android.server.wm.BackgroundActivityStartController.BAL_ALLOW_GRACE_PERIOD; import static com.android.server.wm.BackgroundActivityStartController.BAL_ALLOW_NOTIFICATION_TOKEN; import static com.android.server.wm.BackgroundActivityStartController.BAL_ALLOW_PERMISSION; import static com.android.server.wm.BackgroundActivityStartController.BAL_ALLOW_TOKEN; import static com.android.server.wm.BackgroundActivityStartController.BAL_BLOCK; Loading Loading @@ -152,6 +153,21 @@ public class BackgroundLaunchProcessControllerTests { public void testAllowedByToken() { Binder token = new Binder(); mActivityStartAllowed.add(token); mController.addOrUpdateAllowBackgroundStartPrivileges(token, BackgroundStartPrivileges.allowBackgroundActivityStarts(token)); BalVerdict balVerdict = mController.areBackgroundActivityStartsAllowed( mPid, mUid, mPackageName, mAppSwitchState, mBalCheckConfiguration, mHasActivityInVisibleTask, mInPinnedWindoMode, mHasBackgroundActivityStartPrivileges, mLastStopAppSwitchesTime, mLastActivityLaunchTime, mLastActivityFinishTime); assertThat(balVerdict.getCode()).isEqualTo(BAL_ALLOW_NOTIFICATION_TOKEN); } @Test public void testAllowedByNullToken() { Binder token = new Binder(); mController.addOrUpdateAllowBackgroundStartPrivileges(token, BackgroundStartPrivileges.ALLOW_BAL); BalVerdict balVerdict = mController.areBackgroundActivityStartsAllowed( Loading Loading
services/core/java/com/android/server/wm/BackgroundActivityStartController.java +28 −15 Original line number Diff line number Diff line Loading @@ -80,6 +80,8 @@ import android.util.ArraySet; import android.util.DebugUtils; import android.util.Slog; import android.util.SparseArray; import android.util.SparseIntArray; import android.view.WindowManager; import android.widget.Toast; import com.android.internal.R; Loading Loading @@ -230,6 +232,12 @@ public class BackgroundActivityStartController { static final int BAL_ALLOW_BOUND_BY_FOREGROUND = FrameworkStatsLog.BAL_ALLOWED__ALLOWED_REASON__BAL_ALLOW_BOUND_BY_FOREGROUND; static final int BAL_ALLOW_NOTIFICATION_TOKEN = FrameworkStatsLog.BAL_ALLOWED__ALLOWED_REASON__BAL_ALLOW_NOTIFICATION_TOKEN; static final int BAL_ALLOW_WALLPAPER = FrameworkStatsLog.BAL_ALLOWED__ALLOWED_REASON__BAL_ALLOW_WALLPAPER; static String balCodeToString(@BalCode int balCode) { return switch (balCode) { case BAL_ALLOW_ALLOWLISTED_COMPONENT -> "BAL_ALLOW_ALLOWLISTED_COMPONENT"; Loading @@ -245,6 +253,8 @@ public class BackgroundActivityStartController { case BAL_ALLOW_SDK_SANDBOX -> "BAL_ALLOW_SDK_SANDBOX"; case BAL_ALLOW_TOKEN -> "BAL_ALLOW_TOKEN"; case BAL_ALLOW_VISIBLE_WINDOW -> "BAL_ALLOW_VISIBLE_WINDOW"; case BAL_ALLOW_NOTIFICATION_TOKEN -> "BAL_ALLOW_NOTIFICATION_TOKEN"; case BAL_ALLOW_WALLPAPER -> "BAL_ALLOW_WALLPAPER"; case BAL_BLOCK -> "BAL_BLOCK"; default -> throw new IllegalArgumentException("Unexpected value: " + balCode); }; Loading Loading @@ -1053,14 +1063,22 @@ public class BackgroundActivityStartController { return BalVerdict.BLOCK; }; private final BalExemptionCheck mCheckCallerNonAppVisible = state -> { if (state.mCallingUidHasNonAppVisibleWindow) { private BalVerdict checkNonAppVisibleWindow(int uid, boolean hasNonAppVisibleWindow) { if (hasNonAppVisibleWindow) { SparseIntArray nonAppVisibleWindowDetails = getService().mActiveUids.getNonAppVisibleWindowDetails(uid); if (nonAppVisibleWindowDetails.size() == 1 && nonAppVisibleWindowDetails.get( WindowManager.LayoutParams.TYPE_WALLPAPER) > 0) { return new BalVerdict(BAL_ALLOW_WALLPAPER, "uid has wallpaper window"); } return new BalVerdict(BAL_ALLOW_NON_APP_VISIBLE_WINDOW, "callingUid has non-app visible window " + getService().mActiveUids.getNonAppVisibleWindowDetails(state.mCallingUid)); "uid has non-app visible window " + nonAppVisibleWindowDetails); } return BalVerdict.BLOCK; }; } private final BalExemptionCheck mCheckCallerNonAppVisible = state -> checkNonAppVisibleWindow(state.mCallingUid, state.mCallingUidHasNonAppVisibleWindow); private final BalExemptionCheck mCheckCallerIsAllowlistedUid = state -> { // don't abort for the most important UIDs Loading Loading @@ -1183,15 +1201,9 @@ public class BackgroundActivityStartController { return BalVerdict.BLOCK; }; private final BalExemptionCheck mCheckRealCallerNonAppVisible = state -> { if (state.mRealCallingUidHasNonAppVisibleWindow) { return new BalVerdict(BAL_ALLOW_NON_APP_VISIBLE_WINDOW, "realCallingUid has non-app visible window " + getService().mActiveUids.getNonAppVisibleWindowDetails( state.mRealCallingUid)); } return BalVerdict.BLOCK; }; private final BalExemptionCheck mCheckRealCallerNonAppVisible = state -> checkNonAppVisibleWindow(state.mRealCallingUid, state.mRealCallingUidHasNonAppVisibleWindow); // Don't abort if the realCallerApp or other processes of that uid are considered to be in // the foreground. Loading Loading @@ -1951,7 +1963,8 @@ public class BackgroundActivityStartController { } } logIfOnlyAllowedBy(finalVerdict, state, BAL_ALLOW_NON_APP_VISIBLE_WINDOW); logIfOnlyAllowedBy(finalVerdict, state, BAL_ALLOW_TOKEN); logIfOnlyAllowedBy(finalVerdict, state, BAL_ALLOW_NOTIFICATION_TOKEN); logIfOnlyAllowedBy(finalVerdict, state, BAL_ALLOW_WALLPAPER); if (shouldLogStats(finalVerdict, state)) { String activityName; Loading
services/core/java/com/android/server/wm/BackgroundLaunchProcessController.java +2 −1 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import static com.android.server.wm.ActivityTaskManagerService.APP_SWITCH_DISALL import static com.android.server.wm.BackgroundActivityStartController.BAL_ALLOW_BOUND_BY_FOREGROUND; import static com.android.server.wm.BackgroundActivityStartController.BAL_ALLOW_FOREGROUND; import static com.android.server.wm.BackgroundActivityStartController.BAL_ALLOW_GRACE_PERIOD; import static com.android.server.wm.BackgroundActivityStartController.BAL_ALLOW_NOTIFICATION_TOKEN; import static com.android.server.wm.BackgroundActivityStartController.BAL_ALLOW_PERMISSION; import static com.android.server.wm.BackgroundActivityStartController.BAL_ALLOW_TOKEN; Loading Loading @@ -219,7 +220,7 @@ class BackgroundLaunchProcessController { return new BalVerdict(BAL_ALLOW_TOKEN, "process allowed by callback (token ignored) tokens: " + binderTokens); } return new BalVerdict(BAL_ALLOW_TOKEN, return new BalVerdict(BAL_ALLOW_NOTIFICATION_TOKEN, "process allowed by callback (token: " + activityStartAllowed.token() + ") tokens: " + binderTokens); } Loading
services/tests/wmtests/src/com/android/server/wm/BackgroundActivityStartControllerExemptionTests.java +71 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ import static com.android.server.wm.BackgroundActivityStartController.BAL_ALLOW_ 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_ALLOW_WALLPAPER; import static com.android.server.wm.BackgroundActivityStartController.BAL_BLOCK; import static com.google.common.truth.Truth.assertThat; Loading Loading @@ -451,6 +452,41 @@ public class BackgroundActivityStartControllerExemptionTests { BAL_ALLOW_NON_APP_VISIBLE_WINDOW); } @Test public void testCaller_appHasVisibleWallpaper() { 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, WindowManager.LayoutParams.TYPE_WALLPAPER, 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_WALLPAPER); } @Test public void testRealCaller_appHasNonAppVisibleWindow() { int callingUid = REGULAR_UID_1; Loading Loading @@ -486,6 +522,41 @@ public class BackgroundActivityStartControllerExemptionTests { BAL_ALLOW_NON_APP_VISIBLE_WINDOW); } @Test public void testRealCaller_appHasVisibleWallpaper() { 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, WindowManager.LayoutParams.TYPE_WALLPAPER, 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_WALLPAPER); } @Test @RequiresFlagsEnabled(Flags.FLAG_BAL_ADDITIONAL_START_MODES) public void testCaller_appHasVisibleWindowWithIfVisibleOptIn() { Loading
services/tests/wmtests/src/com/android/server/wm/BackgroundLaunchProcessControllerTests.java +16 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import static com.android.server.wm.ActivityTaskManagerService.APP_SWITCH_DISALL import static com.android.server.wm.BackgroundActivityStartController.BAL_ALLOW_BOUND_BY_FOREGROUND; import static com.android.server.wm.BackgroundActivityStartController.BAL_ALLOW_FOREGROUND; import static com.android.server.wm.BackgroundActivityStartController.BAL_ALLOW_GRACE_PERIOD; import static com.android.server.wm.BackgroundActivityStartController.BAL_ALLOW_NOTIFICATION_TOKEN; import static com.android.server.wm.BackgroundActivityStartController.BAL_ALLOW_PERMISSION; import static com.android.server.wm.BackgroundActivityStartController.BAL_ALLOW_TOKEN; import static com.android.server.wm.BackgroundActivityStartController.BAL_BLOCK; Loading Loading @@ -152,6 +153,21 @@ public class BackgroundLaunchProcessControllerTests { public void testAllowedByToken() { Binder token = new Binder(); mActivityStartAllowed.add(token); mController.addOrUpdateAllowBackgroundStartPrivileges(token, BackgroundStartPrivileges.allowBackgroundActivityStarts(token)); BalVerdict balVerdict = mController.areBackgroundActivityStartsAllowed( mPid, mUid, mPackageName, mAppSwitchState, mBalCheckConfiguration, mHasActivityInVisibleTask, mInPinnedWindoMode, mHasBackgroundActivityStartPrivileges, mLastStopAppSwitchesTime, mLastActivityLaunchTime, mLastActivityFinishTime); assertThat(balVerdict.getCode()).isEqualTo(BAL_ALLOW_NOTIFICATION_TOKEN); } @Test public void testAllowedByNullToken() { Binder token = new Binder(); mController.addOrUpdateAllowBackgroundStartPrivileges(token, BackgroundStartPrivileges.ALLOW_BAL); BalVerdict balVerdict = mController.areBackgroundActivityStartsAllowed( Loading