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

Commit 7c5ef08b authored by Achim Thesmann's avatar Achim Thesmann
Browse files

Split app and non app window code

Test: atest WmTests
Bug: 291794451
Flag: EXEMPT refactoring
Change-Id: I9740a6a35b97c9299c2465c5ba328f188697a814
parent 7639344e
Loading
Loading
Loading
Loading
+31 −16
Original line number Diff line number Diff line
@@ -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;
@@ -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;
@@ -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)
@@ -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;
@@ -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: ")
@@ -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: ")
@@ -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");
        }
@@ -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");
        }
@@ -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));
        }

+89 −4
Original line number Diff line number Diff line
@@ -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;
@@ -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;

@@ -126,6 +129,8 @@ public class BackgroundActivityStartControllerExemptionTests {
    AppOpsManager mAppOpsManager;
    MirrorActiveUids mActiveUids = new MirrorActiveUids();
    WindowProcessControllerMap mProcessMap = new WindowProcessControllerMap();
    @Mock
    VisibleActivityProcessTracker mVisibleActivityProcessTracker;

    @Mock
    ActivityTaskSupervisor mSupervisor;
@@ -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);

@@ -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
@@ -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(
@@ -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
@@ -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(
@@ -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() {
@@ -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
@@ -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(
@@ -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
@@ -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(
+4 −0
Original line number Diff line number Diff line
@@ -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);
    }
+23 −8
Original line number Diff line number Diff line
@@ -111,6 +111,9 @@ public class BackgroundActivityStartControllerTests {
    @Mock
    AppOpsManager mAppOpsManager;
    MirrorActiveUids mActiveUids = new MirrorActiveUids();
    @Mock
    VisibleActivityProcessTracker mVisibleActivityProcessTracker;

    WindowProcessControllerMap mProcessMap = new WindowProcessControllerMap();

    @Mock
@@ -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);
@@ -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; "
@@ -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
@@ -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; "
@@ -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]");
    }
}