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