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 17 package com.android.server.accessibility; 18 19 import static org.junit.Assert.assertFalse; 20 import static org.junit.Assert.assertTrue; 21 import static org.mockito.Matchers.anyBoolean; 22 import static org.mockito.Matchers.anyInt; 23 import static org.mockito.Mockito.times; 24 import static org.mockito.Mockito.verify; 25 import static org.mockito.Mockito.verifyNoMoreInteractions; 26 import static org.mockito.Mockito.when; 27 28 import android.accessibilityservice.FingerprintGestureController; 29 import android.content.res.Resources; 30 import android.hardware.fingerprint.IFingerprintService; 31 import android.view.KeyEvent; 32 33 import com.android.server.accessibility.FingerprintGestureDispatcher.FingerprintGestureClient; 34 import com.android.server.accessibility.test.MessageCapturingHandler; 35 36 import org.junit.After; 37 import org.junit.Before; 38 import org.junit.Test; 39 import org.mockito.Mock; 40 import org.mockito.MockitoAnnotations; 41 42 import java.util.Arrays; 43 import java.util.Collections; 44 45 /** 46 * Tests for FingerprintGestureDispatcher 47 */ 48 public class FingerprintGestureDispatcherTest { 49 50 private @Mock IFingerprintService mMockFingerprintService; 51 private @Mock FingerprintGestureClient mNonGestureCapturingClient; 52 private @Mock FingerprintGestureClient mGestureCapturingClient; 53 private @Mock Resources mMockResources; 54 55 private MessageCapturingHandler mMessageCapturingHandler; 56 private FingerprintGestureDispatcher mFingerprintGestureDispatcher; 57 58 @Before setup()59 public void setup() { 60 MockitoAnnotations.initMocks(this); 61 // For most tests, we support fingerprint gestures 62 when(mMockResources.getBoolean(anyInt())).thenReturn(true); 63 mMessageCapturingHandler = new MessageCapturingHandler( 64 msg -> mFingerprintGestureDispatcher.handleMessage(msg)); 65 mFingerprintGestureDispatcher = new FingerprintGestureDispatcher(mMockFingerprintService, 66 mMockResources, new Object(), mMessageCapturingHandler); 67 when(mNonGestureCapturingClient.isCapturingFingerprintGestures()).thenReturn(false); 68 when(mGestureCapturingClient.isCapturingFingerprintGestures()).thenReturn(true); 69 } 70 71 @After tearDown()72 public void tearDown() { 73 mMessageCapturingHandler.removeAllMessages(); 74 } 75 76 77 @Test testNoServices_doesNotCrashOrConsumeGestures()78 public void testNoServices_doesNotCrashOrConsumeGestures() { 79 mFingerprintGestureDispatcher.onClientActiveChanged(true); 80 mFingerprintGestureDispatcher.onClientActiveChanged(false); 81 assertFalse(mFingerprintGestureDispatcher.onFingerprintGesture( 82 KeyEvent.KEYCODE_SYSTEM_NAVIGATION_UP)); 83 } 84 85 @Test testOneNonCapturingService_doesNotCrashOrConsumeGestures()86 public void testOneNonCapturingService_doesNotCrashOrConsumeGestures() { 87 mFingerprintGestureDispatcher.updateClientList( 88 Arrays.asList(mNonGestureCapturingClient)); 89 mFingerprintGestureDispatcher.onClientActiveChanged(true); 90 mFingerprintGestureDispatcher.onClientActiveChanged(false); 91 assertFalse(mFingerprintGestureDispatcher.onFingerprintGesture( 92 KeyEvent.KEYCODE_SYSTEM_NAVIGATION_UP)); 93 verify(mNonGestureCapturingClient, times(0)) 94 .onFingerprintGestureDetectionActiveChanged(anyBoolean()); 95 verify(mNonGestureCapturingClient, times(0)).onFingerprintGesture(anyInt()); 96 } 97 98 @Test testOneCapturingService_notifiesClientOfActivityChanges()99 public void testOneCapturingService_notifiesClientOfActivityChanges() { 100 mFingerprintGestureDispatcher.updateClientList( 101 Arrays.asList(mGestureCapturingClient)); 102 mFingerprintGestureDispatcher.onClientActiveChanged(true); 103 // Client active means gesture detection isn't. 104 verify(mGestureCapturingClient, times(1)).onFingerprintGestureDetectionActiveChanged(false); 105 verify(mGestureCapturingClient, times(0)).onFingerprintGestureDetectionActiveChanged(true); 106 mFingerprintGestureDispatcher.onClientActiveChanged(false); 107 verify(mGestureCapturingClient, times(1)).onFingerprintGestureDetectionActiveChanged(false); 108 verify(mGestureCapturingClient, times(1)).onFingerprintGestureDetectionActiveChanged(true); 109 } 110 111 @Test testOneCapturingService_consumesGesturesAndPassesThemAlong()112 public void testOneCapturingService_consumesGesturesAndPassesThemAlong() { 113 mFingerprintGestureDispatcher.updateClientList( 114 Arrays.asList(mGestureCapturingClient)); 115 assertTrue(mFingerprintGestureDispatcher.onFingerprintGesture( 116 KeyEvent.KEYCODE_SYSTEM_NAVIGATION_UP)); 117 verify(mGestureCapturingClient, times(1)).onFingerprintGesture( 118 FingerprintGestureController.FINGERPRINT_GESTURE_SWIPE_UP); 119 assertTrue(mFingerprintGestureDispatcher.onFingerprintGesture( 120 KeyEvent.KEYCODE_SYSTEM_NAVIGATION_DOWN)); 121 verify(mGestureCapturingClient, times(1)).onFingerprintGesture( 122 FingerprintGestureController.FINGERPRINT_GESTURE_SWIPE_DOWN); 123 assertTrue(mFingerprintGestureDispatcher.onFingerprintGesture( 124 KeyEvent.KEYCODE_SYSTEM_NAVIGATION_LEFT)); 125 verify(mGestureCapturingClient, times(1)).onFingerprintGesture( 126 FingerprintGestureController.FINGERPRINT_GESTURE_SWIPE_LEFT); 127 assertTrue(mFingerprintGestureDispatcher.onFingerprintGesture( 128 KeyEvent.KEYCODE_SYSTEM_NAVIGATION_RIGHT)); 129 verify(mGestureCapturingClient, times(1)).onFingerprintGesture( 130 FingerprintGestureController.FINGERPRINT_GESTURE_SWIPE_RIGHT); 131 } 132 133 @Test testInvalidKeyCodes_areNotCaptured()134 public void testInvalidKeyCodes_areNotCaptured() { 135 mFingerprintGestureDispatcher.updateClientList( 136 Arrays.asList(mGestureCapturingClient)); 137 assertFalse(mFingerprintGestureDispatcher.onFingerprintGesture( 138 KeyEvent.KEYCODE_SPACE)); 139 verify(mGestureCapturingClient, times(0)).onFingerprintGesture(anyInt()); 140 } 141 142 @Test testWithCapturingService_registersForFingerprintUpdates()143 public void testWithCapturingService_registersForFingerprintUpdates() throws Exception { 144 verifyNoMoreInteractions(mMockFingerprintService); 145 mFingerprintGestureDispatcher.updateClientList( 146 Arrays.asList(mGestureCapturingClient)); 147 mMessageCapturingHandler.sendOneMessage(); 148 verify(mMockFingerprintService).addClientActiveCallback(mFingerprintGestureDispatcher); 149 } 150 151 @Test testWhenCapturingServiceStops_unregistersForFingerprintUpdates()152 public void testWhenCapturingServiceStops_unregistersForFingerprintUpdates() throws Exception { 153 verifyNoMoreInteractions(mMockFingerprintService); 154 mFingerprintGestureDispatcher.updateClientList( 155 Arrays.asList(mGestureCapturingClient)); 156 mMessageCapturingHandler.sendOneMessage(); 157 mFingerprintGestureDispatcher.updateClientList(Collections.emptyList()); 158 mMessageCapturingHandler.sendOneMessage(); 159 verify(mMockFingerprintService).removeClientActiveCallback(mFingerprintGestureDispatcher); 160 } 161 162 @Test testIsGestureDetectionAvailable_dependsOnFingerprintService()163 public void testIsGestureDetectionAvailable_dependsOnFingerprintService() throws Exception { 164 when(mMockFingerprintService.isClientActive()).thenReturn(true); 165 assertFalse(mFingerprintGestureDispatcher.isFingerprintGestureDetectionAvailable()); 166 when(mMockFingerprintService.isClientActive()).thenReturn(false); 167 assertTrue(mFingerprintGestureDispatcher.isFingerprintGestureDetectionAvailable()); 168 } 169 170 @Test ifGestureDetectionNotSupported_neverSaysAvailable()171 public void ifGestureDetectionNotSupported_neverSaysAvailable() throws Exception { 172 when(mMockResources.getBoolean(anyInt())).thenReturn(false); 173 // Need to create a new dispatcher, since it picks up the resource value in its 174 // constructor. This is fine since hardware config values don't change dynamically. 175 FingerprintGestureDispatcher fingerprintGestureDispatcher = 176 new FingerprintGestureDispatcher(mMockFingerprintService, mMockResources, 177 new Object(), mMessageCapturingHandler); 178 179 when(mMockFingerprintService.isClientActive()).thenReturn(false); 180 assertFalse(fingerprintGestureDispatcher.isFingerprintGestureDetectionAvailable()); 181 } 182 } 183