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

Commit c7bbf2ac authored by Michal Karpinski's avatar Michal Karpinski Committed by Android (Google) Code Review
Browse files

Merge "Allow background activity starts if realCallingUid is in the foreground"

parents 20c0d0dd 0ad4e2fd
Loading
Loading
Loading
Loading
+13 −6
Original line number Diff line number Diff line
@@ -738,7 +738,8 @@ class ActivityStarter {
        // not sure if we need to create START_ABORTED_BACKGROUND so for now piggybacking
        // on START_ABORTED
        if (!abort) {
            abort |= shouldAbortBackgroundActivityStart(callingUid, callingPackage, callerApp);
            abort |= shouldAbortBackgroundActivityStart(callingUid, callingPackage, realCallingUid,
                    callerApp);
        }

        // Merge the two options bundles, while realCallerOptions takes precedence.
@@ -886,7 +887,7 @@ class ActivityStarter {
    }

    private boolean shouldAbortBackgroundActivityStart(int callingUid, final String callingPackage,
            WindowProcessController callerApp) {
            int realCallingUid, WindowProcessController callerApp) {
        if (mService.isBackgroundActivityStartsEnabled()) {
            return false;
        }
@@ -898,12 +899,12 @@ class ActivityStarter {
        if (callerApp != null && callerApp.hasForegroundActivities()) {
            return false;
        }
        // don't abort if the callingUid's process is important enough
        if (mService.getUidStateLocked(callingUid) <= ActivityManager.PROCESS_STATE_TOP) {
        // don't abort if the callingUid is in the foreground
        if (isUidForeground(callingUid)) {
            return false;
        }
        // don't abort if the callingUid has any visible window
        if (mService.mWindowManager.isAnyWindowVisibleForUid(callingUid)) {
        // don't abort if the realCallingUid is in the foreground and callingUid isn't
        if ((realCallingUid != callingUid) && isUidForeground(realCallingUid)) {
            return false;
        }
        // don't abort if the caller has the same uid as the recents component
@@ -920,6 +921,12 @@ class ActivityStarter {
        return true;
    }

    /** Returns true if uid has a visible window or its process is in top or persistent state. */
    private boolean isUidForeground(int uid) {
        return (mService.getUidStateLocked(uid) <= ActivityManager.PROCESS_STATE_TOP)
            || mService.mWindowManager.isAnyWindowVisibleForUid(uid);
    }

    private void maybeLogActivityStart(int callingUid, String callingPackage, int realCallingUid,
            Intent intent, WindowProcessController callerApp, ActivityRecord r,
            PendingIntentRecord originatingPendingIntent, boolean abortedStart) {
+64 −25
Original line number Diff line number Diff line
@@ -113,6 +113,7 @@ public class ActivityStarterTests extends ActivityTestsBase {
    private static final int FAKE_REAL_CALLING_UID = 667;
    private static final String FAKE_CALLING_PACKAGE = "com.whatever.dude";
    private static final int UNIMPORTANT_UID = 12345;
    private static final int UNIMPORTANT_UID2 = 12346;

    @Before
    public void setUp() throws Exception {
@@ -561,8 +562,10 @@ public class ActivityStarterTests extends ActivityTestsBase {
    public void testBackgroundActivityStartsAllowed_noStartsAborted() {
        doReturn(true).when(mService).isBackgroundActivityStartsEnabled();

        runAndVerifyBackgroundActivityStartsSubtest("allowed_noStartsAborted",
                false, UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1, false, false);
        runAndVerifyBackgroundActivityStartsSubtest("allowed_noStartsAborted", false,
                UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1,
                UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1,
                false, false);
    }

    /**
@@ -573,8 +576,11 @@ public class ActivityStarterTests extends ActivityTestsBase {
    public void testBackgroundActivityStartsDisallowed_unsupportedStartsAborted() {
        doReturn(false).when(mService).isBackgroundActivityStartsEnabled();

        runAndVerifyBackgroundActivityStartsSubtest("disallowed_unsupportedUsecase_aborted",
                true, UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1, false, false);
        runAndVerifyBackgroundActivityStartsSubtest(
                "disallowed_unsupportedUsecase_aborted", true,
                UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1,
                UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1,
                false, false);
    }

    /**
@@ -586,44 +592,77 @@ public class ActivityStarterTests extends ActivityTestsBase {
    public void testBackgroundActivityStartsDisallowed_supportedStartsNotAborted() {
        doReturn(false).when(mService).isBackgroundActivityStartsEnabled();

        runAndVerifyBackgroundActivityStartsSubtest("disallowed_rootUid_notAborted",
                false, Process.ROOT_UID, false, PROCESS_STATE_TOP + 1, false, false);
        runAndVerifyBackgroundActivityStartsSubtest("disallowed_systemUid_notAborted",
                false, Process.SYSTEM_UID, false, PROCESS_STATE_TOP + 1, false, false);
        runAndVerifyBackgroundActivityStartsSubtest("disallowed_hasVisibleWindow_notAborted",
                false, UNIMPORTANT_UID, true, PROCESS_STATE_TOP + 1, false, false);
        runAndVerifyBackgroundActivityStartsSubtest("disallowed_processStateTop_notAborted",
                false, UNIMPORTANT_UID, false, PROCESS_STATE_TOP, false, false);
        runAndVerifyBackgroundActivityStartsSubtest("disallowed_hasForegroundActivities_notAborted",
                false, UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1, true, false);
        runAndVerifyBackgroundActivityStartsSubtest("disallowed_callerIsRecents_notAborted",
                false, UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1, false, true);
        runAndVerifyBackgroundActivityStartsSubtest("disallowed_rootUid_notAborted", false,
                Process.ROOT_UID, false, PROCESS_STATE_TOP + 1,
                UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1,
                false, false);
        runAndVerifyBackgroundActivityStartsSubtest("disallowed_systemUid_notAborted", false,
                Process.SYSTEM_UID, false, PROCESS_STATE_TOP + 1,
                UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1,
                false, false);
        runAndVerifyBackgroundActivityStartsSubtest(
                "disallowed_callingUidHasVisibleWindow_notAborted", false,
                UNIMPORTANT_UID, true, PROCESS_STATE_TOP + 1,
                UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1,
                false, false);
        runAndVerifyBackgroundActivityStartsSubtest(
                "disallowed_callingUidProcessStateTop_notAborted", false,
                UNIMPORTANT_UID, false, PROCESS_STATE_TOP,
                UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1,
                false, false);
        runAndVerifyBackgroundActivityStartsSubtest(
                "disallowed_realCallingUidHasVisibleWindow_notAborted", false,
                UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1,
                UNIMPORTANT_UID2, true, PROCESS_STATE_TOP + 1,
                false, false);
        runAndVerifyBackgroundActivityStartsSubtest(
                "disallowed_realCallingUidProcessStateTop_notAborted", false,
                UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1,
                UNIMPORTANT_UID2, false, PROCESS_STATE_TOP,
                false, false);
        runAndVerifyBackgroundActivityStartsSubtest(
                "disallowed_hasForegroundActivities_notAborted", false,
                UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1,
                UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1,
                true, false);
        runAndVerifyBackgroundActivityStartsSubtest(
                "disallowed_callerIsRecents_notAborted", false,
                UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1,
                UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1,
                false, true);
    }

    private void runAndVerifyBackgroundActivityStartsSubtest(String name, boolean shouldHaveAborted,
            int testCallingUid, boolean hasVisibleWindow, int procState,
            int callingUid, boolean callingUidHasVisibleWindow, int callingUidProcState,
            int realCallingUid, boolean realCallingUidHasVisibleWindow, int realCallingUidProcState,
            boolean hasForegroundActivities, boolean callerIsRecents) {
        // window visibility
        doReturn(hasVisibleWindow).when(mService.mWindowManager).isAnyWindowVisibleForUid(
                testCallingUid);
        doReturn(callingUidHasVisibleWindow).when(mService.mWindowManager).isAnyWindowVisibleForUid(
                callingUid);
        doReturn(realCallingUidHasVisibleWindow).when(mService.mWindowManager)
                .isAnyWindowVisibleForUid(realCallingUid);
        // process importance
        doReturn(procState).when(mService).getUidStateLocked(testCallingUid);
        doReturn(callingUidProcState).when(mService).getUidStateLocked(callingUid);
        doReturn(realCallingUidProcState).when(mService).getUidStateLocked(realCallingUid);
        // foreground activities
        final IApplicationThread caller = mock(IApplicationThread.class);
        final ApplicationInfo ai = new ApplicationInfo();
        ai.uid = testCallingUid;
        ai.uid = callingUid;
        final WindowProcessController callerApp =
                new WindowProcessController(mService, ai, null, testCallingUid, -1, null, null);
                new WindowProcessController(mService, ai, null, callingUid, -1, null, null);
        callerApp.setHasForegroundActivities(hasForegroundActivities);
        doReturn(callerApp).when(mService).getProcessController(caller);
        // caller is recents
        RecentTasks recentTasks = mock(RecentTasks.class);
        mService.mStackSupervisor.setRecentTasks(recentTasks);
        doReturn(callerIsRecents).when(recentTasks).isCallerRecents(testCallingUid);
        doReturn(callerIsRecents).when(recentTasks).isCallerRecents(callingUid);

        final ActivityOptions options = spy(ActivityOptions.makeBasic());
        ActivityStarter starter = prepareStarter(FLAG_ACTIVITY_NEW_TASK).setCaller(caller)
                .setCallingUid(testCallingUid).setActivityOptions(new SafeActivityOptions(options));
        ActivityStarter starter = prepareStarter(FLAG_ACTIVITY_NEW_TASK)
                .setCaller(caller)
                .setCallingUid(callingUid)
                .setRealCallingUid(realCallingUid)
                .setActivityOptions(new SafeActivityOptions(options));

        final int result = starter.setReason("testBackgroundActivityStarts_" + name).execute();