summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Riddle Hsu <riddlehsu@google.com> 2023-09-01 17:07:16 +0800
committer Jimmy Shiu <jimmyshiu@google.com> 2023-09-14 20:32:09 +0800
commit942d112ce4c325c0640c1f21822d1f2ddda21fb4 (patch)
tree8d8de9abd8f85adf1371626b36932f7eb7a91948
parent33b539cb0d4a99fc18a0f49dc3cd5232a3d241b1 (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
-rw-r--r--services/core/java/com/android/server/wm/ActivityTaskManagerService.java64
-rw-r--r--services/core/java/com/android/server/wm/ActivityTaskSupervisor.java2
-rw-r--r--services/core/java/com/android/server/wm/DisplayContent.java2
-rw-r--r--services/core/java/com/android/server/wm/PhysicalDisplaySwitchTransitionLauncher.java2
-rw-r--r--services/core/java/com/android/server/wm/RecentsAnimation.java3
-rw-r--r--services/core/java/com/android/server/wm/RootWindowContainer.java4
-rw-r--r--services/core/java/com/android/server/wm/TransitionController.java2
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java4
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java37
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)