blob: 7b1f4c3222f3f268516c64c63b93686d1b64b94c [file] [log] [blame]
Dan Gittik8dbd7e92018-12-03 15:35:53 +00001/*
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
17package com.android.server.display.whitebalance;
18
19import android.annotation.NonNull;
20import android.util.Slog;
Daniel Solomonfb393e52019-02-08 20:26:27 -080021import android.util.Spline;
Dan Gittik8dbd7e92018-12-03 15:35:53 +000022
Anthony Han04c78a92019-05-03 13:34:57 -070023import com.android.internal.annotations.VisibleForTesting;
Dan Gittik8dbd7e92018-12-03 15:35:53 +000024import com.android.internal.util.Preconditions;
25import com.android.server.LocalServices;
Christine Franks0ada2772019-02-25 13:54:57 -080026import com.android.server.display.color.ColorDisplayService.ColorDisplayServiceInternal;
Dan Gittik8dbd7e92018-12-03 15:35:53 +000027import com.android.server.display.utils.History;
28
29import java.io.PrintWriter;
30
31/**
32 * The DisplayWhiteBalanceController drives display white-balance (automatically correcting the
Dan Gittik1151ac02019-02-13 14:05:37 +000033 * display color temperature depending on the ambient color temperature).
Dan Gittik8dbd7e92018-12-03 15:35:53 +000034 *
35 * The DisplayWhiteBalanceController:
36 * - Uses the AmbientColorTemperatureSensor to detect changes in the ambient color temperature;
37 * - Uses the AmbientColorTemperatureFilter to average these changes over time, filter out the
38 * noise, and arrive at an estimate of the actual ambient color temperature;
Dan Gittik1151ac02019-02-13 14:05:37 +000039 * - Uses the DisplayWhiteBalanceThrottler to decide whether the display color tempearture should
40 * be updated, suppressing changes that are too frequent or too minor.
Dan Gittik8dbd7e92018-12-03 15:35:53 +000041 */
42public class DisplayWhiteBalanceController implements
43 AmbientSensor.AmbientBrightnessSensor.Callbacks,
44 AmbientSensor.AmbientColorTemperatureSensor.Callbacks {
45
46 protected static final String TAG = "DisplayWhiteBalanceController";
47 protected boolean mLoggingEnabled;
48
49 private boolean mEnabled;
50
51 // To decouple the DisplayPowerController from the DisplayWhiteBalanceController, the DPC
52 // implements Callbacks and passes itself to the DWBC so it can call back into it without
53 // knowing about it.
54 private Callbacks mCallbacks;
55
56 private AmbientSensor.AmbientBrightnessSensor mBrightnessSensor;
Anthony Han04c78a92019-05-03 13:34:57 -070057
58 @VisibleForTesting
59 AmbientFilter mBrightnessFilter;
Dan Gittik8dbd7e92018-12-03 15:35:53 +000060 private AmbientSensor.AmbientColorTemperatureSensor mColorTemperatureSensor;
Anthony Han04c78a92019-05-03 13:34:57 -070061
62 @VisibleForTesting
63 AmbientFilter mColorTemperatureFilter;
Dan Gittik8dbd7e92018-12-03 15:35:53 +000064 private DisplayWhiteBalanceThrottler mThrottler;
65
Dan Gittik8dbd7e92018-12-03 15:35:53 +000066 private final float mLowLightAmbientColorTemperature;
Anthony Han0c8297c2019-06-18 16:56:11 -070067 private final float mHighLightAmbientColorTemperature;
Dan Gittik8dbd7e92018-12-03 15:35:53 +000068
69 private float mAmbientColorTemperature;
Anthony Han04c78a92019-05-03 13:34:57 -070070
71 @VisibleForTesting
72 float mPendingAmbientColorTemperature;
Dan Gittik8dbd7e92018-12-03 15:35:53 +000073 private float mLastAmbientColorTemperature;
74
75 private ColorDisplayServiceInternal mColorDisplayServiceInternal;
76
77 // The most recent ambient color temperature values are kept for debugging purposes.
78 private static final int HISTORY_SIZE = 50;
79 private History mAmbientColorTemperatureHistory;
80
81 // Override the ambient color temperature for debugging purposes.
82 private float mAmbientColorTemperatureOverride;
83
Dan Gittik1151ac02019-02-13 14:05:37 +000084 // A piecewise linear relationship between ambient and display color temperatures.
85 private Spline.LinearSpline mAmbientToDisplayColorTemperatureSpline;
Daniel Solomonfb393e52019-02-08 20:26:27 -080086
Anthony Han0c8297c2019-06-18 16:56:11 -070087 // In very low or very high brightness conditions ambient EQ should to set to a default
88 // instead of using mAmbientToDisplayColorTemperatureSpline. However, setting ambient EQ
89 // based on thresholds can cause the display to rapidly change color temperature. To solve
90 // this, mLowLightAmbientBrightnessToBiasSpline and mHighLightAmbientBrightnessToBiasSpline
91 // are used to smoothly interpolate from ambient color temperature to the defaults.
Anthony Han04c78a92019-05-03 13:34:57 -070092 // A piecewise linear relationship between low light brightness and low light bias.
93 private Spline.LinearSpline mLowLightAmbientBrightnessToBiasSpline;
94
Anthony Han0c8297c2019-06-18 16:56:11 -070095 // A piecewise linear relationship between high light brightness and high light bias.
96 private Spline.LinearSpline mHighLightAmbientBrightnessToBiasSpline;
97
Anthony Han00a490b2019-08-26 14:00:28 -070098 private float mLatestAmbientColorTemperature;
99 private float mLatestAmbientBrightness;
100 private float mLatestLowLightBias;
101 private float mLatestHighLightBias;
102
Dan Gittik8dbd7e92018-12-03 15:35:53 +0000103 /**
104 * @param brightnessSensor
105 * The sensor used to detect changes in the ambient brightness.
106 * @param brightnessFilter
107 * The filter used to avergae ambient brightness changes over time, filter out the noise
108 * and arrive at an estimate of the actual ambient brightness.
109 * @param colorTemperatureSensor
110 * The sensor used to detect changes in the ambient color temperature.
111 * @param colorTemperatureFilter
112 * The filter used to average ambient color temperature changes over time, filter out the
113 * noise and arrive at an estimate of the actual ambient color temperature.
114 * @param throttler
Dan Gittik1151ac02019-02-13 14:05:37 +0000115 * The throttler used to determine whether the new display color temperature should be
Dan Gittik8dbd7e92018-12-03 15:35:53 +0000116 * updated or not.
Anthony Han0c8297c2019-06-18 16:56:11 -0700117 * @param lowLightAmbientBrightnesses
118 * The ambient brightness used to map the ambient brightnesses to the biases used to
119 * interpolate to lowLightAmbientColorTemperature.
120 * @param lowLightAmbientBiases
121 * The biases used to map the ambient brightnesses to the biases used to interpolate to
122 * lowLightAmbientColorTemperature.
Dan Gittik8dbd7e92018-12-03 15:35:53 +0000123 * @param lowLightAmbientColorTemperature
Anthony Han0c8297c2019-06-18 16:56:11 -0700124 * The ambient color temperature to which we interpolate to based on the low light curve.
125 * @param highLightAmbientBrightnesses
126 * The ambient brightness used to map the ambient brightnesses to the biases used to
127 * interpolate to highLightAmbientColorTemperature.
128 * @param highLightAmbientBiases
129 * The biases used to map the ambient brightnesses to the biases used to interpolate to
130 * highLightAmbientColorTemperature.
131 * @param highLightAmbientColorTemperature
132 * The ambient color temperature to which we interpolate to based on the high light curve.
Dan Gittik1151ac02019-02-13 14:05:37 +0000133 * @param ambientColorTemperatures
134 * The ambient color tempeartures used to map the ambient color temperature to the display
135 * color temperature (or null if no mapping is necessary).
136 * @param displayColorTemperatures
137 * The display color temperatures used to map the ambient color temperature to the display
138 * color temperature (or null if no mapping is necessary).
Dan Gittik8dbd7e92018-12-03 15:35:53 +0000139 *
140 * @throws NullPointerException
141 * - brightnessSensor is null;
142 * - brightnessFilter is null;
143 * - colorTemperatureSensor is null;
144 * - colorTemperatureFilter is null;
145 * - throttler is null.
146 */
147 public DisplayWhiteBalanceController(
148 @NonNull AmbientSensor.AmbientBrightnessSensor brightnessSensor,
149 @NonNull AmbientFilter brightnessFilter,
150 @NonNull AmbientSensor.AmbientColorTemperatureSensor colorTemperatureSensor,
151 @NonNull AmbientFilter colorTemperatureFilter,
152 @NonNull DisplayWhiteBalanceThrottler throttler,
Anthony Han04c78a92019-05-03 13:34:57 -0700153 float[] lowLightAmbientBrightnesses, float[] lowLightAmbientBiases,
154 float lowLightAmbientColorTemperature,
Anthony Han0c8297c2019-06-18 16:56:11 -0700155 float[] highLightAmbientBrightnesses, float[] highLightAmbientBiases,
156 float highLightAmbientColorTemperature,
Dan Gittik1151ac02019-02-13 14:05:37 +0000157 float[] ambientColorTemperatures, float[] displayColorTemperatures) {
Dan Gittik8dbd7e92018-12-03 15:35:53 +0000158 validateArguments(brightnessSensor, brightnessFilter, colorTemperatureSensor,
159 colorTemperatureFilter, throttler);
160 mLoggingEnabled = false;
161 mEnabled = false;
162 mCallbacks = null;
163 mBrightnessSensor = brightnessSensor;
164 mBrightnessFilter = brightnessFilter;
165 mColorTemperatureSensor = colorTemperatureSensor;
166 mColorTemperatureFilter = colorTemperatureFilter;
167 mThrottler = throttler;
Dan Gittik8dbd7e92018-12-03 15:35:53 +0000168 mLowLightAmbientColorTemperature = lowLightAmbientColorTemperature;
Anthony Han0c8297c2019-06-18 16:56:11 -0700169 mHighLightAmbientColorTemperature = highLightAmbientColorTemperature;
Dan Gittik8dbd7e92018-12-03 15:35:53 +0000170 mAmbientColorTemperature = -1.0f;
171 mPendingAmbientColorTemperature = -1.0f;
172 mLastAmbientColorTemperature = -1.0f;
173 mAmbientColorTemperatureHistory = new History(HISTORY_SIZE);
174 mAmbientColorTemperatureOverride = -1.0f;
Daniel Solomonfb393e52019-02-08 20:26:27 -0800175
176 try {
Anthony Han04c78a92019-05-03 13:34:57 -0700177 mLowLightAmbientBrightnessToBiasSpline = new Spline.LinearSpline(
178 lowLightAmbientBrightnesses, lowLightAmbientBiases);
179 } catch (Exception e) {
180 Slog.e(TAG, "failed to create low light ambient brightness to bias spline.", e);
181 mLowLightAmbientBrightnessToBiasSpline = null;
182 }
183 if (mLowLightAmbientBrightnessToBiasSpline != null) {
184 if (mLowLightAmbientBrightnessToBiasSpline.interpolate(0.0f) != 0.0f ||
185 mLowLightAmbientBrightnessToBiasSpline.interpolate(Float.POSITIVE_INFINITY)
186 != 1.0f) {
187 Slog.d(TAG, "invalid low light ambient brightness to bias spline, "
Anthony Han0c8297c2019-06-18 16:56:11 -0700188 + "bias must begin at 0.0 and end at 1.0.");
Anthony Han04c78a92019-05-03 13:34:57 -0700189 mLowLightAmbientBrightnessToBiasSpline = null;
190 }
191 }
192
193 try {
Anthony Han0c8297c2019-06-18 16:56:11 -0700194 mHighLightAmbientBrightnessToBiasSpline = new Spline.LinearSpline(
195 highLightAmbientBrightnesses, highLightAmbientBiases);
196 } catch (Exception e) {
197 Slog.e(TAG, "failed to create high light ambient brightness to bias spline.", e);
198 mHighLightAmbientBrightnessToBiasSpline = null;
199 }
200 if (mHighLightAmbientBrightnessToBiasSpline != null) {
201 if (mHighLightAmbientBrightnessToBiasSpline.interpolate(0.0f) != 0.0f ||
202 mHighLightAmbientBrightnessToBiasSpline.interpolate(Float.POSITIVE_INFINITY)
203 != 1.0f) {
204 Slog.d(TAG, "invalid high light ambient brightness to bias spline, "
205 + "bias must begin at 0.0 and end at 1.0.");
206 mHighLightAmbientBrightnessToBiasSpline = null;
207 }
208 }
209
210 if (mLowLightAmbientBrightnessToBiasSpline != null &&
211 mHighLightAmbientBrightnessToBiasSpline != null) {
212 if (lowLightAmbientBrightnesses[lowLightAmbientBrightnesses.length - 1] >
213 highLightAmbientBrightnesses[0]) {
214 Slog.d(TAG, "invalid low light and high light ambient brightness to bias spline "
215 + "combination, defined domains must not intersect.");
216 mLowLightAmbientBrightnessToBiasSpline = null;
217 mHighLightAmbientBrightnessToBiasSpline = null;
218 }
219 }
220
221 try {
Dan Gittik1151ac02019-02-13 14:05:37 +0000222 mAmbientToDisplayColorTemperatureSpline = new Spline.LinearSpline(
223 ambientColorTemperatures, displayColorTemperatures);
Daniel Solomonfb393e52019-02-08 20:26:27 -0800224 } catch (Exception e) {
Anthony Han04c78a92019-05-03 13:34:57 -0700225 Slog.e(TAG, "failed to create ambient to display color temperature spline.", e);
Dan Gittik1151ac02019-02-13 14:05:37 +0000226 mAmbientToDisplayColorTemperatureSpline = null;
Daniel Solomonfb393e52019-02-08 20:26:27 -0800227 }
228
Dan Gittik8dbd7e92018-12-03 15:35:53 +0000229 mColorDisplayServiceInternal = LocalServices.getService(ColorDisplayServiceInternal.class);
230 }
231
232 /**
233 * Enable/disable the controller.
234 *
235 * @param enabled
236 * Whether the controller should be on/off.
237 *
238 * @return Whether the method succeeded or not.
239 */
240 public boolean setEnabled(boolean enabled) {
241 if (enabled) {
242 return enable();
243 } else {
244 return disable();
245 }
246 }
247
248 /**
Dan Gittik1151ac02019-02-13 14:05:37 +0000249 * Set an object to call back to when the display color temperature should be updated.
Dan Gittik8dbd7e92018-12-03 15:35:53 +0000250 *
251 * @param callbacks
252 * The object to call back to.
253 *
254 * @return Whether the method succeeded or not.
255 */
256 public boolean setCallbacks(Callbacks callbacks) {
257 if (mCallbacks == callbacks) {
258 return false;
259 }
260 mCallbacks = callbacks;
261 return true;
262 }
263
264 /**
265 * Enable/disable logging.
266 *
267 * @param loggingEnabled
268 * Whether logging should be on/off.
269 *
270 * @return Whether the method succeeded or not.
271 */
272 public boolean setLoggingEnabled(boolean loggingEnabled) {
273 if (mLoggingEnabled == loggingEnabled) {
274 return false;
275 }
276 mLoggingEnabled = loggingEnabled;
277 mBrightnessSensor.setLoggingEnabled(loggingEnabled);
278 mBrightnessFilter.setLoggingEnabled(loggingEnabled);
279 mColorTemperatureSensor.setLoggingEnabled(loggingEnabled);
280 mColorTemperatureFilter.setLoggingEnabled(loggingEnabled);
281 mThrottler.setLoggingEnabled(loggingEnabled);
282 return true;
283 }
284
285 /**
286 * Set the ambient color temperature override.
287 *
288 * This is only applied when the ambient color temperature changes or is updated (in which case
289 * it overrides the ambient color temperature estimate); in other words, it doesn't necessarily
Dan Gittik1151ac02019-02-13 14:05:37 +0000290 * change the display color temperature immediately.
Dan Gittik8dbd7e92018-12-03 15:35:53 +0000291 *
292 * @param ambientColorTemperatureOverride
293 * The ambient color temperature override.
294 *
295 * @return Whether the method succeeded or not.
296 */
297 public boolean setAmbientColorTemperatureOverride(float ambientColorTemperatureOverride) {
298 if (mAmbientColorTemperatureOverride == ambientColorTemperatureOverride) {
299 return false;
300 }
301 mAmbientColorTemperatureOverride = ambientColorTemperatureOverride;
302 return true;
303 }
304
305 /**
306 * Dump the state.
307 *
308 * @param writer
309 * The writer used to dump the state.
310 */
311 public void dump(PrintWriter writer) {
312 writer.println("DisplayWhiteBalanceController");
313 writer.println(" mLoggingEnabled=" + mLoggingEnabled);
314 writer.println(" mEnabled=" + mEnabled);
315 writer.println(" mCallbacks=" + mCallbacks);
316 mBrightnessSensor.dump(writer);
317 mBrightnessFilter.dump(writer);
318 mColorTemperatureSensor.dump(writer);
319 mColorTemperatureFilter.dump(writer);
320 mThrottler.dump(writer);
Dan Gittik8dbd7e92018-12-03 15:35:53 +0000321 writer.println(" mLowLightAmbientColorTemperature=" + mLowLightAmbientColorTemperature);
Anthony Han0c8297c2019-06-18 16:56:11 -0700322 writer.println(" mHighLightAmbientColorTemperature=" + mHighLightAmbientColorTemperature);
Dan Gittik8dbd7e92018-12-03 15:35:53 +0000323 writer.println(" mAmbientColorTemperature=" + mAmbientColorTemperature);
324 writer.println(" mPendingAmbientColorTemperature=" + mPendingAmbientColorTemperature);
325 writer.println(" mLastAmbientColorTemperature=" + mLastAmbientColorTemperature);
326 writer.println(" mAmbientColorTemperatureHistory=" + mAmbientColorTemperatureHistory);
327 writer.println(" mAmbientColorTemperatureOverride=" + mAmbientColorTemperatureOverride);
Dan Gittik1151ac02019-02-13 14:05:37 +0000328 writer.println(" mAmbientToDisplayColorTemperatureSpline="
329 + mAmbientToDisplayColorTemperatureSpline);
Anthony Han04c78a92019-05-03 13:34:57 -0700330 writer.println(" mLowLightAmbientBrightnessToBiasSpline="
331 + mLowLightAmbientBrightnessToBiasSpline);
Anthony Han0c8297c2019-06-18 16:56:11 -0700332 writer.println(" mHighLightAmbientBrightnessToBiasSpline="
333 + mHighLightAmbientBrightnessToBiasSpline);
Dan Gittik8dbd7e92018-12-03 15:35:53 +0000334 }
335
336 @Override // AmbientSensor.AmbientBrightnessSensor.Callbacks
337 public void onAmbientBrightnessChanged(float value) {
338 final long time = System.currentTimeMillis();
339 mBrightnessFilter.addValue(time, value);
340 updateAmbientColorTemperature();
341 }
342
343 @Override // AmbientSensor.AmbientColorTemperatureSensor.Callbacks
344 public void onAmbientColorTemperatureChanged(float value) {
345 final long time = System.currentTimeMillis();
346 mColorTemperatureFilter.addValue(time, value);
347 updateAmbientColorTemperature();
348 }
349
350 /**
351 * Updates the ambient color temperature.
352 */
353 public void updateAmbientColorTemperature() {
354 final long time = System.currentTimeMillis();
355 float ambientColorTemperature = mColorTemperatureFilter.getEstimate(time);
Anthony Han00a490b2019-08-26 14:00:28 -0700356 mLatestAmbientColorTemperature = ambientColorTemperature;
Dan Gittik8dbd7e92018-12-03 15:35:53 +0000357
Daniel Solomondff8b1b2019-04-08 14:30:51 -0700358 if (mAmbientToDisplayColorTemperatureSpline != null && ambientColorTemperature != -1.0f) {
Daniel Solomonfb393e52019-02-08 20:26:27 -0800359 ambientColorTemperature =
Dan Gittik1151ac02019-02-13 14:05:37 +0000360 mAmbientToDisplayColorTemperatureSpline.interpolate(ambientColorTemperature);
Daniel Solomonfb393e52019-02-08 20:26:27 -0800361 }
362
Anthony Han04c78a92019-05-03 13:34:57 -0700363 float ambientBrightness = mBrightnessFilter.getEstimate(time);
Anthony Han00a490b2019-08-26 14:00:28 -0700364 mLatestAmbientBrightness = ambientBrightness;
Anthony Han04c78a92019-05-03 13:34:57 -0700365
Anthony Han35df7e22019-06-27 17:27:24 -0700366 if (ambientColorTemperature != -1.0f &&
367 mLowLightAmbientBrightnessToBiasSpline != null) {
Anthony Han04c78a92019-05-03 13:34:57 -0700368 float bias = mLowLightAmbientBrightnessToBiasSpline.interpolate(ambientBrightness);
369 ambientColorTemperature =
370 bias * ambientColorTemperature + (1.0f - bias)
371 * mLowLightAmbientColorTemperature;
Anthony Han00a490b2019-08-26 14:00:28 -0700372 mLatestLowLightBias = bias;
Dan Gittik8dbd7e92018-12-03 15:35:53 +0000373 }
Anthony Han35df7e22019-06-27 17:27:24 -0700374 if (ambientColorTemperature != -1.0f &&
375 mHighLightAmbientBrightnessToBiasSpline != null) {
Anthony Han0c8297c2019-06-18 16:56:11 -0700376 float bias = mHighLightAmbientBrightnessToBiasSpline.interpolate(ambientBrightness);
377 ambientColorTemperature =
378 (1.0f - bias) * ambientColorTemperature + bias
379 * mHighLightAmbientColorTemperature;
Anthony Han00a490b2019-08-26 14:00:28 -0700380 mLatestHighLightBias = bias;
Anthony Han0c8297c2019-06-18 16:56:11 -0700381 }
Dan Gittik8dbd7e92018-12-03 15:35:53 +0000382
383 if (mAmbientColorTemperatureOverride != -1.0f) {
384 if (mLoggingEnabled) {
385 Slog.d(TAG, "override ambient color temperature: " + ambientColorTemperature
386 + " => " + mAmbientColorTemperatureOverride);
387 }
388 ambientColorTemperature = mAmbientColorTemperatureOverride;
389 }
390
Dan Gittik1151ac02019-02-13 14:05:37 +0000391 // When the display color temperature needs to be updated, we call DisplayPowerController to
Dan Gittik8dbd7e92018-12-03 15:35:53 +0000392 // call our updateColorTemperature. The reason we don't call it directly is that we want
393 // all changes to the system to happen in a predictable order in DPC's main loop
394 // (updatePowerState).
395 if (ambientColorTemperature == -1.0f || mThrottler.throttle(ambientColorTemperature)) {
396 return;
397 }
398
399 if (mLoggingEnabled) {
400 Slog.d(TAG, "pending ambient color temperature: " + ambientColorTemperature);
401 }
402 mPendingAmbientColorTemperature = ambientColorTemperature;
403 if (mCallbacks != null) {
404 mCallbacks.updateWhiteBalance();
405 }
406 }
407
408 /**
Dan Gittik1151ac02019-02-13 14:05:37 +0000409 * Updates the display color temperature.
Dan Gittik8dbd7e92018-12-03 15:35:53 +0000410 */
Dan Gittik1151ac02019-02-13 14:05:37 +0000411 public void updateDisplayColorTemperature() {
Dan Gittik8dbd7e92018-12-03 15:35:53 +0000412 float ambientColorTemperature = -1.0f;
413
414 // If both the pending and the current ambient color temperatures are -1, it means the DWBC
415 // was just enabled, and we use the last ambient color temperature until new sensor events
416 // give us a better estimate.
417 if (mAmbientColorTemperature == -1.0f && mPendingAmbientColorTemperature == -1.0f) {
418 ambientColorTemperature = mLastAmbientColorTemperature;
419 }
420
421 // Otherwise, we use the pending ambient color temperature, but only if it's non-trivial
422 // and different than the current one.
423 if (mPendingAmbientColorTemperature != -1.0f
424 && mPendingAmbientColorTemperature != mAmbientColorTemperature) {
425 ambientColorTemperature = mPendingAmbientColorTemperature;
426 }
427
428 if (ambientColorTemperature == -1.0f) {
429 return;
430 }
431
432 mAmbientColorTemperature = ambientColorTemperature;
433 if (mLoggingEnabled) {
434 Slog.d(TAG, "ambient color temperature: " + mAmbientColorTemperature);
435 }
436 mPendingAmbientColorTemperature = -1.0f;
437 mAmbientColorTemperatureHistory.add(mAmbientColorTemperature);
Anthony Han00a490b2019-08-26 14:00:28 -0700438 Slog.d(TAG, "Display cct: " + mAmbientColorTemperature
439 + " Latest ambient cct: " + mLatestAmbientColorTemperature
440 + " Latest ambient lux: " + mLatestAmbientBrightness
441 + " Latest low light bias: " + mLatestLowLightBias
442 + " Latest high light bias: " + mLatestHighLightBias);
Dan Gittik8dbd7e92018-12-03 15:35:53 +0000443 mColorDisplayServiceInternal.setDisplayWhiteBalanceColorTemperature(
444 (int) mAmbientColorTemperature);
445 mLastAmbientColorTemperature = mAmbientColorTemperature;
446 }
447
448 /**
449 * The DisplayWhiteBalanceController decouples itself from its parent (DisplayPowerController)
450 * by providing this interface to implement (and a method to set its callbacks object), and
451 * calling these methods.
452 */
453 public interface Callbacks {
454
455 /**
456 * Called whenever the display white-balance state has changed.
457 *
458 * Usually, this means the estimated ambient color temperature has changed enough, and the
Dan Gittik1151ac02019-02-13 14:05:37 +0000459 * display color temperature should be updated; but it is also called if settings change.
Dan Gittik8dbd7e92018-12-03 15:35:53 +0000460 */
461 void updateWhiteBalance();
462 }
463
464 private void validateArguments(AmbientSensor.AmbientBrightnessSensor brightnessSensor,
465 AmbientFilter brightnessFilter,
466 AmbientSensor.AmbientColorTemperatureSensor colorTemperatureSensor,
467 AmbientFilter colorTemperatureFilter,
468 DisplayWhiteBalanceThrottler throttler) {
469 Preconditions.checkNotNull(brightnessSensor, "brightnessSensor must not be null");
470 Preconditions.checkNotNull(brightnessFilter, "brightnessFilter must not be null");
471 Preconditions.checkNotNull(colorTemperatureSensor,
472 "colorTemperatureSensor must not be null");
473 Preconditions.checkNotNull(colorTemperatureFilter,
474 "colorTemperatureFilter must not be null");
475 Preconditions.checkNotNull(throttler, "throttler cannot be null");
476 }
477
478 private boolean enable() {
479 if (mEnabled) {
480 return false;
481 }
482 if (mLoggingEnabled) {
483 Slog.d(TAG, "enabling");
484 }
485 mEnabled = true;
486 mBrightnessSensor.setEnabled(true);
487 mColorTemperatureSensor.setEnabled(true);
488 return true;
489 }
490
491 private boolean disable() {
492 if (!mEnabled) {
493 return false;
494 }
495 if (mLoggingEnabled) {
496 Slog.d(TAG, "disabling");
497 }
498 mEnabled = false;
499 mBrightnessSensor.setEnabled(false);
500 mBrightnessFilter.clear();
501 mColorTemperatureSensor.setEnabled(false);
502 mColorTemperatureFilter.clear();
503 mThrottler.clear();
504 mAmbientColorTemperature = -1.0f;
505 mPendingAmbientColorTemperature = -1.0f;
Daniel Solomon37816412019-04-10 15:17:41 -0700506 mColorDisplayServiceInternal.resetDisplayWhiteBalanceColorTemperature();
Dan Gittik8dbd7e92018-12-03 15:35:53 +0000507 return true;
508 }
509
510}