diff options
7 files changed, 146 insertions, 17 deletions
diff --git a/core/java/android/hardware/display/DisplayManagerInternal.java b/core/java/android/hardware/display/DisplayManagerInternal.java index 36e816af8439..6c1aa90c831b 100644 --- a/core/java/android/hardware/display/DisplayManagerInternal.java +++ b/core/java/android/hardware/display/DisplayManagerInternal.java @@ -92,9 +92,10 @@ public abstract class DisplayManagerInternal { boolean waitForNegativeProximity); /** - * Returns {@code true} if the proximity sensor screen-off function is available. + * Returns {@code true} if the proximity sensor screen-off function is available for the given + * display. */ - public abstract boolean isProximitySensorAvailable(); + public abstract boolean isProximitySensorAvailable(int displayId); /** * Registers a display group listener which will be informed of the addition, removal, or change diff --git a/core/java/android/os/IPowerManager.aidl b/core/java/android/os/IPowerManager.aidl index 5f62b8be45a3..e85e58039828 100644 --- a/core/java/android/os/IPowerManager.aidl +++ b/core/java/android/os/IPowerManager.aidl @@ -42,7 +42,9 @@ interface IPowerManager void updateWakeLockWorkSource(IBinder lock, in WorkSource ws, String historyTag); void updateWakeLockCallback(IBinder lock, IWakeLockCallback callback); + @UnsupportedAppUsage boolean isWakeLockLevelSupported(int level); + boolean isWakeLockLevelSupportedWithDisplayId(int level, int displayId); void userActivity(int displayId, long time, int event, int flags); void wakeUp(long time, int reason, String details, String opPackageName); diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java index b9bae5b9f737..32db3bea7686 100644 --- a/core/java/android/os/PowerManager.java +++ b/core/java/android/os/PowerManager.java @@ -1344,6 +1344,9 @@ public final class PowerManager { * @see #ON_AFTER_RELEASE */ public WakeLock newWakeLock(int levelAndFlags, String tag) { + if (android.companion.virtualdevice.flags.Flags.displayPowerManagerApis()) { + return newWakeLock(levelAndFlags, tag, mContext.getDisplayId()); + } validateWakeLockParameters(levelAndFlags, tag); return new WakeLock(levelAndFlags, tag, mContext.getOpPackageName(), Display.INVALID_DISPLAY); @@ -1734,6 +1737,10 @@ public final class PowerManager { */ public boolean isWakeLockLevelSupported(int level) { try { + if (android.companion.virtualdevice.flags.Flags.displayPowerManagerApis()) { + return mService.isWakeLockLevelSupportedWithDisplayId( + level, mContext.getDisplayId()); + } return mService.isWakeLockLevelSupported(level); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); @@ -1797,6 +1804,9 @@ public final class PowerManager { * @see android.content.Intent#ACTION_SCREEN_OFF */ public boolean isInteractive() { + if (android.companion.virtualdevice.flags.Flags.displayPowerManagerApis()) { + return isInteractive(mContext.getDisplayId()); + } return mInteractiveCache.query(null); } diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java index bb503aaab471..3dc531e86da1 100644 --- a/services/core/java/com/android/server/display/DisplayManagerService.java +++ b/services/core/java/com/android/server/display/DisplayManagerService.java @@ -5233,10 +5233,9 @@ public final class DisplayManagerService extends SystemService { } @Override - public boolean isProximitySensorAvailable() { + public boolean isProximitySensorAvailable(int displayId) { synchronized (mSyncRoot) { - return mDisplayPowerControllers.get(Display.DEFAULT_DISPLAY) - .isProximitySensorAvailable(); + return mDisplayPowerControllers.get(displayId).isProximitySensorAvailable(); } } diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java index 21ab7812e604..65f22416a535 100644 --- a/services/core/java/com/android/server/power/PowerManagerService.java +++ b/services/core/java/com/android/server/power/PowerManagerService.java @@ -743,6 +743,7 @@ public final class PowerManagerService extends SystemService int reason, int uid, int opUid, String opPackageName, String details) { mWakefulnessChanging = true; mDirty |= DIRTY_WAKEFULNESS; + mInjector.invalidateIsInteractiveCaches(); if (wakefulness == WAKEFULNESS_AWAKE) { // Kick user activity to prevent newly awake group from timing out instantly. // The dream may end without user activity if the dream app crashes / is updated, @@ -2035,7 +2036,7 @@ public final class PowerManagerService extends SystemService } @SuppressWarnings("deprecation") - private boolean isWakeLockLevelSupportedInternal(int level) { + private boolean isWakeLockLevelSupportedInternal(int level, int displayId) { synchronized (mLock) { switch (level) { case PowerManager.PARTIAL_WAKE_LOCK: @@ -2047,7 +2048,8 @@ public final class PowerManagerService extends SystemService return true; case PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK: - return mSystemReady && mDisplayManagerInternal.isProximitySensorAvailable(); + return mSystemReady + && mDisplayManagerInternal.isProximitySensorAvailable(displayId); case PowerManager.SCREEN_TIMEOUT_OVERRIDE_WAKE_LOCK: return mSystemReady && mFeatureFlags.isEarlyScreenTimeoutDetectorEnabled() && mScreenTimeoutOverridePolicy != null; @@ -2264,7 +2266,6 @@ public final class PowerManagerService extends SystemService int opUid, String opPackageName, String details) { mPowerGroups.get(groupId).setWakefulnessLocked(wakefulness, eventTime, uid, reason, opUid, opPackageName, details); - mInjector.invalidateIsInteractiveCaches(); } @SuppressWarnings("deprecation") @@ -2329,8 +2330,6 @@ public final class PowerManagerService extends SystemService Trace.traceBegin(Trace.TRACE_TAG_POWER, traceMethodName); try { // Phase 2: Handle wakefulness change and bookkeeping. - // Under lock, invalidate before set ensures caches won't return stale values. - mInjector.invalidateIsInteractiveCaches(); mWakefulnessRaw = newWakefulness; mWakefulnessChanging = true; mDirty |= DIRTY_WAKEFULNESS; @@ -2428,6 +2427,7 @@ public final class PowerManagerService extends SystemService void onPowerGroupEventLocked(int event, PowerGroup powerGroup) { mWakefulnessChanging = true; mDirty |= DIRTY_WAKEFULNESS; + mInjector.invalidateIsInteractiveCaches(); final int groupId = powerGroup.getGroupId(); if (event == DisplayGroupPowerChangeListener.DISPLAY_GROUP_REMOVED) { mPowerGroups.delete(groupId); @@ -3975,6 +3975,9 @@ public final class PowerManagerService extends SystemService private boolean isInteractiveInternal(int displayId, int uid) { synchronized (mLock) { + if (!mSystemReady) { + return isGloballyInteractiveInternal(); + } DisplayInfo displayInfo = mDisplayManagerInternal.getDisplayInfo(displayId); if (displayInfo == null) { Slog.w(TAG, "Did not find DisplayInfo for displayId " + displayId); @@ -5975,7 +5978,17 @@ public final class PowerManagerService extends SystemService public boolean isWakeLockLevelSupported(int level) { final long ident = Binder.clearCallingIdentity(); try { - return isWakeLockLevelSupportedInternal(level); + return isWakeLockLevelSupportedInternal(level, Display.DEFAULT_DISPLAY); + } finally { + Binder.restoreCallingIdentity(ident); + } + } + + @Override // Binder call + public boolean isWakeLockLevelSupportedWithDisplayId(int level, int displayId) { + final long ident = Binder.clearCallingIdentity(); + try { + return isWakeLockLevelSupportedInternal(level, displayId); } finally { Binder.restoreCallingIdentity(ident); } diff --git a/services/tests/powerservicetests/src/com/android/server/power/LowPowerStandbyControllerTest.java b/services/tests/powerservicetests/src/com/android/server/power/LowPowerStandbyControllerTest.java index 0e815d0eab95..3e731a322d4e 100644 --- a/services/tests/powerservicetests/src/com/android/server/power/LowPowerStandbyControllerTest.java +++ b/services/tests/powerservicetests/src/com/android/server/power/LowPowerStandbyControllerTest.java @@ -163,6 +163,7 @@ public class LowPowerStandbyControllerTest { addLocalServiceMock(ActivityManagerInternal.class, mActivityManagerInternalMock); when(mIPowerManagerMock.isInteractive()).thenReturn(true); + when(mIPowerManagerMock.isDisplayInteractive(anyInt())).thenReturn(true); when(mDeviceConfigWrapperMock.enableCustomPolicy()).thenReturn(true); when(mDeviceConfigWrapperMock.enableStandbyPorts()).thenReturn(true); @@ -899,11 +900,13 @@ public class LowPowerStandbyControllerTest { private void setInteractive() throws Exception { when(mIPowerManagerMock.isInteractive()).thenReturn(true); + when(mIPowerManagerMock.isDisplayInteractive(anyInt())).thenReturn(true); mContextSpy.sendBroadcast(new Intent(Intent.ACTION_SCREEN_ON)); } private void setNonInteractive() throws Exception { when(mIPowerManagerMock.isInteractive()).thenReturn(false); + when(mIPowerManagerMock.isDisplayInteractive(anyInt())).thenReturn(false); mContextSpy.sendBroadcast(new Intent(Intent.ACTION_SCREEN_OFF)); } 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 54a02cf3cda3..e9e21dee16a8 100644 --- a/services/tests/powerservicetests/src/com/android/server/power/PowerManagerServiceTest.java +++ b/services/tests/powerservicetests/src/com/android/server/power/PowerManagerServiceTest.java @@ -1659,6 +1659,64 @@ public class PowerManagerServiceTest { } @Test + public void testIsWakeLockLevelSupported_returnsCorrectValue() { + createService(); + startSystem(); + PowerManagerService.BinderService service = mService.getBinderServiceInstance(); + assertThat(service.isWakeLockLevelSupported(PowerManager.PARTIAL_WAKE_LOCK)).isTrue(); + assertThat(service.isWakeLockLevelSupported(PowerManager.SCREEN_BRIGHT_WAKE_LOCK)).isTrue(); + assertThat(service.isWakeLockLevelSupported(PowerManager.FULL_WAKE_LOCK)).isTrue(); + assertThat(service.isWakeLockLevelSupported(PowerManager.DOZE_WAKE_LOCK)).isTrue(); + assertThat(service.isWakeLockLevelSupported(PowerManager.DRAW_WAKE_LOCK)).isTrue(); + + when(mDisplayManagerInternalMock.isProximitySensorAvailable(eq(Display.DEFAULT_DISPLAY))) + .thenReturn(true); + assertThat(service.isWakeLockLevelSupported(PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK)) + .isTrue(); + + when(mDisplayManagerInternalMock.isProximitySensorAvailable(eq(Display.DEFAULT_DISPLAY))) + .thenReturn(false); + assertThat(service.isWakeLockLevelSupported(PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK)) + .isFalse(); + } + + @Test + public void testIsWakeLockLevelSupportedWithDisplayId_nonDefaultDisplay_returnsCorrectValue() { + createService(); + startSystem(); + int displayId = Display.DEFAULT_DISPLAY + 1; + PowerManagerService.BinderService service = mService.getBinderServiceInstance(); + assertThat(service.isWakeLockLevelSupportedWithDisplayId( + PowerManager.PARTIAL_WAKE_LOCK, displayId)) + .isTrue(); + assertThat(service.isWakeLockLevelSupportedWithDisplayId( + PowerManager.SCREEN_BRIGHT_WAKE_LOCK, displayId)) + .isTrue(); + assertThat(service.isWakeLockLevelSupportedWithDisplayId( + PowerManager.FULL_WAKE_LOCK, displayId)) + .isTrue(); + assertThat(service.isWakeLockLevelSupportedWithDisplayId( + PowerManager.DOZE_WAKE_LOCK, displayId)) + .isTrue(); + assertThat(service.isWakeLockLevelSupportedWithDisplayId( + PowerManager.DRAW_WAKE_LOCK, displayId)) + .isTrue(); + + when(mDisplayManagerInternalMock.isProximitySensorAvailable(eq(displayId))) + .thenReturn(true); + assertThat(service.isWakeLockLevelSupportedWithDisplayId( + PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK, displayId)) + .isTrue(); + + when(mDisplayManagerInternalMock.isProximitySensorAvailable(eq(displayId))) + .thenReturn(false); + assertThat(service.isWakeLockLevelSupportedWithDisplayId( + PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK, displayId)) + .isFalse(); + } + + + @Test public void testWakeLock_affectsProperDisplayGroup() { final int nonDefaultDisplayGroupId = Display.DEFAULT_DISPLAY_GROUP + 1; final AtomicReference<DisplayManagerInternal.DisplayGroupListener> listener = @@ -1699,6 +1757,47 @@ public class PowerManagerServiceTest { } @Test + public void testWakeLock_nonDefaultDisplay_affectsProperDisplayGroup() { + final int nonDefaultDisplayId = Display.DEFAULT_DISPLAY + 1; + final int nonDefaultDisplayGroupId = Display.DEFAULT_DISPLAY_GROUP + 1; + final AtomicReference<DisplayManagerInternal.DisplayGroupListener> listener = + new AtomicReference<>(); + doAnswer((Answer<Void>) invocation -> { + listener.set(invocation.getArgument(0)); + return null; + }).when(mDisplayManagerInternalMock).registerDisplayGroupListener(any()); + final DisplayInfo info = new DisplayInfo(); + info.displayGroupId = nonDefaultDisplayGroupId; + when(mDisplayManagerInternalMock.getDisplayInfo(nonDefaultDisplayId)).thenReturn(info); + + final String pkg = mContextSpy.getOpPackageName(); + final Binder token = new Binder(); + final String tag = "testWakeLock_nonDefaultDisplay_affectsProperDisplayGroup"; + + setMinimumScreenOffTimeoutConfig(5); + createService(); + startSystem(); + listener.get().onDisplayGroupAdded(nonDefaultDisplayGroupId); + + mService.getBinderServiceInstance().acquireWakeLock(token, + PowerManager.SCREEN_BRIGHT_WAKE_LOCK, tag, pkg, + null /* workSource */, null /* historyTag */, nonDefaultDisplayId, null); + + assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE); + assertThat(mService.getWakefulnessLocked(Display.DEFAULT_DISPLAY_GROUP)).isEqualTo( + WAKEFULNESS_AWAKE); + assertThat(mService.getWakefulnessLocked(nonDefaultDisplayGroupId)).isEqualTo( + WAKEFULNESS_AWAKE); + + advanceTime(15000); + assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE); + assertThat(mService.getWakefulnessLocked(Display.DEFAULT_DISPLAY_GROUP)).isEqualTo( + WAKEFULNESS_ASLEEP); + assertThat(mService.getWakefulnessLocked(nonDefaultDisplayGroupId)).isEqualTo( + WAKEFULNESS_AWAKE); + } + + @Test public void testInvalidDisplayGroupWakeLock_affectsAllDisplayGroups() { final int nonDefaultDisplayGroupId = Display.DEFAULT_DISPLAY_GROUP + 1; final AtomicReference<DisplayManagerInternal.DisplayGroupListener> listener = @@ -2590,14 +2689,15 @@ public class PowerManagerServiceTest { when(mDisplayManagerInternalMock.getDisplayInfo(nonDefaultDisplay)).thenReturn(info); createService(); startSystem(); - listener.get().onDisplayGroupAdded(nonDefaultDisplayGroupId); - verify(mInvalidateInteractiveCachesMock).call(); + listener.get().onDisplayGroupAdded(nonDefaultDisplayGroupId); + verify(mInvalidateInteractiveCachesMock, times(2)).call(); + mService.setWakefulnessLocked(Display.DEFAULT_DISPLAY_GROUP, WAKEFULNESS_ASLEEP, mClock.now(), 0, PowerManager.GO_TO_SLEEP_REASON_APPLICATION, 0, null, null); - verify(mInvalidateInteractiveCachesMock, times(2)).call(); + verify(mInvalidateInteractiveCachesMock, times(3)).call(); } @Test @@ -2616,14 +2716,15 @@ public class PowerManagerServiceTest { when(mDisplayManagerInternalMock.getDisplayInfo(nonDefaultDisplay)).thenReturn(info); createService(); startSystem(); - listener.get().onDisplayGroupAdded(nonDefaultDisplayGroupId); - verify(mInvalidateInteractiveCachesMock).call(); + listener.get().onDisplayGroupAdded(nonDefaultDisplayGroupId); + verify(mInvalidateInteractiveCachesMock, times(2)).call(); + mService.setWakefulnessLocked(nonDefaultDisplayGroupId, WAKEFULNESS_ASLEEP, mClock.now(), 0, PowerManager.GO_TO_SLEEP_REASON_APPLICATION, 0, null, null); - verify(mInvalidateInteractiveCachesMock, times(2)).call(); + verify(mInvalidateInteractiveCachesMock, times(3)).call(); } @Test |