blob: 6ff4f3b22b9c3c6c138f46798daaddd4396fcd83 [file] [log] [blame]
Santos Cordonceb0ae12019-04-29 18:06:09 +01001/*
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 static org.junit.Assert.assertEquals;
20import static org.junit.Assert.assertTrue;
21import static org.mockito.ArgumentMatchers.anyInt;
22import static org.mockito.ArgumentMatchers.eq;
23import static org.mockito.ArgumentMatchers.isA;
24import static org.mockito.Mockito.spy;
25import static org.mockito.Mockito.verify;
26import static org.mockito.Mockito.when;
27
28import android.content.ContextWrapper;
29import android.content.res.Resources;
30import android.hardware.Sensor;
31import android.hardware.SensorEvent;
32import android.hardware.SensorEventListener;
33import android.hardware.SensorManager;
34import android.os.Handler;
35import android.os.Looper;
36import android.os.SystemClock;
37
38import androidx.test.InstrumentationRegistry;
39
40import com.android.server.display.whitebalance.AmbientSensor.AmbientBrightnessSensor;
41import com.android.server.display.whitebalance.AmbientSensor.AmbientColorTemperatureSensor;
42
43import com.google.common.collect.ImmutableList;
44
45import org.junit.Before;
46import org.junit.Test;
47import org.junit.runner.RunWith;
48import org.junit.runners.JUnit4;
49import org.mockito.ArgumentCaptor;
50import org.mockito.Mock;
51import org.mockito.MockitoAnnotations;
52
53import java.lang.reflect.Constructor;
54import java.lang.reflect.Field;
55import java.lang.reflect.Method;
56import java.util.List;
57import java.util.concurrent.CountDownLatch;
58import java.util.concurrent.TimeUnit;
59
60@RunWith(JUnit4.class)
61public final class AmbientSensorTest {
62 private static final int AMBIENT_COLOR_TYPE = 20705;
63 private static final String AMBIENT_COLOR_TYPE_STR = "colorSensoryDensoryDoc";
64
65 private Handler mHandler = new Handler(Looper.getMainLooper());
66 private Sensor mLightSensor;
67 private Sensor mAmbientColorSensor;
68 private ContextWrapper mContextSpy;
69 private Resources mResourcesSpy;
70
71 @Mock private SensorManager mSensorManagerMock;
72
73 @Before
74 public void setUp() throws Exception {
75 MockitoAnnotations.initMocks(this);
76 mLightSensor = createSensor(Sensor.TYPE_LIGHT, null);
77 mAmbientColorSensor = createSensor(AMBIENT_COLOR_TYPE, AMBIENT_COLOR_TYPE_STR);
78 mContextSpy = spy(new ContextWrapper(InstrumentationRegistry.getContext()));
79 mResourcesSpy = spy(mContextSpy.getResources());
80 when(mContextSpy.getResources()).thenReturn(mResourcesSpy);
81 }
82
83 @Test
84 public void testAmbientBrightnessSensorCallback_NoCallbacks() throws Exception {
85 when(mSensorManagerMock.getDefaultSensor(Sensor.TYPE_LIGHT)).thenReturn(mLightSensor);
86 AmbientBrightnessSensor abs = DisplayWhiteBalanceFactory.createBrightnessSensor(
87 mHandler, mSensorManagerMock, InstrumentationRegistry.getContext().getResources());
88
89 abs.setCallbacks(null);
90 abs.setEnabled(true);
91 ArgumentCaptor<SensorEventListener> captor =
92 ArgumentCaptor.forClass(SensorEventListener.class);
93 verify(mSensorManagerMock).registerListener(captor.capture(), isA(Sensor.class), anyInt(),
94 isA(Handler.class));
95
96 // There should be no issues when we callback the listener, even if there is no callback
97 // set.
98 SensorEventListener listener = captor.getValue();
99 listener.onSensorChanged(createSensorEvent(mLightSensor, 100));
100 }
101
102 @Test
103 public void testAmbientBrightnessSensorCallback_CallbacksCalled() throws Exception {
104 final int luxValue = 83;
105 when(mSensorManagerMock.getDefaultSensor(Sensor.TYPE_LIGHT)).thenReturn(mLightSensor);
106 AmbientBrightnessSensor abs = DisplayWhiteBalanceFactory.createBrightnessSensor(
107 mHandler, mSensorManagerMock, InstrumentationRegistry.getContext().getResources());
108
109 final int[] luxReturned = new int[] { -1 };
110 final CountDownLatch changeSignal = new CountDownLatch(1);
111 abs.setCallbacks(new AmbientBrightnessSensor.Callbacks() {
112 @Override
113 public void onAmbientBrightnessChanged(float value) {
114 luxReturned[0] = (int) value;
115 changeSignal.countDown();
116 }
117 });
118
119 abs.setEnabled(true);
120 ArgumentCaptor<SensorEventListener> captor =
121 ArgumentCaptor.forClass(SensorEventListener.class);
122 verify(mSensorManagerMock).registerListener(captor.capture(), eq(mLightSensor),
123 anyInt(), eq(mHandler));
124 SensorEventListener listener = captor.getValue();
125 listener.onSensorChanged(createSensorEvent(mLightSensor, luxValue));
126 assertTrue(changeSignal.await(5, TimeUnit.SECONDS));
127 assertEquals(luxValue, luxReturned[0]);
128 }
129
130 @Test
131 public void testAmbientColorTemperatureSensorCallback_CallbacksCalled() throws Exception {
132 final int colorTempValue = 79;
133 final List<Sensor> sensorList = ImmutableList.of(mLightSensor, mAmbientColorSensor);
134 when(mSensorManagerMock.getSensorList(Sensor.TYPE_ALL)).thenReturn(sensorList);
135 when(mResourcesSpy.getString(
136 com.android.internal.R.string.config_displayWhiteBalanceColorTemperatureSensorName))
137 .thenReturn(AMBIENT_COLOR_TYPE_STR);
138
139 AmbientColorTemperatureSensor abs = DisplayWhiteBalanceFactory.createColorTemperatureSensor(
140 mHandler, mSensorManagerMock, mResourcesSpy);
141
142 final int[] colorTempReturned = new int[] { -1 };
143 final CountDownLatch changeSignal = new CountDownLatch(1);
144 abs.setCallbacks(new AmbientColorTemperatureSensor.Callbacks() {
145 @Override
146 public void onAmbientColorTemperatureChanged(float value) {
147 colorTempReturned[0] = (int) value;
148 changeSignal.countDown();
149 }
150 });
151
152 abs.setEnabled(true);
153 ArgumentCaptor<SensorEventListener> captor =
154 ArgumentCaptor.forClass(SensorEventListener.class);
155 verify(mSensorManagerMock).registerListener(captor.capture(), eq(mAmbientColorSensor),
156 anyInt(), eq(mHandler));
157 SensorEventListener listener = captor.getValue();
158 listener.onSensorChanged(createSensorEvent(mAmbientColorSensor, colorTempValue));
159 assertTrue(changeSignal.await(5, TimeUnit.SECONDS));
160 assertEquals(colorTempValue, colorTempReturned[0]);
161 }
162
163 private SensorEvent createSensorEvent(Sensor sensor, int lux) throws Exception {
164 final Constructor<SensorEvent> constructor =
165 SensorEvent.class.getDeclaredConstructor(int.class);
166 constructor.setAccessible(true);
167 final SensorEvent event = constructor.newInstance(1);
168 event.sensor = sensor;
169 event.values[0] = lux;
170 event.timestamp = SystemClock.elapsedRealtimeNanos();
171 return event;
172 }
173
174
175 private void setSensorType(Sensor sensor, int type, String strType) throws Exception {
176 Method setter = Sensor.class.getDeclaredMethod("setType", Integer.TYPE);
177 setter.setAccessible(true);
178 setter.invoke(sensor, type);
179 if (strType != null) {
180 Field f = sensor.getClass().getDeclaredField("mStringType");
181 f.setAccessible(true);
182 f.set(sensor, strType);
183 }
184 }
185
186 private Sensor createSensor(int type, String strType) throws Exception {
187 Constructor<Sensor> constr = Sensor.class.getDeclaredConstructor();
188 constr.setAccessible(true);
189 Sensor sensor = constr.newInstance();
190 setSensorType(sensor, type, strType);
191 return sensor;
192 }
193}