Loading core/java/android/os/IPowerManager.aidl +1 −0 Original line number Diff line number Diff line Loading @@ -55,6 +55,7 @@ interface IPowerManager float getBrightnessConstraint(int constraint); @UnsupportedAppUsage boolean isInteractive(); boolean isDisplayInteractive(int displayId); boolean areAutoPowerSaveModesEnabled(); boolean isPowerSaveMode(); PowerSaveState getPowerSaveState(int serviceType); Loading core/java/android/os/PowerManager.java +20 −4 Original line number Diff line number Diff line Loading @@ -1150,13 +1150,17 @@ public final class PowerManager { } }; private final PropertyInvalidatedCache<Void, Boolean> mInteractiveCache = new PropertyInvalidatedCache<Void, Boolean>(MAX_CACHE_ENTRIES, private final PropertyInvalidatedCache<Integer, Boolean> mInteractiveCache = new PropertyInvalidatedCache<Integer, Boolean>(MAX_CACHE_ENTRIES, CACHE_KEY_IS_INTERACTIVE_PROPERTY) { @Override public Boolean recompute(Void query) { public Boolean recompute(Integer displayId) { try { if (displayId == null) { return mService.isInteractive(); } else { return mService.isDisplayInteractive(displayId); } } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } Loading Loading @@ -1802,6 +1806,18 @@ public final class PowerManager { return mInteractiveCache.query(null); } /** * Returns the interactive state for a specific display, which may not be the same as the * global wakefulness (which is true when any display is awake). * * @param displayId * @return whether the given display is present and interactive, or false * * @hide */ public boolean isInteractive(int displayId) { return mInteractiveCache.query(displayId); } /** * Returns {@code true} if this device supports rebooting userspace. Loading packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationController.kt +2 −1 Original line number Diff line number Diff line Loading @@ -8,6 +8,7 @@ import android.database.ContentObserver import android.os.Handler import android.os.PowerManager import android.provider.Settings import android.view.Display import android.view.Surface import android.view.View import android.view.WindowManager.fixScale Loading Loading @@ -272,7 +273,7 @@ class UnlockedScreenOffAnimationController @Inject constructor( // dispatched, a race condition could make it possible for this callback to be run // as the device is waking up. That results in the AOD UI being shown while we wake // up, with unpredictable consequences. if (!powerManager.isInteractive) { if (!powerManager.isInteractive(Display.DEFAULT_DISPLAY)) { aodUiAnimationPlaying = true // Show AOD. That'll cause the KeyguardVisibilityHelper to call Loading packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationControllerTest.kt +18 −1 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import android.os.Handler import android.os.PowerManager import android.testing.AndroidTestingRunner import android.testing.TestableLooper.RunWithLooper import android.view.Display import androidx.test.filters.SmallTest import com.android.internal.jank.InteractionJankMonitor import com.android.systemui.SysuiTestCase Loading @@ -29,6 +30,7 @@ import com.android.systemui.shade.ShadeViewController import com.android.systemui.statusbar.LightRevealScrim import com.android.systemui.statusbar.StatusBarStateControllerImpl import com.android.systemui.statusbar.policy.KeyguardStateController import com.android.systemui.util.mockito.eq import com.android.systemui.util.settings.GlobalSettings import junit.framework.Assert.assertFalse import org.junit.After Loading Loading @@ -141,7 +143,7 @@ class UnlockedScreenOffAnimationControllerTest : SysuiTestCase() { @Test fun testAodUiNotShownIfInteractive() { `when`(dozeParameters.canControlUnlockedScreenOff()).thenReturn(true) `when`(powerManager.isInteractive).thenReturn(true) `when`(powerManager.isInteractive(eq(Display.DEFAULT_DISPLAY))).thenReturn(true) val callbackCaptor = ArgumentCaptor.forClass(Runnable::class.java) controller.startAnimation() Loading @@ -152,6 +154,21 @@ class UnlockedScreenOffAnimationControllerTest : SysuiTestCase() { verify(shadeViewController, never()).showAodUi() } @Test fun testAodUiShownIfGloballyInteractiveButDefaultDisplayNotInteractive() { `when`(dozeParameters.canControlUnlockedScreenOff()).thenReturn(true) `when`(powerManager.isInteractive()).thenReturn(false) `when`(powerManager.isInteractive(eq(Display.DEFAULT_DISPLAY))).thenReturn(false) val callbackCaptor = ArgumentCaptor.forClass(Runnable::class.java) controller.startAnimation() verify(handler).postDelayed(callbackCaptor.capture(), anyLong()) callbackCaptor.value.run() verify(shadeViewController).showAodUi() } @Test fun testNoAnimationPlaying_dozeParamsCanNotControlScreenOff() { `when`(dozeParameters.canControlUnlockedScreenOff()).thenReturn(false) Loading services/core/java/com/android/server/power/PowerManagerService.java +34 −2 Original line number Diff line number Diff line Loading @@ -2079,6 +2079,7 @@ 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") Loading Loading @@ -3743,12 +3744,32 @@ public final class PowerManagerService extends SystemService } } private boolean isInteractiveInternal() { private boolean isGloballyInteractiveInternal() { synchronized (mLock) { return PowerManagerInternal.isInteractive(getGlobalWakefulnessLocked()); } } private boolean isInteractiveInternal(int displayId, int uid) { synchronized (mLock) { DisplayInfo displayInfo = mDisplayManagerInternal.getDisplayInfo(displayId); if (displayInfo == null) { Slog.w(TAG, "Did not find DisplayInfo for displayId " + displayId); return false; } if (!displayInfo.hasAccess(uid)) { throw new SecurityException( "uid " + uid + " does not have access to display " + displayId); } PowerGroup powerGroup = mPowerGroups.get(displayInfo.displayGroupId); if (powerGroup == null) { Slog.w(TAG, "Did not find PowerGroup for displayId " + displayId); return false; } return PowerManagerInternal.isInteractive(powerGroup.getWakefulnessLocked()); } } private boolean setLowPowerModeInternal(boolean enabled) { synchronized (mLock) { if (DEBUG) { Loading Loading @@ -5805,7 +5826,18 @@ public final class PowerManagerService extends SystemService public boolean isInteractive() { final long ident = Binder.clearCallingIdentity(); try { return isInteractiveInternal(); return isGloballyInteractiveInternal(); } finally { Binder.restoreCallingIdentity(ident); } } @Override // Binder call public boolean isDisplayInteractive(int displayId) { int uid = Binder.getCallingUid(); final long ident = Binder.clearCallingIdentity(); try { return isInteractiveInternal(displayId, uid); } finally { Binder.restoreCallingIdentity(ident); } Loading Loading
core/java/android/os/IPowerManager.aidl +1 −0 Original line number Diff line number Diff line Loading @@ -55,6 +55,7 @@ interface IPowerManager float getBrightnessConstraint(int constraint); @UnsupportedAppUsage boolean isInteractive(); boolean isDisplayInteractive(int displayId); boolean areAutoPowerSaveModesEnabled(); boolean isPowerSaveMode(); PowerSaveState getPowerSaveState(int serviceType); Loading
core/java/android/os/PowerManager.java +20 −4 Original line number Diff line number Diff line Loading @@ -1150,13 +1150,17 @@ public final class PowerManager { } }; private final PropertyInvalidatedCache<Void, Boolean> mInteractiveCache = new PropertyInvalidatedCache<Void, Boolean>(MAX_CACHE_ENTRIES, private final PropertyInvalidatedCache<Integer, Boolean> mInteractiveCache = new PropertyInvalidatedCache<Integer, Boolean>(MAX_CACHE_ENTRIES, CACHE_KEY_IS_INTERACTIVE_PROPERTY) { @Override public Boolean recompute(Void query) { public Boolean recompute(Integer displayId) { try { if (displayId == null) { return mService.isInteractive(); } else { return mService.isDisplayInteractive(displayId); } } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } Loading Loading @@ -1802,6 +1806,18 @@ public final class PowerManager { return mInteractiveCache.query(null); } /** * Returns the interactive state for a specific display, which may not be the same as the * global wakefulness (which is true when any display is awake). * * @param displayId * @return whether the given display is present and interactive, or false * * @hide */ public boolean isInteractive(int displayId) { return mInteractiveCache.query(displayId); } /** * Returns {@code true} if this device supports rebooting userspace. Loading
packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationController.kt +2 −1 Original line number Diff line number Diff line Loading @@ -8,6 +8,7 @@ import android.database.ContentObserver import android.os.Handler import android.os.PowerManager import android.provider.Settings import android.view.Display import android.view.Surface import android.view.View import android.view.WindowManager.fixScale Loading Loading @@ -272,7 +273,7 @@ class UnlockedScreenOffAnimationController @Inject constructor( // dispatched, a race condition could make it possible for this callback to be run // as the device is waking up. That results in the AOD UI being shown while we wake // up, with unpredictable consequences. if (!powerManager.isInteractive) { if (!powerManager.isInteractive(Display.DEFAULT_DISPLAY)) { aodUiAnimationPlaying = true // Show AOD. That'll cause the KeyguardVisibilityHelper to call Loading
packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationControllerTest.kt +18 −1 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import android.os.Handler import android.os.PowerManager import android.testing.AndroidTestingRunner import android.testing.TestableLooper.RunWithLooper import android.view.Display import androidx.test.filters.SmallTest import com.android.internal.jank.InteractionJankMonitor import com.android.systemui.SysuiTestCase Loading @@ -29,6 +30,7 @@ import com.android.systemui.shade.ShadeViewController import com.android.systemui.statusbar.LightRevealScrim import com.android.systemui.statusbar.StatusBarStateControllerImpl import com.android.systemui.statusbar.policy.KeyguardStateController import com.android.systemui.util.mockito.eq import com.android.systemui.util.settings.GlobalSettings import junit.framework.Assert.assertFalse import org.junit.After Loading Loading @@ -141,7 +143,7 @@ class UnlockedScreenOffAnimationControllerTest : SysuiTestCase() { @Test fun testAodUiNotShownIfInteractive() { `when`(dozeParameters.canControlUnlockedScreenOff()).thenReturn(true) `when`(powerManager.isInteractive).thenReturn(true) `when`(powerManager.isInteractive(eq(Display.DEFAULT_DISPLAY))).thenReturn(true) val callbackCaptor = ArgumentCaptor.forClass(Runnable::class.java) controller.startAnimation() Loading @@ -152,6 +154,21 @@ class UnlockedScreenOffAnimationControllerTest : SysuiTestCase() { verify(shadeViewController, never()).showAodUi() } @Test fun testAodUiShownIfGloballyInteractiveButDefaultDisplayNotInteractive() { `when`(dozeParameters.canControlUnlockedScreenOff()).thenReturn(true) `when`(powerManager.isInteractive()).thenReturn(false) `when`(powerManager.isInteractive(eq(Display.DEFAULT_DISPLAY))).thenReturn(false) val callbackCaptor = ArgumentCaptor.forClass(Runnable::class.java) controller.startAnimation() verify(handler).postDelayed(callbackCaptor.capture(), anyLong()) callbackCaptor.value.run() verify(shadeViewController).showAodUi() } @Test fun testNoAnimationPlaying_dozeParamsCanNotControlScreenOff() { `when`(dozeParameters.canControlUnlockedScreenOff()).thenReturn(false) Loading
services/core/java/com/android/server/power/PowerManagerService.java +34 −2 Original line number Diff line number Diff line Loading @@ -2079,6 +2079,7 @@ 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") Loading Loading @@ -3743,12 +3744,32 @@ public final class PowerManagerService extends SystemService } } private boolean isInteractiveInternal() { private boolean isGloballyInteractiveInternal() { synchronized (mLock) { return PowerManagerInternal.isInteractive(getGlobalWakefulnessLocked()); } } private boolean isInteractiveInternal(int displayId, int uid) { synchronized (mLock) { DisplayInfo displayInfo = mDisplayManagerInternal.getDisplayInfo(displayId); if (displayInfo == null) { Slog.w(TAG, "Did not find DisplayInfo for displayId " + displayId); return false; } if (!displayInfo.hasAccess(uid)) { throw new SecurityException( "uid " + uid + " does not have access to display " + displayId); } PowerGroup powerGroup = mPowerGroups.get(displayInfo.displayGroupId); if (powerGroup == null) { Slog.w(TAG, "Did not find PowerGroup for displayId " + displayId); return false; } return PowerManagerInternal.isInteractive(powerGroup.getWakefulnessLocked()); } } private boolean setLowPowerModeInternal(boolean enabled) { synchronized (mLock) { if (DEBUG) { Loading Loading @@ -5805,7 +5826,18 @@ public final class PowerManagerService extends SystemService public boolean isInteractive() { final long ident = Binder.clearCallingIdentity(); try { return isInteractiveInternal(); return isGloballyInteractiveInternal(); } finally { Binder.restoreCallingIdentity(ident); } } @Override // Binder call public boolean isDisplayInteractive(int displayId) { int uid = Binder.getCallingUid(); final long ident = Binder.clearCallingIdentity(); try { return isInteractiveInternal(displayId, uid); } finally { Binder.restoreCallingIdentity(ident); } Loading