Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d328b435 authored by Automerger Merge Worker's avatar Automerger Merge Worker
Browse files

Merge "Battery saver dark mode bug" into rvc-dev am: b86cf15c am: b09e86b4

Change-Id: I3778b49ac376efa608e28b0aac2cf0dbaa3b92bf
parents d3cd4eb5 b09e86b4
Loading
Loading
Loading
Loading
+54 −37
Original line number Original line Diff line number Diff line
@@ -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);
@@ -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);
@@ -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;
@@ -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) {
@@ -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();
                    }
                    }
                }
                }
            }
            }
@@ -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);
            }
            }
        }
        }
@@ -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);
@@ -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();


@@ -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
@@ -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();
    }
    }
@@ -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);
@@ -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);
@@ -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();
                        }
                        }


@@ -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();
                        }
                        }
                    }
                    }
                }
                }
@@ -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
@@ -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);
            }
            }
@@ -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);
            }
            }
@@ -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();
        }
        }
    }
    }


@@ -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);
@@ -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);


@@ -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();
@@ -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) {
@@ -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) {
@@ -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();
        }
        }
@@ -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) {
@@ -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;
        }
        }
    }
    }
+41 −9
Original line number Original line Diff line number Diff line
@@ -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;
@@ -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;
@@ -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);
@@ -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
@@ -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 {