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

Commit 8fd7fb99 authored by Jay Aliomer's avatar Jay Aliomer Committed by android-build-merger
Browse files

Dark theme twilight mode backend and tile

am: 381e3300

Change-Id: I0d5b96795d5ad818a9b7a21758721e35059d18ed
parents 02076c7a 381e3300
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
@@ -894,6 +894,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 −6
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.
                }
            }
        }
@@ -227,8 +261,10 @@ final class UiModeManagerService extends SystemService {
    private final ContentObserver mDarkThemeObserver = new ContentObserver(mHandler) {
        @Override
        public void onChange(boolean selfChange, Uri uri) {
            final int mode = Secure.getIntForUser(getContext().getContentResolver(),
                    Secure.UI_NIGHT_MODE, mNightMode, 0);
            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) {
@@ -1022,6 +1116,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