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

Commit 9d2c9335 authored by Jay Aliomer's avatar Jay Aliomer Committed by Android (Google) Code Review
Browse files

Merge "Dark theme twilight mode backend and tile"

parents d88edf91 8b2671b0
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -68,4 +68,9 @@ interface IUiModeManager {
     * Tells if Night mode is locked or not.
     */
    boolean isNightModeLocked();

    /**
    * @hide
    */
    boolean setNightModeActivated(boolean active);
}
+14 −0
Original line number Diff line number Diff line
@@ -473,4 +473,18 @@ public class UiModeManager {
        }
        return true;
    }

    /**
     * @hide*
     */
    public boolean setNightModeActivated(boolean active) {
        if (mService != null) {
            try {
                return mService.setNightModeActivated(active);
            } catch (RemoteException e) {
                throw e.rethrowFromSystemServer();
            }
        }
        return false;
    }
}
+4 −0
Original line number Diff line number Diff line
@@ -916,6 +916,10 @@
    <string name="quick_settings_ui_mode_night_label">Dark theme</string>
    <!-- QuickSettings: Label for the dark theme tile when enabled by battery saver. [CHAR LIMIT=40] -->
    <string name="quick_settings_ui_mode_night_label_battery_saver">Dark theme\nBattery saver</string>
    <!-- QuickSettings: Secondary text for when the Dark Mode will be enabled at sunset. [CHAR LIMIT=20] -->
    <string name="quick_settings_dark_mode_secondary_label_on_at_sunset">On at sunset</string>
    <!-- QuickSettings: Secondary text for when the Dark Mode will be on until sunrise. [CHAR LIMIT=20] -->
    <string name="quick_settings_dark_mode_secondary_label_until_sunrise">Until sunrise</string>

    <!-- QuickSettings: NFC tile [CHAR LIMIT=NONE] -->
    <string name="quick_settings_nfc_label">NFC</string>
+15 −6
Original line number Diff line number Diff line
@@ -21,7 +21,7 @@ import android.content.Intent;
import android.content.res.Configuration;
import android.provider.Settings;
import android.service.quicksettings.Tile;
import android.widget.Switch;
import android.text.TextUtils;

import com.android.internal.logging.nano.MetricsProto;
import com.android.systemui.R;
@@ -79,24 +79,33 @@ public class UiModeNightTile extends QSTileImpl<QSTile.BooleanState> implements
            return;
        }
        boolean newState = !mState.value;
        mUiModeManager.setNightMode(newState ? UiModeManager.MODE_NIGHT_YES
                : UiModeManager.MODE_NIGHT_NO);
        mUiModeManager.setNightModeActivated(newState);
        refreshState(newState);
    }

    @Override
    protected void handleUpdateState(BooleanState state, Object arg) {
        int uiMode = mUiModeManager.getNightMode();
        boolean powerSave = mBatteryController.isPowerSave();
        boolean isAuto = uiMode == UiModeManager.MODE_NIGHT_AUTO;
        boolean nightMode = (mContext.getResources().getConfiguration().uiMode
                        & Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES;

        if (isAuto) {
            state.secondaryLabel = mContext.getResources().getString(nightMode
                    ? R.string.quick_settings_dark_mode_secondary_label_until_sunrise
                    : R.string.quick_settings_dark_mode_secondary_label_on_at_sunset);
        } else {
            state.secondaryLabel = null;
        }
        state.value = nightMode;
        state.label = mContext.getString(powerSave
                ? R.string.quick_settings_ui_mode_night_label_battery_saver
                : R.string.quick_settings_ui_mode_night_label);
        state.contentDescription = state.label;
        state.icon = mIcon;
        state.expandedAccessibilityClassName = Switch.class.getName();
        state.contentDescription = TextUtils.isEmpty(state.secondaryLabel)
                ? state.label
                : TextUtils.concat(state.label, ", ", state.secondaryLabel);
        if (powerSave) {
            state.state = Tile.STATE_UNAVAILABLE;
        } else {
+114 −4
Original line number Diff line number Diff line
@@ -56,8 +56,8 @@ import android.service.vr.IVrManager;
import android.service.vr.IVrStateCallbacks;
import android.util.ArraySet;
import android.util.Slog;

import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.app.DisableCarModeActivity;
import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
import com.android.internal.notification.SystemNotificationChannels;
@@ -65,6 +65,7 @@ import com.android.internal.util.DumpUtils;
import com.android.server.twilight.TwilightListener;
import com.android.server.twilight.TwilightManager;
import com.android.server.twilight.TwilightState;
import com.android.server.wm.WindowManagerInternal;

import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -72,6 +73,8 @@ import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import static android.content.Intent.ACTION_SCREEN_OFF;

final class UiModeManagerService extends SystemService {
    private static final String TAG = UiModeManager.class.getSimpleName();
    private static final boolean LOG = false;
@@ -85,6 +88,10 @@ final class UiModeManagerService extends SystemService {

    private int mLastBroadcastState = Intent.EXTRA_DOCK_STATE_UNDOCKED;
    private int mNightMode = UiModeManager.MODE_NIGHT_NO;
    // we use the override auto mode
    // for example: force night mode off in the night time while in auto mode
    private int mNightModeOverride = mNightMode;
    protected static final String OVERRIDE_NIGHT_MODE = Secure.UI_NIGHT_MODE + "_override";

    private Map<Integer, String> mCarModePackagePriority = new HashMap<>();
    private boolean mCarModeEnabled = false;
@@ -119,6 +126,7 @@ final class UiModeManagerService extends SystemService {
    private TwilightManager mTwilightManager;
    private NotificationManager mNotificationManager;
    private StatusBarManager mStatusBarManager;
    private WindowManagerInternal mWindowManager;

    private PowerManager.WakeLock mWakeLock;

@@ -128,6 +136,17 @@ final class UiModeManagerService extends SystemService {
        super(context);
    }

    @VisibleForTesting
    protected UiModeManagerService(Context context, WindowManagerInternal wm,
                                   PowerManager.WakeLock wl, TwilightManager tm,
                                   boolean setupWizardComplete) {
        super(context);
        mWindowManager = wm;
        mWakeLock = wl;
        mTwilightManager = tm;
        mSetupWizardComplete = setupWizardComplete;
    }

    private static Intent buildHomeIntent(String category) {
        Intent intent = new Intent(Intent.ACTION_MAIN);
        intent.addCategory(category);
@@ -189,8 +208,23 @@ final class UiModeManagerService extends SystemService {
        public void onTwilightStateChanged(@Nullable TwilightState state) {
            synchronized (mLock) {
                if (mNightMode == UiModeManager.MODE_NIGHT_AUTO) {
                    updateComputedNightModeLocked();
                    final IntentFilter intentFilter =
                            new IntentFilter(ACTION_SCREEN_OFF);
                    getContext().registerReceiver(mOnScreenOffHandler, intentFilter);
                }
            }
        }
    };

    private final BroadcastReceiver mOnScreenOffHandler = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            synchronized (mLock) {
                updateLocked(0, 0);
                try {
                    getContext().unregisterReceiver(mOnScreenOffHandler);
                } catch (IllegalArgumentException e) {
                    // we ignore this exception if the receiver is unregistered already.
                }
            }
        }
@@ -229,6 +263,8 @@ final class UiModeManagerService extends SystemService {
        public void onChange(boolean selfChange, Uri uri) {
            int mode = Secure.getIntForUser(getContext().getContentResolver(), Secure.UI_NIGHT_MODE,
                    mNightMode, 0);
            mode = mode == UiModeManager.MODE_NIGHT_AUTO
                    ? UiModeManager.MODE_NIGHT_YES : UiModeManager.MODE_NIGHT_NO;
            SystemProperties.set(SYSTEM_PROPERTY_DEVICE_THEME, Integer.toString(mode));
        }
    };
@@ -247,6 +283,7 @@ final class UiModeManagerService extends SystemService {
        final PowerManager powerManager =
                (PowerManager) context.getSystemService(Context.POWER_SERVICE);
        mWakeLock = powerManager.newWakeLock(PowerManager.FULL_WAKE_LOCK, TAG);
        mWindowManager = LocalServices.getService(WindowManagerInternal.class);

        // 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
@@ -313,6 +350,16 @@ final class UiModeManagerService extends SystemService {
                false, mDarkThemeObserver, 0);
    }

    @VisibleForTesting
    protected IUiModeManager getService() {
        return mService;
    }

    @VisibleForTesting
    protected Configuration getConfiguration() {
        return mConfiguration;
    }

    // Records whether setup wizard has happened or not and adds an observer for this user if not.
    private void verifySetupWizardCompleted() {
        final Context context = getContext();
@@ -347,8 +394,11 @@ final class UiModeManagerService extends SystemService {
        if (mSetupWizardComplete) {
            mNightMode = Secure.getIntForUser(context.getContentResolver(),
                    Secure.UI_NIGHT_MODE, defaultNightMode, userId);
            mNightModeOverride = Secure.getIntForUser(context.getContentResolver(),
                    OVERRIDE_NIGHT_MODE, defaultNightMode, userId);
        } else {
            mNightMode = defaultNightMode;
            mNightModeOverride = defaultNightMode;
        }

        return oldNightMode != mNightMode;
@@ -474,14 +524,30 @@ final class UiModeManagerService extends SystemService {
            try {
                synchronized (mLock) {
                    if (mNightMode != mode) {
                        if (mNightMode == UiModeManager.MODE_NIGHT_AUTO) {
                            try {
                                getContext().unregisterReceiver(mOnScreenOffHandler);
                            } catch (IllegalArgumentException e) {
                                // we ignore this exception if the receiver is unregistered already.
                            }
                        }
                        // Only persist setting if not in car mode
                        if (!mCarModeEnabled) {
                            Secure.putIntForUser(getContext().getContentResolver(),
                                    Secure.UI_NIGHT_MODE, mode, user);
                            Secure.putIntForUser(getContext().getContentResolver(),
                                    OVERRIDE_NIGHT_MODE, mNightModeOverride, user);
                        }

                        mNightMode = mode;
                        mNightModeOverride = mode;
                        //on screen off will update configuration instead
                        if (mNightMode != UiModeManager.MODE_NIGHT_AUTO) {
                            updateLocked(0, 0);
                        } else {
                            getContext().registerReceiver(
                                    mOnScreenOffHandler, new IntentFilter(ACTION_SCREEN_OFF));
                        }
                    }
                }
            } finally {
@@ -521,6 +587,34 @@ final class UiModeManagerService extends SystemService {
            if (!DumpUtils.checkDumpPermission(getContext(), TAG, pw)) return;
            dumpImpl(pw);
        }

        @Override
        public boolean setNightModeActivated(boolean active) {
            synchronized (mLock) {
                final long ident = Binder.clearCallingIdentity();
                try {
                    if (mNightMode == UiModeManager.MODE_NIGHT_AUTO) {
                        try {
                            getContext().unregisterReceiver(mOnScreenOffHandler);
                        } catch (IllegalArgumentException e) {
                        }
                        mNightModeOverride = active
                                ? UiModeManager.MODE_NIGHT_YES : UiModeManager.MODE_NIGHT_NO;
                    } else if (mNightMode == UiModeManager.MODE_NIGHT_NO
                            && active) {
                        mNightMode = UiModeManager.MODE_NIGHT_YES;
                    } else if (mNightMode == UiModeManager.MODE_NIGHT_YES
                            && !active) {
                        mNightMode = UiModeManager.MODE_NIGHT_NO;
                    }
                    updateConfigurationLocked();
                    sendConfigurationLocked();
                    return true;
                } finally {
                    Binder.restoreCallingIdentity(ident);
                }
            }
        }
    };

    void dumpImpl(PrintWriter pw) {
@@ -772,6 +866,8 @@ final class UiModeManagerService extends SystemService {
        if (!mHoldingConfiguration) {
            mConfiguration.uiMode = uiMode;
        }
        // load splash screen instead of screenshot
        mWindowManager.clearSnapshotCache();
    }

    private void sendConfigurationLocked() {
@@ -1022,6 +1118,20 @@ final class UiModeManagerService extends SystemService {
            if (state != null) {
                mComputedNightMode = state.isNight();
            }
            if (mNightModeOverride == UiModeManager.MODE_NIGHT_YES && !mComputedNightMode) {
                mComputedNightMode = true;
                return;
            }
            if (mNightModeOverride == UiModeManager.MODE_NIGHT_NO && mComputedNightMode) {
                mComputedNightMode = false;
                return;
            }

            mNightModeOverride = mNightMode;
            final int user = UserHandle.getCallingUserId();
            Secure.putIntForUser(getContext().getContentResolver(),
                    OVERRIDE_NIGHT_MODE, mNightModeOverride, user);

        }
    }

Loading