Merge "Clamp brightness thresholds to the maximum brightness." into qt-qpr1-dev am: 4274934c01
Change-Id: Ia9cac1aa7627eda8223f664d6a4a8ae1929a1e63
This commit is contained in:
@@ -41,6 +41,7 @@ import android.util.MathUtils;
|
||||
import android.util.Slog;
|
||||
import android.util.TimeUtils;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.internal.os.BackgroundThread;
|
||||
import com.android.server.EventLogTags;
|
||||
|
||||
@@ -215,7 +216,9 @@ class AutomaticBrightnessController {
|
||||
private IActivityTaskManager mActivityTaskManager;
|
||||
private PackageManager mPackageManager;
|
||||
|
||||
public AutomaticBrightnessController(Callbacks callbacks, Looper looper,
|
||||
private final Injector mInjector;
|
||||
|
||||
AutomaticBrightnessController(Callbacks callbacks, Looper looper,
|
||||
SensorManager sensorManager, Sensor lightSensor, BrightnessMappingStrategy mapper,
|
||||
int lightSensorWarmUpTime, int brightnessMin, int brightnessMax, float dozeScaleFactor,
|
||||
int lightSensorRate, int initialLightSensorRate, long brighteningLightDebounceConfig,
|
||||
@@ -223,6 +226,24 @@ class AutomaticBrightnessController {
|
||||
HysteresisLevels ambientBrightnessThresholds,
|
||||
HysteresisLevels screenBrightnessThresholds, long shortTermModelTimeout,
|
||||
PackageManager packageManager) {
|
||||
this(new Injector(), callbacks, looper, sensorManager, lightSensor, mapper,
|
||||
lightSensorWarmUpTime, brightnessMin, brightnessMax, dozeScaleFactor,
|
||||
lightSensorRate, initialLightSensorRate, brighteningLightDebounceConfig,
|
||||
darkeningLightDebounceConfig, resetAmbientLuxAfterWarmUpConfig,
|
||||
ambientBrightnessThresholds, screenBrightnessThresholds, shortTermModelTimeout,
|
||||
packageManager);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
AutomaticBrightnessController(Injector injector, Callbacks callbacks, Looper looper,
|
||||
SensorManager sensorManager, Sensor lightSensor, BrightnessMappingStrategy mapper,
|
||||
int lightSensorWarmUpTime, int brightnessMin, int brightnessMax, float dozeScaleFactor,
|
||||
int lightSensorRate, int initialLightSensorRate, long brighteningLightDebounceConfig,
|
||||
long darkeningLightDebounceConfig, boolean resetAmbientLuxAfterWarmUpConfig,
|
||||
HysteresisLevels ambientBrightnessThresholds,
|
||||
HysteresisLevels screenBrightnessThresholds, long shortTermModelTimeout,
|
||||
PackageManager packageManager) {
|
||||
mInjector = injector;
|
||||
mCallbacks = callbacks;
|
||||
mSensorManager = sensorManager;
|
||||
mBrightnessMapper = mapper;
|
||||
@@ -725,8 +746,8 @@ class AutomaticBrightnessController {
|
||||
float value = mBrightnessMapper.getBrightness(mAmbientLux, mForegroundAppPackageName,
|
||||
mForegroundAppCategory);
|
||||
|
||||
int newScreenAutoBrightness =
|
||||
clampScreenBrightness(Math.round(value * PowerManager.BRIGHTNESS_ON));
|
||||
int newScreenAutoBrightness = Math.round(clampScreenBrightness(
|
||||
value * PowerManager.BRIGHTNESS_ON));
|
||||
|
||||
// If screenAutoBrightness is set, we should have screen{Brightening,Darkening}Threshold,
|
||||
// in which case we ignore the new screen brightness if it doesn't differ enough from the
|
||||
@@ -750,10 +771,10 @@ class AutomaticBrightnessController {
|
||||
}
|
||||
|
||||
mScreenAutoBrightness = newScreenAutoBrightness;
|
||||
mScreenBrighteningThreshold =
|
||||
mScreenBrightnessThresholds.getBrighteningThreshold(newScreenAutoBrightness);
|
||||
mScreenDarkeningThreshold =
|
||||
mScreenBrightnessThresholds.getDarkeningThreshold(newScreenAutoBrightness);
|
||||
mScreenBrighteningThreshold = clampScreenBrightness(
|
||||
mScreenBrightnessThresholds.getBrighteningThreshold(newScreenAutoBrightness));
|
||||
mScreenDarkeningThreshold = clampScreenBrightness(
|
||||
mScreenBrightnessThresholds.getDarkeningThreshold(newScreenAutoBrightness));
|
||||
|
||||
if (sendUpdate) {
|
||||
mCallbacks.updateBrightness();
|
||||
@@ -761,7 +782,7 @@ class AutomaticBrightnessController {
|
||||
}
|
||||
}
|
||||
|
||||
private int clampScreenBrightness(int value) {
|
||||
private float clampScreenBrightness(float value) {
|
||||
return MathUtils.constrain(value,
|
||||
mScreenBrightnessRangeMinimum, mScreenBrightnessRangeMaximum);
|
||||
}
|
||||
@@ -839,7 +860,7 @@ class AutomaticBrightnessController {
|
||||
}
|
||||
// The ActivityTaskManager's lock tends to get contended, so this is done in a background
|
||||
// thread and applied via this thread's handler synchronously.
|
||||
BackgroundThread.getHandler().post(new Runnable() {
|
||||
mInjector.getBackgroundThreadHandler().post(new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
// The foreground app is the top activity of the focused tasks stack.
|
||||
@@ -965,6 +986,9 @@ class AutomaticBrightnessController {
|
||||
private int mCount;
|
||||
|
||||
public AmbientLightRingBuffer(long lightSensorRate, int ambientLightHorizon) {
|
||||
if (lightSensorRate <= 0) {
|
||||
throw new IllegalArgumentException("lightSensorRate must be above 0");
|
||||
}
|
||||
mCapacity = (int) Math.ceil(ambientLightHorizon * BUFFER_SLACK / lightSensorRate);
|
||||
mRingLux = new float[mCapacity];
|
||||
mRingTime = new long[mCapacity];
|
||||
@@ -1076,4 +1100,10 @@ class AutomaticBrightnessController {
|
||||
return index;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Injector {
|
||||
public Handler getBackgroundThreadHandler() {
|
||||
return BackgroundThread.getHandler();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,13 +18,16 @@ package com.android.server.display;
|
||||
|
||||
import android.util.Slog;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* A helper class for handling access to illuminance hysteresis level values.
|
||||
*/
|
||||
final class HysteresisLevels {
|
||||
@VisibleForTesting
|
||||
public class HysteresisLevels {
|
||||
private static final String TAG = "HysteresisLevels";
|
||||
|
||||
// Default hysteresis constraints for brightening or darkening.
|
||||
@@ -60,7 +63,7 @@ final class HysteresisLevels {
|
||||
/**
|
||||
* Return the brightening hysteresis threshold for the given value level.
|
||||
*/
|
||||
float getBrighteningThreshold(float value) {
|
||||
public float getBrighteningThreshold(float value) {
|
||||
float brightConstant = getReferenceLevel(value, mBrighteningThresholds);
|
||||
float brightThreshold = value * (1.0f + brightConstant);
|
||||
if (DEBUG) {
|
||||
@@ -73,7 +76,7 @@ final class HysteresisLevels {
|
||||
/**
|
||||
* Return the darkening hysteresis threshold for the given value level.
|
||||
*/
|
||||
float getDarkeningThreshold(float value) {
|
||||
public float getDarkeningThreshold(float value) {
|
||||
float darkConstant = getReferenceLevel(value, mDarkeningThresholds);
|
||||
float darkThreshold = value * (1.0f - darkConstant);
|
||||
if (DEBUG) {
|
||||
|
||||
@@ -0,0 +1,192 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.any;
|
||||
import static org.mockito.Mockito.anyFloat;
|
||||
import static org.mockito.Mockito.anyInt;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.hardware.Sensor;
|
||||
import android.hardware.SensorEventListener;
|
||||
import android.hardware.SensorManager;
|
||||
import android.hardware.display.DisplayManagerInternal.DisplayPowerRequest;
|
||||
import android.os.Handler;
|
||||
|
||||
import androidx.test.InstrumentationRegistry;
|
||||
import androidx.test.filters.SmallTest;
|
||||
import androidx.test.runner.AndroidJUnit4;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
@SmallTest
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class AutomaticBrightnessControllerTest {
|
||||
|
||||
private static final int BRIGHTNESS_MIN = 1;
|
||||
private static final int BRIGHTNESS_MAX = 255;
|
||||
private static final int LIGHT_SENSOR_RATE = 20;
|
||||
private static final int INITIAL_LIGHT_SENSOR_RATE = 20;
|
||||
private static final int BRIGHTENING_LIGHT_DEBOUNCE_CONFIG = 0;
|
||||
private static final int DARKENING_LIGHT_DEBOUNCE_CONFIG = 0;
|
||||
private static final int SHORT_TERM_MODEL_TIMEOUT = 0;
|
||||
private static final float DOZE_SCALE_FACTOR = 0.0f;
|
||||
private static final boolean RESET_AMBIENT_LUX_AFTER_WARMUP_CONFIG = false;
|
||||
|
||||
private Context mContext;
|
||||
@Mock SensorManager mSensorManager;
|
||||
@Mock BrightnessMappingStrategy mBrightnessMappingStrategy;
|
||||
@Mock HysteresisLevels mAmbientBrightnessThresholds;
|
||||
@Mock HysteresisLevels mScreenBrightnessThresholds;
|
||||
@Mock PackageManager mPackageManager;
|
||||
@Mock Handler mNoopHandler;
|
||||
|
||||
private static final int LIGHT_SENSOR_WARMUP_TIME = 0;
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
mContext = InstrumentationRegistry.getContext();
|
||||
}
|
||||
|
||||
private AutomaticBrightnessController setupController(Sensor lightSensor) {
|
||||
AutomaticBrightnessController controller = new AutomaticBrightnessController(
|
||||
new AutomaticBrightnessController.Injector() {
|
||||
@Override
|
||||
public Handler getBackgroundThreadHandler() {
|
||||
return mNoopHandler;
|
||||
}
|
||||
},
|
||||
() -> { }, mContext.getMainLooper(), mSensorManager, lightSensor,
|
||||
mBrightnessMappingStrategy, LIGHT_SENSOR_WARMUP_TIME, BRIGHTNESS_MIN,
|
||||
BRIGHTNESS_MAX, DOZE_SCALE_FACTOR, LIGHT_SENSOR_RATE, INITIAL_LIGHT_SENSOR_RATE,
|
||||
BRIGHTENING_LIGHT_DEBOUNCE_CONFIG, DARKENING_LIGHT_DEBOUNCE_CONFIG,
|
||||
RESET_AMBIENT_LUX_AFTER_WARMUP_CONFIG, mAmbientBrightnessThresholds,
|
||||
mScreenBrightnessThresholds, SHORT_TERM_MODEL_TIMEOUT, mPackageManager);
|
||||
controller.setLoggingEnabled(true);
|
||||
|
||||
// Configure the brightness controller and grab an instance of the sensor listener,
|
||||
// through which we can deliver fake (for test) sensor values.
|
||||
controller.configure(true /* enable */, null /* configuration */,
|
||||
0 /* brightness */, false /* userChangedBrightness */, 0 /* adjustment */,
|
||||
false /* userChanged */, DisplayPowerRequest.POLICY_BRIGHT);
|
||||
|
||||
return controller;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoHysteresisAtMinBrightness() throws Exception {
|
||||
Sensor lightSensor = TestUtils.createSensor(Sensor.TYPE_LIGHT, "Light Sensor");
|
||||
AutomaticBrightnessController controller = setupController(lightSensor);
|
||||
|
||||
ArgumentCaptor<SensorEventListener> listenerCaptor =
|
||||
ArgumentCaptor.forClass(SensorEventListener.class);
|
||||
verify(mSensorManager).registerListener(listenerCaptor.capture(), eq(lightSensor),
|
||||
eq(INITIAL_LIGHT_SENSOR_RATE * 1000), any(Handler.class));
|
||||
SensorEventListener listener = listenerCaptor.getValue();
|
||||
|
||||
// Set up system to return 5 as a brightness value
|
||||
float lux1 = 100.0f;
|
||||
float normalizedBrightness1 = 0.02f;
|
||||
when(mAmbientBrightnessThresholds.getBrighteningThreshold(lux1))
|
||||
.thenReturn(lux1);
|
||||
when(mAmbientBrightnessThresholds.getDarkeningThreshold(lux1))
|
||||
.thenReturn(lux1);
|
||||
when(mBrightnessMappingStrategy.getBrightness(eq(lux1), eq(null), anyInt()))
|
||||
.thenReturn(normalizedBrightness1);
|
||||
|
||||
// This is the important bit: When the new brightness is set, make sure the new
|
||||
// brightening threshold is beyond the maximum brightness value...so that we can test that
|
||||
// our threshold clamping works.
|
||||
when(mScreenBrightnessThresholds.getBrighteningThreshold(5)).thenReturn(1.0f);
|
||||
|
||||
// Send new sensor value and verify
|
||||
listener.onSensorChanged(TestUtils.createSensorEvent(lightSensor, (int) lux1));
|
||||
assertEquals(5, controller.getAutomaticScreenBrightness());
|
||||
|
||||
|
||||
// Set up system to return 255 as a brightness value
|
||||
float lux2 = 10.0f;
|
||||
float normalizedBrightness2 = 0.0f;
|
||||
when(mAmbientBrightnessThresholds.getBrighteningThreshold(lux2))
|
||||
.thenReturn(lux2);
|
||||
when(mAmbientBrightnessThresholds.getDarkeningThreshold(lux2))
|
||||
.thenReturn(lux2);
|
||||
when(mBrightnessMappingStrategy.getBrightness(anyFloat(), eq(null), anyInt()))
|
||||
.thenReturn(normalizedBrightness2);
|
||||
|
||||
// Send new sensor value and verify
|
||||
listener.onSensorChanged(TestUtils.createSensorEvent(lightSensor, (int) lux2));
|
||||
assertEquals(1, controller.getAutomaticScreenBrightness());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoHysteresisAtMaxBrightness() throws Exception {
|
||||
Sensor lightSensor = TestUtils.createSensor(Sensor.TYPE_LIGHT, "Light Sensor");
|
||||
AutomaticBrightnessController controller = setupController(lightSensor);
|
||||
|
||||
ArgumentCaptor<SensorEventListener> listenerCaptor =
|
||||
ArgumentCaptor.forClass(SensorEventListener.class);
|
||||
verify(mSensorManager).registerListener(listenerCaptor.capture(), eq(lightSensor),
|
||||
eq(INITIAL_LIGHT_SENSOR_RATE * 1000), any(Handler.class));
|
||||
SensorEventListener listener = listenerCaptor.getValue();
|
||||
|
||||
// Set up system to return 250 as a brightness value
|
||||
float lux1 = 100.0f;
|
||||
float normalizedBrightness1 = 0.98f;
|
||||
when(mAmbientBrightnessThresholds.getBrighteningThreshold(lux1))
|
||||
.thenReturn(lux1);
|
||||
when(mAmbientBrightnessThresholds.getDarkeningThreshold(lux1))
|
||||
.thenReturn(lux1);
|
||||
when(mBrightnessMappingStrategy.getBrightness(eq(lux1), eq(null), anyInt()))
|
||||
.thenReturn(normalizedBrightness1);
|
||||
|
||||
// This is the important bit: When the new brightness is set, make sure the new
|
||||
// brightening threshold is beyond the maximum brightness value...so that we can test that
|
||||
// our threshold clamping works.
|
||||
when(mScreenBrightnessThresholds.getBrighteningThreshold(250)).thenReturn(260.0f);
|
||||
|
||||
// Send new sensor value and verify
|
||||
listener.onSensorChanged(TestUtils.createSensorEvent(lightSensor, (int) lux1));
|
||||
assertEquals(250, controller.getAutomaticScreenBrightness());
|
||||
|
||||
|
||||
// Set up system to return 255 as a brightness value
|
||||
float lux2 = 110.0f;
|
||||
float normalizedBrightness2 = 1.0f;
|
||||
when(mAmbientBrightnessThresholds.getBrighteningThreshold(lux2))
|
||||
.thenReturn(lux2);
|
||||
when(mAmbientBrightnessThresholds.getDarkeningThreshold(lux2))
|
||||
.thenReturn(lux2);
|
||||
when(mBrightnessMappingStrategy.getBrightness(anyFloat(), eq(null), anyInt()))
|
||||
.thenReturn(normalizedBrightness2);
|
||||
|
||||
// Send new sensor value and verify
|
||||
listener.onSensorChanged(TestUtils.createSensorEvent(lightSensor, (int) lux2));
|
||||
assertEquals(255, controller.getAutomaticScreenBrightness());
|
||||
}
|
||||
}
|
||||
@@ -11,7 +11,7 @@
|
||||
* 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
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.server.display;
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import android.hardware.Sensor;
|
||||
import android.hardware.SensorEvent;
|
||||
import android.os.SystemClock;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public final class TestUtils {
|
||||
|
||||
public static SensorEvent createSensorEvent(Sensor sensor, int lux) throws Exception {
|
||||
final Constructor<SensorEvent> constructor =
|
||||
SensorEvent.class.getDeclaredConstructor(int.class);
|
||||
constructor.setAccessible(true);
|
||||
final SensorEvent event = constructor.newInstance(1);
|
||||
event.sensor = sensor;
|
||||
event.values[0] = lux;
|
||||
event.timestamp = SystemClock.elapsedRealtimeNanos();
|
||||
return event;
|
||||
}
|
||||
|
||||
|
||||
public static 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);
|
||||
}
|
||||
}
|
||||
|
||||
public static 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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -16,29 +16,19 @@
|
||||
|
||||
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.Mockito.doAnswer;
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.anyLong;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import org.mockito.stubbing.Answer;
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.mockito.Spy;
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
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;
|
||||
@@ -46,15 +36,21 @@ import android.util.TypedValue;
|
||||
|
||||
import androidx.test.InstrumentationRegistry;
|
||||
|
||||
import com.android.internal.R;
|
||||
import com.android.server.display.TestUtils;
|
||||
import com.android.server.display.whitebalance.AmbientFilter;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.JUnit4;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
import org.mockito.stubbing.Answer;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.List;
|
||||
|
||||
@RunWith(JUnit4.class)
|
||||
@@ -80,8 +76,8 @@ public final class AmbientLuxTest {
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mLightSensor = createSensor(Sensor.TYPE_LIGHT, null);
|
||||
mAmbientColorSensor = createSensor(AMBIENT_COLOR_TYPE, AMBIENT_COLOR_TYPE_STR);
|
||||
mLightSensor = TestUtils.createSensor(Sensor.TYPE_LIGHT, null);
|
||||
mAmbientColorSensor = TestUtils.createSensor(AMBIENT_COLOR_TYPE, AMBIENT_COLOR_TYPE_STR);
|
||||
mContextSpy = spy(new ContextWrapper(InstrumentationRegistry.getContext()));
|
||||
mResourcesSpy = spy(mContextSpy.getResources());
|
||||
when(mContextSpy.getResources()).thenReturn(mResourcesSpy);
|
||||
@@ -460,25 +456,6 @@ public final class AmbientLuxTest {
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
@@ -28,15 +28,14 @@ import static org.mockito.Mockito.when;
|
||||
import android.content.ContextWrapper;
|
||||
import android.content.res.Resources;
|
||||
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.os.SystemClock;
|
||||
|
||||
import androidx.test.InstrumentationRegistry;
|
||||
|
||||
import com.android.server.display.TestUtils;
|
||||
import com.android.server.display.whitebalance.AmbientSensor.AmbientBrightnessSensor;
|
||||
import com.android.server.display.whitebalance.AmbientSensor.AmbientColorTemperatureSensor;
|
||||
|
||||
@@ -50,9 +49,6 @@ import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
@@ -73,8 +69,8 @@ public final class AmbientSensorTest {
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mLightSensor = createSensor(Sensor.TYPE_LIGHT, null);
|
||||
mAmbientColorSensor = createSensor(AMBIENT_COLOR_TYPE, AMBIENT_COLOR_TYPE_STR);
|
||||
mLightSensor = TestUtils.createSensor(Sensor.TYPE_LIGHT, null);
|
||||
mAmbientColorSensor = TestUtils.createSensor(AMBIENT_COLOR_TYPE, AMBIENT_COLOR_TYPE_STR);
|
||||
mContextSpy = spy(new ContextWrapper(InstrumentationRegistry.getContext()));
|
||||
mResourcesSpy = spy(mContextSpy.getResources());
|
||||
when(mContextSpy.getResources()).thenReturn(mResourcesSpy);
|
||||
@@ -96,7 +92,7 @@ public final class AmbientSensorTest {
|
||||
// There should be no issues when we callback the listener, even if there is no callback
|
||||
// set.
|
||||
SensorEventListener listener = captor.getValue();
|
||||
listener.onSensorChanged(createSensorEvent(mLightSensor, 100));
|
||||
listener.onSensorChanged(TestUtils.createSensorEvent(mLightSensor, 100));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -122,7 +118,7 @@ public final class AmbientSensorTest {
|
||||
verify(mSensorManagerMock).registerListener(captor.capture(), eq(mLightSensor),
|
||||
anyInt(), eq(mHandler));
|
||||
SensorEventListener listener = captor.getValue();
|
||||
listener.onSensorChanged(createSensorEvent(mLightSensor, luxValue));
|
||||
listener.onSensorChanged(TestUtils.createSensorEvent(mLightSensor, luxValue));
|
||||
assertTrue(changeSignal.await(5, TimeUnit.SECONDS));
|
||||
assertEquals(luxValue, luxReturned[0]);
|
||||
}
|
||||
@@ -155,39 +151,8 @@ public final class AmbientSensorTest {
|
||||
verify(mSensorManagerMock).registerListener(captor.capture(), eq(mAmbientColorSensor),
|
||||
anyInt(), eq(mHandler));
|
||||
SensorEventListener listener = captor.getValue();
|
||||
listener.onSensorChanged(createSensorEvent(mAmbientColorSensor, colorTempValue));
|
||||
listener.onSensorChanged(TestUtils.createSensorEvent(mAmbientColorSensor, colorTempValue));
|
||||
assertTrue(changeSignal.await(5, TimeUnit.SECONDS));
|
||||
assertEquals(colorTempValue, colorTempReturned[0]);
|
||||
}
|
||||
|
||||
private SensorEvent createSensorEvent(Sensor sensor, int lux) throws Exception {
|
||||
final Constructor<SensorEvent> constructor =
|
||||
SensorEvent.class.getDeclaredConstructor(int.class);
|
||||
constructor.setAccessible(true);
|
||||
final SensorEvent event = constructor.newInstance(1);
|
||||
event.sensor = sensor;
|
||||
event.values[0] = lux;
|
||||
event.timestamp = SystemClock.elapsedRealtimeNanos();
|
||||
return event;
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user