Added support for wake-up by displayId
Test: atest PowerManagerServiceTest
Flag: EXEMPT New API in an independent codepath
Bug: 360915895
Change-Id: Ic6b72856d589df031d7ff3d132f9972f28237bb9
diff --git a/core/java/android/os/IPowerManager.aidl b/core/java/android/os/IPowerManager.aidl
index dbb6f92..5f62b8b 100644
--- a/core/java/android/os/IPowerManager.aidl
+++ b/core/java/android/os/IPowerManager.aidl
@@ -46,6 +46,7 @@
void userActivity(int displayId, long time, int event, int flags);
void wakeUp(long time, int reason, String details, String opPackageName);
+ void wakeUpWithDisplayId(long time, int reason, String details, String opPackageName, int displayId);
@UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
void goToSleep(long time, int reason, int flags);
@UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java
index 026013c..432ec727 100644
--- a/core/java/android/os/PowerManager.java
+++ b/core/java/android/os/PowerManager.java
@@ -1566,27 +1566,9 @@
}
/**
- * Forces the {@link android.view.Display#DEFAULT_DISPLAY_GROUP default display group}
- * to turn on.
+ * Forces the {@link android.view.Display#DEFAULT_DISPLAY default display} to turn on.
*
- * <p>If the {@link android.view.Display#DEFAULT_DISPLAY_GROUP default display group} is
- * turned off it will be turned on. Additionally, if the device is asleep it will be awoken. If
- * the {@link android.view.Display#DEFAULT_DISPLAY_GROUP default display group} is already
- * on then nothing will happen.
- *
- * <p>
- * This is what happens when the power key is pressed to turn on the screen.
- * </p><p>
- * Requires the {@link android.Manifest.permission#DEVICE_POWER} permission.
- * </p>
- *
- * @param time The time when the request to wake up was issued, in the
- * {@link SystemClock#uptimeMillis()} time base. This timestamp is used to correctly
- * order the wake up request with other power management functions. It should be set
- * to the timestamp of the input event that caused the request to wake up.
- *
- * @see #userActivity
- * @see #goToSleep
+ * @see #wakeUp(long, int, String, int)
*
* @deprecated Use {@link #wakeUp(long, int, String)} instead.
* @removed Requires signature permission.
@@ -1597,30 +1579,9 @@
}
/**
- * Forces the {@link android.view.Display#DEFAULT_DISPLAY_GROUP default display group}
- * to turn on.
+ * Forces the {@link android.view.Display#DEFAULT_DISPLAY default display} to turn on.
*
- * <p>If the {@link android.view.Display#DEFAULT_DISPLAY_GROUP default display group} is
- * turned off it will be turned on. Additionally, if the device is asleep it will be awoken. If
- * the {@link android.view.Display#DEFAULT_DISPLAY_GROUP default display group} is already
- * on then nothing will happen.
- *
- * <p>
- * This is what happens when the power key is pressed to turn on the screen.
- * </p><p>
- * Requires the {@link android.Manifest.permission#DEVICE_POWER} permission.
- * </p>
- *
- * @param time The time when the request to wake up was issued, in the
- * {@link SystemClock#uptimeMillis()} time base. This timestamp is used to correctly
- * order the wake up request with other power management functions. It should be set
- * to the timestamp of the input event that caused the request to wake up.
- *
- * @param details A free form string to explain the specific details behind the wake up for
- * debugging purposes.
- *
- * @see #userActivity
- * @see #goToSleep
+ * @see #wakeUp(long, int, String, int)
*
* @deprecated Use {@link #wakeUp(long, int, String)} instead.
* @hide
@@ -1634,9 +1595,23 @@
/**
* Forces the {@link android.view.Display#DEFAULT_DISPLAY default display} to turn on.
*
- * <p>If the {@link android.view.Display#DEFAULT_DISPLAY default display} is turned off it will
- * be turned on. Additionally, if the device is asleep it will be awoken. If the {@link
- * android.view.Display#DEFAULT_DISPLAY default display} is already on then nothing will happen.
+ * @see #wakeUp(long, int, String, int)
+ * @hide
+ */
+ public void wakeUp(long time, @WakeReason int reason, String details) {
+ try {
+ mService.wakeUp(time, reason, details, mContext.getOpPackageName());
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Forces the display with the supplied displayId to turn on.
+ *
+ * <p>If the corresponding display is turned off, it will be turned on. Additionally, if the
+ * device is asleep it will be awoken. If the corresponding display is already on then nothing
+ * will happen. If the corresponding display does not exist, then nothing will happen.
*
* <p>If the device is an Android TV playback device, it will attempt to turn on the
* HDMI-connected TV and become the current active source via the HDMI-CEC One Touch Play
@@ -1657,14 +1632,16 @@
*
* @param details A free form string to explain the specific details behind the wake up for
* debugging purposes.
+ * @param displayId The displayId of the display to be woken up.
*
* @see #userActivity
* @see #goToSleep
* @hide
*/
- public void wakeUp(long time, @WakeReason int reason, String details) {
+ public void wakeUp(long time, @WakeReason int reason, String details, int displayId) {
try {
- mService.wakeUp(time, reason, details, mContext.getOpPackageName());
+ mService.wakeUpWithDisplayId(time, reason, details, mContext.getOpPackageName(),
+ displayId);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index 71cb882..e053964 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -2207,7 +2207,7 @@
+ ", groupId=" + powerGroup.getGroupId()
+ ", reason=" + PowerManager.wakeReasonToString(reason) + ", uid=" + uid);
}
- if (mForceSuspendActive || !mSystemReady) {
+ if (mForceSuspendActive || !mSystemReady || (powerGroup == null)) {
return;
}
powerGroup.wakeUpLocked(eventTime, reason, details, uid, opPackageName, opUid,
@@ -6027,6 +6027,12 @@
@Override // Binder call
public void wakeUp(long eventTime, @WakeReason int reason, String details,
String opPackageName) {
+ wakeUpWithDisplayId(eventTime, reason, details, opPackageName, Display.DEFAULT_DISPLAY);
+ }
+
+ @Override // Binder call
+ public void wakeUpWithDisplayId(long eventTime, @WakeReason int reason, String details,
+ String opPackageName, int displayId) {
final long now = mClock.uptimeMillis();
if (eventTime > now) {
Slog.e(TAG, "Event time " + eventTime + " cannot be newer than " + now);
@@ -6039,13 +6045,14 @@
final int uid = Binder.getCallingUid();
final long ident = Binder.clearCallingIdentity();
try {
+ int displayGroupId = getDisplayGroupId(displayId);
synchronized (mLock) {
if (!mBootCompleted && sQuiescent) {
mDirty |= DIRTY_QUIESCENT;
updatePowerStateLocked();
return;
}
- wakePowerGroupLocked(mPowerGroups.get(Display.DEFAULT_DISPLAY_GROUP), eventTime,
+ wakePowerGroupLocked(mPowerGroups.get(displayGroupId), eventTime,
reason, details, uid, opPackageName, uid);
}
} finally {
@@ -7335,4 +7342,12 @@
}
}
}
+
+ private int getDisplayGroupId(int displayId) {
+ DisplayInfo displayInfo = mDisplayManagerInternal.getDisplayInfo(displayId);
+ if (displayInfo == null) {
+ return Display.INVALID_DISPLAY_GROUP;
+ }
+ return displayInfo.displayGroupId;
+ }
}
diff --git a/services/tests/powerservicetests/src/com/android/server/power/PowerManagerServiceTest.java b/services/tests/powerservicetests/src/com/android/server/power/PowerManagerServiceTest.java
index b58c28b..54a02cf 100644
--- a/services/tests/powerservicetests/src/com/android/server/power/PowerManagerServiceTest.java
+++ b/services/tests/powerservicetests/src/com/android/server/power/PowerManagerServiceTest.java
@@ -268,6 +268,10 @@
mClock = new OffsettableClock.Stopped();
mTestLooper = new TestLooper(mClock::now);
+ DisplayInfo displayInfo = Mockito.mock(DisplayInfo.class);
+ displayInfo.displayGroupId = Display.DEFAULT_DISPLAY_GROUP;
+ when(mDisplayManagerInternalMock.getDisplayInfo(Display.DEFAULT_DISPLAY))
+ .thenReturn(displayInfo);
}
private PowerManagerService createService() {
@@ -794,6 +798,57 @@
assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
}
+ @Test
+ public void testWakefulnessPerGroup_IPowerManagerWakeUpWithDisplayId() {
+ final int nonDefaultPowerGroupId = Display.DEFAULT_DISPLAY_GROUP + 1;
+ int displayInNonDefaultGroup = 1;
+ final AtomicReference<DisplayManagerInternal.DisplayGroupListener> listener =
+ new AtomicReference<>();
+ long eventTime1 = 10;
+ long eventTime2 = eventTime1 + 1;
+ long eventTime3 = eventTime2 + 1;
+ doAnswer((Answer<Void>) invocation -> {
+ listener.set(invocation.getArgument(0));
+ return null;
+ }).when(mDisplayManagerInternalMock).registerDisplayGroupListener(any());
+
+ createService();
+ startSystem();
+ listener.get().onDisplayGroupAdded(nonDefaultPowerGroupId);
+
+ // Verify the global wakefulness is AWAKE
+ assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
+
+ // Transition default display to doze, and verify the global wakefulness
+ mService.setWakefulnessLocked(Display.DEFAULT_DISPLAY_GROUP, WAKEFULNESS_DOZING, eventTime1,
+ 0, PowerManager.GO_TO_SLEEP_REASON_INATTENTIVE, 0, null, null);
+ assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
+
+ // Transition the display from non default power group to doze, and verify the change in
+ // the global wakefulness
+ mService.setWakefulnessLocked(nonDefaultPowerGroupId, WAKEFULNESS_DOZING, eventTime2,
+ 0, PowerManager.GO_TO_SLEEP_REASON_APPLICATION, 0, null, null);
+ assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_DOZING);
+ assertThat(mService.getWakefulnessLocked(nonDefaultPowerGroupId))
+ .isEqualTo(WAKEFULNESS_DOZING);
+
+ // Wakeup the display from the non default power group
+ DisplayInfo displayInfo = Mockito.mock(DisplayInfo.class);
+ displayInfo.displayGroupId = nonDefaultPowerGroupId;
+ when(mDisplayManagerInternalMock.getDisplayInfo(displayInNonDefaultGroup))
+ .thenReturn(displayInfo);
+ mClock.fastForward(eventTime3);
+ mService.getBinderServiceInstance().wakeUpWithDisplayId(eventTime3,
+ PowerManager.WAKE_REASON_APPLICATION, "testing IPowerManager.wakeUp()",
+ "pkg.name", displayInNonDefaultGroup);
+
+ assertThat(mService.getWakefulnessLocked(nonDefaultPowerGroupId))
+ .isEqualTo(WAKEFULNESS_AWAKE);
+ assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
+ assertThat(mService.getWakefulnessLocked(Display.DEFAULT_DISPLAY))
+ .isEqualTo(WAKEFULNESS_DOZING);
+ }
+
/**
* Tests a series of variants that control whether a device wakes-up when it is plugged in
* or docked.