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

Commit a65ac3c3 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Consider process priority of unknown visibility launching app" into sc-v2-dev

parents 64f6df94 1d3084bb
Loading
Loading
Loading
Loading
+57 −4
Original line number Diff line number Diff line
@@ -653,16 +653,25 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
     */
    volatile int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;

    /** Whether to keep higher priority to launch app while device is sleeping. */
    private volatile boolean mRetainPowerModeAndTopProcessState;

    /** The timeout to restore power mode if {@link #mRetainPowerModeAndTopProcessState} is set. */
    private static final long POWER_MODE_UNKNOWN_VISIBILITY_TIMEOUT_MS = 1000;

    @Retention(RetentionPolicy.SOURCE)
    @IntDef({
            POWER_MODE_REASON_START_ACTIVITY,
            POWER_MODE_REASON_FREEZE_DISPLAY,
            POWER_MODE_REASON_UNKNOWN_VISIBILITY,
            POWER_MODE_REASON_ALL,
    })
    @interface PowerModeReason {}

    static final int POWER_MODE_REASON_START_ACTIVITY = 1 << 0;
    static final int POWER_MODE_REASON_FREEZE_DISPLAY = 1 << 1;
    /** @see UnknownAppVisibilityController */
    static final int POWER_MODE_REASON_UNKNOWN_VISIBILITY = 1 << 2;
    /** This can only be used by {@link #endLaunchPowerMode(int)}.*/
    static final int POWER_MODE_REASON_ALL = (1 << 2) - 1;

@@ -4248,15 +4257,39 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
    }

    void startLaunchPowerMode(@PowerModeReason int reason) {
        if (mPowerManagerInternal == null) return;
        if (mPowerManagerInternal != null) {
            mPowerManagerInternal.setPowerMode(Mode.LAUNCH, true);
        }
        mLaunchPowerModeReasons |= reason;
        if ((reason & POWER_MODE_REASON_UNKNOWN_VISIBILITY) != 0) {
            if (mRetainPowerModeAndTopProcessState) {
                mH.removeMessages(H.END_POWER_MODE_UNKNOWN_VISIBILITY_MSG);
            }
            mRetainPowerModeAndTopProcessState = true;
            mH.sendEmptyMessageDelayed(H.END_POWER_MODE_UNKNOWN_VISIBILITY_MSG,
                    POWER_MODE_UNKNOWN_VISIBILITY_TIMEOUT_MS);
            Slog.d(TAG, "Temporarily retain top process state for launching app");
        }
    }

    void endLaunchPowerMode(@PowerModeReason int reason) {
        if (mPowerManagerInternal == null || mLaunchPowerModeReasons == 0) return;
        if (mLaunchPowerModeReasons == 0) return;
        mLaunchPowerModeReasons &= ~reason;
        if (mLaunchPowerModeReasons == 0) {

        if ((mLaunchPowerModeReasons & POWER_MODE_REASON_UNKNOWN_VISIBILITY) != 0) {
            boolean allResolved = true;
            for (int i = mRootWindowContainer.getChildCount() - 1; i >= 0; i--) {
                allResolved &= mRootWindowContainer.getChildAt(i).mUnknownAppVisibilityController
                        .allResolved();
            }
            if (allResolved) {
                mLaunchPowerModeReasons &= ~POWER_MODE_REASON_UNKNOWN_VISIBILITY;
                mRetainPowerModeAndTopProcessState = false;
                mH.removeMessages(H.END_POWER_MODE_UNKNOWN_VISIBILITY_MSG);
            }
        }

        if (mLaunchPowerModeReasons == 0 && mPowerManagerInternal != null) {
            mPowerManagerInternal.setPowerMode(Mode.LAUNCH, false);
        }
    }
@@ -5123,6 +5156,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
    final class H extends Handler {
        static final int REPORT_TIME_TRACKER_MSG = 1;
        static final int UPDATE_PROCESS_ANIMATING_STATE = 2;
        static final int END_POWER_MODE_UNKNOWN_VISIBILITY_MSG = 3;

        static final int FIRST_ACTIVITY_TASK_MSG = 100;
        static final int FIRST_SUPERVISOR_TASK_MSG = 200;
@@ -5146,6 +5180,20 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
                    }
                }
                break;
                case END_POWER_MODE_UNKNOWN_VISIBILITY_MSG: {
                    synchronized (mGlobalLock) {
                        mRetainPowerModeAndTopProcessState = false;
                        endLaunchPowerMode(POWER_MODE_REASON_UNKNOWN_VISIBILITY);
                        if (mTopApp != null
                                && mTopProcessState == ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
                            // Restore the scheduling group for sleeping.
                            mTopApp.updateProcessInfo(false /* updateServiceConnection */,
                                    false /* activityChange */, true /* updateOomAdj */,
                                    false /* addPendingTopUid */);
                        }
                    }
                }
                break;
            }
        }
    }
@@ -5464,6 +5512,11 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
        @HotPath(caller = HotPath.OOM_ADJUSTMENT)
        @Override
        public int getTopProcessState() {
            if (mRetainPowerModeAndTopProcessState) {
                // There is a launching app while device may be sleeping, force the top state so
                // the launching process can have top-app scheduling group.
                return ActivityManager.PROCESS_STATE_TOP;
            }
            return mTopProcessState;
        }

+20 −12
Original line number Diff line number Diff line
@@ -3545,14 +3545,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
    }

    void startPowerModeLaunchIfNeeded(boolean forceSend, ActivityRecord targetActivity) {
        final boolean sendPowerModeLaunch;

        if (forceSend) {
            sendPowerModeLaunch = true;
        } else if (targetActivity == null || targetActivity.app == null) {
            // Set power mode if we don't know what we're launching yet.
            sendPowerModeLaunch = true;
        } else {
        if (!forceSend && targetActivity != null && targetActivity.app != null) {
            // Set power mode when the activity's process is different than the current top resumed
            // activity on all display areas, or if there are no resumed activities in the system.
            boolean[] noResumedActivities = {true};
@@ -3568,13 +3561,28 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
                            !resumedActivityProcess.equals(targetActivity.app);
                }
            });
            sendPowerModeLaunch = noResumedActivities[0] || allFocusedProcessesDiffer[0];
            if (!noResumedActivities[0] && !allFocusedProcessesDiffer[0]) {
                // All focused activities are resumed and the process of the target activity is
                // the same as them, e.g. delivering new intent to the current top.
                return;
            }
        }

        if (sendPowerModeLaunch) {
            mService.startLaunchPowerMode(
                    ActivityTaskManagerService.POWER_MODE_REASON_START_ACTIVITY);
        int reason = ActivityTaskManagerService.POWER_MODE_REASON_START_ACTIVITY;
        // If the activity is launching while keyguard is locked (including occluded), the activity
        // may be visible until its first relayout is done (e.g. apply show-when-lock flag). To
        // avoid power mode from being cleared before that, add a special reason to consider whether
        // the unknown visibility is resolved. The case from SystemUI is excluded because it should
        // rely on keyguard-going-away.
        if (mService.mKeyguardController.isKeyguardLocked() && targetActivity != null
                && !targetActivity.isLaunchSourceType(ActivityRecord.LAUNCH_SOURCE_TYPE_SYSTEMUI)) {
            final ActivityOptions opts = targetActivity.getOptions();
            if (opts == null || opts.getSourceInfo() == null
                    || opts.getSourceInfo().type != ActivityOptions.SourceInfo.TYPE_LOCKSCREEN) {
                reason |= ActivityTaskManagerService.POWER_MODE_REASON_UNKNOWN_VISIBILITY;
            }
        }
        mService.startLaunchPowerMode(reason);
    }

    // TODO(b/191434136): handle this properly when we add multi-window support on secondary
+9 −0
Original line number Diff line number Diff line
@@ -301,6 +301,15 @@ public class ActivityTaskManagerServiceTests extends WindowTestsBase {
        // The top app should not change while sleeping.
        assertEquals(topActivity.app, mAtm.mInternal.getTopApp());

        mAtm.startLaunchPowerMode(ActivityTaskManagerService.POWER_MODE_REASON_START_ACTIVITY
                | ActivityTaskManagerService.POWER_MODE_REASON_UNKNOWN_VISIBILITY);
        assertEquals(ActivityManager.PROCESS_STATE_TOP, mAtm.mInternal.getTopProcessState());
        // Because there is no unknown visibility record, the state will be restored if other
        // reasons are all done.
        mAtm.endLaunchPowerMode(ActivityTaskManagerService.POWER_MODE_REASON_START_ACTIVITY);
        assertEquals(ActivityManager.PROCESS_STATE_TOP_SLEEPING,
                mAtm.mInternal.getTopProcessState());

        // If all activities are stopped, the sleep wake lock must be released.
        final Task topRootTask = topActivity.getRootTask();
        doReturn(true).when(rootHomeTask).goToSleepIfPossible(anyBoolean());