• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 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 
17 package android.hardware.input;
18 
19 import static android.hardware.lights.LightsRequest.Builder;
20 
21 import static com.google.common.truth.Truth.assertThat;
22 
23 import static junit.framework.TestCase.assertEquals;
24 import static junit.framework.TestCase.assertNotNull;
25 
26 import static org.junit.Assert.assertTrue;
27 import static org.mockito.ArgumentMatchers.any;
28 import static org.mockito.ArgumentMatchers.anyInt;
29 import static org.mockito.ArgumentMatchers.eq;
30 import static org.mockito.Mockito.doAnswer;
31 import static org.mockito.Mockito.spy;
32 import static org.mockito.Mockito.verify;
33 import static org.mockito.Mockito.when;
34 
35 import android.content.Context;
36 import android.content.ContextWrapper;
37 import android.hardware.lights.Light;
38 import android.hardware.lights.LightState;
39 import android.hardware.lights.LightsManager;
40 import android.hardware.lights.LightsRequest;
41 import android.os.IBinder;
42 import android.platform.test.annotations.Presubmit;
43 import android.util.ArrayMap;
44 import android.view.InputDevice;
45 
46 import androidx.test.platform.app.InstrumentationRegistry;
47 
48 import com.android.test.input.MockInputManagerRule;
49 
50 import org.junit.After;
51 import org.junit.Before;
52 import org.junit.Rule;
53 import org.junit.Test;
54 import org.junit.runner.RunWith;
55 import org.mockito.junit.MockitoJUnitRunner;
56 
57 import java.util.ArrayList;
58 import java.util.Arrays;
59 import java.util.List;
60 
61 /**
62  * Tests for {@link InputDeviceLightsManager}.
63  *
64  * Build/Install/Run:
65  * atest InputTests:InputDeviceLightsManagerTest
66  */
67 @Presubmit
68 @RunWith(MockitoJUnitRunner.class)
69 public class InputDeviceLightsManagerTest {
70     private static final String TAG = "InputDeviceLightsManagerTest";
71 
72     private static final int DEVICE_ID = 1000;
73     private static final int PLAYER_ID = 3;
74 
75     @Rule
76     public final MockInputManagerRule mInputManagerRule = new MockInputManagerRule();
77 
78     private InputManager mInputManager;
79 
80     private InputManagerGlobal.TestSession mInputManagerGlobalSession;
81 
82     @Before
setUp()83     public void setUp() throws Exception {
84         final Context context = spy(
85                 new ContextWrapper(InstrumentationRegistry.getInstrumentation().getContext()));
86         when(mInputManagerRule.getMock().getInputDeviceIds()).thenReturn(new int[]{DEVICE_ID});
87 
88         when(mInputManagerRule.getMock().getInputDevice(eq(DEVICE_ID))).thenReturn(
89                 createInputDevice(DEVICE_ID));
90 
91         mInputManager = new InputManager(context);
92         when(context.getSystemService(eq(Context.INPUT_SERVICE))).thenReturn(mInputManager);
93 
94         ArrayMap<Integer, LightState> lightStatesById = new ArrayMap<>();
95         doAnswer(invocation -> {
96             final int[] lightIds = (int[]) invocation.getArguments()[1];
97             final LightState[] lightStates =
98                     (LightState[]) invocation.getArguments()[2];
99             for (int i = 0; i < lightIds.length; i++) {
100                 lightStatesById.put(lightIds[i], lightStates[i]);
101             }
102             return null;
103         }).when(mInputManagerRule.getMock()).setLightStates(eq(DEVICE_ID),
104                 any(int[].class), any(LightState[].class), any(IBinder.class));
105 
106         doAnswer(invocation -> {
107             int lightId = (int) invocation.getArguments()[1];
108             if (lightStatesById.containsKey(lightId)) {
109                 return lightStatesById.get(lightId);
110             }
111             return new LightState(0);
112         }).when(mInputManagerRule.getMock()).getLightState(eq(DEVICE_ID), anyInt());
113     }
114 
115     @After
tearDown()116     public void tearDown() {
117         if (mInputManagerGlobalSession != null) {
118             mInputManagerGlobalSession.close();
119         }
120     }
121 
createInputDevice(int id)122     private InputDevice createInputDevice(int id) {
123         return new InputDevice.Builder()
124                 .setId(id)
125                 .setName("Test Device " + id)
126                 .build();
127     }
128 
mockLights(Light[] lights)129     private void mockLights(Light[] lights) throws Exception {
130         // Mock the Lights returned form InputManagerService
131         when(mInputManagerRule.getMock().getLights(eq(DEVICE_ID))).thenReturn(
132                 new ArrayList(Arrays.asList(lights)));
133     }
134 
135     @Test
testGetInputDeviceLights()136     public void testGetInputDeviceLights() throws Exception {
137         InputDevice device = mInputManager.getInputDevice(DEVICE_ID);
138         assertNotNull(device);
139 
140         Light[] mockedLights = {
141             new Light(1 /* id */, "Light1", 0 /* ordinal */, Light.LIGHT_TYPE_INPUT,
142                         Light.LIGHT_CAPABILITY_BRIGHTNESS),
143             new Light(2 /* id */, "Light2", 0 /* ordinal */, Light.LIGHT_TYPE_INPUT,
144                         Light.LIGHT_CAPABILITY_COLOR_RGB),
145             new Light(3 /* id */, "Light3", 0 /* ordinal */, Light.LIGHT_TYPE_INPUT,
146                         0 /* capabilities */)
147         };
148         mockLights(mockedLights);
149 
150         LightsManager lightsManager = device.getLightsManager();
151         List<Light> lights = lightsManager.getLights();
152         verify(mInputManagerRule.getMock()).getLights(eq(DEVICE_ID));
153         assertEquals(lights, Arrays.asList(mockedLights));
154     }
155 
156     @Test
testControlMultipleLights()157     public void testControlMultipleLights() throws Exception {
158         InputDevice device = mInputManager.getInputDevice(DEVICE_ID);
159         assertNotNull(device);
160 
161         Light[] mockedLights = {
162             new Light(1 /* id */, "Light1", 0 /* ordinal */, Light.LIGHT_TYPE_INPUT,
163                         Light.LIGHT_CAPABILITY_COLOR_RGB),
164             new Light(2 /* id */, "Light2", 0 /* ordinal */, Light.LIGHT_TYPE_INPUT,
165                         Light.LIGHT_CAPABILITY_COLOR_RGB),
166             new Light(3 /* id */, "Light3", 0 /* ordinal */, Light.LIGHT_TYPE_INPUT,
167                         Light.LIGHT_CAPABILITY_COLOR_RGB),
168             new Light(4 /* id */, "Light4", 0 /* ordinal */, Light.LIGHT_TYPE_INPUT,
169                         Light.LIGHT_CAPABILITY_COLOR_RGB)
170         };
171         mockLights(mockedLights);
172 
173         LightsManager lightsManager = device.getLightsManager();
174         List<Light> lightList = lightsManager.getLights();
175         LightState[] states = new LightState[]{new LightState(0xf1), new LightState(0xf2),
176                 new LightState(0xf3)};
177         // Open a session to request turn 3/4 lights on:
178         LightsManager.LightsSession session = lightsManager.openSession();
179         session.requestLights(new Builder()
180                 .addLight(lightsManager.getLights().get(0), states[0])
181                 .addLight(lightsManager.getLights().get(1), states[1])
182                 .addLight(lightsManager.getLights().get(2), states[2])
183                 .build());
184         IBinder token = session.getToken();
185 
186         verify(mInputManagerRule.getMock()).openLightSession(eq(DEVICE_ID),
187                 any(String.class), eq(token));
188         verify(mInputManagerRule.getMock()).setLightStates(eq(DEVICE_ID), eq(new int[]{1, 2, 3}),
189                 eq(states), eq(token));
190 
191         // Then all 3 should turn on.
192         assertThat(lightsManager.getLightState(lightsManager.getLights().get(0)).getColor())
193                 .isEqualTo(0xf1);
194         assertThat(lightsManager.getLightState(lightsManager.getLights().get(1)).getColor())
195                 .isEqualTo(0xf2);
196         assertThat(lightsManager.getLightState(lightsManager.getLights().get(2)).getColor())
197                 .isEqualTo(0xf3);
198 
199         // And the 4th should remain off.
200         assertThat(lightsManager.getLightState(lightsManager.getLights().get(3)).getColor())
201                 .isEqualTo(0x00);
202 
203         // close session
204         session.close();
205         verify(mInputManagerRule.getMock()).closeLightSession(eq(DEVICE_ID), eq(token));
206     }
207 
208     @Test
testControlPlayerIdLight()209     public void testControlPlayerIdLight() throws Exception {
210         InputDevice device = mInputManager.getInputDevice(DEVICE_ID);
211         assertNotNull(device);
212 
213         Light[] mockedLights = {
214                 new Light(1 /* id */, "Light1", 0 /* ordinal */, Light.LIGHT_TYPE_PLAYER_ID,
215                             0 /* capabilities */),
216                 new Light(2 /* id */, "Light2", 0 /* ordinal */, Light.LIGHT_TYPE_INPUT,
217                             Light.LIGHT_CAPABILITY_COLOR_RGB | Light.LIGHT_CAPABILITY_BRIGHTNESS),
218                 new Light(3 /* id */, "Light3", 0 /* ordinal */, Light.LIGHT_TYPE_INPUT,
219                             Light.LIGHT_CAPABILITY_BRIGHTNESS)
220         };
221         mockLights(mockedLights);
222 
223         LightsManager lightsManager = device.getLightsManager();
224         List<Light> lightList = lightsManager.getLights();
225         LightState[] states = new LightState[]{new LightState(0xf1, PLAYER_ID)};
226         // Open a session to request set Player ID light:
227         LightsManager.LightsSession session = lightsManager.openSession();
228         session.requestLights(new Builder()
229                 .addLight(lightsManager.getLights().get(0), states[0])
230                 .build());
231         IBinder token = session.getToken();
232 
233         verify(mInputManagerRule.getMock()).openLightSession(eq(DEVICE_ID),
234                 any(String.class), eq(token));
235         verify(mInputManagerRule.getMock()).setLightStates(eq(DEVICE_ID), eq(new int[]{1}),
236                 eq(states), eq(token));
237 
238         // Verify the light state
239         assertThat(lightsManager.getLightState(lightsManager.getLights().get(0)).getColor())
240                 .isEqualTo(0xf1);
241         assertThat(lightsManager.getLightState(lightsManager.getLights().get(0)).getPlayerId())
242                 .isEqualTo(PLAYER_ID);
243 
244         // close session
245         session.close();
246         verify(mInputManagerRule.getMock()).closeLightSession(eq(DEVICE_ID), eq(token));
247     }
248 
249     @Test
testLightCapabilities()250     public void testLightCapabilities() throws Exception {
251         Light light = new Light(1 /* id */, "Light1", 0 /* ordinal */, Light.LIGHT_TYPE_INPUT,
252                 Light.LIGHT_CAPABILITY_COLOR_RGB | Light.LIGHT_CAPABILITY_BRIGHTNESS);
253         assertThat(light.getType()).isEqualTo(Light.LIGHT_TYPE_INPUT);
254         assertThat(light.getCapabilities()).isEqualTo(Light.LIGHT_CAPABILITY_COLOR_RGB
255                 | Light.LIGHT_CAPABILITY_BRIGHTNESS);
256         assertTrue(light.hasBrightnessControl());
257         assertTrue(light.hasRgbControl());
258     }
259 
260     @Test
testLightsRequest()261     public void testLightsRequest() throws Exception {
262         Light light1 = new Light(1 /* id */, "Light1", 0 /* ordinal */, Light.LIGHT_TYPE_INPUT,
263                 0 /* capabilities */);
264         Light light2 = new Light(2 /* id */, "Light2", 0 /* ordinal */, Light.LIGHT_TYPE_PLAYER_ID,
265                 0 /* capabilities */);
266         LightState state1 = new LightState(0xf1);
267         LightState state2 = new LightState(0xf2, PLAYER_ID);
268         LightsRequest request = new Builder().addLight(light1, state1)
269                 .addLight(light2, state2).build();
270 
271         // Covers the LightsRequest.getLights
272         assertThat(request.getLights().size()).isEqualTo(2);
273         assertThat(request.getLights().get(0)).isEqualTo(1);
274         assertThat(request.getLights().get(1)).isEqualTo(2);
275 
276         // Covers the LightsRequest.getLightStates
277         assertThat(request.getLightStates().size()).isEqualTo(2);
278         assertThat(request.getLightStates().get(0)).isEqualTo(state1);
279         assertThat(request.getLightStates().get(1)).isEqualTo(state2);
280 
281         // Covers the LightsRequest.getLightsAndStates
282         assertThat(request.getLightsAndStates().size()).isEqualTo(2);
283         assertThat(request.getLightsAndStates().containsKey(light1)).isTrue();
284         assertThat(request.getLightsAndStates().get(light1)).isEqualTo(state1);
285         assertThat(request.getLightsAndStates().get(light2)).isEqualTo(state2);
286     }
287 
288 }
289