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

Commit 8bda2189 authored by Riddle Hsu's avatar Riddle Hsu
Browse files

Activity in foreground task should be able to launch activity

Assume a visible task contains 2 activities:
 Activity B, process X (top-visible)
 Activity A, process Y
Though process Y doesn't have visible activity, it shouldn't be
blocked to launch activity because it is in a visible task.

This restores the accidental behavior change in commit 9b7603b5.

Also simplify rankTaskLayers to reduce unnecessary anonymous class
and duplicated states (changed/scheduled).

Bug: 182694325
Test: atest RootWindowContainerTests#testTaskLayerRank
            BackgroundActivityLaunchTest# \
            testActivityNotBlockedFromBgActivityInFgTask
Change-Id: Ia8739967805aa8a43f99ab18840b02ac50380912
parent a7ee1a9a
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -1429,6 +1429,7 @@ class ActivityStarter {
                + "; allowBackgroundActivityStart: " + allowBackgroundActivityStart
                + "; intent: " + intent
                + "; callerApp: " + callerApp
                + "; inVisibleTask: " + (callerApp != null && callerApp.hasActivityInVisibleTask())
                + "]");
        // log aborted activity start to TRON
        if (mService.isActivityStartsLoggingEnabled()) {
+5 −4
Original line number Diff line number Diff line
@@ -70,9 +70,10 @@ class BackgroundLaunchProcessController {
    }

    boolean areBackgroundActivityStartsAllowed(int pid, int uid, String packageName,
            boolean appSwitchAllowed, boolean isCheckingForFgsStart, boolean hasVisibleActivities,
            boolean hasBackgroundActivityStartPrivileges, long lastStopAppSwitchesTime,
            long lastActivityLaunchTime, long lastActivityFinishTime) {
            boolean appSwitchAllowed, boolean isCheckingForFgsStart,
            boolean hasActivityInVisibleTask, boolean hasBackgroundActivityStartPrivileges,
            long lastStopAppSwitchesTime, long lastActivityLaunchTime,
            long lastActivityFinishTime) {
        // If app switching is not allowed, we ignore all the start activity grace period
        // exception so apps cannot start itself in onPause() after pressing home button.
        if (appSwitchAllowed) {
@@ -110,7 +111,7 @@ class BackgroundLaunchProcessController {
            return true;
        }
        // Allow if the caller has an activity in any foreground task.
        if (appSwitchAllowed && hasVisibleActivities) {
        if (appSwitchAllowed && hasActivityInVisibleTask) {
            if (DEBUG_ACTIVITY_STARTS) {
                Slog.d(TAG, "[Process(" + pid
                        + ")] Activity start allowed: process has activity in foreground task");
+14 −36
Original line number Diff line number Diff line
@@ -273,7 +273,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
    // Whether tasks have moved and we need to rank the tasks before next OOM scoring
    private boolean mTaskLayersChanged = true;
    private int mTmpTaskLayerRank;
    private final LockedScheduler mRankTaskLayersScheduler;
    private final RankTaskLayersRunnable mRankTaskLayersRunnable = new RankTaskLayersRunnable();

    private boolean mTmpBoolean;
    private RemoteException mTmpRemoteException;
@@ -451,12 +451,6 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
        mTaskSupervisor = mService.mTaskSupervisor;
        mTaskSupervisor.mRootWindowContainer = this;
        mDisplayOffTokenAcquirer = mService.new SleepTokenAcquirerImpl("Display-off");
        mRankTaskLayersScheduler = new LockedScheduler(mService) {
            @Override
            public void execute() {
                rankTaskLayersIfNeeded();
            }
        };
    }

    boolean updateFocusedWindowLocked(int mode, boolean updateInputWindows) {
@@ -2660,16 +2654,18 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
    }

    void invalidateTaskLayers() {
        if (!mTaskLayersChanged) {
            mTaskLayersChanged = true;
        mRankTaskLayersScheduler.scheduleIfNeeded();
            mService.mH.post(mRankTaskLayersRunnable);
        }
    }

    /** Generate oom-score-adjustment rank for all tasks in the system based on z-order. */
    void rankTaskLayersIfNeeded() {
        if (!mTaskLayersChanged) {
            return;
        }
    void rankTaskLayers() {
        if (mTaskLayersChanged) {
            mTaskLayersChanged = false;
            mService.mH.removeCallbacks(mRankTaskLayersRunnable);
        }
        mTmpTaskLayerRank = 0;
        // Only rank for leaf tasks because the score of activity is based on immediate parent.
        forAllLeafTasks(task -> {
@@ -3668,32 +3664,14 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
        }
    }

    /**
     * Helper class to schedule the runnable if it hasn't scheduled on display thread inside window
     * manager lock.
     */
    abstract static class LockedScheduler implements Runnable {
        private final ActivityTaskManagerService mService;
        private boolean mScheduled;

        LockedScheduler(ActivityTaskManagerService service) {
            mService = service;
        }

    private class RankTaskLayersRunnable implements Runnable {
        @Override
        public void run() {
            synchronized (mService.mGlobalLock) {
                mScheduled = false;
                execute();
            }
                if (mTaskLayersChanged) {
                    mTaskLayersChanged = false;
                    rankTaskLayers();
                }

        abstract void execute();

        void scheduleIfNeeded() {
            if (!mScheduled) {
                mService.mH.post(this);
                mScheduled = true;
            }
        }
    }
+12 −4
Original line number Diff line number Diff line
@@ -225,6 +225,7 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio
    private static final int ACTIVITY_STATE_FLAG_IS_STOPPING_FINISHING = 1 << 19;
    private static final int ACTIVITY_STATE_FLAG_IS_WINDOW_VISIBLE = 1 << 20;
    private static final int ACTIVITY_STATE_FLAG_HAS_RESUMED = 1 << 21;
    private static final int ACTIVITY_STATE_FLAG_HAS_ACTIVITY_IN_VISIBLE_TASK = 1 << 22;
    private static final int ACTIVITY_STATE_FLAG_MASK_MIN_TASK_LAYER = 0x0000ffff;

    /**
@@ -479,7 +480,7 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio
    }

    void setLastActivityFinishTimeIfNeeded(long finishTime) {
        if (finishTime <= mLastActivityFinishTime || !hasVisibleActivities()) {
        if (finishTime <= mLastActivityFinishTime || !hasActivityInVisibleTask()) {
            return;
        }
        mLastActivityFinishTime = finishTime;
@@ -516,7 +517,7 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio
    private boolean areBackgroundActivityStartsAllowed(boolean appSwitchAllowed,
            boolean isCheckingForFgsStart) {
        return mBgLaunchController.areBackgroundActivityStartsAllowed(mPid, mUid, mInfo.packageName,
                appSwitchAllowed, isCheckingForFgsStart, hasVisibleActivities(),
                appSwitchAllowed, isCheckingForFgsStart, hasActivityInVisibleTask(),
                mInstrumentingWithBackgroundActivityStartPrivileges,
                mAtm.getLastStopAppSwitchesTime(),
                mLastActivityLaunchTime, mLastActivityFinishTime);
@@ -653,6 +654,10 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio
        return (mActivityStateFlags & ACTIVITY_STATE_FLAG_IS_VISIBLE) != 0;
    }

    boolean hasActivityInVisibleTask() {
        return (mActivityStateFlags & ACTIVITY_STATE_FLAG_HAS_ACTIVITY_IN_VISIBLE_TASK) != 0;
    }

    @HotPath(caller = HotPath.LRU_UPDATE)
    public boolean hasActivitiesOrRecentTasks() {
        return mHasActivities || mHasRecentTasks;
@@ -996,11 +1001,14 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio
            if (r.isVisible()) {
                stateFlags |= ACTIVITY_STATE_FLAG_IS_WINDOW_VISIBLE;
            }
            final Task task = r.getTask();
            if (task != null && task.mLayerRank != Task.LAYER_RANK_INVISIBLE) {
                stateFlags |= ACTIVITY_STATE_FLAG_HAS_ACTIVITY_IN_VISIBLE_TASK;
            }
            if (r.mVisibleRequested) {
                if (r.isState(RESUMED)) {
                    stateFlags |= ACTIVITY_STATE_FLAG_HAS_RESUMED;
                }
                final Task task = r.getTask();
                if (task != null && minTaskLayer > 0) {
                    final int layer = task.mLayerRank;
                    if (layer >= 0 && minTaskLayer > layer) {
@@ -1048,7 +1056,7 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio

    /** Called when the process has some oom related changes and it is going to update oom-adj. */
    private void prepareOomAdjustment() {
        mAtm.mRootWindowContainer.rankTaskLayersIfNeeded();
        mAtm.mRootWindowContainer.rankTaskLayers();
        mAtm.mTaskSupervisor.computeProcessActivityStateBatch();
    }

+3 −3
Original line number Diff line number Diff line
@@ -116,8 +116,7 @@ public class RootWindowContainerTests extends WindowTestsBase {
        final Task rootTask = new TaskBuilder(mSupervisor).build();
        final Task task1 = new TaskBuilder(mSupervisor).setParentTask(rootTask).build();
        new ActivityBuilder(mAtm).setTask(task1).build().mVisibleRequested = true;
        // RootWindowContainer#invalidateTaskLayers should post to update.
        waitHandlerIdle(mWm.mH);
        mWm.mRoot.rankTaskLayers();

        assertEquals(1, task1.mLayerRank);
        // Only tasks that directly contain activities have a ranking.
@@ -125,7 +124,7 @@ public class RootWindowContainerTests extends WindowTestsBase {

        final Task task2 = new TaskBuilder(mSupervisor).build();
        new ActivityBuilder(mAtm).setTask(task2).build().mVisibleRequested = true;
        waitHandlerIdle(mWm.mH);
        mWm.mRoot.rankTaskLayers();

        // Note that ensureActivitiesVisible is disabled in SystemServicesTestRule, so both the
        // activities have the visible rank.
@@ -134,6 +133,7 @@ public class RootWindowContainerTests extends WindowTestsBase {
        assertEquals(1, task2.mLayerRank);

        task2.moveToBack("test", null /* task */);
        // RootWindowContainer#invalidateTaskLayers should post to update.
        waitHandlerIdle(mWm.mH);

        assertEquals(1, task1.mLayerRank);