1 /* 2 * Copyright (C) 2016 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 junit.framework.TestCase.assertEquals; 20 import static junit.framework.TestCase.assertFalse; 21 import static junit.framework.TestCase.assertTrue; 22 23 import static org.mockito.Matchers.anyInt; 24 import static org.mockito.Matchers.anyLong; 25 import static org.mockito.Matchers.anyObject; 26 import static org.mockito.Matchers.eq; 27 import static org.mockito.Mockito.mock; 28 import static org.mockito.Mockito.times; 29 import static org.mockito.Mockito.verify; 30 import static org.mockito.Mockito.verifyZeroInteractions; 31 import static org.mockito.Mockito.when; 32 import static org.mockito.hamcrest.MockitoHamcrest.argThat; 33 34 import android.content.Context; 35 import android.os.Handler; 36 import android.os.IPowerManager; 37 import android.os.IThermalService; 38 import android.os.Looper; 39 import android.os.Message; 40 import android.os.PowerManager; 41 import android.os.RemoteException; 42 import android.view.Display; 43 import android.view.KeyEvent; 44 45 import androidx.test.InstrumentationRegistry; 46 import androidx.test.runner.AndroidJUnit4; 47 48 import com.android.server.accessibility.KeyEventDispatcher.KeyEventFilter; 49 import com.android.server.accessibility.test.MessageCapturingHandler; 50 import com.android.server.policy.WindowManagerPolicy; 51 52 import org.hamcrest.Description; 53 import org.hamcrest.TypeSafeMatcher; 54 import org.junit.After; 55 import org.junit.Before; 56 import org.junit.Test; 57 import org.junit.runner.RunWith; 58 import org.mockito.ArgumentCaptor; 59 60 import java.util.Arrays; 61 import java.util.Collections; 62 63 /** 64 * Tests for KeyEventDispatcher 65 */ 66 @RunWith(AndroidJUnit4.class) 67 public class KeyEventDispatcherTest { 68 private static final int SEND_FRAMEWORK_KEY_EVENT = 4; 69 70 private final KeyEvent mKeyEvent = new KeyEvent(KeyEvent.ACTION_DOWN, 0x40); 71 private final KeyEvent mOtherKeyEvent = new KeyEvent(KeyEvent.ACTION_DOWN, 0x50); 72 private final Object mLock = new Object(); 73 private MessageCapturingHandler mInputEventsHandler; 74 private KeyEventDispatcher mKeyEventDispatcher; 75 private KeyEventFilter mKeyEventFilter1; 76 private KeyEventFilter mKeyEventFilter2; 77 private IPowerManager mMockPowerManagerService; 78 private IThermalService mMockThermalService; 79 private MessageCapturingHandler mMessageCapturingHandler; 80 private ArgumentCaptor<Integer> mFilter1SequenceCaptor = ArgumentCaptor.forClass(Integer.class); 81 private ArgumentCaptor<Integer> mFilter2SequenceCaptor = ArgumentCaptor.forClass(Integer.class); 82 83 @Before setUp()84 public void setUp() { 85 Looper looper = InstrumentationRegistry.getContext().getMainLooper(); 86 mInputEventsHandler = new MessageCapturingHandler(looper, null); 87 mMockPowerManagerService = mock(IPowerManager.class); 88 mMockThermalService = mock(IThermalService.class); 89 // TODO: It would be better to mock PowerManager rather than its binder, but the class is 90 // final. 91 PowerManager powerManager = 92 new PowerManager(mock(Context.class), mMockPowerManagerService, mMockThermalService, 93 new Handler(looper)); 94 mMessageCapturingHandler = new MessageCapturingHandler(looper, null); 95 mKeyEventDispatcher = new KeyEventDispatcher(mInputEventsHandler, SEND_FRAMEWORK_KEY_EVENT, 96 mLock, powerManager, mMessageCapturingHandler); 97 98 mKeyEventFilter1 = mock(KeyEventFilter.class); 99 when(mKeyEventFilter1.onKeyEvent((KeyEvent) anyObject(), 100 mFilter1SequenceCaptor.capture().intValue())) 101 .thenReturn(true); 102 103 mKeyEventFilter2 = mock(KeyEventFilter.class); 104 when(mKeyEventFilter2.onKeyEvent((KeyEvent) anyObject(), 105 mFilter2SequenceCaptor.capture().intValue())) 106 .thenReturn(true); 107 } 108 109 @After tearDown()110 public void tearDown() { 111 mInputEventsHandler.removeAllMessages(); 112 mMessageCapturingHandler.removeAllMessages(); 113 } 114 115 116 @Test testNotifyKeyEvent_withNoBoundServices_shouldReturnFalse()117 public void testNotifyKeyEvent_withNoBoundServices_shouldReturnFalse() { 118 assertFalse(mKeyEventDispatcher.notifyKeyEventLocked(mKeyEvent, 0, Collections.EMPTY_LIST)); 119 assertFalse(isTimeoutPending(mMessageCapturingHandler)); 120 } 121 122 @Test testNotifyKeyEvent_boundServiceDoesntProcessEvents_shouldReturnFalse()123 public void testNotifyKeyEvent_boundServiceDoesntProcessEvents_shouldReturnFalse() { 124 KeyEventFilter keyEventFilter = mock(KeyEventFilter.class); 125 when(keyEventFilter.onKeyEvent((KeyEvent) anyObject(), anyInt())).thenReturn(false); 126 assertFalse(mKeyEventDispatcher 127 .notifyKeyEventLocked(mKeyEvent, 0, Arrays.asList(keyEventFilter))); 128 assertFalse(isTimeoutPending(mMessageCapturingHandler)); 129 } 130 131 @Test testNotifyKeyEvent_withOneValidService_shouldNotifyService()132 public void testNotifyKeyEvent_withOneValidService_shouldNotifyService() 133 throws RemoteException { 134 assertTrue(mKeyEventDispatcher 135 .notifyKeyEventLocked(mKeyEvent, 0, Arrays.asList(mKeyEventFilter1))); 136 verify(mKeyEventFilter1, times(1)).onKeyEvent(argThat(new KeyEventMatcher(mKeyEvent)), 137 anyInt()); 138 } 139 140 @Test testNotifyKeyEvent_withTwoValidService_shouldNotifyBoth()141 public void testNotifyKeyEvent_withTwoValidService_shouldNotifyBoth() throws RemoteException { 142 assertTrue(mKeyEventDispatcher.notifyKeyEventLocked( 143 mKeyEvent, 0, Arrays.asList(mKeyEventFilter1, mKeyEventFilter2))); 144 verify(mKeyEventFilter1, times(1)).onKeyEvent(argThat(new KeyEventMatcher(mKeyEvent)), 145 anyInt()); 146 verify(mKeyEventFilter2, times(1)).onKeyEvent(argThat(new KeyEventMatcher(mKeyEvent)), 147 anyInt()); 148 } 149 150 /* 151 * Results from services 152 */ 153 @Test testSetOnKeyResult_eventNotHandled_shouldPassEventToFramework()154 public void testSetOnKeyResult_eventNotHandled_shouldPassEventToFramework() { 155 mKeyEventDispatcher 156 .notifyKeyEventLocked(mKeyEvent, 0, Arrays.asList(mKeyEventFilter1)); 157 158 mKeyEventDispatcher.setOnKeyEventResult(mKeyEventFilter1, false, 159 mFilter1SequenceCaptor.getValue()); 160 161 assertTrue(mInputEventsHandler.hasMessages(SEND_FRAMEWORK_KEY_EVENT)); 162 verifyZeroInteractions(mMockPowerManagerService); 163 assertFalse(isTimeoutPending(mMessageCapturingHandler)); 164 } 165 166 @Test testSetOnKeyResult_eventHandled_shouldNotPassEventToFramework()167 public void testSetOnKeyResult_eventHandled_shouldNotPassEventToFramework() 168 throws RemoteException { 169 mKeyEventDispatcher 170 .notifyKeyEventLocked(mKeyEvent, 0, Arrays.asList(mKeyEventFilter1)); 171 172 mKeyEventDispatcher.setOnKeyEventResult(mKeyEventFilter1, true, 173 mFilter1SequenceCaptor.getValue()); 174 175 assertFalse(mInputEventsHandler.hasMessages(SEND_FRAMEWORK_KEY_EVENT)); 176 verify(mMockPowerManagerService, times(1)).userActivity(eq(Display.DEFAULT_DISPLAY), 177 anyLong(), eq(PowerManager.USER_ACTIVITY_EVENT_ACCESSIBILITY), eq(0)); 178 assertFalse(isTimeoutPending(mMessageCapturingHandler)); 179 } 180 181 @Test testSetOnKeyResult_twoServicesReturnsFalse_shouldPassEventToFramework()182 public void testSetOnKeyResult_twoServicesReturnsFalse_shouldPassEventToFramework() { 183 mKeyEventDispatcher.notifyKeyEventLocked( 184 mKeyEvent, 0, Arrays.asList(mKeyEventFilter1, mKeyEventFilter2)); 185 186 mKeyEventDispatcher.setOnKeyEventResult(mKeyEventFilter1, false, 187 mFilter1SequenceCaptor.getValue()); 188 mKeyEventDispatcher.setOnKeyEventResult(mKeyEventFilter2, false, 189 mFilter2SequenceCaptor.getValue()); 190 191 assertTrue(mInputEventsHandler.hasMessages(SEND_FRAMEWORK_KEY_EVENT)); 192 verifyZeroInteractions(mMockPowerManagerService); 193 assertFalse(isTimeoutPending(mMessageCapturingHandler)); 194 } 195 196 @Test testSetOnKeyResult_twoServicesReturnsTrue_shouldNotPassEventToFramework()197 public void testSetOnKeyResult_twoServicesReturnsTrue_shouldNotPassEventToFramework() 198 throws RemoteException { 199 mKeyEventDispatcher.notifyKeyEventLocked( 200 mKeyEvent, 0, Arrays.asList(mKeyEventFilter1, mKeyEventFilter2)); 201 202 mKeyEventDispatcher.setOnKeyEventResult(mKeyEventFilter1, true, 203 mFilter1SequenceCaptor.getValue()); 204 mKeyEventDispatcher.setOnKeyEventResult(mKeyEventFilter2, true, 205 mFilter2SequenceCaptor.getValue()); 206 207 assertFalse(mInputEventsHandler.hasMessages(SEND_FRAMEWORK_KEY_EVENT)); 208 verify(mMockPowerManagerService, times(1)).userActivity(eq(Display.DEFAULT_DISPLAY), 209 anyLong(), eq(PowerManager.USER_ACTIVITY_EVENT_ACCESSIBILITY), eq(0)); 210 assertFalse(isTimeoutPending(mMessageCapturingHandler)); 211 } 212 213 @Test testSetOnKeyResult_firstOfTwoServicesReturnsTrue_shouldNotPassEventToFramework()214 public void testSetOnKeyResult_firstOfTwoServicesReturnsTrue_shouldNotPassEventToFramework() 215 throws RemoteException { 216 mKeyEventDispatcher.notifyKeyEventLocked( 217 mKeyEvent, 0, Arrays.asList(mKeyEventFilter1, mKeyEventFilter2)); 218 219 mKeyEventDispatcher.setOnKeyEventResult(mKeyEventFilter1, true, 220 mFilter1SequenceCaptor.getValue()); 221 mKeyEventDispatcher.setOnKeyEventResult(mKeyEventFilter2, false, 222 mFilter2SequenceCaptor.getValue()); 223 224 assertFalse(mInputEventsHandler.hasMessages(SEND_FRAMEWORK_KEY_EVENT)); 225 verify(mMockPowerManagerService, times(1)).userActivity(eq(Display.DEFAULT_DISPLAY), 226 anyLong(), eq(PowerManager.USER_ACTIVITY_EVENT_ACCESSIBILITY), eq(0)); 227 assertFalse(isTimeoutPending(mMessageCapturingHandler)); 228 } 229 230 @Test testSetOnKeyResult_secondOfTwoServicesReturnsTrue_shouldNotPassEventToFramework()231 public void testSetOnKeyResult_secondOfTwoServicesReturnsTrue_shouldNotPassEventToFramework() 232 throws RemoteException { 233 mKeyEventDispatcher.notifyKeyEventLocked( 234 mKeyEvent, 0, Arrays.asList(mKeyEventFilter1, mKeyEventFilter2)); 235 236 mKeyEventDispatcher.setOnKeyEventResult(mKeyEventFilter1, false, 237 mFilter1SequenceCaptor.getValue()); 238 mKeyEventDispatcher.setOnKeyEventResult(mKeyEventFilter2, true, 239 mFilter2SequenceCaptor.getValue()); 240 241 assertFalse(mInputEventsHandler.hasMessages(SEND_FRAMEWORK_KEY_EVENT)); 242 verify(mMockPowerManagerService, times(1)).userActivity(eq(Display.DEFAULT_DISPLAY), 243 anyLong(), eq(PowerManager.USER_ACTIVITY_EVENT_ACCESSIBILITY), eq(0)); 244 assertFalse(isTimeoutPending(mMessageCapturingHandler)); 245 } 246 247 // Each event should have its result set only once, but if it's set twice, we should ignore 248 // the second time. 249 @Test testSetOnKeyResult_firstServiceReturnsTwice_secondShouldBeIgnored()250 public void testSetOnKeyResult_firstServiceReturnsTwice_secondShouldBeIgnored() { 251 mKeyEventDispatcher.notifyKeyEventLocked( 252 mKeyEvent, 0, Arrays.asList(mKeyEventFilter1, mKeyEventFilter2)); 253 254 mKeyEventDispatcher.setOnKeyEventResult(mKeyEventFilter1, false, 255 mFilter1SequenceCaptor.getValue()); 256 mKeyEventDispatcher.setOnKeyEventResult(mKeyEventFilter1, false, 257 mFilter1SequenceCaptor.getValue()); 258 assertFalse(mInputEventsHandler.hasMessages(SEND_FRAMEWORK_KEY_EVENT)); 259 260 // Verify event is sent properly when other service responds 261 mKeyEventDispatcher.setOnKeyEventResult(mKeyEventFilter2, false, 262 mFilter2SequenceCaptor.getValue()); 263 assertTrue(mInputEventsHandler.hasMessages(SEND_FRAMEWORK_KEY_EVENT)); 264 verifyZeroInteractions(mMockPowerManagerService); 265 assertFalse(isTimeoutPending(mMessageCapturingHandler)); 266 } 267 268 269 /* 270 * Timeouts 271 */ 272 @Test testEventTimesOut_shouldPassToFramework()273 public void testEventTimesOut_shouldPassToFramework() throws RemoteException { 274 mKeyEventDispatcher.notifyKeyEventLocked( 275 mKeyEvent, 0, Arrays.asList(mKeyEventFilter1, mKeyEventFilter2)); 276 277 assertEquals(1, mMessageCapturingHandler.timedMessages.size()); 278 mKeyEventDispatcher.handleMessage(getTimedMessage(mMessageCapturingHandler, 0)); 279 280 assertTrue(mInputEventsHandler.hasMessages(SEND_FRAMEWORK_KEY_EVENT)); 281 verifyZeroInteractions(mMockPowerManagerService); 282 } 283 284 @Test testEventTimesOut_afterOneServiceReturnsFalse_shouldPassToFramework()285 public void testEventTimesOut_afterOneServiceReturnsFalse_shouldPassToFramework() { 286 mKeyEventDispatcher.notifyKeyEventLocked( 287 mKeyEvent, 0, Arrays.asList(mKeyEventFilter1, mKeyEventFilter2)); 288 289 mKeyEventDispatcher.setOnKeyEventResult(mKeyEventFilter1, false, 290 mFilter1SequenceCaptor.getValue()); 291 292 assertEquals(1, mMessageCapturingHandler.timedMessages.size()); 293 mKeyEventDispatcher.handleMessage(getTimedMessage(mMessageCapturingHandler, 0)); 294 295 assertTrue(mInputEventsHandler.hasMessages(SEND_FRAMEWORK_KEY_EVENT)); 296 verifyZeroInteractions(mMockPowerManagerService); 297 } 298 299 @Test testEventTimesOut_afterOneServiceReturnsTrue_shouldNotPassToFramework()300 public void testEventTimesOut_afterOneServiceReturnsTrue_shouldNotPassToFramework() 301 throws RemoteException { 302 mKeyEventDispatcher.notifyKeyEventLocked( 303 mKeyEvent, 0, Arrays.asList(mKeyEventFilter1, mKeyEventFilter2)); 304 305 mKeyEventDispatcher.setOnKeyEventResult(mKeyEventFilter1, true, 306 mFilter1SequenceCaptor.getValue()); 307 308 assertEquals(1, mMessageCapturingHandler.timedMessages.size()); 309 mKeyEventDispatcher.handleMessage(getTimedMessage(mMessageCapturingHandler, 0)); 310 311 assertFalse(mInputEventsHandler.hasMessages(SEND_FRAMEWORK_KEY_EVENT)); 312 verify(mMockPowerManagerService, times(1)).userActivity(eq(Display.DEFAULT_DISPLAY), 313 anyLong(), eq(PowerManager.USER_ACTIVITY_EVENT_ACCESSIBILITY), eq(0)); 314 } 315 316 @Test testEventTimesOut_thenServiceReturnsFalse_shouldPassToFrameworkOnce()317 public void testEventTimesOut_thenServiceReturnsFalse_shouldPassToFrameworkOnce() { 318 mKeyEventDispatcher.notifyKeyEventLocked(mKeyEvent, 0, Arrays.asList(mKeyEventFilter1)); 319 assertFalse(mInputEventsHandler.hasMessages(SEND_FRAMEWORK_KEY_EVENT)); 320 321 assertEquals(1, mMessageCapturingHandler.timedMessages.size()); 322 mKeyEventDispatcher.handleMessage(getTimedMessage(mMessageCapturingHandler, 0)); 323 assertTrue(mInputEventsHandler.hasMessages(SEND_FRAMEWORK_KEY_EVENT)); 324 325 mInputEventsHandler.removeMessages(SEND_FRAMEWORK_KEY_EVENT); 326 mKeyEventDispatcher.setOnKeyEventResult(mKeyEventFilter1, false, 327 mFilter1SequenceCaptor.getValue()); 328 329 assertFalse(mInputEventsHandler.hasMessages(SEND_FRAMEWORK_KEY_EVENT)); 330 verifyZeroInteractions(mMockPowerManagerService); 331 } 332 333 @Test testEventTimesOut_afterServiceReturnsFalse_shouldPassToFrameworkOnce()334 public void testEventTimesOut_afterServiceReturnsFalse_shouldPassToFrameworkOnce() { 335 mKeyEventDispatcher.notifyKeyEventLocked(mKeyEvent, 0, Arrays.asList(mKeyEventFilter1)); 336 assertFalse(mInputEventsHandler.hasMessages(SEND_FRAMEWORK_KEY_EVENT)); 337 338 mKeyEventDispatcher.setOnKeyEventResult(mKeyEventFilter1, false, 339 mFilter1SequenceCaptor.getValue()); 340 assertTrue(mInputEventsHandler.hasMessages(SEND_FRAMEWORK_KEY_EVENT)); 341 342 mInputEventsHandler.removeMessages(SEND_FRAMEWORK_KEY_EVENT); 343 assertEquals(1, mMessageCapturingHandler.timedMessages.size()); 344 mKeyEventDispatcher.handleMessage(getTimedMessage(mMessageCapturingHandler, 0)); 345 346 assertFalse(mInputEventsHandler.hasMessages(SEND_FRAMEWORK_KEY_EVENT)); 347 verifyZeroInteractions(mMockPowerManagerService); 348 } 349 350 @Test testEventTimesOut_afterServiceReturnsTrue_shouldNotPassToFramework()351 public void testEventTimesOut_afterServiceReturnsTrue_shouldNotPassToFramework() 352 throws RemoteException { 353 mKeyEventDispatcher.notifyKeyEventLocked(mKeyEvent, 0, Arrays.asList(mKeyEventFilter1)); 354 355 mKeyEventDispatcher.setOnKeyEventResult(mKeyEventFilter1, true, 356 mFilter1SequenceCaptor.getValue()); 357 assertEquals(1, mMessageCapturingHandler.timedMessages.size()); 358 mKeyEventDispatcher.handleMessage(getTimedMessage(mMessageCapturingHandler, 0)); 359 360 assertFalse(mInputEventsHandler.hasMessages(SEND_FRAMEWORK_KEY_EVENT)); 361 verify(mMockPowerManagerService, times(1)).userActivity(eq(Display.DEFAULT_DISPLAY), 362 anyLong(), eq(PowerManager.USER_ACTIVITY_EVENT_ACCESSIBILITY), eq(0)); 363 } 364 365 /* 366 * Flush services 367 */ 368 @Test testFlushService_withPendingEvent_shouldPassToFramework()369 public void testFlushService_withPendingEvent_shouldPassToFramework() { 370 mKeyEventDispatcher.notifyKeyEventLocked(mKeyEvent, 0, Arrays.asList(mKeyEventFilter1)); 371 assertFalse(mInputEventsHandler.hasMessages(SEND_FRAMEWORK_KEY_EVENT)); 372 373 mKeyEventDispatcher.flush(mKeyEventFilter1); 374 375 assertTrue(mInputEventsHandler.hasMessages(SEND_FRAMEWORK_KEY_EVENT)); 376 } 377 378 @Test testFlushTwpServices_withPendingEvent_shouldPassToFramework()379 public void testFlushTwpServices_withPendingEvent_shouldPassToFramework() { 380 mKeyEventDispatcher.notifyKeyEventLocked( 381 mKeyEvent, 0, Arrays.asList(mKeyEventFilter1, mKeyEventFilter2)); 382 383 mKeyEventDispatcher.flush(mKeyEventFilter1); 384 mKeyEventDispatcher.flush(mKeyEventFilter2); 385 386 assertTrue(mInputEventsHandler.hasMessages(SEND_FRAMEWORK_KEY_EVENT)); 387 } 388 389 @Test testFlushOneService_thenOtherReturnsTrue_shouldNotPassToFramework()390 public void testFlushOneService_thenOtherReturnsTrue_shouldNotPassToFramework() { 391 mKeyEventDispatcher.notifyKeyEventLocked( 392 mKeyEvent, 0, Arrays.asList(mKeyEventFilter1, mKeyEventFilter2)); 393 394 mKeyEventDispatcher.flush(mKeyEventFilter1); 395 mKeyEventDispatcher.setOnKeyEventResult(mKeyEventFilter2, true, 396 mFilter2SequenceCaptor.getValue()); 397 398 assertFalse(mInputEventsHandler.hasMessages(SEND_FRAMEWORK_KEY_EVENT)); 399 } 400 401 @Test testFlushOneService_thenOtherReturnsFalse_shouldPassToFramework()402 public void testFlushOneService_thenOtherReturnsFalse_shouldPassToFramework() { 403 mKeyEventDispatcher.notifyKeyEventLocked( 404 mKeyEvent, 0, Arrays.asList(mKeyEventFilter1, mKeyEventFilter2)); 405 406 mKeyEventDispatcher.flush(mKeyEventFilter1); 407 mKeyEventDispatcher.setOnKeyEventResult(mKeyEventFilter2, false, 408 mFilter2SequenceCaptor.getValue()); 409 410 assertTrue(mInputEventsHandler.hasMessages(SEND_FRAMEWORK_KEY_EVENT)); 411 } 412 413 @Test testFlushServiceWithNoEvents_shouldNotCrash()414 public void testFlushServiceWithNoEvents_shouldNotCrash() { 415 mKeyEventDispatcher.flush(mKeyEventFilter1); 416 } 417 418 /* 419 * Multiple Events 420 */ 421 @Test twoEvents_serviceReturnsFalse_sentToFramework()422 public void twoEvents_serviceReturnsFalse_sentToFramework() { 423 mKeyEventDispatcher.notifyKeyEventLocked(mKeyEvent, 0, Arrays.asList(mKeyEventFilter1)); 424 mKeyEventDispatcher 425 .notifyKeyEventLocked(mOtherKeyEvent, 0, Arrays.asList(mKeyEventFilter1)); 426 assertFalse(mInputEventsHandler.hasMessages(SEND_FRAMEWORK_KEY_EVENT)); 427 428 mKeyEventDispatcher.setOnKeyEventResult(mKeyEventFilter1, false, 429 mFilter1SequenceCaptor.getAllValues().get(0)); 430 mInputEventsHandler.removeMessages(SEND_FRAMEWORK_KEY_EVENT); 431 mKeyEventDispatcher.setOnKeyEventResult(mKeyEventFilter1, false, 432 mFilter1SequenceCaptor.getAllValues().get(1)); 433 434 assertTwoKeyEventsSentToFrameworkInOrder(mKeyEvent, mOtherKeyEvent); 435 } 436 437 @Test twoEvents_serviceReturnsTrue_notSentToFramework()438 public void twoEvents_serviceReturnsTrue_notSentToFramework() { 439 mKeyEventDispatcher.notifyKeyEventLocked(mKeyEvent, 0, Arrays.asList(mKeyEventFilter1)); 440 mKeyEventDispatcher 441 .notifyKeyEventLocked(mOtherKeyEvent, 0, Arrays.asList(mKeyEventFilter1)); 442 assertFalse(mInputEventsHandler.hasMessages(SEND_FRAMEWORK_KEY_EVENT)); 443 444 mKeyEventDispatcher.setOnKeyEventResult(mKeyEventFilter1, true, 445 mFilter1SequenceCaptor.getAllValues().get(0)); 446 mKeyEventDispatcher.setOnKeyEventResult(mKeyEventFilter1, true, 447 mFilter1SequenceCaptor.getAllValues().get(1)); 448 449 assertFalse(mInputEventsHandler.hasMessages(SEND_FRAMEWORK_KEY_EVENT)); 450 } 451 452 @Test twoEvents_serviceHandlesFirst_otherSentToFramework()453 public void twoEvents_serviceHandlesFirst_otherSentToFramework() { 454 mKeyEventDispatcher.notifyKeyEventLocked(mKeyEvent, 0, Arrays.asList(mKeyEventFilter1)); 455 mKeyEventDispatcher 456 .notifyKeyEventLocked(mOtherKeyEvent, 0, Arrays.asList(mKeyEventFilter1)); 457 assertFalse(mInputEventsHandler.hasMessages(SEND_FRAMEWORK_KEY_EVENT)); 458 459 mKeyEventDispatcher.setOnKeyEventResult(mKeyEventFilter1, true, 460 mFilter1SequenceCaptor.getAllValues().get(0)); 461 mKeyEventDispatcher.setOnKeyEventResult(mKeyEventFilter1, false, 462 mFilter1SequenceCaptor.getAllValues().get(1)); 463 464 assertOneKeyEventSentToFramework(mOtherKeyEvent); 465 } 466 467 @Test twoEvents_serviceHandlesSecond_otherSentToFramework()468 public void twoEvents_serviceHandlesSecond_otherSentToFramework() { 469 mKeyEventDispatcher.notifyKeyEventLocked(mKeyEvent, 0, Arrays.asList(mKeyEventFilter1)); 470 mKeyEventDispatcher 471 .notifyKeyEventLocked(mOtherKeyEvent, 0, Arrays.asList(mKeyEventFilter1)); 472 assertFalse(mInputEventsHandler.hasMessages(SEND_FRAMEWORK_KEY_EVENT)); 473 474 mKeyEventDispatcher.setOnKeyEventResult(mKeyEventFilter1, false, 475 mFilter1SequenceCaptor.getAllValues().get(0)); 476 mKeyEventDispatcher.setOnKeyEventResult(mKeyEventFilter1, true, 477 mFilter1SequenceCaptor.getAllValues().get(1)); 478 479 assertOneKeyEventSentToFramework(mKeyEvent); 480 } 481 482 @Test twoEvents_firstTimesOutThenServiceHandlesBoth_firstSentToFramework()483 public void twoEvents_firstTimesOutThenServiceHandlesBoth_firstSentToFramework() { 484 mKeyEventDispatcher.notifyKeyEventLocked(mKeyEvent, 0, Arrays.asList(mKeyEventFilter1)); 485 mKeyEventDispatcher 486 .notifyKeyEventLocked(mOtherKeyEvent, 0, Arrays.asList(mKeyEventFilter1)); 487 assertFalse(mInputEventsHandler.hasMessages(SEND_FRAMEWORK_KEY_EVENT)); 488 489 mKeyEventDispatcher.handleMessage(getTimedMessage(mMessageCapturingHandler, 0)); 490 mKeyEventDispatcher.setOnKeyEventResult(mKeyEventFilter1, true, 491 mFilter1SequenceCaptor.getAllValues().get(0)); 492 mKeyEventDispatcher.setOnKeyEventResult(mKeyEventFilter1, true, 493 mFilter1SequenceCaptor.getAllValues().get(1)); 494 495 assertOneKeyEventSentToFramework(mKeyEvent); 496 } 497 498 @Test addServiceBetweenTwoEvents_neitherEventHandled_bothSentToFramework()499 public void addServiceBetweenTwoEvents_neitherEventHandled_bothSentToFramework() { 500 mKeyEventDispatcher.notifyKeyEventLocked(mKeyEvent, 0, Arrays.asList(mKeyEventFilter1)); 501 mKeyEventDispatcher.notifyKeyEventLocked( 502 mOtherKeyEvent, 0, Arrays.asList(mKeyEventFilter1, mKeyEventFilter2)); 503 assertFalse(mInputEventsHandler.hasMessages(SEND_FRAMEWORK_KEY_EVENT)); 504 505 mKeyEventDispatcher.setOnKeyEventResult(mKeyEventFilter2, false, 506 mFilter2SequenceCaptor.getValue()); 507 mKeyEventDispatcher.setOnKeyEventResult(mKeyEventFilter1, false, 508 mFilter1SequenceCaptor.getAllValues().get(0)); 509 mKeyEventDispatcher.setOnKeyEventResult(mKeyEventFilter1, false, 510 mFilter1SequenceCaptor.getAllValues().get(1)); 511 512 assertTwoKeyEventsSentToFrameworkInOrder(mKeyEvent, mOtherKeyEvent); 513 } 514 515 @Test removeServiceBetweenTwoEvents_neitherEventHandled_bothSentToFramework()516 public void removeServiceBetweenTwoEvents_neitherEventHandled_bothSentToFramework() { 517 mKeyEventDispatcher.notifyKeyEventLocked( 518 mKeyEvent, 0, Arrays.asList(mKeyEventFilter1, mKeyEventFilter2)); 519 mKeyEventDispatcher.flush(mKeyEventFilter1); 520 mKeyEventDispatcher.notifyKeyEventLocked( 521 mOtherKeyEvent, 0, Arrays.asList(mKeyEventFilter2)); 522 assertFalse(mInputEventsHandler.hasMessages(SEND_FRAMEWORK_KEY_EVENT)); 523 524 mKeyEventDispatcher.setOnKeyEventResult(mKeyEventFilter2, false, 525 mFilter2SequenceCaptor.getAllValues().get(0)); 526 mKeyEventDispatcher.setOnKeyEventResult(mKeyEventFilter2, false, 527 mFilter2SequenceCaptor.getAllValues().get(1)); 528 529 assertTwoKeyEventsSentToFrameworkInOrder(mKeyEvent, mOtherKeyEvent); 530 } 531 532 /* 533 * Misc 534 */ 535 @Test twoEvents_serviceReturnsFalseOutOfOrder_sentToFramework()536 public void twoEvents_serviceReturnsFalseOutOfOrder_sentToFramework() { 537 mKeyEventDispatcher.notifyKeyEventLocked(mKeyEvent, 0, Arrays.asList(mKeyEventFilter1)); 538 mKeyEventDispatcher 539 .notifyKeyEventLocked(mOtherKeyEvent, 0, Arrays.asList(mKeyEventFilter1)); 540 541 mKeyEventDispatcher.setOnKeyEventResult(mKeyEventFilter1, false, 542 mFilter1SequenceCaptor.getAllValues().get(1)); 543 mKeyEventDispatcher.setOnKeyEventResult(mKeyEventFilter1, false, 544 mFilter1SequenceCaptor.getAllValues().get(0)); 545 546 // Order doesn't really matter since this is really checking that we don't do something 547 // really bad, but we'll send them in the order they are reported 548 assertTwoKeyEventsSentToFrameworkInOrder(mOtherKeyEvent, mKeyEvent); 549 } 550 assertOneKeyEventSentToFramework(KeyEvent event)551 private void assertOneKeyEventSentToFramework(KeyEvent event) { 552 assertEquals(1, mInputEventsHandler.timedMessages.size()); 553 554 Message m = getTimedMessage(mInputEventsHandler, 0); 555 assertEquals(SEND_FRAMEWORK_KEY_EVENT, m.what); 556 assertEquals(WindowManagerPolicy.FLAG_PASS_TO_USER, m.arg1); 557 assertTrue(new KeyEventMatcher(event).matches(m.obj)); 558 } 559 assertTwoKeyEventsSentToFrameworkInOrder(KeyEvent first, KeyEvent second)560 private void assertTwoKeyEventsSentToFrameworkInOrder(KeyEvent first, KeyEvent second) { 561 assertEquals(2, mInputEventsHandler.timedMessages.size()); 562 563 Message m0 = getTimedMessage(mInputEventsHandler, 0); 564 assertEquals(SEND_FRAMEWORK_KEY_EVENT, m0.what); 565 assertEquals(WindowManagerPolicy.FLAG_PASS_TO_USER, m0.arg1); 566 assertTrue(new KeyEventMatcher(first).matches(m0.obj)); 567 568 Message m1 = getTimedMessage(mInputEventsHandler, 1); 569 assertEquals(SEND_FRAMEWORK_KEY_EVENT, m1.what); 570 assertEquals(WindowManagerPolicy.FLAG_PASS_TO_USER, m1.arg1); 571 assertTrue(new KeyEventMatcher(second).matches(m1.obj)); 572 } 573 getTimedMessage(MessageCapturingHandler handler, int i)574 private static Message getTimedMessage(MessageCapturingHandler handler, int i) { 575 return handler.timedMessages.get(i).first; 576 } 577 isTimeoutPending(MessageCapturingHandler handler)578 private static boolean isTimeoutPending(MessageCapturingHandler handler) { 579 return handler.hasMessages(KeyEventDispatcher.MSG_ON_KEY_EVENT_TIMEOUT); 580 } 581 582 private class KeyEventMatcher extends TypeSafeMatcher<KeyEvent> { 583 private KeyEvent mEventToMatch; 584 KeyEventMatcher(KeyEvent eventToMatch)585 KeyEventMatcher(KeyEvent eventToMatch) { 586 mEventToMatch = eventToMatch; 587 } 588 589 @Override matchesSafely(KeyEvent keyEvent)590 public boolean matchesSafely(KeyEvent keyEvent) { 591 return (mEventToMatch.getAction() == keyEvent.getAction()) 592 && (mEventToMatch.getKeyCode() == keyEvent.getKeyCode()); 593 } 594 595 @Override describeTo(Description description)596 public void describeTo(Description description) { 597 description.appendText("Key event matcher"); 598 } 599 } 600 } 601