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

Commit 4430bb40 authored by Jay Aliomer's avatar Jay Aliomer
Browse files

UiMode TwilightManager null

Twilight manager is initialized before it was ready
To fix this issue, all initialization is moved to the
SYSTEM_SERVICES_READY phase

Test: manual test. make sure schedling works
Fixes: 151282449
Change-Id: I635da1e2a9522c8a056d534094c0bf5c1cf0f1d1
parent 25f8496e
Loading
Loading
Loading
Loading
+59 −75
Original line number Diff line number Diff line
@@ -159,22 +159,13 @@ final class UiModeManagerService extends SystemService {

    public UiModeManagerService(Context context) {
        super(context);
        mConfiguration.setToDefaults();
    }

    @VisibleForTesting
    protected UiModeManagerService(Context context, WindowManagerInternal wm, AlarmManager am,
                                   PowerManager pm, PowerManager.WakeLock wl, TwilightManager tm,
                                   PowerManagerInternal localPowerManager,
                                   boolean setupWizardComplete) {
        super(context);
        mWindowManager = wm;
        mWakeLock = wl;
        mTwilightManager = tm;
    protected UiModeManagerService(Context context, boolean setupWizardComplete) {
        this(context);
        mSetupWizardComplete = setupWizardComplete;
        mAlarmManager = am;
        mPowerManager = pm;
        mLocalPowerManager = localPowerManager;
        initPowerSave();
    }

    private static Intent buildHomeIntent(String category) {
@@ -333,33 +324,44 @@ final class UiModeManagerService extends SystemService {
    }

    @Override
    public void onStart() {
    public void onBootPhase(int phase) {
        if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
            synchronized (mLock) {
                final Context context = getContext();

                mSystemReady = true;
                mPowerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
                mWakeLock = mPowerManager.newWakeLock(PowerManager.FULL_WAKE_LOCK, TAG);
                mWindowManager = LocalServices.getService(WindowManagerInternal.class);
                mAlarmManager = (AlarmManager) getContext().getSystemService(Context.ALARM_SERVICE);

        // If setup isn't complete for this user listen for completion so we can unblock
        // being able to send a night mode configuration change event
        verifySetupWizardCompleted();

                mLocalPowerManager =
                        LocalServices.getService(PowerManagerInternal.class);
                mTwilightManager = getLocalService(TwilightManager.class);
                initPowerSave();
                mCarModeEnabled = mDockState == Intent.EXTRA_DOCK_STATE_CAR;
                registerVrStateListener();
                // register listeners
                context.getContentResolver()
                        .registerContentObserver(Secure.getUriFor(Secure.UI_NIGHT_MODE),
                                false, mDarkThemeObserver, 0);
                context.registerReceiver(mDockModeReceiver,
                        new IntentFilter(Intent.ACTION_DOCK_EVENT));
                IntentFilter batteryFilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
                context.registerReceiver(mBatteryReceiver, batteryFilter);
                IntentFilter filter = new IntentFilter();
                filter.addAction(Intent.ACTION_USER_SWITCHED);
                context.registerReceiver(new UserSwitchedReceiver(), filter, null, mHandler);
                updateConfigurationLocked();
                applyConfigurationExternallyLocked();
            }
        }
    }

        context.registerReceiver(mSettingsRestored,
                new IntentFilter(Intent.ACTION_SETTING_RESTORED), null, mHandler);

        mLocalPowerManager =
                LocalServices.getService(PowerManagerInternal.class);
        initPowerSave();

        mTwilightManager = getLocalService(TwilightManager.class);

        mConfiguration.setToDefaults();
    @Override
    public void onStart() {
        final Context context = getContext();
        // If setup isn't complete for this user listen for completion so we can unblock
        // being able to send a night mode configuration change event
        verifySetupWizardCompleted();

        final Resources res = context.getResources();
        mDefaultUiModeType = res.getInteger(
@@ -383,21 +385,12 @@ final class UiModeManagerService extends SystemService {
        SystemServerInitThreadPool.submit(() -> {
            synchronized (mLock) {
                updateNightModeFromSettingsLocked(context, res, UserHandle.getCallingUserId());
                updateConfigurationLocked();
                applyConfigurationExternallyLocked();
                updateSystemProperties();
            }

        }, TAG + ".onStart");
        publishBinderService(Context.UI_MODE_SERVICE, mService);
        publishLocalService(UiModeManagerInternal.class, mLocalService);

        IntentFilter filter = new IntentFilter();
        filter.addAction(Intent.ACTION_USER_SWITCHED);
        context.registerReceiver(new UserSwitchedReceiver(), filter, null, mHandler);

        context.getContentResolver().registerContentObserver(Secure.getUriFor(Secure.UI_NIGHT_MODE),
                false, mDarkThemeObserver, 0);
        mHandler.post(() -> updateSystemProperties());
    }

    private final BroadcastReceiver mSettingsRestored = new BroadcastReceiver() {
@@ -475,6 +468,7 @@ final class UiModeManagerService extends SystemService {
    /**
     * Updates the night mode setting in Settings.Global and returns if the value was successfully
     * changed.
     *
     * @param context A valid context
     * @param res     A valid resource object
     * @param userId  The user to update the setting for
@@ -863,18 +857,6 @@ final class UiModeManagerService extends SystemService {
        }
    }

    @Override
    public void onBootPhase(int phase) {
        if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
            synchronized (mLock) {
                mSystemReady = true;
                mCarModeEnabled = mDockState == Intent.EXTRA_DOCK_STATE_CAR;
                registerVrStateListener();
                updateLocked(0, 0);
            }
        }
    }

    /**
     * Updates the global car mode state.
     * The device is considered to be in car mode if there exists an app at any priority level which
@@ -931,7 +913,8 @@ final class UiModeManagerService extends SystemService {
                // Anyone can disable the default priority.
                isDefaultPriority
                // If priority was enabled, only enabling package can disable it.
                || isPriorityTracked && mCarModePackagePriority.get(priority).equals(packageName)
                || isPriorityTracked && mCarModePackagePriority.get(priority).equals(
                packageName)
                // Disable all priorities flag can disable all regardless.
                || isDisableAll;
        if (isChangeAllowed) {
@@ -1382,7 +1365,8 @@ final class UiModeManagerService extends SystemService {
                        .setContentText(
                                context.getString(R.string.car_mode_disable_notification_message))
                        .setContentIntent(
                                PendingIntent.getActivityAsUser(context, 0, carModeOffIntent, 0,
                                PendingIntent.getActivityAsUser(context, 0,
                                        carModeOffIntent, 0,
                                        null, UserHandle.CURRENT));
                mNotificationManager.notifyAsUser(null,
                        SystemMessage.NOTE_CAR_MODE_DISABLE, n.build(), UserHandle.ALL);
+18 −5
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ import android.os.PowerManager;
import android.os.PowerManagerInternal;
import android.os.PowerSaveState;
import android.os.RemoteException;
import android.provider.Settings;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import com.android.server.twilight.TwilightManager;
@@ -54,6 +55,7 @@ import static junit.framework.TestCase.assertFalse;
import static junit.framework.TestCase.assertTrue;
import static org.junit.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.anyString;
@@ -113,6 +115,7 @@ public class UiModeManagerServiceTest extends UiServiceTestCase {
        when(mContext.getResources()).thenReturn(mResources);
        when(mContext.getContentResolver()).thenReturn(mContentResolver);
        when(mPowerManager.isInteractive()).thenReturn(true);
        when(mPowerManager.newWakeLock(anyInt(), anyString())).thenReturn(mWakeLock);
        when(mTwilightManager.getLastTwilightState()).thenReturn(mTwilightState);
        when(mTwilightState.isNight()).thenReturn(true);
        when(mContext.registerReceiver(notNull(), notNull())).then(inv -> {
@@ -135,23 +138,33 @@ public class UiModeManagerServiceTest extends UiServiceTestCase {
            mCustomListener = () -> {};
            return null;
        }).when(mAlarmManager).cancel(eq(mCustomListener));

        mUiManagerService = new UiModeManagerService(mContext,
                mWindowManager, mAlarmManager, mPowerManager,
                mWakeLock, mTwilightManager, mLocalPowerManager, true);
        when(mContext.getSystemService(eq(Context.POWER_SERVICE)))
                .thenReturn(mPowerManager);
        when(mContext.getSystemService(eq(Context.ALARM_SERVICE)))
                .thenReturn(mAlarmManager);
        addLocalService(WindowManagerInternal.class, mWindowManager);
        addLocalService(PowerManagerInternal.class, mLocalPowerManager);
        addLocalService(TwilightManager.class, mTwilightManager);
        
        mUiManagerService = new UiModeManagerService(mContext, true);
        try {
            mUiManagerService.onBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY);
        } catch (SecurityException e) {/* ignore for permission denial */}
        mService = mUiManagerService.getService();
    }

    private <T> void addLocalService(Class<T> clazz, T service) {
        LocalServices.removeServiceForTest(clazz);
        LocalServices.addService(clazz, service);
    }

    @Test
    public void setAutoMode_screenOffRegistered() throws RemoteException {
        try {
            mService.setNightMode(MODE_NIGHT_NO);
        } catch (SecurityException e) { /* we should ignore this update config exception*/ }
        mService.setNightMode(MODE_NIGHT_AUTO);
        verify(mContext).registerReceiver(any(BroadcastReceiver.class), any());
        verify(mContext, atLeastOnce()).registerReceiver(any(BroadcastReceiver.class), any());
    }

    @Test