diff options
4 files changed, 98 insertions, 50 deletions
diff --git a/core/java/android/os/IPowerManager.aidl b/core/java/android/os/IPowerManager.aidl index dbb6f92c6411..5f62b8be45a3 100644 --- a/core/java/android/os/IPowerManager.aidl +++ b/core/java/android/os/IPowerManager.aidl @@ -46,6 +46,7 @@ interface IPowerManager 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 e4c12b6ff834..b9bae5b9f737 100644 --- a/core/java/android/os/PowerManager.java +++ b/core/java/android/os/PowerManager.java @@ -1567,27 +1567,9 @@ public final class PowerManager { } /** - * Forces the {@link android.view.Display#DEFAULT_DISPLAY_GROUP default display group} - * 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. + * Forces the {@link android.view.Display#DEFAULT_DISPLAY default display} to turn on. * - * @see #userActivity - * @see #goToSleep + * @see #wakeUp(long, int, String, int) * * @deprecated Use {@link #wakeUp(long, int, String)} instead. * @removed Requires signature permission. @@ -1598,30 +1580,9 @@ public final class PowerManager { } /** - * Forces the {@link android.view.Display#DEFAULT_DISPLAY_GROUP default display group} - * 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. + * Forces the {@link android.view.Display#DEFAULT_DISPLAY default display} to turn on. * - * @see #userActivity - * @see #goToSleep + * @see #wakeUp(long, int, String, int) * * @deprecated Use {@link #wakeUp(long, int, String)} instead. * @hide @@ -1635,9 +1596,23 @@ public final class PowerManager { /** * 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 @@ -1658,14 +1633,16 @@ public final class PowerManager { * * @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 71cb8820761f..e0539647d061 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 @@ public final class PowerManagerService extends SystemService + ", 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 @@ public final class PowerManagerService extends SystemService @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 @@ public final class PowerManagerService extends SystemService 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 @@ public final class PowerManagerService extends SystemService } } } + + 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 b58c28bfbe62..54a02cf3cda3 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 @@ public class PowerManagerServiceTest { 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 @@ public class PowerManagerServiceTest { 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. |