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