Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 294a98e5 authored by Achim Thesmann's avatar Achim Thesmann Committed by Android Build Coastguard Worker
Browse files

Revert "RESTRICT AUTOMERGE Ignore pinned Windows"

This reverts commit 85f96289058efd23af98480e8cc74cc073662676.

Reason for revert: app compatibility regression

Bug: 406880479
Cherrypick-From: https://googleplex-android-review.googlesource.com/q/commit:1ee36749484bf96fd866081c24f7bca8fd47fdd7
Merged-In: I7f1239055d24718529afdd34e7b44497f7051518
Change-Id: I7f1239055d24718529afdd34e7b44497f7051518
parent bc7d429e
Loading
Loading
Loading
Loading
+16 −48
Original line number Diff line number Diff line
@@ -245,9 +245,7 @@ public class BackgroundActivityStartController {
        private final int mCallingUid;
        private final int mCallingPid;
        private final @ActivityTaskManagerService.AppSwitchState int mAppSwitchState;
        private final boolean mCallingUidHasVisibleActivity;
        private final boolean mCallingUidHasVisibleNotPinnedActivity;
        private final boolean mCallingUidHasNonAppVisibleWindow;
        private final boolean mCallingUidHasAnyVisibleWindow;
        private final @ActivityManager.ProcessState int mCallingUidProcState;
        private final boolean mIsCallingUidPersistentSystemProcess;
        final BackgroundStartPrivileges mBalAllowedByPiSender;
@@ -256,9 +254,7 @@ public class BackgroundActivityStartController {
        private final String mRealCallingPackage;
        private final int mRealCallingUid;
        private final int mRealCallingPid;
        private final boolean mRealCallingUidHasVisibleActivity;
        private final boolean mRealCallingUidHasVisibleNotPinnedActivity;
        private final boolean mRealCallingUidHasNonAppVisibleWindow;
        private final boolean mRealCallingUidHasAnyVisibleWindow;
        private final @ActivityManager.ProcessState int mRealCallingUidProcState;
        private final boolean mIsRealCallingUidPersistentSystemProcess;
        private final PendingIntentRecord mOriginatingPendingIntent;
@@ -357,25 +353,16 @@ public class BackgroundActivityStartController {
            mCallingUidProcState = mService.mActiveUids.getUidState(callingUid);
            mIsCallingUidPersistentSystemProcess =
                    mCallingUidProcState <= ActivityManager.PROCESS_STATE_PERSISTENT_UI;
            mCallingUidHasVisibleActivity =
                    mService.mVisibleActivityProcessTracker.hasVisibleActivity(callingUid);
            mCallingUidHasVisibleNotPinnedActivity = mService.mVisibleActivityProcessTracker
                    .hasVisibleNotPinnedActivity(callingUid);
            mCallingUidHasNonAppVisibleWindow = mService.mActiveUids.hasNonAppVisibleWindow(
                    callingUid);
            mCallingUidHasAnyVisibleWindow = mService.hasActiveVisibleWindow(callingUid);
            if (realCallingUid == NO_PROCESS_UID) {
                // no process provided
                mRealCallingUidProcState = PROCESS_STATE_NONEXISTENT;
                mRealCallingUidHasVisibleActivity = false;
                mRealCallingUidHasNonAppVisibleWindow = false;
                mRealCallingUidHasVisibleNotPinnedActivity = false;
                mRealCallingUidHasAnyVisibleWindow = false;
                mRealCallerApp = null;
                mIsRealCallingUidPersistentSystemProcess = false;
            } else if (callingUid == realCallingUid) {
                mRealCallingUidProcState = mCallingUidProcState;
                mRealCallingUidHasVisibleActivity = mCallingUidHasVisibleActivity;
                mRealCallingUidHasVisibleNotPinnedActivity = mCallingUidHasVisibleNotPinnedActivity;
                mRealCallingUidHasNonAppVisibleWindow = mCallingUidHasNonAppVisibleWindow;
                mRealCallingUidHasAnyVisibleWindow = mCallingUidHasAnyVisibleWindow;
                // In the PendingIntent case callerApp is not passed in, so resolve it ourselves.
                mRealCallerApp = callerApp == null
                        ? mService.getProcessController(realCallingPid, realCallingUid)
@@ -383,14 +370,8 @@ public class BackgroundActivityStartController {
                mIsRealCallingUidPersistentSystemProcess = mIsCallingUidPersistentSystemProcess;
            } else {
                mRealCallingUidProcState = mService.mActiveUids.getUidState(realCallingUid);
                mRealCallingUidHasVisibleActivity =
                        mService.mVisibleActivityProcessTracker.hasVisibleActivity(
                                realCallingUid);
                mRealCallingUidHasVisibleNotPinnedActivity =
                        mService.mVisibleActivityProcessTracker.hasVisibleNotPinnedActivity(
                                realCallingUid);
                mRealCallingUidHasNonAppVisibleWindow =
                        mService.mActiveUids.hasNonAppVisibleWindow(realCallingUid);
                mRealCallingUidHasAnyVisibleWindow =
                        mService.hasActiveVisibleWindow(realCallingUid);
                mRealCallerApp = mService.getProcessController(realCallingPid, realCallingUid);
                mIsRealCallingUidPersistentSystemProcess =
                        mRealCallingUidProcState <= ActivityManager.PROCESS_STATE_PERSISTENT_UI;
@@ -519,11 +500,7 @@ public class BackgroundActivityStartController {
            sb.append("; callingUid: ").append(mCallingUid);
            sb.append("; callingPid: ").append(mCallingPid);
            sb.append("; appSwitchState: ").append(mAppSwitchState);
            sb.append("; callingUidHasVisibleActivity: ").append(mCallingUidHasVisibleActivity);
            sb.append("; callingUidHasVisibleNotPinnedActivity: ")
                    .append(mCallingUidHasVisibleNotPinnedActivity);
            sb.append("; callingUidHasNonAppVisibleWindow: ").append(
                    mCallingUidHasNonAppVisibleWindow);
            sb.append("; callingUidHasAnyVisibleWindow: ").append(mCallingUidHasAnyVisibleWindow);
            sb.append("; callingUidProcState: ").append(DebugUtils.valueToString(
                    ActivityManager.class, "PROCESS_STATE_", mCallingUidProcState));
            sb.append("; isCallingUidPersistentSystemProcess: ")
@@ -549,12 +526,8 @@ public class BackgroundActivityStartController {
                        .append(getTargetSdk(mRealCallingPackage));
                sb.append("; realCallingUid: ").append(mRealCallingUid);
                sb.append("; realCallingPid: ").append(mRealCallingPid);
                sb.append("; realCallingUidHasVisibleActivity: ")
                        .append(mRealCallingUidHasVisibleActivity);
                sb.append("; realCallingUidHasVisibleNotPinnedActivity: ")
                        .append(mRealCallingUidHasVisibleNotPinnedActivity);
                sb.append("; realCallingUidHasNonAppVisibleWindow: ")
                        .append(mRealCallingUidHasNonAppVisibleWindow);
                sb.append("; realCallingUidHasAnyVisibleWindow: ")
                        .append(mRealCallingUidHasAnyVisibleWindow);
                sb.append("; realCallingUidProcState: ").append(DebugUtils.valueToString(
                        ActivityManager.class, "PROCESS_STATE_", mRealCallingUidProcState));
                sb.append("; isRealCallingUidPersistentSystemProcess: ")
@@ -601,10 +574,6 @@ public class BackgroundActivityStartController {
        /** indicates that this verdict is based on the real calling UID and not the calling UID */
        private boolean mBasedOnRealCaller;

        BalVerdict(@BalCode int balCode, String message) {
            this(balCode, true, message);
        }

        BalVerdict(@BalCode int balCode, boolean background, String message) {
            this.mBackground = background;
            this.mCode = balCode;
@@ -835,9 +804,9 @@ 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.mCallingUidHasVisibleNotPinnedActivity) {
        if (appSwitchAllowedOrFg && state.mCallingUidHasAnyVisibleWindow) {
            return new BalVerdict(BAL_ALLOW_VISIBLE_WINDOW,
                    "callingUid has visible non-pinned window");
                    /*background*/ false, "callingUid has visible window");
        }
        if (mService.mActiveUids.hasNonAppVisibleWindow(state.mCallingUid)) {
            return new BalVerdict(BAL_ALLOW_NON_APP_VISIBLE_WINDOW,
@@ -949,7 +918,7 @@ public class BackgroundActivityStartController {
                || state.mAppSwitchState == APP_SWITCH_FG_ONLY
                || isHomeApp(state.mRealCallingUid, state.mRealCallingPackage);
        if (balImproveRealCallerVisibilityCheck()) {
            if (appSwitchAllowedOrFg && state.mRealCallingUidHasVisibleNotPinnedActivity) {
            if (appSwitchAllowedOrFg && state.mRealCallingUidHasAnyVisibleWindow) {
                return new BalVerdict(BAL_ALLOW_VISIBLE_WINDOW,
                        /*background*/ false, "realCallingUid has visible window");
            }
@@ -960,8 +929,7 @@ public class BackgroundActivityStartController {
        } else {
            // don't abort if the realCallingUid has a visible window
            // TODO(b/171459802): We should check appSwitchAllowed also
            if (state.mRealCallingUidHasVisibleNotPinnedActivity
                    || mService.mActiveUids.hasNonAppVisibleWindow(state.mRealCallingUid)) {
            if (state.mRealCallingUidHasAnyVisibleWindow) {
                return new BalVerdict(BAL_ALLOW_VISIBLE_WINDOW,
                        /*background*/ false,
                        "realCallingUid has visible (non-toast) window.");
@@ -1673,10 +1641,10 @@ public class BackgroundActivityStartController {
                            state.mCallingUid,
                            state.mCallingPackage,
                            state.mCallingUidProcState,
                            state.mCallingUidHasVisibleActivity,
                            state.mCallingUidHasAnyVisibleWindow,
                            state.mRealCallingUid,
                            state.mRealCallingUidProcState,
                            state.mRealCallingUidHasVisibleActivity,
                            state.mRealCallingUidHasAnyVisibleWindow,
                            (state.mOriginatingPendingIntent != null));
        }

+4 −7
Original line number Diff line number Diff line
@@ -100,8 +100,7 @@ class BackgroundLaunchProcessController {
    BalVerdict areBackgroundActivityStartsAllowed(
            int pid, int uid, String packageName,
            int appSwitchState, boolean isCheckingForFgsStart,
            boolean hasActivityInVisibleTask, boolean inPinnedWindow,
            boolean hasBackgroundActivityStartPrivileges,
            boolean hasActivityInVisibleTask, boolean hasBackgroundActivityStartPrivileges,
            long lastStopAppSwitchesTime, long lastActivityLaunchTime,
            long lastActivityFinishTime) {
        // Allow if the proc is instrumenting with background activity starts privs.
@@ -124,11 +123,9 @@ class BackgroundLaunchProcessController {
            return new BalVerdict(BAL_ALLOW_VISIBLE_WINDOW, /*background*/ false,
                    "process bound by foreground uid");
        }
        // Allow if the caller has an activity in any foreground task, unless it's a pinned window
        // and not a foreground service start.
        if ((isCheckingForFgsStart || !inPinnedWindow)
                && hasActivityInVisibleTask && appSwitchState != APP_SWITCH_DISALLOW) {
            return new BalVerdict(BAL_ALLOW_FOREGROUND, /*background*/
        // Allow if the caller has an activity in any foreground task.
        if (hasActivityInVisibleTask && appSwitchState != APP_SWITCH_DISALLOW) {
            return new BalVerdict(BAL_ALLOW_FOREGROUND, /*background*/ false,
                    "process has activity in foreground task");
        }

+2 −10
Original line number Diff line number Diff line
@@ -80,22 +80,14 @@ class VisibleActivityProcessTracker {
     * {@link ActivityRecord#mVisibleRequested} or {@link ActivityRecord#isVisible()} is true.
     */
    boolean hasVisibleActivity(int uid) {
        return match(uid, WindowContainer.alwaysTruePredicate());
    }

    /**
     * Returns {@code true} if the uid has a process that contains an activity with
     * {@link ActivityRecord#mVisibleRequested} or {@link ActivityRecord#isVisible()} is true.
     */
    boolean hasVisibleNotPinnedActivity(int uid) {
        return match(uid, wpc -> !wpc.inPinnedWindowingMode());
        return match(uid, null /* predicate */);
    }

    private boolean match(int uid, Predicate<WindowProcessController> predicate) {
        synchronized (mProcMap) {
            for (int i = mProcMap.size() - 1; i >= 0; i--) {
                final WindowProcessController wpc = mProcMap.keyAt(i);
                if (wpc.mUid == uid && predicate.test(wpc)) {
                if (wpc.mUid == uid && (predicate == null || predicate.test(wpc))) {
                    return true;
                }
            }
+1 −2
Original line number Diff line number Diff line
@@ -700,8 +700,7 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio
            int appSwitchState, boolean isCheckingForFgsStart) {
        return mBgLaunchController.areBackgroundActivityStartsAllowed(mPid, mUid,
                mInfo.packageName, appSwitchState, isCheckingForFgsStart,
                hasActivityInVisibleTask(), inPinnedWindowingMode(),
                mInstrumentingWithBackgroundActivityStartPrivileges,
                hasActivityInVisibleTask(), mInstrumentingWithBackgroundActivityStartPrivileges,
                mAtm.getLastStopAppSwitchesTime(),
                mLastActivityLaunchTime, mLastActivityFinishTime);
    }
+7 −180
Original line number Diff line number Diff line
@@ -19,11 +19,9 @@ package com.android.server.wm;
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;
@@ -43,7 +41,6 @@ import android.content.Intent;
import android.content.pm.PackageManagerInternal;
import android.os.UserHandle;
import android.platform.test.annotations.Presubmit;
import android.platform.test.flag.junit.SetFlagsRule;
import android.provider.DeviceConfig;
import android.util.Pair;

@@ -56,7 +53,6 @@ import com.android.server.wm.BackgroundActivityStartController.BalVerdict;

import org.junit.After;
import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -82,10 +78,6 @@ import java.util.Set;
@RunWith(JUnit4.class)
public class BackgroundActivityStartControllerExemptionTests {

    @ClassRule
    public static final SetFlagsRule.ClassRule mClassRule = new SetFlagsRule.ClassRule();
    @Rule public final SetFlagsRule mSetFlagsRule = mClassRule.createSetFlagsRule();

    private static final int REGULAR_UID_1 = 10100;
    private static final int REGULAR_UID_2 = 10200;
    private static final int NO_UID = -1;
@@ -125,8 +117,6 @@ public class BackgroundActivityStartControllerExemptionTests {
    AppOpsManager mAppOpsManager;
    MirrorActiveUids mActiveUids = new MirrorActiveUids();
    WindowProcessControllerMap mProcessMap = new WindowProcessControllerMap();
    @Mock
    VisibleActivityProcessTracker mVisibleActivityProcessTracker;

    @Mock
    ActivityTaskSupervisor mSupervisor;
@@ -184,8 +174,6 @@ public class BackgroundActivityStartControllerExemptionTests {
        mService.mRootWindowContainer = mRootWindowContainer;
        when(mService.getAppOpsManager()).thenReturn(mAppOpsManager);
        setViaReflection(mService, "mProcessMap", mProcessMap);
        setViaReflection(mService, "mVisibleActivityProcessTracker",
                mVisibleActivityProcessTracker);

        //Mockito.when(mSupervisor.getBackgroundActivityLaunchController()).thenReturn(mController);
        setViaReflection(mSupervisor, "mRecentTasks", mRecentTasks);
@@ -248,9 +236,9 @@ public class BackgroundActivityStartControllerExemptionTests {

        // assertions
        assertWithMessage(balState.toString()).that(callerVerdict.getCode()).isEqualTo(
                BAL_BLOCK);
                BackgroundActivityStartController.BAL_BLOCK);
        assertWithMessage(balState.toString()).that(realCallerVerdict.getCode()).isEqualTo(
                BAL_BLOCK);
                BackgroundActivityStartController.BAL_BLOCK);
    }

    @Test
@@ -262,9 +250,7 @@ public class BackgroundActivityStartControllerExemptionTests {
        int realCallingPid = REGULAR_PID_2;

        // setup state
        when(mVisibleActivityProcessTracker.hasVisibleActivity(eq(callingUid))).thenReturn(true);
        when(mVisibleActivityProcessTracker.hasVisibleNotPinnedActivity(eq(callingUid)))
                .thenReturn(false);
        when(mService.hasActiveVisibleWindow(eq(callingUid))).thenReturn(true);
        when(mService.getBalAppSwitchesState()).thenReturn(APP_SWITCH_ALLOW);

        // prepare call
@@ -276,165 +262,6 @@ public class BackgroundActivityStartControllerExemptionTests {
                callingPid, callingPackage, realCallingUid, realCallingPid, mCallerApp,
                originatingPendingIntent, forcedBalByPiSender, mResultRecord, intent,
                checkedOptions);
        assertThat(balState.toString()).contains("callingUidHasVisibleActivity: true");
        assertThat(balState.toString()).contains("callingUidHasVisibleNotPinnedActivity: false");
        assertThat(balState.toString()).contains("callingUidHasNonAppVisibleWindow: false");

        // call
        BalVerdict callerVerdict = mController.checkBackgroundActivityStartAllowedByCaller(
                balState);
        balState.setResultForCaller(callerVerdict);

        // assertions
        assertWithMessage(balState + " -> " + callerVerdict)
                .that(callerVerdict.getCode())
                .isEqualTo(BAL_BLOCK);
    }

    @Test
    public void testCaller_appHasVisiblePinnedWindow() {
        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
        when(mVisibleActivityProcessTracker.hasVisibleActivity(eq(callingUid))).thenReturn(true);
        when(mVisibleActivityProcessTracker.hasVisibleNotPinnedActivity(eq(callingUid)))
                .thenReturn(true);
        when(mService.getBalAppSwitchesState()).thenReturn(APP_SWITCH_ALLOW);

        // prepare call
        PendingIntentRecord originatingPendingIntent = mPendingIntentRecord;
        BackgroundStartPrivileges allowBalExemptionForSystemProcess =
                BackgroundStartPrivileges.NONE;
        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: true");
        assertThat(balState.toString()).contains("callingUidHasVisibleNotPinnedActivity: true");
        assertThat(balState.toString()).contains("callingUidHasNonAppVisibleWindow: false");

        // call
        BalVerdict callerVerdict = mController.checkBackgroundActivityStartAllowedByCaller(
                balState);
        balState.setResultForCaller(callerVerdict);

        // assertions
        assertWithMessage(balState + " -> " + callerVerdict)
                .that(callerVerdict.getCode())
                .isEqualTo(BAL_ALLOW_VISIBLE_WINDOW);
    }

    @Test
    public void testRealCaller_appHasVisibleWindow() {
        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
        when(mVisibleActivityProcessTracker.hasVisibleActivity(eq(realCallingUid)))
                .thenReturn(true);
        when(mVisibleActivityProcessTracker.hasVisibleNotPinnedActivity(eq(realCallingUid)))
                .thenReturn(false);
        when(mService.getBalAppSwitchesState()).thenReturn(APP_SWITCH_ALLOW);

        // prepare call
        PendingIntentRecord originatingPendingIntent = mPendingIntentRecord;
        BackgroundStartPrivileges allowBalExemptionForSystemProcess =
                BackgroundStartPrivileges.NONE;
        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: true");
        assertThat(balState.toString())
                .contains("realCallingUidHasVisibleNotPinnedActivity: false");
        assertThat(balState.toString()).contains("realCallingUidHasNonAppVisibleWindow: false");

        // call
        BalVerdict realCallerVerdict = mController.checkBackgroundActivityStartAllowedBySender(
                balState);
        balState.setResultForRealCaller(realCallerVerdict);

        // assertions
        assertWithMessage(balState + " -> " + realCallerVerdict)
                .that(realCallerVerdict.getCode())
                .isEqualTo(BAL_BLOCK);
    }

    @Test
    public void testRealCaller_appHasNotPinnedVisibleWindow() {
        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
        when(mVisibleActivityProcessTracker.hasVisibleActivity(eq(realCallingUid)))
                .thenReturn(true);
        when(mVisibleActivityProcessTracker.hasVisibleNotPinnedActivity(eq(realCallingUid)))
                .thenReturn(true);
        when(mService.getBalAppSwitchesState()).thenReturn(APP_SWITCH_ALLOW);

        // prepare call
        PendingIntentRecord originatingPendingIntent = mPendingIntentRecord;
        BackgroundStartPrivileges allowBalExemptionForSystemProcess =
                BackgroundStartPrivileges.NONE;
        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: true");
        assertThat(balState.toString()).contains("realCallingUidHasVisibleNotPinnedActivity: true");
        assertThat(balState.toString()).contains("realCallingUidHasNonAppVisibleWindow: false");

        // call
        BalVerdict realCallerVerdict = mController.checkBackgroundActivityStartAllowedBySender(
                balState);
        balState.setResultForRealCaller(realCallerVerdict);

        // assertions
        assertWithMessage(balState + " -> " + realCallerVerdict)
                .that(realCallerVerdict.getCode())
                .isEqualTo(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;
        BackgroundStartPrivileges allowBalExemptionForSystemProcess =
                BackgroundStartPrivileges.NONE;
        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(
@@ -443,11 +270,11 @@ public class BackgroundActivityStartControllerExemptionTests {

        // assertions
        assertWithMessage(balState.toString()).that(callerVerdict.getCode()).isEqualTo(
                BAL_ALLOW_NON_APP_VISIBLE_WINDOW);
                BAL_ALLOW_VISIBLE_WINDOW);
    }

    @Test
    public void testRealCaller_appHasNonAppVisibleWindow() {
    public void testRealCaller_appHasVisibleWindow() {
        int callingUid = REGULAR_UID_1;
        int callingPid = REGULAR_PID_1;
        final String callingPackage = REGULAR_PACKAGE_1;
@@ -455,7 +282,7 @@ public class BackgroundActivityStartControllerExemptionTests {
        int realCallingPid = REGULAR_PID_2;

        // setup state
        mActiveUids.onNonAppSurfaceVisibilityChanged(realCallingUid, true);
        when(mService.hasActiveVisibleWindow(eq(realCallingUid))).thenReturn(true);
        when(mService.getBalAppSwitchesState()).thenReturn(APP_SWITCH_ALLOW);

        // prepare call
@@ -475,7 +302,7 @@ public class BackgroundActivityStartControllerExemptionTests {

        // assertions
        assertWithMessage(balState.toString()).that(realCallerVerdict.getCode()).isEqualTo(
                BAL_ALLOW_NON_APP_VISIBLE_WINDOW);
                BAL_ALLOW_VISIBLE_WINDOW);
    }

    @Test
Loading