From a7991ab88856594e5a2121e5a9c745e1aa3d3544 Mon Sep 17 00:00:00 2001 From: Santos Cordon Date: Thu, 28 Nov 2019 11:24:21 +0000 Subject: Clamp brightness thresholds to the maximum brightness. Bug: 144702254 Test: atest AutomaticBrightnessControllerTest Change-Id: Ia8ac92cf306424d1324d028559f4260b9f80d482 Merged-In: Ia8ac92cf306424d1324d028559f4260b9f80d482 --- .../display/AutomaticBrightnessController.java | 48 +++++- .../android/server/display/HysteresisLevels.java | 9 +- .../display/AutomaticBrightnessControllerTest.java | 192 +++++++++++++++++++++ .../server/display/DisplayManagerServiceTest.java | 2 +- .../src/com/android/server/display/TestUtils.java | 60 +++++++ .../display/whitebalance/AmbientLuxTest.java | 55 ++---- .../display/whitebalance/AmbientSensorTest.java | 47 +---- 7 files changed, 320 insertions(+), 93 deletions(-) create mode 100644 services/tests/servicestests/src/com/android/server/display/AutomaticBrightnessControllerTest.java create mode 100644 services/tests/servicestests/src/com/android/server/display/TestUtils.java diff --git a/services/core/java/com/android/server/display/AutomaticBrightnessController.java b/services/core/java/com/android/server/display/AutomaticBrightnessController.java index 31632dc007a5..177e2d8b5fa2 100644 --- a/services/core/java/com/android/server/display/AutomaticBrightnessController.java +++ b/services/core/java/com/android/server/display/AutomaticBrightnessController.java @@ -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,26 @@ 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, + long darkeningLightDebounceConfig, boolean resetAmbientLuxAfterWarmUpConfig, + 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, @@ -223,6 +243,7 @@ class AutomaticBrightnessController { 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(); + } + } } diff --git a/services/core/java/com/android/server/display/HysteresisLevels.java b/services/core/java/com/android/server/display/HysteresisLevels.java index 2db1d03893d2..f0a505d4d818 100644 --- a/services/core/java/com/android/server/display/HysteresisLevels.java +++ b/services/core/java/com/android/server/display/HysteresisLevels.java @@ -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) { diff --git a/services/tests/servicestests/src/com/android/server/display/AutomaticBrightnessControllerTest.java b/services/tests/servicestests/src/com/android/server/display/AutomaticBrightnessControllerTest.java new file mode 100644 index 000000000000..f6c4d3aa5f5f --- /dev/null +++ b/services/tests/servicestests/src/com/android/server/display/AutomaticBrightnessControllerTest.java @@ -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 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 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()); + } +} diff --git a/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java index 4742a73b17a8..8d5939ad6ef6 100644 --- a/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java @@ -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; diff --git a/services/tests/servicestests/src/com/android/server/display/TestUtils.java b/services/tests/servicestests/src/com/android/server/display/TestUtils.java new file mode 100644 index 000000000000..859dfe3c3fa4 --- /dev/null +++ b/services/tests/servicestests/src/com/android/server/display/TestUtils.java @@ -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 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 constr = Sensor.class.getDeclaredConstructor(); + constr.setAccessible(true); + Sensor sensor = constr.newInstance(); + setSensorType(sensor, type, strType); + return sensor; + } + +} diff --git a/services/tests/servicestests/src/com/android/server/display/whitebalance/AmbientLuxTest.java b/services/tests/servicestests/src/com/android/server/display/whitebalance/AmbientLuxTest.java index 6b0798bdce22..e25c1c6c7291 100644 --- a/services/tests/servicestests/src/com/android/server/display/whitebalance/AmbientLuxTest.java +++ b/services/tests/servicestests/src/com/android/server/display/whitebalance/AmbientLuxTest.java @@ -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 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; diff --git a/services/tests/servicestests/src/com/android/server/display/whitebalance/AmbientSensorTest.java b/services/tests/servicestests/src/com/android/server/display/whitebalance/AmbientSensorTest.java index 6ff4f3b22b9c..3e3e535df986 100644 --- a/services/tests/servicestests/src/com/android/server/display/whitebalance/AmbientSensorTest.java +++ b/services/tests/servicestests/src/com/android/server/display/whitebalance/AmbientSensorTest.java @@ -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 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 constr = Sensor.class.getDeclaredConstructor(); - constr.setAccessible(true); - Sensor sensor = constr.newInstance(); - setSensorType(sensor, type, strType); - return sensor; - } } -- cgit v1.2.3-59-g8ed1b