Home | History | Annotate | Download | only in app
      1 /*
      2  * Copyright (C) 2016 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.internal.app;
     18 
     19 import android.annotation.IntDef;
     20 import android.annotation.NonNull;
     21 import android.app.ActivityManager;
     22 import android.content.ContentResolver;
     23 import android.content.Context;
     24 import android.database.ContentObserver;
     25 import android.metrics.LogMaker;
     26 import android.net.Uri;
     27 import android.os.Handler;
     28 import android.os.Looper;
     29 import android.os.SystemProperties;
     30 import android.provider.Settings.Secure;
     31 import android.provider.Settings.System;
     32 import android.util.Slog;
     33 
     34 import com.android.internal.R;
     35 import com.android.internal.logging.MetricsLogger;
     36 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
     37 
     38 import java.lang.annotation.Retention;
     39 import java.lang.annotation.RetentionPolicy;
     40 import java.time.DateTimeException;
     41 import java.time.Instant;
     42 import java.time.LocalDateTime;
     43 import java.time.LocalTime;
     44 import java.time.ZoneId;
     45 import java.time.format.DateTimeParseException;
     46 
     47 /**
     48  * Controller for managing night display and color mode settings.
     49  * <p/>
     50  * Night display tints your screen red at night. This makes it easier to look at your screen in
     51  * dim light and may help you fall asleep more easily.
     52  */
     53 public final class ColorDisplayController {
     54 
     55     private static final String TAG = "ColorDisplayController";
     56     private static final boolean DEBUG = false;
     57 
     58     @Retention(RetentionPolicy.SOURCE)
     59     @IntDef({ AUTO_MODE_DISABLED, AUTO_MODE_CUSTOM, AUTO_MODE_TWILIGHT })
     60     public @interface AutoMode {}
     61 
     62     /**
     63      * Auto mode value to prevent Night display from being automatically activated. It can still
     64      * be activated manually via {@link #setActivated(boolean)}.
     65      *
     66      * @see #setAutoMode(int)
     67      */
     68     public static final int AUTO_MODE_DISABLED = 0;
     69     /**
     70      * Auto mode value to automatically activate Night display at a specific start and end time.
     71      *
     72      * @see #setAutoMode(int)
     73      * @see #setCustomStartTime(LocalTime)
     74      * @see #setCustomEndTime(LocalTime)
     75      */
     76     public static final int AUTO_MODE_CUSTOM = 1;
     77     /**
     78      * Auto mode value to automatically activate Night display from sunset to sunrise.
     79      *
     80      * @see #setAutoMode(int)
     81      */
     82     public static final int AUTO_MODE_TWILIGHT = 2;
     83 
     84     @Retention(RetentionPolicy.SOURCE)
     85     @IntDef({ COLOR_MODE_NATURAL, COLOR_MODE_BOOSTED, COLOR_MODE_SATURATED, COLOR_MODE_AUTOMATIC })
     86     public @interface ColorMode {}
     87 
     88     /**
     89      * Color mode with natural colors.
     90      *
     91      * @see #setColorMode(int)
     92      */
     93     public static final int COLOR_MODE_NATURAL = 0;
     94     /**
     95      * Color mode with boosted colors.
     96      *
     97      * @see #setColorMode(int)
     98      */
     99     public static final int COLOR_MODE_BOOSTED = 1;
    100     /**
    101      * Color mode with saturated colors.
    102      *
    103      * @see #setColorMode(int)
    104      */
    105     public static final int COLOR_MODE_SATURATED = 2;
    106     /**
    107      * Color mode with automatic colors.
    108      *
    109      * @see #setColorMode(int)
    110      */
    111     public static final int COLOR_MODE_AUTOMATIC = 3;
    112 
    113     private final Context mContext;
    114     private final int mUserId;
    115     private final ContentObserver mContentObserver;
    116 
    117     private Callback mCallback;
    118     private MetricsLogger mMetricsLogger;
    119 
    120     public ColorDisplayController(@NonNull Context context) {
    121         this(context, ActivityManager.getCurrentUser());
    122     }
    123 
    124     public ColorDisplayController(@NonNull Context context, int userId) {
    125         mContext = context.getApplicationContext();
    126         mUserId = userId;
    127 
    128         mContentObserver = new ContentObserver(new Handler(Looper.getMainLooper())) {
    129             @Override
    130             public void onChange(boolean selfChange, Uri uri) {
    131                 super.onChange(selfChange, uri);
    132 
    133                 final String setting = uri == null ? null : uri.getLastPathSegment();
    134                 if (setting != null) {
    135                     onSettingChanged(setting);
    136                 }
    137             }
    138         };
    139     }
    140 
    141     /**
    142      * Returns {@code true} when Night display is activated (the display is tinted red).
    143      */
    144     public boolean isActivated() {
    145         return Secure.getIntForUser(mContext.getContentResolver(),
    146                 Secure.NIGHT_DISPLAY_ACTIVATED, 0, mUserId) == 1;
    147     }
    148 
    149     /**
    150      * Sets whether Night display should be activated. This also sets the last activated time.
    151      *
    152      * @param activated {@code true} if Night display should be activated
    153      * @return {@code true} if the activated value was set successfully
    154      */
    155     public boolean setActivated(boolean activated) {
    156         if (isActivated() != activated) {
    157             Secure.putStringForUser(mContext.getContentResolver(),
    158                     Secure.NIGHT_DISPLAY_LAST_ACTIVATED_TIME,
    159                     LocalDateTime.now().toString(),
    160                     mUserId);
    161         }
    162         return Secure.putIntForUser(mContext.getContentResolver(),
    163                 Secure.NIGHT_DISPLAY_ACTIVATED, activated ? 1 : 0, mUserId);
    164     }
    165 
    166     /**
    167      * Returns the time when Night display's activation state last changed, or {@code null} if it
    168      * has never been changed.
    169      */
    170     public LocalDateTime getLastActivatedTime() {
    171         final ContentResolver cr = mContext.getContentResolver();
    172         final String lastActivatedTime = Secure.getStringForUser(
    173                 cr, Secure.NIGHT_DISPLAY_LAST_ACTIVATED_TIME, mUserId);
    174         if (lastActivatedTime != null) {
    175             try {
    176                 return LocalDateTime.parse(lastActivatedTime);
    177             } catch (DateTimeParseException ignored) {}
    178             // Uses the old epoch time.
    179             try {
    180                 return LocalDateTime.ofInstant(
    181                     Instant.ofEpochMilli(Long.parseLong(lastActivatedTime)),
    182                     ZoneId.systemDefault());
    183             } catch (DateTimeException|NumberFormatException ignored) {}
    184         }
    185         return null;
    186     }
    187 
    188     /**
    189      * Returns the current auto mode value controlling when Night display will be automatically
    190      * activated. One of {@link #AUTO_MODE_DISABLED}, {@link #AUTO_MODE_CUSTOM}, or
    191      * {@link #AUTO_MODE_TWILIGHT}.
    192      */
    193     public @AutoMode int getAutoMode() {
    194         int autoMode = Secure.getIntForUser(mContext.getContentResolver(),
    195                 Secure.NIGHT_DISPLAY_AUTO_MODE, -1, mUserId);
    196         if (autoMode == -1) {
    197             if (DEBUG) {
    198                 Slog.d(TAG, "Using default value for setting: " + Secure.NIGHT_DISPLAY_AUTO_MODE);
    199             }
    200             autoMode = mContext.getResources().getInteger(
    201                     R.integer.config_defaultNightDisplayAutoMode);
    202         }
    203 
    204         if (autoMode != AUTO_MODE_DISABLED
    205                 && autoMode != AUTO_MODE_CUSTOM
    206                 && autoMode != AUTO_MODE_TWILIGHT) {
    207             Slog.e(TAG, "Invalid autoMode: " + autoMode);
    208             autoMode = AUTO_MODE_DISABLED;
    209         }
    210 
    211         return autoMode;
    212     }
    213 
    214     /**
    215      * Returns the current auto mode value, without validation, or {@code 1} if the auto mode has
    216      * never been set.
    217      */
    218     public int getAutoModeRaw() {
    219         return Secure.getIntForUser(mContext.getContentResolver(), Secure.NIGHT_DISPLAY_AUTO_MODE,
    220                 -1, mUserId);
    221     }
    222 
    223     /**
    224      * Sets the current auto mode value controlling when Night display will be automatically
    225      * activated. One of {@link #AUTO_MODE_DISABLED}, {@link #AUTO_MODE_CUSTOM}, or
    226      * {@link #AUTO_MODE_TWILIGHT}.
    227      *
    228      * @param autoMode the new auto mode to use
    229      * @return {@code true} if new auto mode was set successfully
    230      */
    231     public boolean setAutoMode(@AutoMode int autoMode) {
    232         if (autoMode != AUTO_MODE_DISABLED
    233                 && autoMode != AUTO_MODE_CUSTOM
    234                 && autoMode != AUTO_MODE_TWILIGHT) {
    235             throw new IllegalArgumentException("Invalid autoMode: " + autoMode);
    236         }
    237 
    238         if (getAutoMode() != autoMode) {
    239             Secure.putStringForUser(mContext.getContentResolver(),
    240                     Secure.NIGHT_DISPLAY_LAST_ACTIVATED_TIME,
    241                     null,
    242                     mUserId);
    243             getMetricsLogger().write(new LogMaker(
    244                     MetricsEvent.ACTION_NIGHT_DISPLAY_AUTO_MODE_CHANGED)
    245                     .setType(MetricsEvent.TYPE_ACTION)
    246                     .setSubtype(autoMode));
    247         }
    248 
    249         return Secure.putIntForUser(mContext.getContentResolver(),
    250                 Secure.NIGHT_DISPLAY_AUTO_MODE, autoMode, mUserId);
    251     }
    252 
    253     /**
    254      * Returns the local time when Night display will be automatically activated when using
    255      * {@link #AUTO_MODE_CUSTOM}.
    256      */
    257     public @NonNull LocalTime getCustomStartTime() {
    258         int startTimeValue = Secure.getIntForUser(mContext.getContentResolver(),
    259                 Secure.NIGHT_DISPLAY_CUSTOM_START_TIME, -1, mUserId);
    260         if (startTimeValue == -1) {
    261             if (DEBUG) {
    262                 Slog.d(TAG, "Using default value for setting: "
    263                         + Secure.NIGHT_DISPLAY_CUSTOM_START_TIME);
    264             }
    265             startTimeValue = mContext.getResources().getInteger(
    266                     R.integer.config_defaultNightDisplayCustomStartTime);
    267         }
    268 
    269         return LocalTime.ofSecondOfDay(startTimeValue / 1000);
    270     }
    271 
    272     /**
    273      * Sets the local time when Night display will be automatically activated when using
    274      * {@link #AUTO_MODE_CUSTOM}.
    275      *
    276      * @param startTime the local time to automatically activate Night display
    277      * @return {@code true} if the new custom start time was set successfully
    278      */
    279     public boolean setCustomStartTime(@NonNull LocalTime startTime) {
    280         if (startTime == null) {
    281             throw new IllegalArgumentException("startTime cannot be null");
    282         }
    283         getMetricsLogger().write(new LogMaker(
    284                 MetricsEvent.ACTION_NIGHT_DISPLAY_AUTO_MODE_CUSTOM_TIME_CHANGED)
    285                 .setType(MetricsEvent.TYPE_ACTION)
    286                 .setSubtype(0));
    287         return Secure.putIntForUser(mContext.getContentResolver(),
    288                 Secure.NIGHT_DISPLAY_CUSTOM_START_TIME, startTime.toSecondOfDay() * 1000, mUserId);
    289     }
    290 
    291     /**
    292      * Returns the local time when Night display will be automatically deactivated when using
    293      * {@link #AUTO_MODE_CUSTOM}.
    294      */
    295     public @NonNull LocalTime getCustomEndTime() {
    296         int endTimeValue = Secure.getIntForUser(mContext.getContentResolver(),
    297                 Secure.NIGHT_DISPLAY_CUSTOM_END_TIME, -1, mUserId);
    298         if (endTimeValue == -1) {
    299             if (DEBUG) {
    300                 Slog.d(TAG, "Using default value for setting: "
    301                         + Secure.NIGHT_DISPLAY_CUSTOM_END_TIME);
    302             }
    303             endTimeValue = mContext.getResources().getInteger(
    304                     R.integer.config_defaultNightDisplayCustomEndTime);
    305         }
    306 
    307         return LocalTime.ofSecondOfDay(endTimeValue / 1000);
    308     }
    309 
    310     /**
    311      * Sets the local time when Night display will be automatically deactivated when using
    312      * {@link #AUTO_MODE_CUSTOM}.
    313      *
    314      * @param endTime the local time to automatically deactivate Night display
    315      * @return {@code true} if the new custom end time was set successfully
    316      */
    317     public boolean setCustomEndTime(@NonNull LocalTime endTime) {
    318         if (endTime == null) {
    319             throw new IllegalArgumentException("endTime cannot be null");
    320         }
    321         getMetricsLogger().write(new LogMaker(
    322                 MetricsEvent.ACTION_NIGHT_DISPLAY_AUTO_MODE_CUSTOM_TIME_CHANGED)
    323                 .setType(MetricsEvent.TYPE_ACTION)
    324                 .setSubtype(1));
    325         return Secure.putIntForUser(mContext.getContentResolver(),
    326                 Secure.NIGHT_DISPLAY_CUSTOM_END_TIME, endTime.toSecondOfDay() * 1000, mUserId);
    327     }
    328 
    329     /**
    330      * Returns the color temperature (in Kelvin) to tint the display when activated.
    331      */
    332     public int getColorTemperature() {
    333         int colorTemperature = Secure.getIntForUser(mContext.getContentResolver(),
    334                 Secure.NIGHT_DISPLAY_COLOR_TEMPERATURE, -1, mUserId);
    335         if (colorTemperature == -1) {
    336             if (DEBUG) {
    337                 Slog.d(TAG, "Using default value for setting: "
    338                         + Secure.NIGHT_DISPLAY_COLOR_TEMPERATURE);
    339             }
    340             colorTemperature = getDefaultColorTemperature();
    341         }
    342         final int minimumTemperature = getMinimumColorTemperature();
    343         final int maximumTemperature = getMaximumColorTemperature();
    344         if (colorTemperature < minimumTemperature) {
    345             colorTemperature = minimumTemperature;
    346         } else if (colorTemperature > maximumTemperature) {
    347             colorTemperature = maximumTemperature;
    348         }
    349 
    350         return colorTemperature;
    351     }
    352 
    353     /**
    354      * Sets the current temperature.
    355      *
    356      * @param colorTemperature the temperature, in Kelvin.
    357      * @return {@code true} if new temperature was set successfully.
    358      */
    359     public boolean setColorTemperature(int colorTemperature) {
    360         return Secure.putIntForUser(mContext.getContentResolver(),
    361                 Secure.NIGHT_DISPLAY_COLOR_TEMPERATURE, colorTemperature, mUserId);
    362     }
    363 
    364     /**
    365      * Get the current color mode from system properties, or return -1.
    366      *
    367      * See com.android.server.display.DisplayTransformManager.
    368      */
    369     private @ColorMode int getCurrentColorModeFromSystemProperties() {
    370         final int displayColorSetting = SystemProperties.getInt("persist.sys.sf.native_mode", 0);
    371         if (displayColorSetting == 0) {
    372             return "1.0".equals(SystemProperties.get("persist.sys.sf.color_saturation"))
    373                     ? COLOR_MODE_NATURAL : COLOR_MODE_BOOSTED;
    374         } else if (displayColorSetting == 1) {
    375             return COLOR_MODE_SATURATED;
    376         } else if (displayColorSetting == 2) {
    377             return COLOR_MODE_AUTOMATIC;
    378         } else {
    379             return -1;
    380         }
    381     }
    382 
    383     private boolean isColorModeAvailable(@ColorMode int colorMode) {
    384         final int[] availableColorModes = mContext.getResources().getIntArray(
    385                 R.array.config_availableColorModes);
    386         if (availableColorModes != null) {
    387             for (int mode : availableColorModes) {
    388                 if (mode == colorMode) {
    389                     return true;
    390                 }
    391             }
    392         }
    393         return false;
    394     }
    395 
    396     /**
    397      * Get the current color mode.
    398      */
    399     public int getColorMode() {
    400         if (getAccessibilityTransformActivated()) {
    401             if (isColorModeAvailable(COLOR_MODE_SATURATED)) {
    402                 return COLOR_MODE_SATURATED;
    403             } else if (isColorModeAvailable(COLOR_MODE_AUTOMATIC)) {
    404                 return COLOR_MODE_AUTOMATIC;
    405             }
    406         }
    407 
    408         int colorMode = System.getIntForUser(mContext.getContentResolver(),
    409                 System.DISPLAY_COLOR_MODE, -1, mUserId);
    410         if (colorMode == -1) {
    411             // There might be a system property controlling color mode that we need to respect; if
    412             // not, this will set a suitable default.
    413             colorMode = getCurrentColorModeFromSystemProperties();
    414         }
    415 
    416         // This happens when a color mode is no longer available (e.g., after system update or B&R)
    417         // or the device does not support any color mode.
    418         if (!isColorModeAvailable(colorMode)) {
    419             if (colorMode == COLOR_MODE_BOOSTED && isColorModeAvailable(COLOR_MODE_NATURAL)) {
    420                 colorMode = COLOR_MODE_NATURAL;
    421             } else if (colorMode == COLOR_MODE_SATURATED
    422                     && isColorModeAvailable(COLOR_MODE_AUTOMATIC)) {
    423                 colorMode = COLOR_MODE_AUTOMATIC;
    424             } else if (colorMode == COLOR_MODE_AUTOMATIC
    425                     && isColorModeAvailable(COLOR_MODE_SATURATED)) {
    426                 colorMode = COLOR_MODE_SATURATED;
    427             } else {
    428                 colorMode = -1;
    429             }
    430         }
    431 
    432         return colorMode;
    433     }
    434 
    435     /**
    436      * Set the current color mode.
    437      *
    438      * @param colorMode the color mode
    439      */
    440     public void setColorMode(@ColorMode int colorMode) {
    441         if (!isColorModeAvailable(colorMode)) {
    442             throw new IllegalArgumentException("Invalid colorMode: " + colorMode);
    443         }
    444         System.putIntForUser(mContext.getContentResolver(), System.DISPLAY_COLOR_MODE, colorMode,
    445                 mUserId);
    446     }
    447 
    448     /**
    449      * Returns the minimum allowed color temperature (in Kelvin) to tint the display when activated.
    450      */
    451     public int getMinimumColorTemperature() {
    452         return mContext.getResources().getInteger(
    453                 R.integer.config_nightDisplayColorTemperatureMin);
    454     }
    455 
    456     /**
    457      * Returns the maximum allowed color temperature (in Kelvin) to tint the display when activated.
    458      */
    459     public int getMaximumColorTemperature() {
    460         return mContext.getResources().getInteger(
    461                 R.integer.config_nightDisplayColorTemperatureMax);
    462     }
    463 
    464     /**
    465      * Returns the default color temperature (in Kelvin) to tint the display when activated.
    466      */
    467     public int getDefaultColorTemperature() {
    468         return mContext.getResources().getInteger(
    469                 R.integer.config_nightDisplayColorTemperatureDefault);
    470     }
    471 
    472     /**
    473      * Returns true if any Accessibility color transforms are enabled.
    474      */
    475     public boolean getAccessibilityTransformActivated() {
    476         final ContentResolver cr = mContext.getContentResolver();
    477         return
    478             Secure.getIntForUser(cr, Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED,
    479                     0, mUserId) == 1
    480             || Secure.getIntForUser(cr, Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED,
    481                     0, mUserId) == 1;
    482     }
    483 
    484     private void onSettingChanged(@NonNull String setting) {
    485         if (DEBUG) {
    486             Slog.d(TAG, "onSettingChanged: " + setting);
    487         }
    488 
    489         if (mCallback != null) {
    490             switch (setting) {
    491                 case Secure.NIGHT_DISPLAY_ACTIVATED:
    492                     mCallback.onActivated(isActivated());
    493                     break;
    494                 case Secure.NIGHT_DISPLAY_AUTO_MODE:
    495                     mCallback.onAutoModeChanged(getAutoMode());
    496                     break;
    497                 case Secure.NIGHT_DISPLAY_CUSTOM_START_TIME:
    498                     mCallback.onCustomStartTimeChanged(getCustomStartTime());
    499                     break;
    500                 case Secure.NIGHT_DISPLAY_CUSTOM_END_TIME:
    501                     mCallback.onCustomEndTimeChanged(getCustomEndTime());
    502                     break;
    503                 case Secure.NIGHT_DISPLAY_COLOR_TEMPERATURE:
    504                     mCallback.onColorTemperatureChanged(getColorTemperature());
    505                     break;
    506                 case System.DISPLAY_COLOR_MODE:
    507                     mCallback.onDisplayColorModeChanged(getColorMode());
    508                     break;
    509                 case Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED:
    510                 case Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED:
    511                     mCallback.onAccessibilityTransformChanged(getAccessibilityTransformActivated());
    512                     break;
    513             }
    514         }
    515     }
    516 
    517     /**
    518      * Register a callback to be invoked whenever the Night display settings are changed.
    519      */
    520     public void setListener(Callback callback) {
    521         final Callback oldCallback = mCallback;
    522         if (oldCallback != callback) {
    523             mCallback = callback;
    524 
    525             if (callback == null) {
    526                 // Stop listening for changes now that there IS NOT a listener.
    527                 mContext.getContentResolver().unregisterContentObserver(mContentObserver);
    528             } else if (oldCallback == null) {
    529                 // Start listening for changes now that there IS a listener.
    530                 final ContentResolver cr = mContext.getContentResolver();
    531                 cr.registerContentObserver(Secure.getUriFor(Secure.NIGHT_DISPLAY_ACTIVATED),
    532                         false /* notifyForDescendants */, mContentObserver, mUserId);
    533                 cr.registerContentObserver(Secure.getUriFor(Secure.NIGHT_DISPLAY_AUTO_MODE),
    534                         false /* notifyForDescendants */, mContentObserver, mUserId);
    535                 cr.registerContentObserver(Secure.getUriFor(Secure.NIGHT_DISPLAY_CUSTOM_START_TIME),
    536                         false /* notifyForDescendants */, mContentObserver, mUserId);
    537                 cr.registerContentObserver(Secure.getUriFor(Secure.NIGHT_DISPLAY_CUSTOM_END_TIME),
    538                         false /* notifyForDescendants */, mContentObserver, mUserId);
    539                 cr.registerContentObserver(Secure.getUriFor(Secure.NIGHT_DISPLAY_COLOR_TEMPERATURE),
    540                         false /* notifyForDescendants */, mContentObserver, mUserId);
    541                 cr.registerContentObserver(System.getUriFor(System.DISPLAY_COLOR_MODE),
    542                         false /* notifyForDecendants */, mContentObserver, mUserId);
    543                 cr.registerContentObserver(
    544                         Secure.getUriFor(Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED),
    545                         false /* notifyForDecendants */, mContentObserver, mUserId);
    546                 cr.registerContentObserver(
    547                         Secure.getUriFor(Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED),
    548                         false /* notifyForDecendants */, mContentObserver, mUserId);
    549             }
    550         }
    551     }
    552 
    553     private MetricsLogger getMetricsLogger() {
    554         if (mMetricsLogger == null) {
    555             mMetricsLogger = new MetricsLogger();
    556         }
    557         return mMetricsLogger;
    558     }
    559 
    560     /**
    561      * Returns {@code true} if Night display is supported by the device.
    562      */
    563     public static boolean isAvailable(Context context) {
    564         return context.getResources().getBoolean(R.bool.config_nightDisplayAvailable);
    565     }
    566 
    567     /**
    568      * Callback invoked whenever the Night display settings are changed.
    569      */
    570     public interface Callback {
    571         /**
    572          * Callback invoked when the activated state changes.
    573          *
    574          * @param activated {@code true} if Night display is activated
    575          */
    576         default void onActivated(boolean activated) {}
    577         /**
    578          * Callback invoked when the auto mode changes.
    579          *
    580          * @param autoMode the auto mode to use
    581          */
    582         default void onAutoModeChanged(int autoMode) {}
    583         /**
    584          * Callback invoked when the time to automatically activate Night display changes.
    585          *
    586          * @param startTime the local time to automatically activate Night display
    587          */
    588         default void onCustomStartTimeChanged(LocalTime startTime) {}
    589         /**
    590          * Callback invoked when the time to automatically deactivate Night display changes.
    591          *
    592          * @param endTime the local time to automatically deactivate Night display
    593          */
    594         default void onCustomEndTimeChanged(LocalTime endTime) {}
    595 
    596         /**
    597          * Callback invoked when the color temperature changes.
    598          *
    599          * @param colorTemperature the color temperature to tint the screen
    600          */
    601         default void onColorTemperatureChanged(int colorTemperature) {}
    602 
    603         /**
    604          * Callback invoked when the color mode changes.
    605          *
    606          * @param displayColorMode the color mode
    607          */
    608         default void onDisplayColorModeChanged(int displayColorMode) {}
    609 
    610         /**
    611          * Callback invoked when Accessibility color transforms change.
    612          *
    613          * @param state the state Accessibility color transforms (true of active)
    614          */
    615         default void onAccessibilityTransformChanged(boolean state) {}
    616     }
    617 }
    618