GestureLauncherServiceTest.java revision acf62e66d62e6198986489311fbc8777d732155d
1/*
2 * Copyright (C) 2017 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;
18
19import static org.junit.Assert.assertFalse;
20import static org.junit.Assert.assertTrue;
21import static org.mockito.Matchers.anyInt;
22import static org.mockito.Mockito.verify;
23import static org.mockito.Mockito.when;
24
25import android.app.StatusBarManager;
26import android.content.Context;
27import android.content.res.Resources;
28import android.os.Looper;
29import android.os.UserHandle;
30import android.platform.test.annotations.Presubmit;
31import android.provider.Settings;
32import android.support.test.InstrumentationRegistry;
33import android.support.test.filters.SmallTest;
34import android.support.test.runner.AndroidJUnit4;
35import android.test.mock.MockContentResolver;
36import android.view.KeyEvent;
37import android.util.MutableBoolean;
38
39import com.android.internal.util.test.FakeSettingsProvider;
40import com.android.server.LocalServices;
41import com.android.server.statusbar.StatusBarManagerInternal;
42
43import org.junit.Before;
44import org.junit.BeforeClass;
45import org.junit.Test;
46import org.junit.runner.RunWith;
47import org.junit.runners.JUnit4;
48import org.mockito.Mock;
49import org.mockito.MockitoAnnotations;
50
51/**
52 * Unit tests for {@link GestureLauncherService}.
53 * runtest frameworks-services -c com.android.server.GestureLauncherServiceTest
54 */
55@Presubmit
56@SmallTest
57@RunWith(AndroidJUnit4.class)
58public class GestureLauncherServiceTest {
59
60    private static final int FAKE_USER_ID = 1337;
61    private static final int FAKE_SOURCE = 1982;
62    private static final long INITIAL_EVENT_TIME_MILLIS = 20000L;
63    private static final long IGNORED_DOWN_TIME = 1234L;
64    private static final int IGNORED_ACTION = 13;
65    private static final int IGNORED_CODE = 1999;
66    private static final int IGNORED_REPEAT = 42;
67
68    private @Mock Context mContext;
69    private @Mock Resources mResources;
70    private @Mock StatusBarManagerInternal mStatusBarManagerInternal;
71    private MockContentResolver mContentResolver;
72    private GestureLauncherService mGestureLauncherService;
73
74    @BeforeClass
75    public static void oneTimeInitialization() {
76        if (Looper.myLooper() == null) {
77            Looper.prepare();
78        }
79    }
80
81    @Before
82    public void setup() {
83        MockitoAnnotations.initMocks(this);
84
85        LocalServices.removeServiceForTest(StatusBarManagerInternal.class);
86        LocalServices.addService(StatusBarManagerInternal.class, mStatusBarManagerInternal);
87
88        final Context originalContext = InstrumentationRegistry.getContext();
89        when(mContext.getApplicationInfo()).thenReturn(originalContext.getApplicationInfo());
90        when(mContext.getResources()).thenReturn(mResources);
91        mContentResolver = new MockContentResolver(mContext);
92        mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
93        when(mContext.getContentResolver()).thenReturn(mContentResolver);
94
95        mGestureLauncherService = new GestureLauncherService(mContext);
96    }
97
98    @Test
99    public void testIsCameraDoubleTapPowerEnabled_configFalse() {
100        withCameraDoubleTapPowerEnableConfigValue(false);
101        assertFalse(mGestureLauncherService.isCameraDoubleTapPowerEnabled(mResources));
102    }
103
104    @Test
105    public void testIsCameraDoubleTapPowerEnabled_configTrue() {
106        withCameraDoubleTapPowerEnableConfigValue(true);
107        assertTrue(mGestureLauncherService.isCameraDoubleTapPowerEnabled(mResources));
108    }
109
110    @Test
111    public void testIsCameraDoubleTapPowerSettingEnabled_configFalseSettingDisabled() {
112        withCameraDoubleTapPowerEnableConfigValue(false);
113        withCameraDoubleTapPowerDisableSettingValue(1);
114        assertFalse(mGestureLauncherService.isCameraDoubleTapPowerSettingEnabled(
115                mContext, FAKE_USER_ID));
116    }
117
118    @Test
119    public void testIsCameraDoubleTapPowerSettingEnabled_configFalseSettingEnabled() {
120        withCameraDoubleTapPowerEnableConfigValue(false);
121        withCameraDoubleTapPowerDisableSettingValue(0);
122        assertFalse(mGestureLauncherService.isCameraDoubleTapPowerSettingEnabled(
123                mContext, FAKE_USER_ID));
124    }
125
126    @Test
127    public void testIsCameraDoubleTapPowerSettingEnabled_configTrueSettingDisabled() {
128        withCameraDoubleTapPowerEnableConfigValue(true);
129        withCameraDoubleTapPowerDisableSettingValue(1);
130        assertFalse(mGestureLauncherService.isCameraDoubleTapPowerSettingEnabled(
131                mContext, FAKE_USER_ID));
132    }
133
134    @Test
135    public void testIsCameraDoubleTapPowerSettingEnabled_configTrueSettingEnabled() {
136        withCameraDoubleTapPowerEnableConfigValue(true);
137        withCameraDoubleTapPowerDisableSettingValue(0);
138        assertTrue(mGestureLauncherService.isCameraDoubleTapPowerSettingEnabled(
139                mContext, FAKE_USER_ID));
140    }
141
142    @Test
143    public void testHandleCameraLaunchGesture_userSetupComplete() {
144        withUserSetupCompleteValue(true);
145
146        boolean useWakeLock = false;
147        assertTrue(mGestureLauncherService.handleCameraLaunchGesture(useWakeLock, FAKE_SOURCE));
148        verify(mStatusBarManagerInternal).onCameraLaunchGestureDetected(FAKE_SOURCE);
149    }
150
151    @Test
152    public void testHandleCameraLaunchGesture_userSetupNotComplete() {
153        withUserSetupCompleteValue(false);
154
155        boolean useWakeLock = false;
156        assertFalse(mGestureLauncherService.handleCameraLaunchGesture(useWakeLock, FAKE_SOURCE));
157    }
158
159    @Test
160    public void testInterceptPowerKeyDown_firstPowerDownCameraPowerGestureOnInteractive() {
161        withCameraDoubleTapPowerEnableConfigValue(true);
162        withCameraDoubleTapPowerDisableSettingValue(0);
163        mGestureLauncherService.updateCameraDoubleTapPowerEnabled();
164
165        long eventTime = INITIAL_EVENT_TIME_MILLIS +
166                GestureLauncherService.CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS - 1;
167        KeyEvent keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE,
168                IGNORED_REPEAT);
169        boolean interactive = true;
170        MutableBoolean outLaunched = new MutableBoolean(true);
171        boolean intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive,
172                outLaunched);
173        assertFalse(intercepted);
174        assertFalse(outLaunched.value);
175    }
176
177    @Test
178    public void testInterceptPowerKeyDown_intervalInBoundsCameraPowerGestureOffInteractive() {
179        withCameraDoubleTapPowerEnableConfigValue(false);
180        withCameraDoubleTapPowerDisableSettingValue(1);
181        mGestureLauncherService.updateCameraDoubleTapPowerEnabled();
182
183        long eventTime = INITIAL_EVENT_TIME_MILLIS;
184        KeyEvent keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE,
185                IGNORED_REPEAT);
186        boolean interactive = true;
187        MutableBoolean outLaunched = new MutableBoolean(true);
188        boolean intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive,
189                outLaunched);
190        assertFalse(intercepted);
191        assertFalse(outLaunched.value);
192
193        eventTime += GestureLauncherService.CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS - 1;
194        keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE,
195                IGNORED_REPEAT);
196        outLaunched.value = true;
197        intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive,
198                outLaunched);
199        assertFalse(intercepted);
200        assertFalse(outLaunched.value);
201    }
202
203    @Test
204    public void testInterceptPowerKeyDown_intervalOutOfBoundsCameraPowerGestureOffInteractive() {
205        withCameraDoubleTapPowerEnableConfigValue(false);
206        withCameraDoubleTapPowerDisableSettingValue(1);
207        mGestureLauncherService.updateCameraDoubleTapPowerEnabled();
208
209        long eventTime = INITIAL_EVENT_TIME_MILLIS;
210        KeyEvent keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE,
211                IGNORED_REPEAT);
212        boolean interactive = true;
213        MutableBoolean outLaunched = new MutableBoolean(true);
214        boolean intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive,
215                outLaunched);
216        assertFalse(intercepted);
217        assertFalse(outLaunched.value);
218
219        eventTime += GestureLauncherService.CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS;
220        keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE,
221                IGNORED_REPEAT);
222        outLaunched.value = true;
223        intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive,
224                outLaunched);
225        assertFalse(intercepted);
226        assertFalse(outLaunched.value);
227    }
228
229    @Test
230    public void
231    testInterceptPowerKeyDown_intervalInBoundsCameraPowerGestureOnInteractiveSetupComplete() {
232        withCameraDoubleTapPowerEnableConfigValue(true);
233        withCameraDoubleTapPowerDisableSettingValue(0);
234        mGestureLauncherService.updateCameraDoubleTapPowerEnabled();
235        withUserSetupCompleteValue(true);
236
237        long eventTime = INITIAL_EVENT_TIME_MILLIS;
238        KeyEvent keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE,
239                IGNORED_REPEAT);
240        boolean interactive = true;
241        MutableBoolean outLaunched = new MutableBoolean(true);
242        boolean intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive,
243                outLaunched);
244        assertFalse(intercepted);
245        assertFalse(outLaunched.value);
246
247        eventTime += GestureLauncherService.CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS - 1;
248        keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE,
249                IGNORED_REPEAT);
250        outLaunched.value = false;
251        intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive,
252                outLaunched);
253        assertTrue(intercepted);
254        assertTrue(outLaunched.value);
255        verify(mStatusBarManagerInternal).onCameraLaunchGestureDetected(
256                StatusBarManager.CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP);
257    }
258
259    @Test
260    public void
261    testInterceptPowerKeyDown_intervalInBoundsCameraPowerGestureOnInteractiveSetupIncomplete() {
262        withCameraDoubleTapPowerEnableConfigValue(true);
263        withCameraDoubleTapPowerDisableSettingValue(0);
264        mGestureLauncherService.updateCameraDoubleTapPowerEnabled();
265        withUserSetupCompleteValue(false);
266
267        long eventTime = INITIAL_EVENT_TIME_MILLIS;
268        KeyEvent keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE,
269                IGNORED_REPEAT);
270        boolean interactive = true;
271        MutableBoolean outLaunched = new MutableBoolean(true);
272        boolean intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive,
273                outLaunched);
274        assertFalse(intercepted);
275        assertFalse(outLaunched.value);
276
277        eventTime += GestureLauncherService.CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS - 1;
278        keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE,
279                IGNORED_REPEAT);
280        outLaunched.value = true;
281        intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive,
282                outLaunched);
283        assertFalse(intercepted);
284        assertFalse(outLaunched.value);
285    }
286
287    @Test
288    public void testInterceptPowerKeyDown_intervalOutOfBoundsCameraPowerGestureOnInteractive() {
289        withCameraDoubleTapPowerEnableConfigValue(true);
290        withCameraDoubleTapPowerDisableSettingValue(0);
291        mGestureLauncherService.updateCameraDoubleTapPowerEnabled();
292
293        long eventTime = INITIAL_EVENT_TIME_MILLIS;
294        KeyEvent keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE,
295                IGNORED_REPEAT);
296        boolean interactive = true;
297        MutableBoolean outLaunched = new MutableBoolean(true);
298        boolean intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive,
299                outLaunched);
300        assertFalse(intercepted);
301        assertFalse(outLaunched.value);
302
303        eventTime += GestureLauncherService.CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS;
304        keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE,
305                IGNORED_REPEAT);
306        outLaunched.value = true;
307        intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive,
308                outLaunched);
309        assertFalse(intercepted);
310        assertFalse(outLaunched.value);
311    }
312
313    @Test
314    public void testInterceptPowerKeyDown_intervalInBoundsCameraPowerGestureOffNotInteractive() {
315        withCameraDoubleTapPowerEnableConfigValue(false);
316        withCameraDoubleTapPowerDisableSettingValue(1);
317        mGestureLauncherService.updateCameraDoubleTapPowerEnabled();
318
319        long eventTime = INITIAL_EVENT_TIME_MILLIS;
320        KeyEvent keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE,
321                IGNORED_REPEAT);
322        boolean interactive = false;
323        MutableBoolean outLaunched = new MutableBoolean(true);
324        boolean intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive,
325                outLaunched);
326        assertFalse(intercepted);
327        assertFalse(outLaunched.value);
328
329        eventTime += GestureLauncherService.CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS - 1;
330        keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE,
331                IGNORED_REPEAT);
332        outLaunched.value = true;
333        intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive,
334                outLaunched);
335        assertFalse(intercepted);
336        assertFalse(outLaunched.value);
337    }
338
339    @Test
340    public void testInterceptPowerKeyDown_intervalOutOfBoundsCameraPowerGestureOffNotInteractive() {
341        withCameraDoubleTapPowerEnableConfigValue(false);
342        withCameraDoubleTapPowerDisableSettingValue(1);
343        mGestureLauncherService.updateCameraDoubleTapPowerEnabled();
344
345        long eventTime = INITIAL_EVENT_TIME_MILLIS;
346        KeyEvent keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE,
347                IGNORED_REPEAT);
348        boolean interactive = false;
349        MutableBoolean outLaunched = new MutableBoolean(true);
350        boolean intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive,
351                outLaunched);
352        assertFalse(intercepted);
353        assertFalse(outLaunched.value);
354
355        eventTime += GestureLauncherService.CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS;
356        keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE,
357                IGNORED_REPEAT);
358        outLaunched.value = true;
359        intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive,
360                outLaunched);
361        assertFalse(intercepted);
362        assertFalse(outLaunched.value);
363    }
364
365    @Test
366    public void
367    testInterceptPowerKeyDown_intervalInBoundsCameraPowerGestureOnNotInteractiveSetupComplete() {
368        withCameraDoubleTapPowerEnableConfigValue(true);
369        withCameraDoubleTapPowerDisableSettingValue(0);
370        mGestureLauncherService.updateCameraDoubleTapPowerEnabled();
371        withUserSetupCompleteValue(true);
372
373        long eventTime = INITIAL_EVENT_TIME_MILLIS;
374        KeyEvent keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE,
375                IGNORED_REPEAT);
376        boolean interactive = false;
377        MutableBoolean outLaunched = new MutableBoolean(true);
378        boolean intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive,
379                outLaunched);
380        assertFalse(intercepted);
381        assertFalse(outLaunched.value);
382
383        eventTime += GestureLauncherService.CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS - 1;
384        keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE,
385                IGNORED_REPEAT);
386        intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive,
387                outLaunched);
388        assertFalse(intercepted);
389        assertTrue(outLaunched.value);
390        verify(mStatusBarManagerInternal).onCameraLaunchGestureDetected(
391                StatusBarManager.CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP);
392    }
393
394    @Test
395    public void
396    testInterceptPowerKeyDown_intervalInBoundsCameraPowerGestureOnNotInteractiveSetupIncomplete() {
397        withCameraDoubleTapPowerEnableConfigValue(true);
398        withCameraDoubleTapPowerDisableSettingValue(0);
399        mGestureLauncherService.updateCameraDoubleTapPowerEnabled();
400        withUserSetupCompleteValue(false);
401
402        long eventTime = INITIAL_EVENT_TIME_MILLIS;
403        KeyEvent keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE,
404                IGNORED_REPEAT);
405        boolean interactive = false;
406        MutableBoolean outLaunched = new MutableBoolean(true);
407        boolean intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive,
408                outLaunched);
409        assertFalse(intercepted);
410        assertFalse(outLaunched.value);
411
412        eventTime += GestureLauncherService.CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS - 1;
413        keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE,
414                IGNORED_REPEAT);
415        outLaunched.value = true;
416        intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive,
417                outLaunched);
418        assertFalse(intercepted);
419        assertFalse(outLaunched.value);
420    }
421
422    @Test
423    public void testInterceptPowerKeyDown_intervalOutOfBoundsCameraPowerGestureOnNotInteractive() {
424        withCameraDoubleTapPowerEnableConfigValue(true);
425        withCameraDoubleTapPowerDisableSettingValue(0);
426        mGestureLauncherService.updateCameraDoubleTapPowerEnabled();
427
428        long eventTime = INITIAL_EVENT_TIME_MILLIS;
429        KeyEvent keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE,
430                IGNORED_REPEAT);
431        boolean interactive = false;
432        MutableBoolean outLaunched = new MutableBoolean(true);
433        boolean intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive,
434                outLaunched);
435        assertFalse(intercepted);
436        assertFalse(outLaunched.value);
437
438        eventTime += GestureLauncherService.CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS;
439        keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE,
440                IGNORED_REPEAT);
441        outLaunched.value = true;
442        intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive,
443                outLaunched);
444        assertFalse(intercepted);
445        assertFalse(outLaunched.value);
446    }
447
448    private void withCameraDoubleTapPowerEnableConfigValue(boolean enableConfigValue) {
449        when(mResources.getBoolean(
450                com.android.internal.R.bool.config_cameraDoubleTapPowerGestureEnabled))
451                .thenReturn(enableConfigValue);
452    }
453
454    private void withCameraDoubleTapPowerDisableSettingValue(int disableSettingValue) {
455        Settings.Secure.putIntForUser(
456                mContentResolver,
457                Settings.Secure.CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED,
458                disableSettingValue,
459                UserHandle.USER_CURRENT);
460    }
461
462    private void withUserSetupCompleteValue(boolean userSetupComplete) {
463        int userSetupCompleteValue = userSetupComplete ? 1 : 0;
464        Settings.Secure.putIntForUser(
465                mContentResolver,
466                Settings.Secure.USER_SETUP_COMPLETE,
467                userSetupCompleteValue,
468                UserHandle.USER_CURRENT);
469    }
470}
471