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 ColorDisplayController(@onNull Context context)120 public ColorDisplayController(@NonNull Context context) { 121 this(context, ActivityManager.getCurrentUser()); 122 } 123 ColorDisplayController(@onNull Context context, int userId)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 */ isActivated()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 */ setActivated(boolean activated)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 */ getLastActivatedTime()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 */ getAutoMode()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 */ getAutoModeRaw()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 */ setAutoMode(@utoMode int autoMode)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 */ getCustomStartTime()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 */ setCustomStartTime(@onNull LocalTime startTime)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 */ getCustomEndTime()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 */ setCustomEndTime(@onNull LocalTime endTime)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 */ getColorTemperature()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 */ setColorTemperature(int colorTemperature)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 */ getCurrentColorModeFromSystemProperties()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 isColorModeAvailable(@olorMode int colorMode)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 */ getColorMode()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 */ setColorMode(@olorMode int colorMode)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 */ getMinimumColorTemperature()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 */ getMaximumColorTemperature()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 */ getDefaultColorTemperature()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 */ getAccessibilityTransformActivated()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 onSettingChanged(@onNull String setting)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 */ setListener(Callback callback)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 getMetricsLogger()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 */ isAvailable(Context context)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 */ onActivated(boolean activated)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 */ onAutoModeChanged(int autoMode)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 */ onCustomStartTimeChanged(LocalTime startTime)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 */ onCustomEndTimeChanged(LocalTime endTime)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 */ onColorTemperatureChanged(int colorTemperature)601 default void onColorTemperatureChanged(int colorTemperature) {} 602 603 /** 604 * Callback invoked when the color mode changes. 605 * 606 * @param displayColorMode the color mode 607 */ onDisplayColorModeChanged(int displayColorMode)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 */ onAccessibilityTransformChanged(boolean state)615 default void onAccessibilityTransformChanged(boolean state) {} 616 } 617 } 618