diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java index 4bcef408d9a0b..f97af6259c9c3 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java +++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java @@ -176,6 +176,7 @@ import android.database.ContentObserver; import android.graphics.Bitmap; import android.graphics.Point; import android.graphics.Rect; +import android.hardware.power.Mode; import android.net.Uri; import android.os.Binder; import android.os.Build; @@ -343,7 +344,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { private StatusBarManagerInternal mStatusBarManagerInternal; @VisibleForTesting final ActivityTaskManagerInternal mInternal; - PowerManagerInternal mPowerManagerInternal; + private PowerManagerInternal mPowerManagerInternal; private UsageStatsManagerInternal mUsageStatsInternal; PendingIntentController mPendingIntentController; @@ -589,6 +590,22 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { */ volatile int mTopProcessState = ActivityManager.PROCESS_STATE_TOP; + @Retention(RetentionPolicy.SOURCE) + @IntDef({ + POWER_MODE_REASON_START_ACTIVITY, + POWER_MODE_REASON_FREEZE_DISPLAY, + 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; + /** This can only be used by {@link #endLaunchPowerMode(int)}.*/ + static final int POWER_MODE_REASON_ALL = (1 << 2) - 1; + + /** The reasons to use {@link Mode#LAUNCH} power mode. */ + private @PowerModeReason int mLaunchPowerModeReasons; + @Retention(RetentionPolicy.SOURCE) @IntDef({ LAYOUT_REASON_CONFIG_CHANGED, @@ -4095,6 +4112,20 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { return changes; } + void startLaunchPowerMode(@PowerModeReason int reason) { + if (mPowerManagerInternal == null) return; + mPowerManagerInternal.setPowerMode(Mode.LAUNCH, true); + mLaunchPowerModeReasons |= reason; + } + + void endLaunchPowerMode(@PowerModeReason int reason) { + if (mPowerManagerInternal == null || mLaunchPowerModeReasons == 0) return; + mLaunchPowerModeReasons &= ~reason; + if (mLaunchPowerModeReasons == 0) { + mPowerManagerInternal.setPowerMode(Mode.LAUNCH, false); + } + } + /** @see WindowSurfacePlacer#deferLayout */ void deferWindowLayout() { if (!mWindowManager.mWindowPlacerLocked.isLayoutDeferred()) { diff --git a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java index de436437769ac..1264d0c53e0cc 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java +++ b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java @@ -1755,7 +1755,7 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks { } // End power mode launch before going sleep - mRootWindowContainer.endPowerModeLaunchIfNeeded(); + mService.endLaunchPowerMode(ActivityTaskManagerService.POWER_MODE_REASON_ALL); removeSleepTimeouts(); diff --git a/services/core/java/com/android/server/wm/RecentsAnimation.java b/services/core/java/com/android/server/wm/RecentsAnimation.java index 26f0f096278c3..4f8ea1ac377a2 100644 --- a/services/core/java/com/android/server/wm/RecentsAnimation.java +++ b/services/core/java/com/android/server/wm/RecentsAnimation.java @@ -284,7 +284,8 @@ class RecentsAnimation implements RecentsAnimationCallbacks, OnRootTaskOrderChan // Just to be sure end the launch hint in case the target activity was never launched. // However, if we're keeping the activity and making it visible, we can leave it on. if (reorderMode != REORDER_KEEP_IN_PLACE) { - mService.mRootWindowContainer.endPowerModeLaunchIfNeeded(); + mService.endLaunchPowerMode( + ActivityTaskManagerService.POWER_MODE_REASON_START_ACTIVITY); } // Once the target is shown, prevent spurious background app switches diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java index 2c97f783e14df..8f2d8239f5fc4 100644 --- a/services/core/java/com/android/server/wm/RootWindowContainer.java +++ b/services/core/java/com/android/server/wm/RootWindowContainer.java @@ -267,9 +267,6 @@ class RootWindowContainer extends WindowContainer */ final SparseArray mSleepTokens = new SparseArray<>(); - /** Set when a power mode launch has started, but not ended. */ - private boolean mPowerModeLaunchStarted; - // The default minimal size that will be used if the activity doesn't specify its minimal size. // It will be calculated when the default display gets added. int mDefaultMinSizeOfResizeableTaskDp = -1; @@ -3327,7 +3324,7 @@ class RootWindowContainer extends WindowContainer } } // End power mode launch when idle. - endPowerModeLaunchIfNeeded(); + mService.endLaunchPowerMode(ActivityTaskManagerService.POWER_MODE_REASON_START_ACTIVITY); return true; } @@ -3540,17 +3537,9 @@ class RootWindowContainer extends WindowContainer sendPowerModeLaunch = noResumedActivities[0] || allFocusedProcessesDiffer[0]; } - if (sendPowerModeLaunch && mService.mPowerManagerInternal != null) { - mService.mPowerManagerInternal.setPowerMode(Mode.LAUNCH, true); - mPowerModeLaunchStarted = true; - } - } - - void endPowerModeLaunchIfNeeded() { - // Trigger launch power mode off if activity is launched - if (mPowerModeLaunchStarted && mService.mPowerManagerInternal != null) { - mService.mPowerManagerInternal.setPowerMode(Mode.LAUNCH, false); - mPowerModeLaunchStarted = false; + if (sendPowerModeLaunch) { + mService.startLaunchPowerMode( + ActivityTaskManagerService.POWER_MODE_REASON_START_ACTIVITY); } } diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index e456a4efce06c..8a65762f5082f 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -100,6 +100,7 @@ import static com.android.internal.util.LatencyTracker.ACTION_ROTATE_SCREEN; import static com.android.server.LockGuard.INDEX_WINDOW; import static com.android.server.LockGuard.installLock; import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER; +import static com.android.server.wm.ActivityTaskManagerService.POWER_MODE_REASON_FREEZE_DISPLAY; import static com.android.server.wm.DisplayContent.IME_TARGET_CONTROL; import static com.android.server.wm.DisplayContent.IME_TARGET_INPUT; import static com.android.server.wm.DisplayContent.IME_TARGET_LAYERING; @@ -5841,6 +5842,9 @@ public class WindowManagerService extends IWindowManager.Stub "startFreezingDisplayLocked: exitAnim=%d enterAnim=%d called by %s", exitAnim, enterAnim, Debug.getCallers(8)); mScreenFrozenLock.acquire(); + // Apply launch power mode to reduce screen frozen time because orientation change may + // relaunch activity and redraw windows. This may also help speed up user switching. + mAtmService.startLaunchPowerMode(POWER_MODE_REASON_FREEZE_DISPLAY); mDisplayFrozen = true; mDisplayFreezeTime = SystemClock.elapsedRealtime(); @@ -5984,6 +5988,7 @@ public class WindowManagerService extends IWindowManager.Stub if (configChanged) { displayContent.sendNewConfiguration(); } + mAtmService.endLaunchPowerMode(POWER_MODE_REASON_FREEZE_DISPLAY); mLatencyTracker.onActionEnd(ACTION_ROTATE_SCREEN); }