From 4bc0e4eb1250d6eccfb8d4404f7bc22001eb61fd Mon Sep 17 00:00:00 2001 From: Riddle Hsu Date: Sat, 6 Feb 2021 00:24:53 +0800 Subject: [PATCH] Apply launch power mode during freezing screen The most common case of freezing screen is display orientation change. It usually needs to relaunch activity and redraw windows, that is similar to the scenario of normal activity launch. So also apply the "launch" power mode to speed up the procedure. This can reduce about 10% freezing time for both relaunch and no-relaunch cases. Bug: 178472794 Test: Rotate device and check log "Screen frozen for". Change-Id: Idd4a2374d8ce978af36d75135b680a10c240f66d --- .../server/wm/ActivityTaskManagerService.java | 33 ++++++++++++++++++- .../server/wm/ActivityTaskSupervisor.java | 2 +- .../android/server/wm/RecentsAnimation.java | 3 +- .../server/wm/RootWindowContainer.java | 19 +++-------- .../server/wm/WindowManagerService.java | 5 +++ 5 files changed, 44 insertions(+), 18 deletions(-) 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); }