Merge "Interpolate low light white balance" into qt-r1-dev
am: 5622e1bff7
Change-Id: I18edab10bf4af20e3e6b4d8a21d7694f48e17686
This commit is contained in:
@@ -4034,9 +4034,28 @@
|
||||
</array>
|
||||
|
||||
<!-- See DisplayWhiteBalanceController.
|
||||
The ambient brightness threshold (in lux) beneath which we fall back to a fixed ambient
|
||||
color temperature. -->
|
||||
<item name="config_displayWhiteBalanceLowLightAmbientBrightnessThreshold" format="float" type="dimen">10.0</item>
|
||||
A float array containing a list of ambient brightnesses, in Lux. This array,
|
||||
together with config_displayWhiteBalanceLowLightAmbientBiases, is used to generate a
|
||||
lookup table used in DisplayWhiteBalanceController. This lookup table is used to map
|
||||
ambient brightness readings to a bias, where the bias is used to linearly interpolate
|
||||
between ambient color temperature and
|
||||
config_displayWhiteBalanceLowLightAmbientColorTemperature.
|
||||
This table is optional. If used, this array must,
|
||||
1) Contain at least two entries
|
||||
2) Be the same length as config_displayWhiteBalanceLowLightAmbientBiases. -->
|
||||
<array name ="config_displayWhiteBalanceLowLightAmbientBrightnesses">
|
||||
<item>10.0</item>
|
||||
<item>10.0</item>
|
||||
</array>
|
||||
|
||||
<!-- See DisplayWhiteBalanceController.
|
||||
An array containing a list of biases. See
|
||||
config_displayWhiteBalanceLowLightAmbientBrightnesses for additional details.
|
||||
This array must be in the range of [0.0, 1.0]. -->
|
||||
<array name ="config_displayWhiteBalanceLowLightAmbientBiases">
|
||||
<item>0.0</item>
|
||||
<item>1.0</item>
|
||||
</array>
|
||||
|
||||
<!-- See DisplayWhiteBalanceController.
|
||||
The ambient color temperature (in cct) to which we fall back when the ambient brightness
|
||||
|
||||
@@ -3749,7 +3749,8 @@
|
||||
<java-symbol type="array" name="config_displayWhiteBalanceBaseThresholds" />
|
||||
<java-symbol type="array" name="config_displayWhiteBalanceIncreaseThresholds" />
|
||||
<java-symbol type="array" name="config_displayWhiteBalanceDecreaseThresholds" />
|
||||
<java-symbol type="dimen" name="config_displayWhiteBalanceLowLightAmbientBrightnessThreshold" />
|
||||
<java-symbol type="array" name="config_displayWhiteBalanceLowLightAmbientBrightnesses" />
|
||||
<java-symbol type="array" name="config_displayWhiteBalanceLowLightAmbientBiases" />
|
||||
<java-symbol type="dimen" name="config_displayWhiteBalanceLowLightAmbientColorTemperature" />
|
||||
<java-symbol type="array" name="config_displayWhiteBalanceAmbientColorTemperatures" />
|
||||
<java-symbol type="array" name="config_displayWhiteBalanceDisplayColorTemperatures" />
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.android.server.display.whitebalance;
|
||||
|
||||
import android.util.Slog;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.server.display.utils.RollingBuffer;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
@@ -155,7 +156,8 @@ abstract class AmbientFilter {
|
||||
/**
|
||||
* A weighted average prioritising recent changes.
|
||||
*/
|
||||
static class WeightedMovingAverageAmbientFilter extends AmbientFilter {
|
||||
@VisibleForTesting
|
||||
public static class WeightedMovingAverageAmbientFilter extends AmbientFilter {
|
||||
|
||||
// How long the latest ambient value change is predicted to last.
|
||||
private static final int PREDICTION_TIME = 100; // Milliseconds
|
||||
|
||||
@@ -20,6 +20,7 @@ import android.annotation.NonNull;
|
||||
import android.util.Slog;
|
||||
import android.util.Spline;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.internal.util.Preconditions;
|
||||
import com.android.server.LocalServices;
|
||||
import com.android.server.display.color.ColorDisplayService.ColorDisplayServiceInternal;
|
||||
@@ -53,18 +54,21 @@ public class DisplayWhiteBalanceController implements
|
||||
private Callbacks mCallbacks;
|
||||
|
||||
private AmbientSensor.AmbientBrightnessSensor mBrightnessSensor;
|
||||
private AmbientFilter mBrightnessFilter;
|
||||
|
||||
@VisibleForTesting
|
||||
AmbientFilter mBrightnessFilter;
|
||||
private AmbientSensor.AmbientColorTemperatureSensor mColorTemperatureSensor;
|
||||
private AmbientFilter mColorTemperatureFilter;
|
||||
|
||||
@VisibleForTesting
|
||||
AmbientFilter mColorTemperatureFilter;
|
||||
private DisplayWhiteBalanceThrottler mThrottler;
|
||||
|
||||
// When the brightness drops below a certain threshold, it affects the color temperature
|
||||
// accuracy, so we fall back to a fixed ambient color temperature.
|
||||
private final float mLowLightAmbientBrightnessThreshold;
|
||||
private final float mLowLightAmbientColorTemperature;
|
||||
|
||||
private float mAmbientColorTemperature;
|
||||
private float mPendingAmbientColorTemperature;
|
||||
|
||||
@VisibleForTesting
|
||||
float mPendingAmbientColorTemperature;
|
||||
private float mLastAmbientColorTemperature;
|
||||
|
||||
private ColorDisplayServiceInternal mColorDisplayServiceInternal;
|
||||
@@ -79,6 +83,9 @@ public class DisplayWhiteBalanceController implements
|
||||
// A piecewise linear relationship between ambient and display color temperatures.
|
||||
private Spline.LinearSpline mAmbientToDisplayColorTemperatureSpline;
|
||||
|
||||
// A piecewise linear relationship between low light brightness and low light bias.
|
||||
private Spline.LinearSpline mLowLightAmbientBrightnessToBiasSpline;
|
||||
|
||||
/**
|
||||
* @param brightnessSensor
|
||||
* The sensor used to detect changes in the ambient brightness.
|
||||
@@ -119,7 +126,8 @@ public class DisplayWhiteBalanceController implements
|
||||
@NonNull AmbientSensor.AmbientColorTemperatureSensor colorTemperatureSensor,
|
||||
@NonNull AmbientFilter colorTemperatureFilter,
|
||||
@NonNull DisplayWhiteBalanceThrottler throttler,
|
||||
float lowLightAmbientBrightnessThreshold, float lowLightAmbientColorTemperature,
|
||||
float[] lowLightAmbientBrightnesses, float[] lowLightAmbientBiases,
|
||||
float lowLightAmbientColorTemperature,
|
||||
float[] ambientColorTemperatures, float[] displayColorTemperatures) {
|
||||
validateArguments(brightnessSensor, brightnessFilter, colorTemperatureSensor,
|
||||
colorTemperatureFilter, throttler);
|
||||
@@ -131,7 +139,6 @@ public class DisplayWhiteBalanceController implements
|
||||
mColorTemperatureSensor = colorTemperatureSensor;
|
||||
mColorTemperatureFilter = colorTemperatureFilter;
|
||||
mThrottler = throttler;
|
||||
mLowLightAmbientBrightnessThreshold = lowLightAmbientBrightnessThreshold;
|
||||
mLowLightAmbientColorTemperature = lowLightAmbientColorTemperature;
|
||||
mAmbientColorTemperature = -1.0f;
|
||||
mPendingAmbientColorTemperature = -1.0f;
|
||||
@@ -139,10 +146,28 @@ public class DisplayWhiteBalanceController implements
|
||||
mAmbientColorTemperatureHistory = new History(HISTORY_SIZE);
|
||||
mAmbientColorTemperatureOverride = -1.0f;
|
||||
|
||||
try {
|
||||
mLowLightAmbientBrightnessToBiasSpline = new Spline.LinearSpline(
|
||||
lowLightAmbientBrightnesses, lowLightAmbientBiases);
|
||||
} catch (Exception e) {
|
||||
Slog.e(TAG, "failed to create low light ambient brightness to bias spline.", e);
|
||||
mLowLightAmbientBrightnessToBiasSpline = null;
|
||||
}
|
||||
if (mLowLightAmbientBrightnessToBiasSpline != null) {
|
||||
if (mLowLightAmbientBrightnessToBiasSpline.interpolate(0.0f) != 0.0f ||
|
||||
mLowLightAmbientBrightnessToBiasSpline.interpolate(Float.POSITIVE_INFINITY)
|
||||
!= 1.0f) {
|
||||
Slog.d(TAG, "invalid low light ambient brightness to bias spline, "
|
||||
+ "bias must begin at 0.0 and end at 1.0");
|
||||
mLowLightAmbientBrightnessToBiasSpline = null;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
mAmbientToDisplayColorTemperatureSpline = new Spline.LinearSpline(
|
||||
ambientColorTemperatures, displayColorTemperatures);
|
||||
} catch (Exception e) {
|
||||
Slog.e(TAG, "failed to create ambient to display color temperature spline.", e);
|
||||
mAmbientToDisplayColorTemperatureSpline = null;
|
||||
}
|
||||
|
||||
@@ -238,8 +263,6 @@ public class DisplayWhiteBalanceController implements
|
||||
mColorTemperatureSensor.dump(writer);
|
||||
mColorTemperatureFilter.dump(writer);
|
||||
mThrottler.dump(writer);
|
||||
writer.println(" mLowLightAmbientBrightnessThreshold="
|
||||
+ mLowLightAmbientBrightnessThreshold);
|
||||
writer.println(" mLowLightAmbientColorTemperature=" + mLowLightAmbientColorTemperature);
|
||||
writer.println(" mAmbientColorTemperature=" + mAmbientColorTemperature);
|
||||
writer.println(" mPendingAmbientColorTemperature=" + mPendingAmbientColorTemperature);
|
||||
@@ -248,6 +271,8 @@ public class DisplayWhiteBalanceController implements
|
||||
writer.println(" mAmbientColorTemperatureOverride=" + mAmbientColorTemperatureOverride);
|
||||
writer.println(" mAmbientToDisplayColorTemperatureSpline="
|
||||
+ mAmbientToDisplayColorTemperatureSpline);
|
||||
writer.println(" mLowLightAmbientBrightnessToBiasSpline="
|
||||
+ mLowLightAmbientBrightnessToBiasSpline);
|
||||
}
|
||||
|
||||
@Override // AmbientSensor.AmbientBrightnessSensor.Callbacks
|
||||
@@ -276,15 +301,13 @@ public class DisplayWhiteBalanceController implements
|
||||
mAmbientToDisplayColorTemperatureSpline.interpolate(ambientColorTemperature);
|
||||
}
|
||||
|
||||
final float ambientBrightness = mBrightnessFilter.getEstimate(time);
|
||||
if (ambientBrightness < mLowLightAmbientBrightnessThreshold) {
|
||||
if (mLoggingEnabled) {
|
||||
Slog.d(TAG, "low light ambient brightness: " + ambientBrightness + " < "
|
||||
+ mLowLightAmbientBrightnessThreshold
|
||||
+ ", falling back to fixed ambient color temperature: "
|
||||
+ ambientColorTemperature + " => " + mLowLightAmbientColorTemperature);
|
||||
}
|
||||
ambientColorTemperature = mLowLightAmbientColorTemperature;
|
||||
float ambientBrightness = mBrightnessFilter.getEstimate(time);
|
||||
|
||||
if (mLowLightAmbientBrightnessToBiasSpline != null) {
|
||||
float bias = mLowLightAmbientBrightnessToBiasSpline.interpolate(ambientBrightness);
|
||||
ambientColorTemperature =
|
||||
bias * ambientColorTemperature + (1.0f - bias)
|
||||
* mLowLightAmbientColorTemperature;
|
||||
}
|
||||
|
||||
if (mAmbientColorTemperatureOverride != -1.0f) {
|
||||
|
||||
@@ -63,9 +63,12 @@ public class DisplayWhiteBalanceFactory {
|
||||
createColorTemperatureSensor(handler, sensorManager, resources);
|
||||
final AmbientFilter colorTemperatureFilter = createColorTemperatureFilter(resources);
|
||||
final DisplayWhiteBalanceThrottler throttler = createThrottler(resources);
|
||||
final float lowLightAmbientBrightnessThreshold = getFloat(resources,
|
||||
com.android.internal.R.dimen
|
||||
.config_displayWhiteBalanceLowLightAmbientBrightnessThreshold);
|
||||
final float[] displayWhiteBalanceLowLightAmbientBrightnesses = getFloatArray(resources,
|
||||
com.android.internal.R.array
|
||||
.config_displayWhiteBalanceLowLightAmbientBrightnesses);
|
||||
final float[] displayWhiteBalanceLowLightAmbientBiases = getFloatArray(resources,
|
||||
com.android.internal.R.array
|
||||
.config_displayWhiteBalanceLowLightAmbientBiases);
|
||||
final float lowLightAmbientColorTemperature = getFloat(resources,
|
||||
com.android.internal.R.dimen
|
||||
.config_displayWhiteBalanceLowLightAmbientColorTemperature);
|
||||
@@ -75,7 +78,8 @@ public class DisplayWhiteBalanceFactory {
|
||||
com.android.internal.R.array.config_displayWhiteBalanceDisplayColorTemperatures);
|
||||
final DisplayWhiteBalanceController controller = new DisplayWhiteBalanceController(
|
||||
brightnessSensor, brightnessFilter, colorTemperatureSensor, colorTemperatureFilter,
|
||||
throttler, lowLightAmbientBrightnessThreshold, lowLightAmbientColorTemperature,
|
||||
throttler, displayWhiteBalanceLowLightAmbientBrightnesses,
|
||||
displayWhiteBalanceLowLightAmbientBiases, lowLightAmbientColorTemperature,
|
||||
ambientColorTemperatures, displayColorTempeartures);
|
||||
brightnessSensor.setCallbacks(controller);
|
||||
colorTemperatureSensor.setCallbacks(controller);
|
||||
|
||||
@@ -0,0 +1,299 @@
|
||||
/*
|
||||
* Copyright (C) 2019 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.server.display.whitebalance;
|
||||
|
||||
import com.android.internal.R;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.mockito.Matchers.anyLong;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.mockito.Spy;
|
||||
|
||||
import android.content.ContextWrapper;
|
||||
import android.content.res.Resources;
|
||||
import android.content.res.TypedArray;
|
||||
import android.hardware.Sensor;
|
||||
import android.hardware.SensorEvent;
|
||||
import android.hardware.SensorEventListener;
|
||||
import android.hardware.SensorManager;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.util.TypedValue;
|
||||
|
||||
import androidx.test.InstrumentationRegistry;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.JUnit4;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.List;
|
||||
|
||||
@RunWith(JUnit4.class)
|
||||
public final class AmbientLuxTest {
|
||||
private static final int AMBIENT_COLOR_TYPE = 20705;
|
||||
private static final String AMBIENT_COLOR_TYPE_STR = "colorSensoryDensoryDoc";
|
||||
private static final float LOW_LIGHT_AMBIENT_COLOR_TEMPERATURE = 5700;
|
||||
|
||||
private Handler mHandler = new Handler(Looper.getMainLooper());
|
||||
private Sensor mLightSensor;
|
||||
private Sensor mAmbientColorSensor;
|
||||
private ContextWrapper mContextSpy;
|
||||
private Resources mResourcesSpy;
|
||||
|
||||
@Mock private SensorManager mSensorManagerMock;
|
||||
|
||||
@Mock private TypedArray mBrightnesses;
|
||||
@Mock private TypedArray mBiases;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mLightSensor = createSensor(Sensor.TYPE_LIGHT, null);
|
||||
mAmbientColorSensor = createSensor(AMBIENT_COLOR_TYPE, AMBIENT_COLOR_TYPE_STR);
|
||||
mContextSpy = spy(new ContextWrapper(InstrumentationRegistry.getContext()));
|
||||
mResourcesSpy = spy(mContextSpy.getResources());
|
||||
when(mContextSpy.getResources()).thenReturn(mResourcesSpy);
|
||||
when(mSensorManagerMock.getDefaultSensor(Sensor.TYPE_LIGHT)).thenReturn(mLightSensor);
|
||||
final List<Sensor> sensorList = ImmutableList.of(mLightSensor, mAmbientColorSensor);
|
||||
when(mSensorManagerMock.getSensorList(Sensor.TYPE_ALL)).thenReturn(sensorList);
|
||||
when(mResourcesSpy.getString(
|
||||
R.string.config_displayWhiteBalanceColorTemperatureSensorName))
|
||||
.thenReturn(AMBIENT_COLOR_TYPE_STR);
|
||||
when(mResourcesSpy.getInteger(
|
||||
R.integer.config_displayWhiteBalanceDecreaseDebounce))
|
||||
.thenReturn(0);
|
||||
when(mResourcesSpy.getInteger(
|
||||
R.integer.config_displayWhiteBalanceIncreaseDebounce))
|
||||
.thenReturn(0);
|
||||
when(mResourcesSpy.getFloat(
|
||||
R.dimen.config_displayWhiteBalanceLowLightAmbientColorTemperature))
|
||||
.thenReturn(LOW_LIGHT_AMBIENT_COLOR_TEMPERATURE);
|
||||
when(mResourcesSpy.obtainTypedArray(
|
||||
R.array.config_displayWhiteBalanceAmbientColorTemperatures))
|
||||
.thenReturn(createTypedArray());
|
||||
when(mResourcesSpy.obtainTypedArray(
|
||||
R.array.config_displayWhiteBalanceDisplayColorTemperatures))
|
||||
.thenReturn(createTypedArray());
|
||||
|
||||
when(mResourcesSpy.obtainTypedArray(
|
||||
R.array.config_displayWhiteBalanceLowLightAmbientBrightnesses))
|
||||
.thenReturn(mBrightnesses);
|
||||
when(mResourcesSpy.obtainTypedArray(
|
||||
R.array.config_displayWhiteBalanceLowLightAmbientBiases))
|
||||
.thenReturn(mBiases);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoSpline() throws Exception {
|
||||
setBrightnesses();
|
||||
setBiases();
|
||||
|
||||
DisplayWhiteBalanceController controller =
|
||||
DisplayWhiteBalanceFactory.create(mHandler, mSensorManagerMock, mResourcesSpy);
|
||||
final float ambientColorTemperature = 8000.0f;
|
||||
setEstimatedColorTemperature(controller, ambientColorTemperature);
|
||||
controller.mBrightnessFilter = spy(controller.mBrightnessFilter);
|
||||
|
||||
for (float luxOverride = 0.1f; luxOverride <= 10000; luxOverride *= 10) {
|
||||
setEstimatedBrightnessAndUpdate(controller, luxOverride);
|
||||
assertEquals(controller.mPendingAmbientColorTemperature,
|
||||
ambientColorTemperature, 0.001);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSpline_OneSegment() throws Exception {
|
||||
final float lowerBrightness = 10.0f;
|
||||
final float upperBrightness = 50.0f;
|
||||
setBrightnesses(lowerBrightness, upperBrightness);
|
||||
setBiases(0.0f, 1.0f);
|
||||
|
||||
DisplayWhiteBalanceController controller =
|
||||
DisplayWhiteBalanceFactory.create(mHandler, mSensorManagerMock, mResourcesSpy);
|
||||
final float ambientColorTemperature = 8000.0f;
|
||||
setEstimatedColorTemperature(controller, ambientColorTemperature);
|
||||
controller.mBrightnessFilter = spy(controller.mBrightnessFilter);
|
||||
|
||||
for (float t = 0.0f; t <= 1.0f; t += 0.1f) {
|
||||
setEstimatedBrightnessAndUpdate(controller,
|
||||
mix(lowerBrightness, upperBrightness, t));
|
||||
assertEquals(controller.mPendingAmbientColorTemperature,
|
||||
mix(LOW_LIGHT_AMBIENT_COLOR_TEMPERATURE, ambientColorTemperature, t), 0.001);
|
||||
}
|
||||
|
||||
setEstimatedBrightnessAndUpdate(controller, 0.0f);
|
||||
assertEquals(controller.mPendingAmbientColorTemperature,
|
||||
LOW_LIGHT_AMBIENT_COLOR_TEMPERATURE, 0.001);
|
||||
|
||||
setEstimatedBrightnessAndUpdate(controller, upperBrightness + 1.0f);
|
||||
assertEquals(controller.mPendingAmbientColorTemperature, ambientColorTemperature, 0.001);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSpline_TwoSegments() throws Exception {
|
||||
final float brightness0 = 10.0f;
|
||||
final float brightness1 = 50.0f;
|
||||
final float brightness2 = 60.0f;
|
||||
setBrightnesses(brightness0, brightness1, brightness2);
|
||||
final float bias0 = 0.0f;
|
||||
final float bias1 = 0.25f;
|
||||
final float bias2 = 1.0f;
|
||||
setBiases(bias0, bias1, bias2);
|
||||
|
||||
DisplayWhiteBalanceController controller =
|
||||
DisplayWhiteBalanceFactory.create(mHandler, mSensorManagerMock, mResourcesSpy);
|
||||
final float ambientColorTemperature = 8000.0f;
|
||||
setEstimatedColorTemperature(controller, ambientColorTemperature);
|
||||
controller.mBrightnessFilter = spy(controller.mBrightnessFilter);
|
||||
|
||||
for (float t = 0.0f; t <= 1.0f; t += 0.1f) {
|
||||
float luxOverride = mix(brightness0, brightness1, t);
|
||||
setEstimatedBrightnessAndUpdate(controller, luxOverride);
|
||||
float bias = mix(bias0, bias1, t);
|
||||
assertEquals(controller.mPendingAmbientColorTemperature,
|
||||
mix(LOW_LIGHT_AMBIENT_COLOR_TEMPERATURE, ambientColorTemperature, bias), 0.001);
|
||||
}
|
||||
|
||||
for (float t = 0.0f; t <= 1.0f; t += 0.1f) {
|
||||
float luxOverride = mix(brightness1, brightness2, t);
|
||||
setEstimatedBrightnessAndUpdate(controller, luxOverride);
|
||||
float bias = mix(bias1, bias2, t);
|
||||
assertEquals(controller.mPendingAmbientColorTemperature,
|
||||
mix(LOW_LIGHT_AMBIENT_COLOR_TEMPERATURE, ambientColorTemperature, bias), 0.001);
|
||||
}
|
||||
|
||||
setEstimatedBrightnessAndUpdate(controller, 0.0f);
|
||||
assertEquals(controller.mPendingAmbientColorTemperature,
|
||||
LOW_LIGHT_AMBIENT_COLOR_TEMPERATURE, 0.001);
|
||||
|
||||
setEstimatedBrightnessAndUpdate(controller, brightness2 + 1.0f);
|
||||
assertEquals(controller.mPendingAmbientColorTemperature, ambientColorTemperature, 0.001);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSpline_VerticalSegment() throws Exception {
|
||||
final float lowerBrightness = 10.0f;
|
||||
final float upperBrightness = 10.0f;
|
||||
setBrightnesses(lowerBrightness, upperBrightness);
|
||||
setBiases(0.0f, 1.0f);
|
||||
|
||||
DisplayWhiteBalanceController controller =
|
||||
DisplayWhiteBalanceFactory.create(mHandler, mSensorManagerMock, mResourcesSpy);
|
||||
final float ambientColorTemperature = 8000.0f;
|
||||
setEstimatedColorTemperature(controller, ambientColorTemperature);
|
||||
controller.mBrightnessFilter = spy(controller.mBrightnessFilter);
|
||||
|
||||
setEstimatedBrightnessAndUpdate(controller, 0.0f);
|
||||
assertEquals(controller.mPendingAmbientColorTemperature,
|
||||
LOW_LIGHT_AMBIENT_COLOR_TEMPERATURE, 0.001);
|
||||
|
||||
setEstimatedBrightnessAndUpdate(controller, upperBrightness + 1.0f);
|
||||
assertEquals(controller.mPendingAmbientColorTemperature, ambientColorTemperature, 0.001);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSpline_InvalidBiases() throws Exception {
|
||||
float[][] invalidBrightnesses =
|
||||
{{10.0f, 1000.0f}, {10.0f, 1000.0f}, {10.0f, 1000.0f}, {10.0f, 1000.0f},
|
||||
{10.0f, 1000.0f}, {-1.0f, 1.0f}, {-1.0f, 1.0f}};
|
||||
float[][] invalidBiases =
|
||||
{{0.0f, 2.0f}, {0.0f, 0.9f}, {0.1f, 1.0f}, {-0.1f, 1.0f},
|
||||
{0.1f, 1.1f}, {0.0f, 1.0f}, {-2.0f, 1.0f}};
|
||||
for (int i = 0; i < invalidBrightnesses.length; ++i) {
|
||||
setBrightnesses(invalidBrightnesses[i][0], invalidBrightnesses[i][1]);
|
||||
setBiases(invalidBiases[i][0], invalidBiases[i][1]);
|
||||
|
||||
DisplayWhiteBalanceController controller =
|
||||
DisplayWhiteBalanceFactory.create(mHandler, mSensorManagerMock, mResourcesSpy);
|
||||
final float ambientColorTemperature = 8000.0f;
|
||||
setEstimatedColorTemperature(controller, ambientColorTemperature);
|
||||
controller.mBrightnessFilter = spy(controller.mBrightnessFilter);
|
||||
|
||||
for (float luxOverride = 0.1f; luxOverride <= 10000; luxOverride *= 10) {
|
||||
setEstimatedBrightnessAndUpdate(controller, luxOverride);
|
||||
assertEquals(controller.mPendingAmbientColorTemperature,
|
||||
ambientColorTemperature, 0.001);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void setEstimatedColorTemperature(DisplayWhiteBalanceController controller,
|
||||
float ambientColorTemperature) {
|
||||
AmbientFilter colorTemperatureFilter = spy(controller.mColorTemperatureFilter);
|
||||
controller.mColorTemperatureFilter = colorTemperatureFilter;
|
||||
when(colorTemperatureFilter.getEstimate(anyLong())).thenReturn(ambientColorTemperature);
|
||||
}
|
||||
|
||||
private void setEstimatedBrightnessAndUpdate(DisplayWhiteBalanceController controller,
|
||||
float brightness) {
|
||||
when(controller.mBrightnessFilter.getEstimate(anyLong())).thenReturn(brightness);
|
||||
controller.updateAmbientColorTemperature();
|
||||
}
|
||||
|
||||
private void setBrightnesses(float... vals) {
|
||||
setFloatArrayResource(mBrightnesses, vals);
|
||||
}
|
||||
|
||||
private void setBiases(float... vals) {
|
||||
setFloatArrayResource(mBiases, vals);
|
||||
}
|
||||
|
||||
private void setFloatArrayResource(TypedArray array, float[] vals) {
|
||||
when(array.length()).thenReturn(vals.length);
|
||||
for (int i = 0; i < vals.length; i++) {
|
||||
when(array.getFloat(i, Float.NaN)).thenReturn(vals[i]);
|
||||
}
|
||||
}
|
||||
|
||||
private void setSensorType(Sensor sensor, int type, String strType) throws Exception {
|
||||
Method setter = Sensor.class.getDeclaredMethod("setType", Integer.TYPE);
|
||||
setter.setAccessible(true);
|
||||
setter.invoke(sensor, type);
|
||||
if (strType != null) {
|
||||
Field f = sensor.getClass().getDeclaredField("mStringType");
|
||||
f.setAccessible(true);
|
||||
f.set(sensor, strType);
|
||||
}
|
||||
}
|
||||
|
||||
private Sensor createSensor(int type, String strType) throws Exception {
|
||||
Constructor<Sensor> constr = Sensor.class.getDeclaredConstructor();
|
||||
constr.setAccessible(true);
|
||||
Sensor sensor = constr.newInstance();
|
||||
setSensorType(sensor, type, strType);
|
||||
return sensor;
|
||||
}
|
||||
|
||||
private TypedArray createTypedArray() throws Exception {
|
||||
TypedArray mockArray = mock(TypedArray.class);
|
||||
return mockArray;
|
||||
}
|
||||
|
||||
private static float mix(float a, float b, float t) {
|
||||
return (1.0f - t) * a + t * b;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user