Loading core/java/android/os/IPowerManager.aidl +1 −0 Original line number Diff line number Diff line Loading @@ -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) Loading core/java/android/os/PowerManager.java +25 −48 Original line number Diff line number Diff line Loading @@ -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. Loading @@ -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 Loading @@ -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 Loading @@ -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(); } Loading services/core/java/com/android/server/power/PowerManagerService.java +17 −2 Original line number Diff line number Diff line Loading @@ -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, Loading Loading @@ -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); Loading @@ -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 { Loading Loading @@ -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; } } services/tests/powerservicetests/src/com/android/server/power/PowerManagerServiceTest.java +55 −0 Original line number Diff line number Diff line Loading @@ -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() { Loading Loading @@ -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. Loading Loading
core/java/android/os/IPowerManager.aidl +1 −0 Original line number Diff line number Diff line Loading @@ -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) Loading
core/java/android/os/PowerManager.java +25 −48 Original line number Diff line number Diff line Loading @@ -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. Loading @@ -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 Loading @@ -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 Loading @@ -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(); } Loading
services/core/java/com/android/server/power/PowerManagerService.java +17 −2 Original line number Diff line number Diff line Loading @@ -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, Loading Loading @@ -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); Loading @@ -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 { Loading Loading @@ -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; } }
services/tests/powerservicetests/src/com/android/server/power/PowerManagerServiceTest.java +55 −0 Original line number Diff line number Diff line Loading @@ -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() { Loading Loading @@ -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. Loading