diff options
| author | 2023-09-01 17:07:16 +0800 | |
|---|---|---|
| committer | 2023-09-14 20:32:09 +0800 | |
| commit | 942d112ce4c325c0640c1f21822d1f2ddda21fb4 (patch) | |
| tree | 8d8de9abd8f85adf1371626b36932f7eb7a91948 | |
| parent | 33b539cb0d4a99fc18a0f49dc3cd5232a3d241b1 (diff) | |
Use separated power mode for display change
To distinguish whether it is actual launching apps.
Bug: 298150450
Test: atest ActivityTaskManagerServiceTests#testSetPowerMode
Change-Id: Ib058a6924eadb4c329b5fd74acd83472debdf332
9 files changed, 91 insertions, 29 deletions
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java index 6999c6a2a5d8..ccdf9546fb2e 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java +++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java @@ -187,7 +187,6 @@ 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; @@ -709,11 +708,15 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { static final int POWER_MODE_REASON_CHANGE_DISPLAY = 1 << 1; /** @see UnknownAppVisibilityController */ static final int POWER_MODE_REASON_UNKNOWN_VISIBILITY = 1 << 2; - /** This can only be used by {@link #endLaunchPowerMode(int)}.*/ + /** + * This can only be used by {@link #endPowerMode(int)}. Excluding UNKNOWN_VISIBILITY because + * that is guarded by a timeout while keyguard is locked. + */ static final int POWER_MODE_REASON_ALL = (1 << 2) - 1; - /** The reasons to use {@link Mode#LAUNCH} power mode. */ - private @PowerModeReason int mLaunchPowerModeReasons; + /** The reasons to apply power modes. */ + @PowerModeReason + private int mPowerModeReasons; @Retention(RetentionPolicy.SOURCE) @IntDef({ @@ -4629,11 +4632,9 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { } } - void startLaunchPowerMode(@PowerModeReason int reason) { - if (mPowerManagerInternal != null) { - mPowerManagerInternal.setPowerMode(Mode.LAUNCH, true); - } - mLaunchPowerModeReasons |= reason; + void startPowerMode(@PowerModeReason int reason) { + final int prevReasons = mPowerModeReasons; + mPowerModeReasons |= reason; if ((reason & POWER_MODE_REASON_UNKNOWN_VISIBILITY) != 0) { if (mRetainPowerModeAndTopProcessState) { mH.removeMessages(H.END_POWER_MODE_UNKNOWN_VISIBILITY_MSG); @@ -4643,27 +4644,56 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { POWER_MODE_UNKNOWN_VISIBILITY_TIMEOUT_MS); Slog.d(TAG, "Temporarily retain top process state for launching app"); } + if (mPowerManagerInternal == null) { + return; + } + + // START_ACTIVITY can be used with UNKNOWN_VISIBILITY. CHANGE_DISPLAY should be used alone. + if ((reason & POWER_MODE_REASON_START_ACTIVITY) != 0 + && (prevReasons & POWER_MODE_REASON_START_ACTIVITY) == 0) { + Trace.instant(Trace.TRACE_TAG_WINDOW_MANAGER, "StartModeLaunch"); + mPowerManagerInternal.setPowerMode(PowerManagerInternal.MODE_LAUNCH, true); + } else if (reason == POWER_MODE_REASON_CHANGE_DISPLAY + && (prevReasons & POWER_MODE_REASON_CHANGE_DISPLAY) == 0) { + Trace.instant(Trace.TRACE_TAG_WINDOW_MANAGER, "StartModeDisplayChange"); + mPowerManagerInternal.setPowerMode(PowerManagerInternal.MODE_DISPLAY_CHANGE, true); + } } - void endLaunchPowerMode(@PowerModeReason int reason) { - if (mLaunchPowerModeReasons == 0) return; - mLaunchPowerModeReasons &= ~reason; + void endPowerMode(@PowerModeReason int reason) { + if (mPowerModeReasons == 0) return; + final int prevReasons = mPowerModeReasons; + mPowerModeReasons &= ~reason; - if ((mLaunchPowerModeReasons & POWER_MODE_REASON_UNKNOWN_VISIBILITY) != 0) { + if ((mPowerModeReasons & 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; + mPowerModeReasons &= ~POWER_MODE_REASON_UNKNOWN_VISIBILITY; mRetainPowerModeAndTopProcessState = false; mH.removeMessages(H.END_POWER_MODE_UNKNOWN_VISIBILITY_MSG); } } + if (mPowerManagerInternal == null) { + return; + } - if (mLaunchPowerModeReasons == 0 && mPowerManagerInternal != null) { - mPowerManagerInternal.setPowerMode(Mode.LAUNCH, false); + // If the launching apps have unknown visibility, only end launch power mode until the + // states are resolved. + final int endLaunchModeReasons = POWER_MODE_REASON_START_ACTIVITY + | POWER_MODE_REASON_UNKNOWN_VISIBILITY; + if ((prevReasons & endLaunchModeReasons) != 0 + && (mPowerModeReasons & endLaunchModeReasons) == 0) { + Trace.instant(Trace.TRACE_TAG_WINDOW_MANAGER, "EndModeLaunch"); + mPowerManagerInternal.setPowerMode(PowerManagerInternal.MODE_LAUNCH, false); + } + if ((prevReasons & POWER_MODE_REASON_CHANGE_DISPLAY) != 0 + && (mPowerModeReasons & POWER_MODE_REASON_CHANGE_DISPLAY) == 0) { + Trace.instant(Trace.TRACE_TAG_WINDOW_MANAGER, "EndModeDisplayChange"); + mPowerManagerInternal.setPowerMode(PowerManagerInternal.MODE_DISPLAY_CHANGE, false); } } @@ -5723,7 +5753,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { case END_POWER_MODE_UNKNOWN_VISIBILITY_MSG: { synchronized (mGlobalLock) { mRetainPowerModeAndTopProcessState = false; - endLaunchPowerMode(POWER_MODE_REASON_UNKNOWN_VISIBILITY); + endPowerMode(POWER_MODE_REASON_UNKNOWN_VISIBILITY); if (mTopApp != null && mTopProcessState == ActivityManager.PROCESS_STATE_TOP_SLEEPING) { // Restore the scheduling group for sleeping. diff --git a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java index e523119ee9a0..63ed76bca941 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java +++ b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java @@ -2004,7 +2004,7 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks { } // End power mode launch before going sleep - mService.endLaunchPowerMode(ActivityTaskManagerService.POWER_MODE_REASON_ALL); + mService.endPowerMode(ActivityTaskManagerService.POWER_MODE_REASON_ALL); // Rank task layers to make sure the {@link Task#mLayerRank} is updated. mRootWindowContainer.rankTaskLayers(); diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index daa73db4684d..4a2390a0438b 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -3474,7 +3474,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp final Transition t = controller.requestTransitionIfNeeded(TRANSIT_CHANGE, 0 /* flags */, this, this, null /* remoteTransition */, displayChange); if (t != null) { - mAtmService.startLaunchPowerMode(POWER_MODE_REASON_CHANGE_DISPLAY); + mAtmService.startPowerMode(POWER_MODE_REASON_CHANGE_DISPLAY); if (mAsyncRotationController != null) { // Give a chance to update the transform if the current rotation is changed when // some windows haven't finished previous rotation. diff --git a/services/core/java/com/android/server/wm/PhysicalDisplaySwitchTransitionLauncher.java b/services/core/java/com/android/server/wm/PhysicalDisplaySwitchTransitionLauncher.java index f0757db76bda..5f4a1c5ca32c 100644 --- a/services/core/java/com/android/server/wm/PhysicalDisplaySwitchTransitionLauncher.java +++ b/services/core/java/com/android/server/wm/PhysicalDisplaySwitchTransitionLauncher.java @@ -123,7 +123,7 @@ public class PhysicalDisplaySwitchTransitionLauncher { displayChange); if (t != null) { - mDisplayContent.mAtmService.startLaunchPowerMode(POWER_MODE_REASON_CHANGE_DISPLAY); + mDisplayContent.mAtmService.startPowerMode(POWER_MODE_REASON_CHANGE_DISPLAY); mTransition = t; } diff --git a/services/core/java/com/android/server/wm/RecentsAnimation.java b/services/core/java/com/android/server/wm/RecentsAnimation.java index be9058840492..972d75bd02c3 100644 --- a/services/core/java/com/android/server/wm/RecentsAnimation.java +++ b/services/core/java/com/android/server/wm/RecentsAnimation.java @@ -293,8 +293,7 @@ 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.endLaunchPowerMode( - ActivityTaskManagerService.POWER_MODE_REASON_START_ACTIVITY); + mService.endPowerMode(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 2fdfec04b895..543471e4912e 100644 --- a/services/core/java/com/android/server/wm/RootWindowContainer.java +++ b/services/core/java/com/android/server/wm/RootWindowContainer.java @@ -3250,7 +3250,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent> } } // End power mode launch when idle. - mService.endLaunchPowerMode(ActivityTaskManagerService.POWER_MODE_REASON_START_ACTIVITY); + mService.endPowerMode(ActivityTaskManagerService.POWER_MODE_REASON_START_ACTIVITY); return true; } @@ -3456,7 +3456,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent> reason |= ActivityTaskManagerService.POWER_MODE_REASON_UNKNOWN_VISIBILITY; } } - mService.startLaunchPowerMode(reason); + mService.startPowerMode(reason); } /** diff --git a/services/core/java/com/android/server/wm/TransitionController.java b/services/core/java/com/android/server/wm/TransitionController.java index 0d7870131133..1407a7595792 100644 --- a/services/core/java/com/android/server/wm/TransitionController.java +++ b/services/core/java/com/android/server/wm/TransitionController.java @@ -864,7 +864,7 @@ class TransitionController { // It is usually a no-op but make sure that the metric consumer is removed. mTransitionMetricsReporter.reportAnimationStart(record.getToken(), 0 /* startTime */); // It is a no-op if the transition did not change the display. - mAtm.endLaunchPowerMode(POWER_MODE_REASON_CHANGE_DISPLAY); + mAtm.endPowerMode(POWER_MODE_REASON_CHANGE_DISPLAY); if (!mPlayingTransitions.contains(record)) { Slog.e(TAG, "Trying to finish a non-playing transition " + record); return; diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 439b7193dd4b..08d37183342e 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -6192,7 +6192,7 @@ public class WindowManagerService extends IWindowManager.Stub 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_CHANGE_DISPLAY); + mAtmService.startPowerMode(POWER_MODE_REASON_CHANGE_DISPLAY); mDisplayFrozen = true; mDisplayFreezeTime = SystemClock.elapsedRealtime(); @@ -6334,7 +6334,7 @@ public class WindowManagerService extends IWindowManager.Stub if (configChanged) { displayContent.sendNewConfiguration(); } - mAtmService.endLaunchPowerMode(POWER_MODE_REASON_CHANGE_DISPLAY); + mAtmService.endPowerMode(POWER_MODE_REASON_CHANGE_DISPLAY); mLatencyTracker.onActionEnd(ACTION_ROTATE_SCREEN); } diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java index 5341588c3992..f0a6de95c67a 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java @@ -43,6 +43,7 @@ import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.atLeast; import static org.mockito.Mockito.doCallRealMethod; +import static org.mockito.Mockito.never; import android.annotation.NonNull; import android.annotation.Nullable; @@ -58,6 +59,7 @@ import android.content.res.Configuration; import android.graphics.Rect; import android.os.Binder; import android.os.LocaleList; +import android.os.PowerManagerInternal; import android.os.RemoteException; import android.platform.test.annotations.Presubmit; import android.view.Display; @@ -378,12 +380,12 @@ 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 + mAtm.startPowerMode(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); + mAtm.endPowerMode(ActivityTaskManagerService.POWER_MODE_REASON_START_ACTIVITY); assertEquals(ActivityManager.PROCESS_STATE_TOP_SLEEPING, mAtm.mInternal.getTopProcessState()); @@ -408,6 +410,37 @@ public class ActivityTaskManagerServiceTests extends WindowTestsBase { } @Test + public void testSetPowerMode() { + // Depends on the mocked power manager set in SystemServicesTestRule#setUpLocalServices. + mAtm.onInitPowerManagement(); + + // Apply different power modes according to the reasons. + mAtm.startPowerMode(ActivityTaskManagerService.POWER_MODE_REASON_START_ACTIVITY); + verify(mWm.mPowerManagerInternal).setPowerMode( + PowerManagerInternal.MODE_LAUNCH, true); + mAtm.startPowerMode(ActivityTaskManagerService.POWER_MODE_REASON_CHANGE_DISPLAY); + verify(mWm.mPowerManagerInternal).setPowerMode( + PowerManagerInternal.MODE_DISPLAY_CHANGE, true); + + // If there is unknown visibility launching app, the launch power mode won't be canceled + // even if REASON_START_ACTIVITY is cleared. + mAtm.startPowerMode(ActivityTaskManagerService.POWER_MODE_REASON_UNKNOWN_VISIBILITY); + mDisplayContent.mUnknownAppVisibilityController.notifyLaunched(mock(ActivityRecord.class)); + mAtm.endPowerMode(ActivityTaskManagerService.POWER_MODE_REASON_START_ACTIVITY); + verify(mWm.mPowerManagerInternal, never()).setPowerMode( + PowerManagerInternal.MODE_LAUNCH, false); + + mDisplayContent.mUnknownAppVisibilityController.clear(); + mAtm.endPowerMode(ActivityTaskManagerService.POWER_MODE_REASON_START_ACTIVITY); + verify(mWm.mPowerManagerInternal).setPowerMode( + PowerManagerInternal.MODE_LAUNCH, false); + + mAtm.endPowerMode(ActivityTaskManagerService.POWER_MODE_REASON_CHANGE_DISPLAY); + verify(mWm.mPowerManagerInternal).setPowerMode( + PowerManagerInternal.MODE_DISPLAY_CHANGE, false); + } + + @Test public void testSupportsMultiWindow_resizable() { final ActivityRecord activity = new ActivityBuilder(mAtm) .setCreateTask(true) |