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

Commit 854ab96c authored by Archisha Baranwal's avatar Archisha Baranwal Committed by Android (Google) Code Review
Browse files

Merge "Add a binder cache to UiModeManager#getNightMode" into main

parents 4fd5ac04 ec914ad7
Loading
Loading
Loading
Loading
+52 −7
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package android.app;

import static android.app.Flags.enableNightModeCache;

import android.annotation.CallbackExecutor;
import android.annotation.FlaggedApi;
import android.annotation.FloatRange;
@@ -31,6 +33,7 @@ import android.compat.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.content.res.Configuration;
import android.os.Binder;
import android.os.IpcDataCache;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.ServiceManager.ServiceNotFoundException;
@@ -874,6 +877,51 @@ public class UiModeManager {
        }
    }

    private Integer getNightModeFromServer() {
        try {
            if (sGlobals != null) {
                return sGlobals.mService.getNightMode();
            }
            return -1;
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }


    /**
     * Retrieve the night mode for the user.
     */
    private final IpcDataCache.QueryHandler<Void, Integer> mNightModeQuery =
            new IpcDataCache.QueryHandler<>() {

                @Override
                @NonNull
                public Integer apply(Void query) {
                    return getNightModeFromServer();
                }
            };

    private static final String NIGHT_MODE_API = "getNightMode";

    /**
     * Cache the night mode for a user.
     */
    private final IpcDataCache<Void, Integer> mNightModeCache =
            new IpcDataCache<>(1, IpcDataCache.MODULE_SYSTEM,
                    NIGHT_MODE_API, /* cacheName= */ "NightModeCache", mNightModeQuery);

    /**
     * Invalidate the night mode cache.
     *
     * @hide
     */
    @FlaggedApi(Flags.FLAG_ENABLE_NIGHT_MODE_CACHE)
    public static void invalidateNightModeCache() {
        IpcDataCache.invalidateCache(IpcDataCache.MODULE_SYSTEM,
                NIGHT_MODE_API);
    }

    /**
     * Returns the currently configured night mode.
     * <p>
@@ -890,15 +938,12 @@ public class UiModeManager {
     * @see #setNightMode(int)
     */
    public @NightMode int getNightMode() {
        if (sGlobals != null) {
            try {
                return sGlobals.mService.getNightMode();
            } catch (RemoteException e) {
                throw e.rethrowFromSystemServer();
        if (enableNightModeCache()) {
            return mNightModeCache.query(null);
        } else {
            return getNightModeFromServer();
        }
    }
        return -1;
    }

    /**
     * @return If UI mode is locked or not. When UI mode is locked, calls to change UI mode
+8 −0
Original line number Diff line number Diff line
package: "android.app"

flag {
     namespace: "system_performance"
     name: "enable_night_mode_cache"
     description: "Enables the use of binder caching for system night mode."
     bug: "255999432"
}
 No newline at end of file
+60 −31
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.server;

import static android.app.Flags.modesApi;
import static android.app.Flags.enableNightModeCache;
import static android.app.UiModeManager.ContrastUtils.CONTRAST_DEFAULT_VALUE;
import static android.app.UiModeManager.DEFAULT_PRIORITY;
import static android.app.UiModeManager.MODE_ATTENTION_THEME_OVERLAY_OFF;
@@ -135,7 +136,23 @@ final class UiModeManagerService extends SystemService {
    private int mDockState = Intent.EXTRA_DOCK_STATE_UNDOCKED;

    private int mLastBroadcastState = Intent.EXTRA_DOCK_STATE_UNDOCKED;
    private int mNightMode = UiModeManager.MODE_NIGHT_NO;

    private final NightMode mNightMode = new NightMode(){
        private int mNightModeValue = UiModeManager.MODE_NIGHT_NO;

        @Override
        public int get() {
            return mNightModeValue;
        }

        @Override
        public void set(int mode) {
            mNightModeValue = mode;
            if (enableNightModeCache()) {
                UiModeManager.invalidateNightModeCache();
            }
        }
    };
    private int mNightModeCustomType = UiModeManager.MODE_NIGHT_CUSTOM_TYPE_UNKNOWN;
    private int mAttentionModeThemeOverlay = UiModeManager.MODE_ATTENTION_THEME_OVERLAY_OFF;
    private final LocalTime DEFAULT_CUSTOM_NIGHT_START_TIME = LocalTime.of(22, 0);
@@ -297,7 +314,7 @@ final class UiModeManagerService extends SystemService {
        @Override
        public void onTwilightStateChanged(@Nullable TwilightState state) {
            synchronized (mLock) {
                if (mNightMode == UiModeManager.MODE_NIGHT_AUTO && mSystemReady) {
                if (mNightMode.get() == UiModeManager.MODE_NIGHT_AUTO && mSystemReady) {
                    if (shouldApplyAutomaticChangesImmediately()) {
                        updateLocked(0, 0);
                    } else {
@@ -392,7 +409,7 @@ final class UiModeManagerService extends SystemService {

    private void updateSystemProperties() {
        int mode = Secure.getIntForUser(getContext().getContentResolver(), Secure.UI_NIGHT_MODE,
                mNightMode, 0);
                mNightMode.get(), 0);
        if (mode == MODE_NIGHT_AUTO || mode == MODE_NIGHT_CUSTOM) {
            mode = MODE_NIGHT_YES;
        }
@@ -412,7 +429,7 @@ final class UiModeManagerService extends SystemService {
    @Override
    public void onUserSwitching(@Nullable TargetUser from, @NonNull TargetUser to) {
        mCurrentUser = to.getUserIdentifier();
        if (mNightMode == MODE_NIGHT_AUTO) persistComputedNightMode(from.getUserIdentifier());
        if (mNightMode.get() == MODE_NIGHT_AUTO) persistComputedNightMode(from.getUserIdentifier());
        getContext().getContentResolver().unregisterContentObserver(mSetupWizardObserver);
        verifySetupWizardCompleted();
        synchronized (mLock) {
@@ -471,12 +488,12 @@ final class UiModeManagerService extends SystemService {
        verifySetupWizardCompleted();

        final Resources res = context.getResources();
        mNightMode.set(res.getInteger(
                com.android.internal.R.integer.config_defaultNightMode));
        mStartDreamImmediatelyOnDock = res.getBoolean(
                com.android.internal.R.bool.config_startDreamImmediatelyOnDock);
        mDreamsDisabledByAmbientModeSuppression = res.getBoolean(
                com.android.internal.R.bool.config_dreamsDisabledByAmbientModeSuppressionConfig);
        mNightMode = res.getInteger(
                com.android.internal.R.integer.config_defaultNightMode);
        mDefaultUiModeType = res.getInteger(
                com.android.internal.R.integer.config_defaultUiModeType);
        mCarModeKeepsScreenOn = (res.getInteger(
@@ -510,7 +527,7 @@ final class UiModeManagerService extends SystemService {
    private final BroadcastReceiver mOnShutdown = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (mNightMode == MODE_NIGHT_AUTO) {
            if (mNightMode.get() == MODE_NIGHT_AUTO) {
                persistComputedNightMode(mCurrentUser);
            }
        }
@@ -585,7 +602,7 @@ final class UiModeManagerService extends SystemService {
    }

    private void updateCustomTimeLocked() {
        if (mNightMode != MODE_NIGHT_CUSTOM) return;
        if (mNightMode.get() != MODE_NIGHT_CUSTOM) return;
        if (shouldApplyAutomaticChangesImmediately()) {
            updateLocked(0, 0);
        } else {
@@ -606,9 +623,9 @@ final class UiModeManagerService extends SystemService {
            return;
        }
        if (mSetupWizardComplete) {
            mNightMode = Secure.getIntForUser(context.getContentResolver(),
            mNightMode.set(Secure.getIntForUser(context.getContentResolver(),
                    Secure.UI_NIGHT_MODE, res.getInteger(
                            com.android.internal.R.integer.config_defaultNightMode), userId);
                            com.android.internal.R.integer.config_defaultNightMode), userId));
            mNightModeCustomType = Secure.getIntForUser(context.getContentResolver(),
                    Secure.UI_NIGHT_MODE_CUSTOM_TYPE, MODE_NIGHT_CUSTOM_TYPE_UNKNOWN, userId);
                    mOverrideNightModeOn = Secure.getIntForUser(context.getContentResolver(),
@@ -623,7 +640,7 @@ final class UiModeManagerService extends SystemService {
                    Secure.getLongForUser(context.getContentResolver(),
                            Secure.DARK_THEME_CUSTOM_END_TIME,
                            DEFAULT_CUSTOM_NIGHT_END_TIME.toNanoOfDay() / 1000L, userId) * 1000);
            if (mNightMode == MODE_NIGHT_AUTO) {
            if (mNightMode.get() == MODE_NIGHT_AUTO) {
                mComputedNightMode = Secure.getIntForUser(context.getContentResolver(),
                        Secure.UI_NIGHT_MODE_LAST_COMPUTED, 0, userId) != 0;
            }
@@ -834,21 +851,23 @@ final class UiModeManagerService extends SystemService {
            final long ident = Binder.clearCallingIdentity();
            try {
                synchronized (mLock) {
                    if (mNightMode != mode || mNightModeCustomType != customModeType) {
                        if (mNightMode == MODE_NIGHT_AUTO || mNightMode == MODE_NIGHT_CUSTOM) {
                    if (mNightMode.get() != mode || mNightModeCustomType != customModeType) {
                        if (mNightMode.get() == MODE_NIGHT_AUTO
                                || mNightMode.get() == MODE_NIGHT_CUSTOM) {
                            unregisterDeviceInactiveListenerLocked();
                            cancelCustomAlarm();
                        }
                        mNightModeCustomType = mode == MODE_NIGHT_CUSTOM
                                ? customModeType
                                : MODE_NIGHT_CUSTOM_TYPE_UNKNOWN;
                        mNightMode = mode;
                        mNightMode.set(mode);
                        //deactivates AttentionMode if user toggles DarkTheme
                        mAttentionModeThemeOverlay = MODE_ATTENTION_THEME_OVERLAY_OFF;
                        resetNightModeOverrideLocked();
                        persistNightMode(user);
                        // on screen off will update configuration instead
                        if ((mNightMode != MODE_NIGHT_AUTO && mNightMode != MODE_NIGHT_CUSTOM)
                        if ((mNightMode.get() != MODE_NIGHT_AUTO
                                && mNightMode.get() != MODE_NIGHT_CUSTOM)
                                || shouldApplyAutomaticChangesImmediately()) {
                            unregisterDeviceInactiveListenerLocked();
                            updateLocked(0, 0);
@@ -865,7 +884,7 @@ final class UiModeManagerService extends SystemService {
        @Override
        public int getNightMode() {
            synchronized (mLock) {
                return mNightMode;
                return mNightMode.get();
            }
        }

@@ -999,18 +1018,19 @@ final class UiModeManagerService extends SystemService {
            synchronized (mLock) {
                final long ident = Binder.clearCallingIdentity();
                try {
                    if (mNightMode == MODE_NIGHT_AUTO || mNightMode == MODE_NIGHT_CUSTOM) {
                    if (mNightMode.get() == MODE_NIGHT_AUTO
                            || mNightMode.get() == MODE_NIGHT_CUSTOM) {
                        unregisterDeviceInactiveListenerLocked();
                        mOverrideNightModeOff = !active;
                        mOverrideNightModeOn = active;
                        mOverrideNightModeUser = mCurrentUser;
                        persistNightModeOverrides(mCurrentUser);
                    } else if (mNightMode == UiModeManager.MODE_NIGHT_NO
                    } else if (mNightMode.get() == UiModeManager.MODE_NIGHT_NO
                            && active) {
                        mNightMode = UiModeManager.MODE_NIGHT_YES;
                    } else if (mNightMode == UiModeManager.MODE_NIGHT_YES
                        mNightMode.set(UiModeManager.MODE_NIGHT_YES);
                    } else if (mNightMode.get() == UiModeManager.MODE_NIGHT_YES
                            && !active) {
                        mNightMode = UiModeManager.MODE_NIGHT_NO;
                        mNightMode.set(UiModeManager.MODE_NIGHT_NO);
                    }
                    updateConfigurationLocked();
                    applyConfigurationExternallyLocked();
@@ -1414,7 +1434,7 @@ final class UiModeManagerService extends SystemService {

    private void onCustomTimeUpdated(int user) {
        persistNightMode(user);
        if (mNightMode != MODE_NIGHT_CUSTOM) return;
        if (mNightMode.get() != MODE_NIGHT_CUSTOM) return;
        if (shouldApplyAutomaticChangesImmediately()) {
            unregisterDeviceInactiveListenerLocked();
            updateLocked(0, 0);
@@ -1431,8 +1451,8 @@ final class UiModeManagerService extends SystemService {

            pw.print(" mStartDreamImmediatelyOnDock="); pw.print(mStartDreamImmediatelyOnDock);

            pw.print("  mNightMode="); pw.print(mNightMode); pw.print(" (");
            pw.print(Shell.nightModeToStr(mNightMode, mNightModeCustomType)); pw.print(") ");
            pw.print("  mNightMode="); pw.print(mNightMode.get()); pw.print(" (");
            pw.print(Shell.nightModeToStr(mNightMode.get(), mNightModeCustomType)); pw.print(") ");
            pw.print(" mOverrideOn/Off="); pw.print(mOverrideNightModeOn);
            pw.print("/"); pw.print(mOverrideNightModeOff);
            pw.print("  mAttentionModeThemeOverlay="); pw.print(mAttentionModeThemeOverlay);
@@ -1623,7 +1643,7 @@ final class UiModeManagerService extends SystemService {
        // Only persist setting if not in car mode
        if (mCarModeEnabled || mCar) return;
        Secure.putIntForUser(getContext().getContentResolver(),
                Secure.UI_NIGHT_MODE, mNightMode, user);
                Secure.UI_NIGHT_MODE, mNightMode.get(), user);
        Secure.putLongForUser(getContext().getContentResolver(),
                Secure.UI_NIGHT_MODE_CUSTOM_TYPE, mNightModeCustomType, user);
        Secure.putLongForUser(getContext().getContentResolver(),
@@ -1659,11 +1679,11 @@ final class UiModeManagerService extends SystemService {
            uiMode = Configuration.UI_MODE_TYPE_VR_HEADSET;
        }

        if (mNightMode == MODE_NIGHT_YES || mNightMode == UiModeManager.MODE_NIGHT_NO) {
            updateComputedNightModeLocked(mNightMode == MODE_NIGHT_YES);
        if (mNightMode.get() == MODE_NIGHT_YES || mNightMode.get() == UiModeManager.MODE_NIGHT_NO) {
            updateComputedNightModeLocked(mNightMode.get() == MODE_NIGHT_YES);
        }

        if (mNightMode == MODE_NIGHT_AUTO) {
        if (mNightMode.get() == MODE_NIGHT_AUTO) {
            boolean activateNightMode = mComputedNightMode;
            if (mTwilightManager != null) {
                mTwilightManager.registerListener(mTwilightListener, mHandler);
@@ -1677,7 +1697,7 @@ final class UiModeManagerService extends SystemService {
            }
        }

        if (mNightMode == MODE_NIGHT_CUSTOM) {
        if (mNightMode.get() == MODE_NIGHT_CUSTOM) {
            if (mNightModeCustomType == MODE_NIGHT_CUSTOM_TYPE_BEDTIME) {
                updateComputedNightModeLocked(mLastBedtimeRequestedNightMode);
            } else {
@@ -2010,7 +2030,7 @@ final class UiModeManagerService extends SystemService {

    private void updateComputedNightModeLocked(boolean activate) {
        boolean newComputedValue = activate;
        if (mNightMode != MODE_NIGHT_YES && mNightMode != UiModeManager.MODE_NIGHT_NO) {
        if (mNightMode.get() != MODE_NIGHT_YES && mNightMode.get() != UiModeManager.MODE_NIGHT_NO) {
            if (mOverrideNightModeOn && !newComputedValue) {
                newComputedValue = true;
            } else if (mOverrideNightModeOff && newComputedValue) {
@@ -2029,7 +2049,7 @@ final class UiModeManagerService extends SystemService {
            mComputedNightMode = newComputedValue;
        }

        if (mNightMode != MODE_NIGHT_AUTO || (mTwilightManager != null
        if (mNightMode.get() != MODE_NIGHT_AUTO || (mTwilightManager != null
                && mTwilightManager.getLastTwilightState() != null)) {
            resetNightModeOverrideLocked();
        }
@@ -2279,4 +2299,13 @@ final class UiModeManagerService extends SystemService {
            Sandman.startDreamWhenDockedIfAppropriate(context);
        }
    }

    /**
     * Interface to contain the value for system night mode. We make the night mode accessible
     * through this class to ensure that the reassignment of this value invalidates the cache.
     */
    private interface NightMode {
        int get();
        void set(int mode);
    }
}
+6 −0
Original line number Diff line number Diff line
@@ -82,6 +82,7 @@ import android.content.res.Resources;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.IpcDataCache;
import android.os.PowerManager;
import android.os.PowerManagerInternal;
import android.os.PowerSaveState;
@@ -173,6 +174,11 @@ public class UiModeManagerServiceTest extends UiServiceTestCase {
            SetFlagsRule.DefaultInitValueType.DEVICE_DEFAULT);


    @Before
    public void disableProcessCaches() {
        IpcDataCache.disableForTestMode();
    }

    @Before
    public void setUp() {
        // The AIDL stub will use PermissionEnforcer to check permission from the caller.