1 /* 2 * Copyright (C) 2019 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.server.display.whitebalance; 18 19 import android.annotation.NonNull; 20 import android.util.Slog; 21 import android.util.Spline; 22 23 import com.android.internal.annotations.VisibleForTesting; 24 import com.android.server.LocalServices; 25 import com.android.server.display.color.ColorDisplayService.ColorDisplayServiceInternal; 26 import com.android.server.display.utils.AmbientFilter; 27 import com.android.server.display.utils.History; 28 29 import java.io.PrintWriter; 30 import java.util.Objects; 31 32 /** 33 * The DisplayWhiteBalanceController drives display white-balance (automatically correcting the 34 * display color temperature depending on the ambient color temperature). 35 * 36 * The DisplayWhiteBalanceController: 37 * - Uses the AmbientColorTemperatureSensor to detect changes in the ambient color temperature; 38 * - Uses the AmbientColorTemperatureFilter to average these changes over time, filter out the 39 * noise, and arrive at an estimate of the actual ambient color temperature; 40 * - Uses the DisplayWhiteBalanceThrottler to decide whether the display color tempearture should 41 * be updated, suppressing changes that are too frequent or too minor. 42 */ 43 public class DisplayWhiteBalanceController implements 44 AmbientSensor.AmbientBrightnessSensor.Callbacks, 45 AmbientSensor.AmbientColorTemperatureSensor.Callbacks { 46 47 private static final String TAG = "DisplayWhiteBalanceController"; 48 private boolean mLoggingEnabled; 49 50 private final ColorDisplayServiceInternal mColorDisplayServiceInternal; 51 52 private final AmbientSensor.AmbientBrightnessSensor mBrightnessSensor; 53 @VisibleForTesting 54 AmbientFilter mBrightnessFilter; 55 private final AmbientSensor.AmbientColorTemperatureSensor mColorTemperatureSensor; 56 @VisibleForTesting 57 AmbientFilter mColorTemperatureFilter; 58 private final DisplayWhiteBalanceThrottler mThrottler; 59 // In low brightness conditions the ALS readings are more noisy and produce 60 // high errors. This default is introduced to provide a fixed display color 61 // temperature when sensor readings become unreliable. 62 private final float mLowLightAmbientColorTemperature; 63 // In high brightness conditions certain color temperatures can cause peak display 64 // brightness to drop. This fixed color temperature can be used to compensate for 65 // this effect. 66 private final float mHighLightAmbientColorTemperature; 67 68 private final boolean mLightModeAllowed; 69 70 private float mAmbientColorTemperature; 71 @VisibleForTesting 72 float mPendingAmbientColorTemperature; 73 private float mLastAmbientColorTemperature; 74 75 // The most recent ambient color temperature values are kept for debugging purposes. 76 private final History mAmbientColorTemperatureHistory; 77 78 // Override the ambient color temperature for debugging purposes. 79 private float mAmbientColorTemperatureOverride; 80 81 // A piecewise linear relationship between ambient and display color temperatures. 82 private Spline.LinearSpline mAmbientToDisplayColorTemperatureSpline; 83 84 // A piecewise linear relationship between ambient and display color temperatures, with a 85 // stronger change between the two sets of values. 86 private Spline.LinearSpline mStrongAmbientToDisplayColorTemperatureSpline; 87 88 // In very low or very high brightness conditions Display White Balance should 89 // be to set to a default instead of using mAmbientToDisplayColorTemperatureSpline. 90 // However, setting Display White Balance based on thresholds can cause the 91 // display to rapidly change color temperature. To solve this, 92 // mLowLightAmbientBrightnessToBiasSpline and 93 // mHighLightAmbientBrightnessToBiasSpline are used to smoothly interpolate from 94 // ambient color temperature to the defaults. A piecewise linear relationship 95 // between low light brightness and low light bias. 96 private Spline.LinearSpline mLowLightAmbientBrightnessToBiasSpline; 97 98 // A piecewise linear relationship between high light brightness and high light bias. 99 private Spline.LinearSpline mHighLightAmbientBrightnessToBiasSpline; 100 101 private float mLatestAmbientColorTemperature; 102 private float mLatestAmbientBrightness; 103 private float mLatestLowLightBias; 104 private float mLatestHighLightBias; 105 106 private boolean mEnabled; 107 108 // Whether a higher-strength adjustment should be applied; this must be enabled in addition to 109 // mEnabled in order to be applied. 110 private boolean mStrongModeEnabled; 111 112 // To decouple the DisplayPowerController from the DisplayWhiteBalanceController, the DPC 113 // implements Callbacks and passes itself to the DWBC so it can call back into it without 114 // knowing about it. 115 private Callbacks mDisplayPowerControllerCallbacks; 116 117 /** 118 * @param brightnessSensor 119 * The sensor used to detect changes in the ambient brightness. 120 * @param brightnessFilter 121 * The filter used to avergae ambient brightness changes over time, filter out the noise 122 * and arrive at an estimate of the actual ambient brightness. 123 * @param colorTemperatureSensor 124 * The sensor used to detect changes in the ambient color temperature. 125 * @param colorTemperatureFilter 126 * The filter used to average ambient color temperature changes over time, filter out the 127 * noise and arrive at an estimate of the actual ambient color temperature. 128 * @param throttler 129 * The throttler used to determine whether the new display color temperature should be 130 * updated or not. 131 * @param lowLightAmbientBrightnesses 132 * The ambient brightness used to map the ambient brightnesses to the biases used to 133 * interpolate to lowLightAmbientColorTemperature. 134 * @param lowLightAmbientBiases 135 * The biases used to map the ambient brightnesses to the biases used to interpolate to 136 * lowLightAmbientColorTemperature. 137 * @param lowLightAmbientColorTemperature 138 * The ambient color temperature to which we interpolate to based on the low light curve. 139 * @param highLightAmbientBrightnesses 140 * The ambient brightness used to map the ambient brightnesses to the biases used to 141 * interpolate to highLightAmbientColorTemperature. 142 * @param highLightAmbientBiases 143 * The biases used to map the ambient brightnesses to the biases used to interpolate to 144 * highLightAmbientColorTemperature. 145 * @param highLightAmbientColorTemperature 146 * The ambient color temperature to which we interpolate to based on the high light curve. 147 * @param ambientColorTemperatures 148 * The ambient color tempeartures used to map the ambient color temperature to the display 149 * color temperature (or null if no mapping is necessary). 150 * @param displayColorTemperatures 151 * The display color temperatures used to map the ambient color temperature to the display 152 * color temperature (or null if no mapping is necessary). 153 * @param lightModeAllowed 154 * Whether a lighter version should be applied when Strong Mode is not enabled. 155 * 156 * @throws NullPointerException 157 * - brightnessSensor is null; 158 * - brightnessFilter is null; 159 * - colorTemperatureSensor is null; 160 * - colorTemperatureFilter is null; 161 * - throttler is null. 162 */ DisplayWhiteBalanceController( @onNull AmbientSensor.AmbientBrightnessSensor brightnessSensor, @NonNull AmbientFilter brightnessFilter, @NonNull AmbientSensor.AmbientColorTemperatureSensor colorTemperatureSensor, @NonNull AmbientFilter colorTemperatureFilter, @NonNull DisplayWhiteBalanceThrottler throttler, float[] lowLightAmbientBrightnesses, float[] lowLightAmbientBiases, float lowLightAmbientColorTemperature, float[] highLightAmbientBrightnesses, float[] highLightAmbientBiases, float highLightAmbientColorTemperature, float[] ambientColorTemperatures, float[] displayColorTemperatures, float[] strongAmbientColorTemperatures, float[] strongDisplayColorTemperatures, boolean lightModeAllowed)163 public DisplayWhiteBalanceController( 164 @NonNull AmbientSensor.AmbientBrightnessSensor brightnessSensor, 165 @NonNull AmbientFilter brightnessFilter, 166 @NonNull AmbientSensor.AmbientColorTemperatureSensor colorTemperatureSensor, 167 @NonNull AmbientFilter colorTemperatureFilter, 168 @NonNull DisplayWhiteBalanceThrottler throttler, 169 float[] lowLightAmbientBrightnesses, 170 float[] lowLightAmbientBiases, 171 float lowLightAmbientColorTemperature, 172 float[] highLightAmbientBrightnesses, 173 float[] highLightAmbientBiases, 174 float highLightAmbientColorTemperature, 175 float[] ambientColorTemperatures, 176 float[] displayColorTemperatures, 177 float[] strongAmbientColorTemperatures, 178 float[] strongDisplayColorTemperatures, 179 boolean lightModeAllowed) { 180 validateArguments(brightnessSensor, brightnessFilter, colorTemperatureSensor, 181 colorTemperatureFilter, throttler); 182 mBrightnessSensor = brightnessSensor; 183 mBrightnessFilter = brightnessFilter; 184 mColorTemperatureSensor = colorTemperatureSensor; 185 mColorTemperatureFilter = colorTemperatureFilter; 186 mThrottler = throttler; 187 mLowLightAmbientColorTemperature = lowLightAmbientColorTemperature; 188 mHighLightAmbientColorTemperature = highLightAmbientColorTemperature; 189 mAmbientColorTemperature = -1.0f; 190 mPendingAmbientColorTemperature = -1.0f; 191 mLastAmbientColorTemperature = -1.0f; 192 mAmbientColorTemperatureHistory = new History(/* size= */ 50); 193 mAmbientColorTemperatureOverride = -1.0f; 194 mLightModeAllowed = lightModeAllowed; 195 196 try { 197 mLowLightAmbientBrightnessToBiasSpline = new Spline.LinearSpline( 198 lowLightAmbientBrightnesses, lowLightAmbientBiases); 199 } catch (Exception e) { 200 Slog.e(TAG, "failed to create low light ambient brightness to bias spline.", e); 201 mLowLightAmbientBrightnessToBiasSpline = null; 202 } 203 if (mLowLightAmbientBrightnessToBiasSpline != null) { 204 if (mLowLightAmbientBrightnessToBiasSpline.interpolate(0.0f) != 0.0f || 205 mLowLightAmbientBrightnessToBiasSpline.interpolate(Float.POSITIVE_INFINITY) 206 != 1.0f) { 207 Slog.d(TAG, "invalid low light ambient brightness to bias spline, " 208 + "bias must begin at 0.0 and end at 1.0."); 209 mLowLightAmbientBrightnessToBiasSpline = null; 210 } 211 } 212 213 try { 214 mHighLightAmbientBrightnessToBiasSpline = new Spline.LinearSpline( 215 highLightAmbientBrightnesses, highLightAmbientBiases); 216 } catch (Exception e) { 217 Slog.e(TAG, "failed to create high light ambient brightness to bias spline.", e); 218 mHighLightAmbientBrightnessToBiasSpline = null; 219 } 220 if (mHighLightAmbientBrightnessToBiasSpline != null) { 221 if (mHighLightAmbientBrightnessToBiasSpline.interpolate(0.0f) != 0.0f || 222 mHighLightAmbientBrightnessToBiasSpline.interpolate(Float.POSITIVE_INFINITY) 223 != 1.0f) { 224 Slog.d(TAG, "invalid high light ambient brightness to bias spline, " 225 + "bias must begin at 0.0 and end at 1.0."); 226 mHighLightAmbientBrightnessToBiasSpline = null; 227 } 228 } 229 230 if (mLowLightAmbientBrightnessToBiasSpline != null && 231 mHighLightAmbientBrightnessToBiasSpline != null) { 232 if (lowLightAmbientBrightnesses[lowLightAmbientBrightnesses.length - 1] > 233 highLightAmbientBrightnesses[0]) { 234 Slog.d(TAG, "invalid low light and high light ambient brightness to bias spline " 235 + "combination, defined domains must not intersect."); 236 mLowLightAmbientBrightnessToBiasSpline = null; 237 mHighLightAmbientBrightnessToBiasSpline = null; 238 } 239 } 240 241 try { 242 mAmbientToDisplayColorTemperatureSpline = new Spline.LinearSpline( 243 ambientColorTemperatures, displayColorTemperatures); 244 } catch (Exception e) { 245 Slog.e(TAG, "failed to create ambient to display color temperature spline.", e); 246 mAmbientToDisplayColorTemperatureSpline = null; 247 } 248 249 try { 250 mStrongAmbientToDisplayColorTemperatureSpline = new Spline.LinearSpline( 251 strongAmbientColorTemperatures, strongDisplayColorTemperatures); 252 } catch (Exception e) { 253 Slog.e(TAG, "Failed to create strong ambient to display color temperature spline", e); 254 } 255 256 mColorDisplayServiceInternal = LocalServices.getService(ColorDisplayServiceInternal.class); 257 } 258 259 /** 260 * Enable/disable the controller. 261 * 262 * @param enabled 263 * Whether the controller should be on/off. 264 * 265 * @return Whether the method succeeded or not. 266 */ setEnabled(boolean enabled)267 public boolean setEnabled(boolean enabled) { 268 if (enabled) { 269 return enable(); 270 } else { 271 return disable(); 272 } 273 } 274 275 /** 276 * Enable/disable the stronger adjustment option. 277 * 278 * @param enabled whether the stronger adjustment option should be turned on 279 */ setStrongModeEnabled(boolean enabled)280 public void setStrongModeEnabled(boolean enabled) { 281 mStrongModeEnabled = enabled; 282 mColorDisplayServiceInternal.setDisplayWhiteBalanceAllowed(mLightModeAllowed 283 || mStrongModeEnabled); 284 if (mEnabled) { 285 updateAmbientColorTemperature(); 286 updateDisplayColorTemperature(); 287 } 288 } 289 290 /** 291 * Set an object to call back to when the display color temperature should be updated. 292 * 293 * @param callbacks 294 * The object to call back to. 295 * 296 * @return Whether the method succeeded or not. 297 */ setCallbacks(Callbacks callbacks)298 public boolean setCallbacks(Callbacks callbacks) { 299 if (mDisplayPowerControllerCallbacks == callbacks) { 300 return false; 301 } 302 mDisplayPowerControllerCallbacks = callbacks; 303 return true; 304 } 305 306 /** 307 * Enable/disable logging. 308 * 309 * @param loggingEnabled 310 * Whether logging should be on/off. 311 * 312 * @return Whether the method succeeded or not. 313 */ setLoggingEnabled(boolean loggingEnabled)314 public boolean setLoggingEnabled(boolean loggingEnabled) { 315 if (mLoggingEnabled == loggingEnabled) { 316 return false; 317 } 318 mLoggingEnabled = loggingEnabled; 319 mBrightnessSensor.setLoggingEnabled(loggingEnabled); 320 mBrightnessFilter.setLoggingEnabled(loggingEnabled); 321 mColorTemperatureSensor.setLoggingEnabled(loggingEnabled); 322 mColorTemperatureFilter.setLoggingEnabled(loggingEnabled); 323 mThrottler.setLoggingEnabled(loggingEnabled); 324 return true; 325 } 326 327 /** 328 * Set the ambient color temperature override. 329 * 330 * This is only applied when the ambient color temperature changes or is updated (in which case 331 * it overrides the ambient color temperature estimate); in other words, it doesn't necessarily 332 * change the display color temperature immediately. 333 * 334 * @param ambientColorTemperatureOverride 335 * The ambient color temperature override. 336 * 337 * @return Whether the method succeeded or not. 338 */ setAmbientColorTemperatureOverride(float ambientColorTemperatureOverride)339 public boolean setAmbientColorTemperatureOverride(float ambientColorTemperatureOverride) { 340 if (mAmbientColorTemperatureOverride == ambientColorTemperatureOverride) { 341 return false; 342 } 343 mAmbientColorTemperatureOverride = ambientColorTemperatureOverride; 344 return true; 345 } 346 347 /** 348 * Dump the state. 349 * 350 * @param writer 351 * The writer used to dump the state. 352 */ dump(PrintWriter writer)353 public void dump(PrintWriter writer) { 354 writer.println("DisplayWhiteBalanceController"); 355 writer.println(" mLoggingEnabled=" + mLoggingEnabled); 356 writer.println(" mEnabled=" + mEnabled); 357 writer.println(" mStrongModeEnabled=" + mStrongModeEnabled); 358 writer.println(" mDisplayPowerControllerCallbacks=" + mDisplayPowerControllerCallbacks); 359 mBrightnessSensor.dump(writer); 360 mBrightnessFilter.dump(writer); 361 mColorTemperatureSensor.dump(writer); 362 mColorTemperatureFilter.dump(writer); 363 mThrottler.dump(writer); 364 writer.println(" mLowLightAmbientColorTemperature=" + mLowLightAmbientColorTemperature); 365 writer.println(" mHighLightAmbientColorTemperature=" + mHighLightAmbientColorTemperature); 366 writer.println(" mAmbientColorTemperature=" + mAmbientColorTemperature); 367 writer.println(" mPendingAmbientColorTemperature=" + mPendingAmbientColorTemperature); 368 writer.println(" mLastAmbientColorTemperature=" + mLastAmbientColorTemperature); 369 writer.println(" mAmbientColorTemperatureHistory=" + mAmbientColorTemperatureHistory); 370 writer.println(" mAmbientColorTemperatureOverride=" + mAmbientColorTemperatureOverride); 371 writer.println(" mAmbientToDisplayColorTemperatureSpline=" 372 + mAmbientToDisplayColorTemperatureSpline); 373 writer.println(" mStrongAmbientToDisplayColorTemperatureSpline=" 374 + mStrongAmbientToDisplayColorTemperatureSpline); 375 writer.println(" mLowLightAmbientBrightnessToBiasSpline=" 376 + mLowLightAmbientBrightnessToBiasSpline); 377 writer.println(" mHighLightAmbientBrightnessToBiasSpline=" 378 + mHighLightAmbientBrightnessToBiasSpline); 379 } 380 381 @Override // AmbientSensor.AmbientBrightnessSensor.Callbacks onAmbientBrightnessChanged(float value)382 public void onAmbientBrightnessChanged(float value) { 383 final long time = System.currentTimeMillis(); 384 mBrightnessFilter.addValue(time, value); 385 updateAmbientColorTemperature(); 386 } 387 388 @Override // AmbientSensor.AmbientColorTemperatureSensor.Callbacks onAmbientColorTemperatureChanged(float value)389 public void onAmbientColorTemperatureChanged(float value) { 390 final long time = System.currentTimeMillis(); 391 mColorTemperatureFilter.addValue(time, value); 392 updateAmbientColorTemperature(); 393 } 394 395 /** 396 * Updates the ambient color temperature. 397 */ updateAmbientColorTemperature()398 public void updateAmbientColorTemperature() { 399 final long time = System.currentTimeMillis(); 400 float ambientColorTemperature = mColorTemperatureFilter.getEstimate(time); 401 mLatestAmbientColorTemperature = ambientColorTemperature; 402 403 if (mStrongModeEnabled) { 404 if (mStrongAmbientToDisplayColorTemperatureSpline != null 405 && ambientColorTemperature != -1.0f) { 406 ambientColorTemperature = 407 mStrongAmbientToDisplayColorTemperatureSpline.interpolate( 408 ambientColorTemperature); 409 } 410 } else { 411 if (mAmbientToDisplayColorTemperatureSpline != null 412 && ambientColorTemperature != -1.0f) { 413 ambientColorTemperature = 414 mAmbientToDisplayColorTemperatureSpline.interpolate( 415 ambientColorTemperature); 416 } 417 } 418 419 float ambientBrightness = mBrightnessFilter.getEstimate(time); 420 mLatestAmbientBrightness = ambientBrightness; 421 422 if (ambientColorTemperature != -1.0f && ambientBrightness != -1.0f 423 && mLowLightAmbientBrightnessToBiasSpline != null) { 424 float bias = mLowLightAmbientBrightnessToBiasSpline.interpolate(ambientBrightness); 425 ambientColorTemperature = 426 bias * ambientColorTemperature + (1.0f - bias) 427 * mLowLightAmbientColorTemperature; 428 mLatestLowLightBias = bias; 429 } 430 if (ambientColorTemperature != -1.0f && ambientBrightness != -1.0f 431 && mHighLightAmbientBrightnessToBiasSpline != null) { 432 float bias = mHighLightAmbientBrightnessToBiasSpline.interpolate(ambientBrightness); 433 ambientColorTemperature = 434 (1.0f - bias) * ambientColorTemperature + bias 435 * mHighLightAmbientColorTemperature; 436 mLatestHighLightBias = bias; 437 } 438 439 if (mAmbientColorTemperatureOverride != -1.0f) { 440 if (mLoggingEnabled) { 441 Slog.d(TAG, "override ambient color temperature: " + ambientColorTemperature 442 + " => " + mAmbientColorTemperatureOverride); 443 } 444 ambientColorTemperature = mAmbientColorTemperatureOverride; 445 } 446 447 // When the display color temperature needs to be updated, we call DisplayPowerController to 448 // call our updateColorTemperature. The reason we don't call it directly is that we want 449 // all changes to the system to happen in a predictable order in DPC's main loop 450 // (updatePowerState). 451 if (ambientColorTemperature == -1.0f || mThrottler.throttle(ambientColorTemperature)) { 452 return; 453 } 454 455 if (mLoggingEnabled) { 456 Slog.d(TAG, "pending ambient color temperature: " + ambientColorTemperature); 457 } 458 mPendingAmbientColorTemperature = ambientColorTemperature; 459 if (mDisplayPowerControllerCallbacks != null) { 460 mDisplayPowerControllerCallbacks.updateWhiteBalance(); 461 } 462 } 463 464 /** 465 * Updates the display color temperature. 466 */ updateDisplayColorTemperature()467 public void updateDisplayColorTemperature() { 468 float ambientColorTemperature = -1.0f; 469 470 // If both the pending and the current ambient color temperatures are -1, it means the DWBC 471 // was just enabled, and we use the last ambient color temperature until new sensor events 472 // give us a better estimate. 473 if (mAmbientColorTemperature == -1.0f && mPendingAmbientColorTemperature == -1.0f) { 474 ambientColorTemperature = mLastAmbientColorTemperature; 475 } 476 477 // Otherwise, we use the pending ambient color temperature, but only if it's non-trivial 478 // and different than the current one. 479 if (mPendingAmbientColorTemperature != -1.0f 480 && mPendingAmbientColorTemperature != mAmbientColorTemperature) { 481 ambientColorTemperature = mPendingAmbientColorTemperature; 482 } 483 484 if (ambientColorTemperature == -1.0f) { 485 return; 486 } 487 488 mAmbientColorTemperature = ambientColorTemperature; 489 if (mLoggingEnabled) { 490 Slog.d(TAG, "ambient color temperature: " + mAmbientColorTemperature); 491 } 492 mPendingAmbientColorTemperature = -1.0f; 493 mAmbientColorTemperatureHistory.add(mAmbientColorTemperature); 494 Slog.d(TAG, "Display cct: " + mAmbientColorTemperature 495 + " Latest ambient cct: " + mLatestAmbientColorTemperature 496 + " Latest ambient lux: " + mLatestAmbientBrightness 497 + " Latest low light bias: " + mLatestLowLightBias 498 + " Latest high light bias: " + mLatestHighLightBias); 499 mColorDisplayServiceInternal.setDisplayWhiteBalanceColorTemperature( 500 (int) mAmbientColorTemperature); 501 mLastAmbientColorTemperature = mAmbientColorTemperature; 502 } 503 504 /** 505 * Calculate the adjusted brightness, in nits, due to the DWB color adaptation 506 * 507 * @param requestedBrightnessNits brightness the framework requires to be output 508 * @return the adjusted brightness the framework needs to output to counter the drop in 509 * brightness due to DWB, or the requestedBrightnessNits if an adjustment cannot be made 510 */ calculateAdjustedBrightnessNits(float requestedBrightnessNits)511 public float calculateAdjustedBrightnessNits(float requestedBrightnessNits) { 512 float luminance = mColorDisplayServiceInternal.getDisplayWhiteBalanceLuminance(); 513 if (luminance == -1) { 514 return requestedBrightnessNits; 515 } 516 float effectiveBrightness = requestedBrightnessNits * luminance; 517 return (requestedBrightnessNits - effectiveBrightness) + requestedBrightnessNits; 518 } 519 520 /** 521 * The DisplayWhiteBalanceController decouples itself from its parent (DisplayPowerController) 522 * by providing this interface to implement (and a method to set its callbacks object), and 523 * calling these methods. 524 */ 525 public interface Callbacks { 526 527 /** 528 * Called whenever the display white-balance state has changed. 529 * 530 * Usually, this means the estimated ambient color temperature has changed enough, and the 531 * display color temperature should be updated; but it is also called if settings change. 532 */ updateWhiteBalance()533 void updateWhiteBalance(); 534 } 535 validateArguments(AmbientSensor.AmbientBrightnessSensor brightnessSensor, AmbientFilter brightnessFilter, AmbientSensor.AmbientColorTemperatureSensor colorTemperatureSensor, AmbientFilter colorTemperatureFilter, DisplayWhiteBalanceThrottler throttler)536 private void validateArguments(AmbientSensor.AmbientBrightnessSensor brightnessSensor, 537 AmbientFilter brightnessFilter, 538 AmbientSensor.AmbientColorTemperatureSensor colorTemperatureSensor, 539 AmbientFilter colorTemperatureFilter, 540 DisplayWhiteBalanceThrottler throttler) { 541 Objects.requireNonNull(brightnessSensor, "brightnessSensor must not be null"); 542 Objects.requireNonNull(brightnessFilter, "brightnessFilter must not be null"); 543 Objects.requireNonNull(colorTemperatureSensor, 544 "colorTemperatureSensor must not be null"); 545 Objects.requireNonNull(colorTemperatureFilter, 546 "colorTemperatureFilter must not be null"); 547 Objects.requireNonNull(throttler, "throttler cannot be null"); 548 } 549 enable()550 private boolean enable() { 551 if (mEnabled) { 552 return false; 553 } 554 if (mLoggingEnabled) { 555 Slog.d(TAG, "enabling"); 556 } 557 mEnabled = true; 558 mBrightnessSensor.setEnabled(true); 559 mColorTemperatureSensor.setEnabled(true); 560 return true; 561 } 562 disable()563 private boolean disable() { 564 if (!mEnabled) { 565 return false; 566 } 567 if (mLoggingEnabled) { 568 Slog.d(TAG, "disabling"); 569 } 570 mEnabled = false; 571 mBrightnessSensor.setEnabled(false); 572 mBrightnessFilter.clear(); 573 mColorTemperatureSensor.setEnabled(false); 574 mColorTemperatureFilter.clear(); 575 mThrottler.clear(); 576 mAmbientColorTemperature = -1.0f; 577 mPendingAmbientColorTemperature = -1.0f; 578 mColorDisplayServiceInternal.resetDisplayWhiteBalanceColorTemperature(); 579 return true; 580 } 581 582 } 583