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

Commit e17d742c authored by Christine Franks's avatar Christine Franks
Browse files

Synchronize NightDisplayListener

Bug: 124232236
Test: manual
Change-Id: Ie0db4e53d20781f21f4fe49670706721e56c9ca7
parent 1d92c9b8
Loading
Loading
Loading
Loading
+72 −54
Original line number Diff line number Diff line
@@ -35,119 +35,137 @@ import java.time.LocalTime;
public class NightDisplayListener {

    private final Context mContext;
    private final int mUserId;
    private final ColorDisplayManager mManager;
    private final Handler mHandler;
    private final ContentObserver mContentObserver;
    private final int mUserId;

    private ContentObserver mContentObserver;
    private Callback mCallback;

    public NightDisplayListener(@NonNull Context context) {
        this(context, ActivityManager.getCurrentUser());
        this(context, ActivityManager.getCurrentUser(), new Handler(Looper.getMainLooper()));
    }

    public NightDisplayListener(@NonNull Context context, @NonNull Handler handler) {
        this(context, ActivityManager.getCurrentUser(), handler);
    }

    public NightDisplayListener(@NonNull Context context, @UserIdInt int userId) {
    public NightDisplayListener(@NonNull Context context, @UserIdInt int userId,
            @NonNull Handler handler) {
        mContext = context.getApplicationContext();
        mUserId = userId;
        mManager = mContext.getSystemService(ColorDisplayManager.class);
        mUserId = userId;

        mHandler = handler;
        mContentObserver = new ContentObserver(mHandler) {
            @Override
            public void onChange(boolean selfChange, Uri uri) {
                super.onChange(selfChange, uri);
                final String setting = uri == null ? null : uri.getLastPathSegment();
                if (setting != null && mCallback != null) {
                    switch (setting) {
                        case Secure.NIGHT_DISPLAY_ACTIVATED:
                            mCallback.onActivated(mManager.isNightDisplayActivated());
                            break;
                        case Secure.NIGHT_DISPLAY_AUTO_MODE:
                            mCallback.onAutoModeChanged(mManager.getNightDisplayAutoMode());
                            break;
                        case Secure.NIGHT_DISPLAY_CUSTOM_START_TIME:
                            mCallback.onCustomStartTimeChanged(
                                    mManager.getNightDisplayCustomStartTime());
                            break;
                        case Secure.NIGHT_DISPLAY_CUSTOM_END_TIME:
                            mCallback.onCustomEndTimeChanged(
                                    mManager.getNightDisplayCustomEndTime());
                            break;
                        case Secure.NIGHT_DISPLAY_COLOR_TEMPERATURE:
                            mCallback.onColorTemperatureChanged(
                                    mManager.getNightDisplayColorTemperature());
                            break;
                    }
                }
            }
        };
    }

    /**
     * Register a callback to be invoked whenever the Night display settings are changed.
     */
    public void setCallback(Callback callback) {
        final Callback oldCallback = mCallback;
        if (oldCallback != callback) {
            mCallback = callback;

            if (mContentObserver == null) {
                mContentObserver = new ContentObserver(new Handler(Looper.getMainLooper())) {
                    @Override
                    public void onChange(boolean selfChange, Uri uri) {
                        super.onChange(selfChange, uri);
                        onSettingChanged(uri);
        if (Looper.myLooper() != mHandler.getLooper()) {
            mHandler.post(() -> setCallbackInternal(callback));
        }
                };
        setCallbackInternal(callback);
    }

            if (callback == null) {
                // Stop listening for changes now that there IS NOT a callback.
    private void setCallbackInternal(Callback newCallback) {
        final Callback oldCallback = mCallback;
        if (oldCallback != newCallback) {
            mCallback = newCallback;
            if (mCallback == null) {
                mContext.getContentResolver().unregisterContentObserver(mContentObserver);
            } else if (oldCallback == null) {
                // Start listening for changes now that there IS a callback.
                final ContentResolver cr = mContext.getContentResolver();
                cr.registerContentObserver(Secure.getUriFor(Secure.NIGHT_DISPLAY_ACTIVATED),
                        false /* notifyForDescendants */, mContentObserver, mUserId);
                cr.registerContentObserver(Secure.getUriFor(Secure.NIGHT_DISPLAY_AUTO_MODE),
                        false /* notifyForDescendants */, mContentObserver, mUserId);
                cr.registerContentObserver(Secure.getUriFor(Secure.NIGHT_DISPLAY_CUSTOM_START_TIME),
                cr.registerContentObserver(
                        Secure.getUriFor(Secure.NIGHT_DISPLAY_CUSTOM_START_TIME),
                        false /* notifyForDescendants */, mContentObserver, mUserId);
                cr.registerContentObserver(Secure.getUriFor(Secure.NIGHT_DISPLAY_CUSTOM_END_TIME),
                cr.registerContentObserver(
                        Secure.getUriFor(Secure.NIGHT_DISPLAY_CUSTOM_END_TIME),
                        false /* notifyForDescendants */, mContentObserver, mUserId);
                cr.registerContentObserver(Secure.getUriFor(Secure.NIGHT_DISPLAY_COLOR_TEMPERATURE),
                cr.registerContentObserver(
                        Secure.getUriFor(Secure.NIGHT_DISPLAY_COLOR_TEMPERATURE),
                        false /* notifyForDescendants */, mContentObserver, mUserId);
            }
        }
    }

    private void onSettingChanged(Uri uri) {
        final String setting = uri == null ? null : uri.getLastPathSegment();
        if (setting == null || mCallback == null) {
            return;
        }

        switch (setting) {
            case Secure.NIGHT_DISPLAY_ACTIVATED:
                mCallback.onActivated(mManager.isNightDisplayActivated());
                break;
            case Secure.NIGHT_DISPLAY_AUTO_MODE:
                mCallback.onAutoModeChanged(mManager.getNightDisplayAutoMode());
                break;
            case Secure.NIGHT_DISPLAY_CUSTOM_START_TIME:
                mCallback.onCustomStartTimeChanged(mManager.getNightDisplayCustomStartTime());
                break;
            case Secure.NIGHT_DISPLAY_CUSTOM_END_TIME:
                mCallback.onCustomEndTimeChanged(mManager.getNightDisplayCustomEndTime());
                break;
            case Secure.NIGHT_DISPLAY_COLOR_TEMPERATURE:
                mCallback.onColorTemperatureChanged(mManager.getNightDisplayColorTemperature());
                break;
        }
    }

    /**
     * Callback invoked whenever the Night display settings are changed.
     */
    public interface Callback {

        /**
         * Callback invoked when the activated state changes.
         *
         * @param activated {@code true} if Night display is activated
         */
        default void onActivated(boolean activated) {}
        default void onActivated(boolean activated) {
        }

        /**
         * Callback invoked when the auto mode changes.
         *
         * @param autoMode the auto mode to use
         */
        default void onAutoModeChanged(int autoMode) {}
        default void onAutoModeChanged(int autoMode) {
        }

        /**
         * Callback invoked when the time to automatically activate Night display changes.
         *
         * @param startTime the local time to automatically activate Night display
         */
        default void onCustomStartTimeChanged(LocalTime startTime) {}
        default void onCustomStartTimeChanged(LocalTime startTime) {
        }

        /**
         * Callback invoked when the time to automatically deactivate Night display changes.
         *
         * @param endTime the local time to automatically deactivate Night display
         */
        default void onCustomEndTimeChanged(LocalTime endTime) {}
        default void onCustomEndTimeChanged(LocalTime endTime) {
        }

        /**
         * Callback invoked when the color temperature changes.
         *
         * @param colorTemperature the color temperature to tint the screen
         */
        default void onColorTemperatureChanged(int colorTemperature) {}
        default void onColorTemperatureChanged(int colorTemperature) {
        }
    }
}
+3 −2
Original line number Diff line number Diff line
@@ -155,8 +155,9 @@ public class DependencyProvider {

    @Singleton
    @Provides
    public NightDisplayListener provideNightDisplayListener(Context context) {
        return new NightDisplayListener(context);
    public NightDisplayListener provideNightDisplayListener(Context context,
            @Named(BG_HANDLER_NAME) Handler bgHandler) {
        return new NightDisplayListener(context, bgHandler);
    }

    @Singleton
+4 −3
Original line number Diff line number Diff line
@@ -19,11 +19,12 @@ package com.android.systemui.qs.tiles;
import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_QS_MODE;

import android.annotation.Nullable;
import android.app.ActivityManager;
import android.content.Intent;
import android.hardware.display.ColorDisplayManager;
import android.hardware.display.NightDisplayListener;
import android.metrics.LogMaker;
import android.os.Handler;
import android.os.Looper;
import android.provider.Settings;
import android.service.quicksettings.Tile;
import android.text.TextUtils;
@@ -66,7 +67,7 @@ public class NightDisplayTile extends QSTileImpl<BooleanState> implements
    public NightDisplayTile(QSHost host) {
        super(host);
        mManager = mContext.getSystemService(ColorDisplayManager.class);
        mListener = new NightDisplayListener(mContext, ActivityManager.getCurrentUser());
        mListener = new NightDisplayListener(mContext, new Handler(Looper.myLooper()));
    }

    @Override
@@ -102,7 +103,7 @@ public class NightDisplayTile extends QSTileImpl<BooleanState> implements
        }

        // Make a new controller for the new user.
        mListener = new NightDisplayListener(mContext, newUserId);
        mListener = new NightDisplayListener(mContext, newUserId, new Handler(Looper.myLooper()));
        if (mIsListening) {
            mListener.setCallback(this);
        }