Loading services/core/java/com/android/server/UiModeManagerService.java +54 −37 Original line number Original line Diff line number Diff line Loading @@ -98,7 +98,8 @@ final class UiModeManagerService extends SystemService { private int mLastBroadcastState = Intent.EXTRA_DOCK_STATE_UNDOCKED; private int mLastBroadcastState = Intent.EXTRA_DOCK_STATE_UNDOCKED; private int mNightMode = UiModeManager.MODE_NIGHT_NO; private int mNightMode = UiModeManager.MODE_NIGHT_NO; // we use the override auto mode // we use the override auto mode // for example: force night mode off in the night time while in auto mode // for example: force night mode off in the night time // while in auto mode private int mNightModeOverride = mNightMode; private int mNightModeOverride = mNightMode; private final LocalTime DEFAULT_CUSTOM_NIGHT_START_TIME = LocalTime.of(22, 0); private final LocalTime DEFAULT_CUSTOM_NIGHT_START_TIME = LocalTime.of(22, 0); private final LocalTime DEFAULT_CUSTOM_NIGHT_END_TIME = LocalTime.of(6, 0); private final LocalTime DEFAULT_CUSTOM_NIGHT_END_TIME = LocalTime.of(6, 0); Loading Loading @@ -152,6 +153,7 @@ final class UiModeManagerService extends SystemService { private PowerManager.WakeLock mWakeLock; private PowerManager.WakeLock mWakeLock; private final LocalService mLocalService = new LocalService(); private final LocalService mLocalService = new LocalService(); private PowerManagerInternal mLocalPowerManager; public UiModeManagerService(Context context) { public UiModeManagerService(Context context) { super(context); super(context); Loading @@ -160,6 +162,7 @@ final class UiModeManagerService extends SystemService { @VisibleForTesting @VisibleForTesting protected UiModeManagerService(Context context, WindowManagerInternal wm, AlarmManager am, protected UiModeManagerService(Context context, WindowManagerInternal wm, AlarmManager am, PowerManager pm, PowerManager.WakeLock wl, TwilightManager tm, PowerManager pm, PowerManager.WakeLock wl, TwilightManager tm, PowerManagerInternal localPowerManager, boolean setupWizardComplete) { boolean setupWizardComplete) { super(context); super(context); mWindowManager = wm; mWindowManager = wm; Loading @@ -168,6 +171,8 @@ final class UiModeManagerService extends SystemService { mSetupWizardComplete = setupWizardComplete; mSetupWizardComplete = setupWizardComplete; mAlarmManager = am; mAlarmManager = am; mPowerManager = pm; mPowerManager = pm; mLocalPowerManager = localPowerManager; initPowerSave(); } } private static Intent buildHomeIntent(String category) { private static Intent buildHomeIntent(String category) { Loading Loading @@ -230,11 +235,11 @@ final class UiModeManagerService extends SystemService { @Override @Override public void onTwilightStateChanged(@Nullable TwilightState state) { public void onTwilightStateChanged(@Nullable TwilightState state) { synchronized (mLock) { synchronized (mLock) { if (mNightMode == UiModeManager.MODE_NIGHT_AUTO) { if (mNightMode == UiModeManager.MODE_NIGHT_AUTO && mSystemReady) { if (mCar) { if (mCar) { updateLocked(0, 0); updateLocked(0, 0); } else { } else { registerScreenOffEvent(); registerScreenOffEventLocked(); } } } } } } Loading @@ -250,7 +255,7 @@ final class UiModeManagerService extends SystemService { public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) { synchronized (mLock) { synchronized (mLock) { // must unregister first before updating // must unregister first before updating unregisterScreenOffEvent(); unregisterScreenOffEventLocked(); updateLocked(0, 0); updateLocked(0, 0); } } } } Loading Loading @@ -326,8 +331,7 @@ final class UiModeManagerService extends SystemService { public void onStart() { public void onStart() { final Context context = getContext(); final Context context = getContext(); mPowerManager = mPowerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE); (PowerManager) context.getSystemService(Context.POWER_SERVICE); mWakeLock = mPowerManager.newWakeLock(PowerManager.FULL_WAKE_LOCK, TAG); mWakeLock = mPowerManager.newWakeLock(PowerManager.FULL_WAKE_LOCK, TAG); mWindowManager = LocalServices.getService(WindowManagerInternal.class); mWindowManager = LocalServices.getService(WindowManagerInternal.class); mAlarmManager = (AlarmManager) getContext().getSystemService(Context.ALARM_SERVICE); mAlarmManager = (AlarmManager) getContext().getSystemService(Context.ALARM_SERVICE); Loading @@ -341,21 +345,11 @@ final class UiModeManagerService extends SystemService { IntentFilter batteryFilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED); IntentFilter batteryFilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED); context.registerReceiver(mBatteryReceiver, batteryFilter); context.registerReceiver(mBatteryReceiver, batteryFilter); PowerManagerInternal localPowerManager = mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class); LocalServices.getService(PowerManagerInternal.class); mPowerSave = localPowerManager.getLowPowerState(ServiceType.NIGHT_MODE).batterySaverEnabled; initPowerSave(); localPowerManager.registerLowPowerModeObserver(ServiceType.NIGHT_MODE, state -> { mTwilightManager = getLocalService(TwilightManager.class); synchronized (mLock) { if (mPowerSave == state.batterySaverEnabled) { return; } mPowerSave = state.batterySaverEnabled; if (mSystemReady) { updateLocked(0, 0); } } }); mConfiguration.setToDefaults(); mConfiguration.setToDefaults(); Loading Loading @@ -396,7 +390,24 @@ final class UiModeManagerService extends SystemService { context.getContentResolver().registerContentObserver(Secure.getUriFor(Secure.UI_NIGHT_MODE), context.getContentResolver().registerContentObserver(Secure.getUriFor(Secure.UI_NIGHT_MODE), false, mDarkThemeObserver, 0); false, mDarkThemeObserver, 0); updateSystemProperties(); mHandler.post(() -> updateSystemProperties()); } private void initPowerSave() { mPowerSave = mLocalPowerManager.getLowPowerState(ServiceType.NIGHT_MODE) .batterySaverEnabled; mLocalPowerManager.registerLowPowerModeObserver(ServiceType.NIGHT_MODE, state -> { synchronized (mLock) { if (mPowerSave == state.batterySaverEnabled) { return; } mPowerSave = state.batterySaverEnabled; if (mSystemReady) { updateLocked(0, 0); } } }); } } @VisibleForTesting @VisibleForTesting Loading Loading @@ -433,7 +444,7 @@ final class UiModeManagerService extends SystemService { if (shouldApplyAutomaticChangesImmediately()) { if (shouldApplyAutomaticChangesImmediately()) { updateLocked(0, 0); updateLocked(0, 0); } else { } else { registerScreenOffEvent(); registerScreenOffEventLocked(); } } scheduleNextCustomTimeListener(); scheduleNextCustomTimeListener(); } } Loading Loading @@ -473,7 +484,8 @@ final class UiModeManagerService extends SystemService { return oldNightMode != mNightMode; return oldNightMode != mNightMode; } } private void registerScreenOffEvent() { private void registerScreenOffEventLocked() { if (mPowerSave) return; mWaitForScreenOff = true; mWaitForScreenOff = true; final IntentFilter intentFilter = final IntentFilter intentFilter = new IntentFilter(Intent.ACTION_SCREEN_OFF); new IntentFilter(Intent.ACTION_SCREEN_OFF); Loading @@ -484,7 +496,7 @@ final class UiModeManagerService extends SystemService { mAlarmManager.cancel(mCustomTimeListener); mAlarmManager.cancel(mCustomTimeListener); } } private void unregisterScreenOffEvent() { private void unregisterScreenOffEventLocked() { mWaitForScreenOff = false; mWaitForScreenOff = false; try { try { getContext().unregisterReceiver(mOnScreenOffHandler); getContext().unregisterReceiver(mOnScreenOffHandler); Loading Loading @@ -630,7 +642,7 @@ final class UiModeManagerService extends SystemService { synchronized (mLock) { synchronized (mLock) { if (mNightMode != mode) { if (mNightMode != mode) { if (mNightMode == MODE_NIGHT_AUTO || mNightMode == MODE_NIGHT_CUSTOM) { if (mNightMode == MODE_NIGHT_AUTO || mNightMode == MODE_NIGHT_CUSTOM) { unregisterScreenOffEvent(); unregisterScreenOffEventLocked(); cancelCustomAlarm(); cancelCustomAlarm(); } } Loading @@ -643,10 +655,10 @@ final class UiModeManagerService extends SystemService { // on screen off will update configuration instead // on screen off will update configuration instead if ((mNightMode != MODE_NIGHT_AUTO && mNightMode != MODE_NIGHT_CUSTOM) if ((mNightMode != MODE_NIGHT_AUTO && mNightMode != MODE_NIGHT_CUSTOM) || shouldApplyAutomaticChangesImmediately()) { || shouldApplyAutomaticChangesImmediately()) { unregisterScreenOffEvent(); unregisterScreenOffEventLocked(); updateLocked(0, 0); updateLocked(0, 0); } else { } else { registerScreenOffEvent(); registerScreenOffEventLocked(); } } } } } } Loading Loading @@ -695,7 +707,7 @@ final class UiModeManagerService extends SystemService { final long ident = Binder.clearCallingIdentity(); final long ident = Binder.clearCallingIdentity(); try { try { if (mNightMode == MODE_NIGHT_AUTO || mNightMode == MODE_NIGHT_CUSTOM) { if (mNightMode == MODE_NIGHT_AUTO || mNightMode == MODE_NIGHT_CUSTOM) { unregisterScreenOffEvent(); unregisterScreenOffEventLocked(); mNightModeOverride = active mNightModeOverride = active ? UiModeManager.MODE_NIGHT_YES : UiModeManager.MODE_NIGHT_NO; ? UiModeManager.MODE_NIGHT_YES : UiModeManager.MODE_NIGHT_NO; } else if (mNightMode == UiModeManager.MODE_NIGHT_NO } else if (mNightMode == UiModeManager.MODE_NIGHT_NO Loading Loading @@ -737,7 +749,7 @@ final class UiModeManagerService extends SystemService { persistNightMode(user); persistNightMode(user); onCustomTimeUpdated(user); onCustomTimeUpdated(user); } catch (DateTimeException e) { } catch (DateTimeException e) { unregisterScreenOffEvent(); unregisterScreenOffEventLocked(); } finally { } finally { Binder.restoreCallingIdentity(ident); Binder.restoreCallingIdentity(ident); } } Loading @@ -764,7 +776,7 @@ final class UiModeManagerService extends SystemService { mCustomAutoNightModeEndMilliseconds = newTime; mCustomAutoNightModeEndMilliseconds = newTime; onCustomTimeUpdated(user); onCustomTimeUpdated(user); } catch (DateTimeException e) { } catch (DateTimeException e) { unregisterScreenOffEvent(); unregisterScreenOffEventLocked(); } finally { } finally { Binder.restoreCallingIdentity(ident); Binder.restoreCallingIdentity(ident); } } Loading @@ -775,10 +787,10 @@ final class UiModeManagerService extends SystemService { persistNightMode(user); persistNightMode(user); if (mNightMode != MODE_NIGHT_CUSTOM) return; if (mNightMode != MODE_NIGHT_CUSTOM) return; if (shouldApplyAutomaticChangesImmediately()) { if (shouldApplyAutomaticChangesImmediately()) { unregisterScreenOffEvent(); unregisterScreenOffEventLocked(); updateLocked(0, 0); updateLocked(0, 0); } else { } else { registerScreenOffEvent(); registerScreenOffEventLocked(); } } } } Loading @@ -788,6 +800,7 @@ final class UiModeManagerService extends SystemService { pw.print(" mDockState="); pw.print(mDockState); pw.print(" mDockState="); pw.print(mDockState); pw.print(" mLastBroadcastState="); pw.println(mLastBroadcastState); pw.print(" mLastBroadcastState="); pw.println(mLastBroadcastState); pw.print(" mNightModeOverride="); pw.print(mNightModeOverride); pw.print(" mNightMode="); pw.print(mNightMode); pw.print(" ("); pw.print(" mNightMode="); pw.print(mNightMode); pw.print(" ("); pw.print(Shell.nightModeToStr(mNightMode)); pw.print(") "); pw.print(Shell.nightModeToStr(mNightMode)); pw.print(") "); pw.print(" mNightModeLocked="); pw.println(mNightModeLocked); pw.print(" mNightModeLocked="); pw.println(mNightModeLocked); Loading @@ -802,6 +815,8 @@ final class UiModeManagerService extends SystemService { } } pw.println(""); pw.println(""); pw.print(" mComputedNightMode="); pw.print(mComputedNightMode); pw.print(" mComputedNightMode="); pw.print(mComputedNightMode); pw.print(" customStart="); pw.print(mCustomAutoNightModeStartMilliseconds); pw.print(" customEnd"); pw.print(mCustomAutoNightModeEndMilliseconds); pw.print(" mCarModeEnableFlags="); pw.print(mCarModeEnableFlags); pw.print(" mCarModeEnableFlags="); pw.print(mCarModeEnableFlags); pw.print(" mEnableCarDockLaunch="); pw.println(mEnableCarDockLaunch); pw.print(" mEnableCarDockLaunch="); pw.println(mEnableCarDockLaunch); Loading @@ -824,7 +839,6 @@ final class UiModeManagerService extends SystemService { public void onBootPhase(int phase) { public void onBootPhase(int phase) { if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) { if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) { synchronized (mLock) { synchronized (mLock) { mTwilightManager = getLocalService(TwilightManager.class); mSystemReady = true; mSystemReady = true; mCarModeEnabled = mDockState == Intent.EXTRA_DOCK_STATE_CAR; mCarModeEnabled = mDockState == Intent.EXTRA_DOCK_STATE_CAR; registerVrStateListener(); registerVrStateListener(); Loading Loading @@ -1011,6 +1025,10 @@ final class UiModeManagerService extends SystemService { uiMode = Configuration.UI_MODE_TYPE_VR_HEADSET; uiMode = Configuration.UI_MODE_TYPE_VR_HEADSET; } } if (mNightMode == MODE_NIGHT_YES || mNightMode == UiModeManager.MODE_NIGHT_NO) { updateComputedNightModeLocked(mNightMode == MODE_NIGHT_YES); } if (mNightMode == MODE_NIGHT_AUTO) { if (mNightMode == MODE_NIGHT_AUTO) { boolean activateNightMode = mComputedNightMode; boolean activateNightMode = mComputedNightMode; if (mTwilightManager != null) { if (mTwilightManager != null) { Loading @@ -1020,12 +1038,10 @@ final class UiModeManagerService extends SystemService { } } updateComputedNightModeLocked(activateNightMode); updateComputedNightModeLocked(activateNightMode); uiMode = getComputedUiModeConfiguration(uiMode); } else { } else { if (mTwilightManager != null) { if (mTwilightManager != null) { mTwilightManager.unregisterListener(mTwilightListener); mTwilightManager.unregisterListener(mTwilightListener); } } uiMode |= mNightMode << 4; } } if (mNightMode == MODE_NIGHT_CUSTOM) { if (mNightMode == MODE_NIGHT_CUSTOM) { Loading @@ -1033,7 +1049,6 @@ final class UiModeManagerService extends SystemService { final boolean activate = computeCustomNightMode(); final boolean activate = computeCustomNightMode(); updateComputedNightModeLocked(activate); updateComputedNightModeLocked(activate); scheduleNextCustomTimeListener(); scheduleNextCustomTimeListener(); uiMode = getComputedUiModeConfiguration(uiMode); } else { } else { unregisterTimeChangeEvent(); unregisterTimeChangeEvent(); } } Loading @@ -1042,6 +1057,8 @@ final class UiModeManagerService extends SystemService { if (mPowerSave && !mCarModeEnabled) { if (mPowerSave && !mCarModeEnabled) { uiMode &= ~Configuration.UI_MODE_NIGHT_NO; uiMode &= ~Configuration.UI_MODE_NIGHT_NO; uiMode |= Configuration.UI_MODE_NIGHT_YES; uiMode |= Configuration.UI_MODE_NIGHT_YES; } else { uiMode = getComputedUiModeConfiguration(uiMode); } } if (LOG) { if (LOG) { Loading @@ -1053,7 +1070,7 @@ final class UiModeManagerService extends SystemService { } } mCurUiMode = uiMode; mCurUiMode = uiMode; if (!mHoldingConfiguration && !mWaitForScreenOff) { if (!mHoldingConfiguration && (!mWaitForScreenOff || mPowerSave)) { mConfiguration.uiMode = uiMode; mConfiguration.uiMode = uiMode; } } } } Loading services/tests/uiservicestests/src/com/android/server/UiModeManagerServiceTest.java +41 −9 Original line number Original line Diff line number Diff line Loading @@ -28,6 +28,8 @@ import android.content.res.Configuration; import android.content.res.Resources; import android.content.res.Resources; import android.os.Handler; import android.os.Handler; import android.os.PowerManager; import android.os.PowerManager; import android.os.PowerManagerInternal; import android.os.PowerSaveState; import android.os.RemoteException; import android.os.RemoteException; import android.testing.AndroidTestingRunner; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; import android.testing.TestableLooper; Loading @@ -42,6 +44,7 @@ import org.mockito.Mock; import java.time.LocalDateTime; import java.time.LocalDateTime; import java.time.LocalTime; import java.time.LocalTime; import java.time.ZoneId; import java.time.ZoneId; import java.util.function.Consumer; import static android.app.UiModeManager.MODE_NIGHT_AUTO; import static android.app.UiModeManager.MODE_NIGHT_AUTO; import static android.app.UiModeManager.MODE_NIGHT_CUSTOM; import static android.app.UiModeManager.MODE_NIGHT_CUSTOM; Loading Loading @@ -79,29 +82,34 @@ public class UiModeManagerServiceTest extends UiServiceTestCase { @Mock @Mock private Resources mResources; private Resources mResources; @Mock @Mock TwilightManager mTwilightManager; private TwilightManager mTwilightManager; @Mock @Mock PowerManager.WakeLock mWakeLock; private PowerManager.WakeLock mWakeLock; @Mock @Mock AlarmManager mAlarmManager; private AlarmManager mAlarmManager; @Mock @Mock PowerManager mPowerManager; private PowerManager mPowerManager; @Mock @Mock TwilightState mTwilightState; private TwilightState mTwilightState; @Mock PowerManagerInternal mLocalPowerManager; private BroadcastReceiver mScreenOffCallback; private BroadcastReceiver mScreenOffCallback; private BroadcastReceiver mTimeChangedCallback; private BroadcastReceiver mTimeChangedCallback; private AlarmManager.OnAlarmListener mCustomListener; private AlarmManager.OnAlarmListener mCustomListener; private Consumer<PowerSaveState> mPowerSaveConsumer; @Before @Before public void setUp() { public void setUp() { initMocks(this); initMocks(this); mUiManagerService = new UiModeManagerService(mContext, mWindowManager, mAlarmManager, mPowerManager, mWakeLock, mTwilightManager, true); mService = mUiManagerService.getService(); when(mContext.checkCallingOrSelfPermission(anyString())) when(mContext.checkCallingOrSelfPermission(anyString())) .thenReturn(PackageManager.PERMISSION_GRANTED); .thenReturn(PackageManager.PERMISSION_GRANTED); doAnswer(inv -> { mPowerSaveConsumer = (Consumer<PowerSaveState>) inv.getArgument(1); return null; }).when(mLocalPowerManager).registerLowPowerModeObserver(anyInt(), any()); when(mLocalPowerManager.getLowPowerState(anyInt())) .thenReturn(new PowerSaveState.Builder().setBatterySaverEnabled(false).build()); when(mContext.getResources()).thenReturn(mResources); when(mContext.getResources()).thenReturn(mResources); when(mContext.getContentResolver()).thenReturn(mContentResolver); when(mContext.getContentResolver()).thenReturn(mContentResolver); when(mPowerManager.isInteractive()).thenReturn(true); when(mPowerManager.isInteractive()).thenReturn(true); Loading @@ -127,6 +135,14 @@ public class UiModeManagerServiceTest extends UiServiceTestCase { mCustomListener = () -> {}; mCustomListener = () -> {}; return null; return null; }).when(mAlarmManager).cancel(eq(mCustomListener)); }).when(mAlarmManager).cancel(eq(mCustomListener)); mUiManagerService = new UiModeManagerService(mContext, mWindowManager, mAlarmManager, mPowerManager, mWakeLock, mTwilightManager, mLocalPowerManager, true); try { mUiManagerService.onBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY); } catch (SecurityException e) {/* ignore for permission denial */} mService = mUiManagerService.getService(); } } @Test @Test Loading @@ -150,6 +166,22 @@ public class UiModeManagerServiceTest extends UiServiceTestCase { verify(mContext, atLeastOnce()).unregisterReceiver(any(BroadcastReceiver.class)); verify(mContext, atLeastOnce()).unregisterReceiver(any(BroadcastReceiver.class)); } } @Test public void autoNightModeSwitch_batterySaverOn() throws RemoteException { mService.setNightMode(MODE_NIGHT_NO); when(mTwilightState.isNight()).thenReturn(false); mService.setNightMode(MODE_NIGHT_AUTO); // night NO assertFalse(isNightModeActivated()); mPowerSaveConsumer.accept( new PowerSaveState.Builder().setBatterySaverEnabled(true).build()); // night YES assertTrue(isNightModeActivated()); } @Test @Test public void setAutoMode_clearCache() throws RemoteException { public void setAutoMode_clearCache() throws RemoteException { try { try { Loading Loading
services/core/java/com/android/server/UiModeManagerService.java +54 −37 Original line number Original line Diff line number Diff line Loading @@ -98,7 +98,8 @@ final class UiModeManagerService extends SystemService { private int mLastBroadcastState = Intent.EXTRA_DOCK_STATE_UNDOCKED; private int mLastBroadcastState = Intent.EXTRA_DOCK_STATE_UNDOCKED; private int mNightMode = UiModeManager.MODE_NIGHT_NO; private int mNightMode = UiModeManager.MODE_NIGHT_NO; // we use the override auto mode // we use the override auto mode // for example: force night mode off in the night time while in auto mode // for example: force night mode off in the night time // while in auto mode private int mNightModeOverride = mNightMode; private int mNightModeOverride = mNightMode; private final LocalTime DEFAULT_CUSTOM_NIGHT_START_TIME = LocalTime.of(22, 0); private final LocalTime DEFAULT_CUSTOM_NIGHT_START_TIME = LocalTime.of(22, 0); private final LocalTime DEFAULT_CUSTOM_NIGHT_END_TIME = LocalTime.of(6, 0); private final LocalTime DEFAULT_CUSTOM_NIGHT_END_TIME = LocalTime.of(6, 0); Loading Loading @@ -152,6 +153,7 @@ final class UiModeManagerService extends SystemService { private PowerManager.WakeLock mWakeLock; private PowerManager.WakeLock mWakeLock; private final LocalService mLocalService = new LocalService(); private final LocalService mLocalService = new LocalService(); private PowerManagerInternal mLocalPowerManager; public UiModeManagerService(Context context) { public UiModeManagerService(Context context) { super(context); super(context); Loading @@ -160,6 +162,7 @@ final class UiModeManagerService extends SystemService { @VisibleForTesting @VisibleForTesting protected UiModeManagerService(Context context, WindowManagerInternal wm, AlarmManager am, protected UiModeManagerService(Context context, WindowManagerInternal wm, AlarmManager am, PowerManager pm, PowerManager.WakeLock wl, TwilightManager tm, PowerManager pm, PowerManager.WakeLock wl, TwilightManager tm, PowerManagerInternal localPowerManager, boolean setupWizardComplete) { boolean setupWizardComplete) { super(context); super(context); mWindowManager = wm; mWindowManager = wm; Loading @@ -168,6 +171,8 @@ final class UiModeManagerService extends SystemService { mSetupWizardComplete = setupWizardComplete; mSetupWizardComplete = setupWizardComplete; mAlarmManager = am; mAlarmManager = am; mPowerManager = pm; mPowerManager = pm; mLocalPowerManager = localPowerManager; initPowerSave(); } } private static Intent buildHomeIntent(String category) { private static Intent buildHomeIntent(String category) { Loading Loading @@ -230,11 +235,11 @@ final class UiModeManagerService extends SystemService { @Override @Override public void onTwilightStateChanged(@Nullable TwilightState state) { public void onTwilightStateChanged(@Nullable TwilightState state) { synchronized (mLock) { synchronized (mLock) { if (mNightMode == UiModeManager.MODE_NIGHT_AUTO) { if (mNightMode == UiModeManager.MODE_NIGHT_AUTO && mSystemReady) { if (mCar) { if (mCar) { updateLocked(0, 0); updateLocked(0, 0); } else { } else { registerScreenOffEvent(); registerScreenOffEventLocked(); } } } } } } Loading @@ -250,7 +255,7 @@ final class UiModeManagerService extends SystemService { public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) { synchronized (mLock) { synchronized (mLock) { // must unregister first before updating // must unregister first before updating unregisterScreenOffEvent(); unregisterScreenOffEventLocked(); updateLocked(0, 0); updateLocked(0, 0); } } } } Loading Loading @@ -326,8 +331,7 @@ final class UiModeManagerService extends SystemService { public void onStart() { public void onStart() { final Context context = getContext(); final Context context = getContext(); mPowerManager = mPowerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE); (PowerManager) context.getSystemService(Context.POWER_SERVICE); mWakeLock = mPowerManager.newWakeLock(PowerManager.FULL_WAKE_LOCK, TAG); mWakeLock = mPowerManager.newWakeLock(PowerManager.FULL_WAKE_LOCK, TAG); mWindowManager = LocalServices.getService(WindowManagerInternal.class); mWindowManager = LocalServices.getService(WindowManagerInternal.class); mAlarmManager = (AlarmManager) getContext().getSystemService(Context.ALARM_SERVICE); mAlarmManager = (AlarmManager) getContext().getSystemService(Context.ALARM_SERVICE); Loading @@ -341,21 +345,11 @@ final class UiModeManagerService extends SystemService { IntentFilter batteryFilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED); IntentFilter batteryFilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED); context.registerReceiver(mBatteryReceiver, batteryFilter); context.registerReceiver(mBatteryReceiver, batteryFilter); PowerManagerInternal localPowerManager = mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class); LocalServices.getService(PowerManagerInternal.class); mPowerSave = localPowerManager.getLowPowerState(ServiceType.NIGHT_MODE).batterySaverEnabled; initPowerSave(); localPowerManager.registerLowPowerModeObserver(ServiceType.NIGHT_MODE, state -> { mTwilightManager = getLocalService(TwilightManager.class); synchronized (mLock) { if (mPowerSave == state.batterySaverEnabled) { return; } mPowerSave = state.batterySaverEnabled; if (mSystemReady) { updateLocked(0, 0); } } }); mConfiguration.setToDefaults(); mConfiguration.setToDefaults(); Loading Loading @@ -396,7 +390,24 @@ final class UiModeManagerService extends SystemService { context.getContentResolver().registerContentObserver(Secure.getUriFor(Secure.UI_NIGHT_MODE), context.getContentResolver().registerContentObserver(Secure.getUriFor(Secure.UI_NIGHT_MODE), false, mDarkThemeObserver, 0); false, mDarkThemeObserver, 0); updateSystemProperties(); mHandler.post(() -> updateSystemProperties()); } private void initPowerSave() { mPowerSave = mLocalPowerManager.getLowPowerState(ServiceType.NIGHT_MODE) .batterySaverEnabled; mLocalPowerManager.registerLowPowerModeObserver(ServiceType.NIGHT_MODE, state -> { synchronized (mLock) { if (mPowerSave == state.batterySaverEnabled) { return; } mPowerSave = state.batterySaverEnabled; if (mSystemReady) { updateLocked(0, 0); } } }); } } @VisibleForTesting @VisibleForTesting Loading Loading @@ -433,7 +444,7 @@ final class UiModeManagerService extends SystemService { if (shouldApplyAutomaticChangesImmediately()) { if (shouldApplyAutomaticChangesImmediately()) { updateLocked(0, 0); updateLocked(0, 0); } else { } else { registerScreenOffEvent(); registerScreenOffEventLocked(); } } scheduleNextCustomTimeListener(); scheduleNextCustomTimeListener(); } } Loading Loading @@ -473,7 +484,8 @@ final class UiModeManagerService extends SystemService { return oldNightMode != mNightMode; return oldNightMode != mNightMode; } } private void registerScreenOffEvent() { private void registerScreenOffEventLocked() { if (mPowerSave) return; mWaitForScreenOff = true; mWaitForScreenOff = true; final IntentFilter intentFilter = final IntentFilter intentFilter = new IntentFilter(Intent.ACTION_SCREEN_OFF); new IntentFilter(Intent.ACTION_SCREEN_OFF); Loading @@ -484,7 +496,7 @@ final class UiModeManagerService extends SystemService { mAlarmManager.cancel(mCustomTimeListener); mAlarmManager.cancel(mCustomTimeListener); } } private void unregisterScreenOffEvent() { private void unregisterScreenOffEventLocked() { mWaitForScreenOff = false; mWaitForScreenOff = false; try { try { getContext().unregisterReceiver(mOnScreenOffHandler); getContext().unregisterReceiver(mOnScreenOffHandler); Loading Loading @@ -630,7 +642,7 @@ final class UiModeManagerService extends SystemService { synchronized (mLock) { synchronized (mLock) { if (mNightMode != mode) { if (mNightMode != mode) { if (mNightMode == MODE_NIGHT_AUTO || mNightMode == MODE_NIGHT_CUSTOM) { if (mNightMode == MODE_NIGHT_AUTO || mNightMode == MODE_NIGHT_CUSTOM) { unregisterScreenOffEvent(); unregisterScreenOffEventLocked(); cancelCustomAlarm(); cancelCustomAlarm(); } } Loading @@ -643,10 +655,10 @@ final class UiModeManagerService extends SystemService { // on screen off will update configuration instead // on screen off will update configuration instead if ((mNightMode != MODE_NIGHT_AUTO && mNightMode != MODE_NIGHT_CUSTOM) if ((mNightMode != MODE_NIGHT_AUTO && mNightMode != MODE_NIGHT_CUSTOM) || shouldApplyAutomaticChangesImmediately()) { || shouldApplyAutomaticChangesImmediately()) { unregisterScreenOffEvent(); unregisterScreenOffEventLocked(); updateLocked(0, 0); updateLocked(0, 0); } else { } else { registerScreenOffEvent(); registerScreenOffEventLocked(); } } } } } } Loading Loading @@ -695,7 +707,7 @@ final class UiModeManagerService extends SystemService { final long ident = Binder.clearCallingIdentity(); final long ident = Binder.clearCallingIdentity(); try { try { if (mNightMode == MODE_NIGHT_AUTO || mNightMode == MODE_NIGHT_CUSTOM) { if (mNightMode == MODE_NIGHT_AUTO || mNightMode == MODE_NIGHT_CUSTOM) { unregisterScreenOffEvent(); unregisterScreenOffEventLocked(); mNightModeOverride = active mNightModeOverride = active ? UiModeManager.MODE_NIGHT_YES : UiModeManager.MODE_NIGHT_NO; ? UiModeManager.MODE_NIGHT_YES : UiModeManager.MODE_NIGHT_NO; } else if (mNightMode == UiModeManager.MODE_NIGHT_NO } else if (mNightMode == UiModeManager.MODE_NIGHT_NO Loading Loading @@ -737,7 +749,7 @@ final class UiModeManagerService extends SystemService { persistNightMode(user); persistNightMode(user); onCustomTimeUpdated(user); onCustomTimeUpdated(user); } catch (DateTimeException e) { } catch (DateTimeException e) { unregisterScreenOffEvent(); unregisterScreenOffEventLocked(); } finally { } finally { Binder.restoreCallingIdentity(ident); Binder.restoreCallingIdentity(ident); } } Loading @@ -764,7 +776,7 @@ final class UiModeManagerService extends SystemService { mCustomAutoNightModeEndMilliseconds = newTime; mCustomAutoNightModeEndMilliseconds = newTime; onCustomTimeUpdated(user); onCustomTimeUpdated(user); } catch (DateTimeException e) { } catch (DateTimeException e) { unregisterScreenOffEvent(); unregisterScreenOffEventLocked(); } finally { } finally { Binder.restoreCallingIdentity(ident); Binder.restoreCallingIdentity(ident); } } Loading @@ -775,10 +787,10 @@ final class UiModeManagerService extends SystemService { persistNightMode(user); persistNightMode(user); if (mNightMode != MODE_NIGHT_CUSTOM) return; if (mNightMode != MODE_NIGHT_CUSTOM) return; if (shouldApplyAutomaticChangesImmediately()) { if (shouldApplyAutomaticChangesImmediately()) { unregisterScreenOffEvent(); unregisterScreenOffEventLocked(); updateLocked(0, 0); updateLocked(0, 0); } else { } else { registerScreenOffEvent(); registerScreenOffEventLocked(); } } } } Loading @@ -788,6 +800,7 @@ final class UiModeManagerService extends SystemService { pw.print(" mDockState="); pw.print(mDockState); pw.print(" mDockState="); pw.print(mDockState); pw.print(" mLastBroadcastState="); pw.println(mLastBroadcastState); pw.print(" mLastBroadcastState="); pw.println(mLastBroadcastState); pw.print(" mNightModeOverride="); pw.print(mNightModeOverride); pw.print(" mNightMode="); pw.print(mNightMode); pw.print(" ("); pw.print(" mNightMode="); pw.print(mNightMode); pw.print(" ("); pw.print(Shell.nightModeToStr(mNightMode)); pw.print(") "); pw.print(Shell.nightModeToStr(mNightMode)); pw.print(") "); pw.print(" mNightModeLocked="); pw.println(mNightModeLocked); pw.print(" mNightModeLocked="); pw.println(mNightModeLocked); Loading @@ -802,6 +815,8 @@ final class UiModeManagerService extends SystemService { } } pw.println(""); pw.println(""); pw.print(" mComputedNightMode="); pw.print(mComputedNightMode); pw.print(" mComputedNightMode="); pw.print(mComputedNightMode); pw.print(" customStart="); pw.print(mCustomAutoNightModeStartMilliseconds); pw.print(" customEnd"); pw.print(mCustomAutoNightModeEndMilliseconds); pw.print(" mCarModeEnableFlags="); pw.print(mCarModeEnableFlags); pw.print(" mCarModeEnableFlags="); pw.print(mCarModeEnableFlags); pw.print(" mEnableCarDockLaunch="); pw.println(mEnableCarDockLaunch); pw.print(" mEnableCarDockLaunch="); pw.println(mEnableCarDockLaunch); Loading @@ -824,7 +839,6 @@ final class UiModeManagerService extends SystemService { public void onBootPhase(int phase) { public void onBootPhase(int phase) { if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) { if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) { synchronized (mLock) { synchronized (mLock) { mTwilightManager = getLocalService(TwilightManager.class); mSystemReady = true; mSystemReady = true; mCarModeEnabled = mDockState == Intent.EXTRA_DOCK_STATE_CAR; mCarModeEnabled = mDockState == Intent.EXTRA_DOCK_STATE_CAR; registerVrStateListener(); registerVrStateListener(); Loading Loading @@ -1011,6 +1025,10 @@ final class UiModeManagerService extends SystemService { uiMode = Configuration.UI_MODE_TYPE_VR_HEADSET; uiMode = Configuration.UI_MODE_TYPE_VR_HEADSET; } } if (mNightMode == MODE_NIGHT_YES || mNightMode == UiModeManager.MODE_NIGHT_NO) { updateComputedNightModeLocked(mNightMode == MODE_NIGHT_YES); } if (mNightMode == MODE_NIGHT_AUTO) { if (mNightMode == MODE_NIGHT_AUTO) { boolean activateNightMode = mComputedNightMode; boolean activateNightMode = mComputedNightMode; if (mTwilightManager != null) { if (mTwilightManager != null) { Loading @@ -1020,12 +1038,10 @@ final class UiModeManagerService extends SystemService { } } updateComputedNightModeLocked(activateNightMode); updateComputedNightModeLocked(activateNightMode); uiMode = getComputedUiModeConfiguration(uiMode); } else { } else { if (mTwilightManager != null) { if (mTwilightManager != null) { mTwilightManager.unregisterListener(mTwilightListener); mTwilightManager.unregisterListener(mTwilightListener); } } uiMode |= mNightMode << 4; } } if (mNightMode == MODE_NIGHT_CUSTOM) { if (mNightMode == MODE_NIGHT_CUSTOM) { Loading @@ -1033,7 +1049,6 @@ final class UiModeManagerService extends SystemService { final boolean activate = computeCustomNightMode(); final boolean activate = computeCustomNightMode(); updateComputedNightModeLocked(activate); updateComputedNightModeLocked(activate); scheduleNextCustomTimeListener(); scheduleNextCustomTimeListener(); uiMode = getComputedUiModeConfiguration(uiMode); } else { } else { unregisterTimeChangeEvent(); unregisterTimeChangeEvent(); } } Loading @@ -1042,6 +1057,8 @@ final class UiModeManagerService extends SystemService { if (mPowerSave && !mCarModeEnabled) { if (mPowerSave && !mCarModeEnabled) { uiMode &= ~Configuration.UI_MODE_NIGHT_NO; uiMode &= ~Configuration.UI_MODE_NIGHT_NO; uiMode |= Configuration.UI_MODE_NIGHT_YES; uiMode |= Configuration.UI_MODE_NIGHT_YES; } else { uiMode = getComputedUiModeConfiguration(uiMode); } } if (LOG) { if (LOG) { Loading @@ -1053,7 +1070,7 @@ final class UiModeManagerService extends SystemService { } } mCurUiMode = uiMode; mCurUiMode = uiMode; if (!mHoldingConfiguration && !mWaitForScreenOff) { if (!mHoldingConfiguration && (!mWaitForScreenOff || mPowerSave)) { mConfiguration.uiMode = uiMode; mConfiguration.uiMode = uiMode; } } } } Loading
services/tests/uiservicestests/src/com/android/server/UiModeManagerServiceTest.java +41 −9 Original line number Original line Diff line number Diff line Loading @@ -28,6 +28,8 @@ import android.content.res.Configuration; import android.content.res.Resources; import android.content.res.Resources; import android.os.Handler; import android.os.Handler; import android.os.PowerManager; import android.os.PowerManager; import android.os.PowerManagerInternal; import android.os.PowerSaveState; import android.os.RemoteException; import android.os.RemoteException; import android.testing.AndroidTestingRunner; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; import android.testing.TestableLooper; Loading @@ -42,6 +44,7 @@ import org.mockito.Mock; import java.time.LocalDateTime; import java.time.LocalDateTime; import java.time.LocalTime; import java.time.LocalTime; import java.time.ZoneId; import java.time.ZoneId; import java.util.function.Consumer; import static android.app.UiModeManager.MODE_NIGHT_AUTO; import static android.app.UiModeManager.MODE_NIGHT_AUTO; import static android.app.UiModeManager.MODE_NIGHT_CUSTOM; import static android.app.UiModeManager.MODE_NIGHT_CUSTOM; Loading Loading @@ -79,29 +82,34 @@ public class UiModeManagerServiceTest extends UiServiceTestCase { @Mock @Mock private Resources mResources; private Resources mResources; @Mock @Mock TwilightManager mTwilightManager; private TwilightManager mTwilightManager; @Mock @Mock PowerManager.WakeLock mWakeLock; private PowerManager.WakeLock mWakeLock; @Mock @Mock AlarmManager mAlarmManager; private AlarmManager mAlarmManager; @Mock @Mock PowerManager mPowerManager; private PowerManager mPowerManager; @Mock @Mock TwilightState mTwilightState; private TwilightState mTwilightState; @Mock PowerManagerInternal mLocalPowerManager; private BroadcastReceiver mScreenOffCallback; private BroadcastReceiver mScreenOffCallback; private BroadcastReceiver mTimeChangedCallback; private BroadcastReceiver mTimeChangedCallback; private AlarmManager.OnAlarmListener mCustomListener; private AlarmManager.OnAlarmListener mCustomListener; private Consumer<PowerSaveState> mPowerSaveConsumer; @Before @Before public void setUp() { public void setUp() { initMocks(this); initMocks(this); mUiManagerService = new UiModeManagerService(mContext, mWindowManager, mAlarmManager, mPowerManager, mWakeLock, mTwilightManager, true); mService = mUiManagerService.getService(); when(mContext.checkCallingOrSelfPermission(anyString())) when(mContext.checkCallingOrSelfPermission(anyString())) .thenReturn(PackageManager.PERMISSION_GRANTED); .thenReturn(PackageManager.PERMISSION_GRANTED); doAnswer(inv -> { mPowerSaveConsumer = (Consumer<PowerSaveState>) inv.getArgument(1); return null; }).when(mLocalPowerManager).registerLowPowerModeObserver(anyInt(), any()); when(mLocalPowerManager.getLowPowerState(anyInt())) .thenReturn(new PowerSaveState.Builder().setBatterySaverEnabled(false).build()); when(mContext.getResources()).thenReturn(mResources); when(mContext.getResources()).thenReturn(mResources); when(mContext.getContentResolver()).thenReturn(mContentResolver); when(mContext.getContentResolver()).thenReturn(mContentResolver); when(mPowerManager.isInteractive()).thenReturn(true); when(mPowerManager.isInteractive()).thenReturn(true); Loading @@ -127,6 +135,14 @@ public class UiModeManagerServiceTest extends UiServiceTestCase { mCustomListener = () -> {}; mCustomListener = () -> {}; return null; return null; }).when(mAlarmManager).cancel(eq(mCustomListener)); }).when(mAlarmManager).cancel(eq(mCustomListener)); mUiManagerService = new UiModeManagerService(mContext, mWindowManager, mAlarmManager, mPowerManager, mWakeLock, mTwilightManager, mLocalPowerManager, true); try { mUiManagerService.onBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY); } catch (SecurityException e) {/* ignore for permission denial */} mService = mUiManagerService.getService(); } } @Test @Test Loading @@ -150,6 +166,22 @@ public class UiModeManagerServiceTest extends UiServiceTestCase { verify(mContext, atLeastOnce()).unregisterReceiver(any(BroadcastReceiver.class)); verify(mContext, atLeastOnce()).unregisterReceiver(any(BroadcastReceiver.class)); } } @Test public void autoNightModeSwitch_batterySaverOn() throws RemoteException { mService.setNightMode(MODE_NIGHT_NO); when(mTwilightState.isNight()).thenReturn(false); mService.setNightMode(MODE_NIGHT_AUTO); // night NO assertFalse(isNightModeActivated()); mPowerSaveConsumer.accept( new PowerSaveState.Builder().setBatterySaverEnabled(true).build()); // night YES assertTrue(isNightModeActivated()); } @Test @Test public void setAutoMode_clearCache() throws RemoteException { public void setAutoMode_clearCache() throws RemoteException { try { try { Loading