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