InputDispatcher.cpp revision 65fd251c3913fc921468a3dad190810db19eb9df
1/* 2 * Copyright (C) 2010 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#define LOG_TAG "InputDispatcher" 18 19//#define LOG_NDEBUG 0 20 21// Log detailed debug messages about each inbound event notification to the dispatcher. 22#define DEBUG_INBOUND_EVENT_DETAILS 0 23 24// Log detailed debug messages about each outbound event processed by the dispatcher. 25#define DEBUG_OUTBOUND_EVENT_DETAILS 0 26 27// Log debug messages about batching. 28#define DEBUG_BATCHING 0 29 30// Log debug messages about the dispatch cycle. 31#define DEBUG_DISPATCH_CYCLE 0 32 33// Log debug messages about registrations. 34#define DEBUG_REGISTRATION 0 35 36// Log debug messages about performance statistics. 37#define DEBUG_PERFORMANCE_STATISTICS 0 38 39// Log debug messages about input event injection. 40#define DEBUG_INJECTION 0 41 42// Log debug messages about input event throttling. 43#define DEBUG_THROTTLING 0 44 45// Log debug messages about input focus tracking. 46#define DEBUG_FOCUS 0 47 48// Log debug messages about the app switch latency optimization. 49#define DEBUG_APP_SWITCH 0 50 51// Log debug messages about hover events. 52#define DEBUG_HOVER 0 53 54#include "InputDispatcher.h" 55 56#include <cutils/log.h> 57#include <ui/PowerManager.h> 58 59#include <stddef.h> 60#include <unistd.h> 61#include <errno.h> 62#include <limits.h> 63 64#define INDENT " " 65#define INDENT2 " " 66 67namespace android { 68 69// Default input dispatching timeout if there is no focused application or paused window 70// from which to determine an appropriate dispatching timeout. 71const nsecs_t DEFAULT_INPUT_DISPATCHING_TIMEOUT = 5000 * 1000000LL; // 5 sec 72 73// Amount of time to allow for all pending events to be processed when an app switch 74// key is on the way. This is used to preempt input dispatch and drop input events 75// when an application takes too long to respond and the user has pressed an app switch key. 76const nsecs_t APP_SWITCH_TIMEOUT = 500 * 1000000LL; // 0.5sec 77 78// Amount of time to allow for an event to be dispatched (measured since its eventTime) 79// before considering it stale and dropping it. 80const nsecs_t STALE_EVENT_TIMEOUT = 10000 * 1000000LL; // 10sec 81 82// Motion samples that are received within this amount of time are simply coalesced 83// when batched instead of being appended. This is done because some drivers update 84// the location of pointers one at a time instead of all at once. 85// For example, when there are 10 fingers down, the input dispatcher may receive 10 86// samples in quick succession with only one finger's location changed in each sample. 87// 88// This value effectively imposes an upper bound on the touch sampling rate. 89// Touch sensors typically have a 50Hz - 200Hz sampling rate, so we expect distinct 90// samples to become available 5-20ms apart but individual finger reports can trickle 91// in over a period of 2-4ms or so. 92// 93// Empirical testing shows that a 2ms coalescing interval (500Hz) is not enough, 94// a 3ms coalescing interval (333Hz) works well most of the time and doesn't introduce 95// significant quantization noise on current hardware. 96const nsecs_t MOTION_SAMPLE_COALESCE_INTERVAL = 3 * 1000000LL; // 3ms, 333Hz 97 98 99static inline nsecs_t now() { 100 return systemTime(SYSTEM_TIME_MONOTONIC); 101} 102 103static inline const char* toString(bool value) { 104 return value ? "true" : "false"; 105} 106 107static inline int32_t getMotionEventActionPointerIndex(int32_t action) { 108 return (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) 109 >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT; 110} 111 112static bool isValidKeyAction(int32_t action) { 113 switch (action) { 114 case AKEY_EVENT_ACTION_DOWN: 115 case AKEY_EVENT_ACTION_UP: 116 return true; 117 default: 118 return false; 119 } 120} 121 122static bool validateKeyEvent(int32_t action) { 123 if (! isValidKeyAction(action)) { 124 LOGE("Key event has invalid action code 0x%x", action); 125 return false; 126 } 127 return true; 128} 129 130static bool isValidMotionAction(int32_t action, size_t pointerCount) { 131 switch (action & AMOTION_EVENT_ACTION_MASK) { 132 case AMOTION_EVENT_ACTION_DOWN: 133 case AMOTION_EVENT_ACTION_UP: 134 case AMOTION_EVENT_ACTION_CANCEL: 135 case AMOTION_EVENT_ACTION_MOVE: 136 case AMOTION_EVENT_ACTION_OUTSIDE: 137 case AMOTION_EVENT_ACTION_HOVER_ENTER: 138 case AMOTION_EVENT_ACTION_HOVER_MOVE: 139 case AMOTION_EVENT_ACTION_HOVER_EXIT: 140 case AMOTION_EVENT_ACTION_SCROLL: 141 return true; 142 case AMOTION_EVENT_ACTION_POINTER_DOWN: 143 case AMOTION_EVENT_ACTION_POINTER_UP: { 144 int32_t index = getMotionEventActionPointerIndex(action); 145 return index >= 0 && size_t(index) < pointerCount; 146 } 147 default: 148 return false; 149 } 150} 151 152static bool validateMotionEvent(int32_t action, size_t pointerCount, 153 const PointerProperties* pointerProperties) { 154 if (! isValidMotionAction(action, pointerCount)) { 155 LOGE("Motion event has invalid action code 0x%x", action); 156 return false; 157 } 158 if (pointerCount < 1 || pointerCount > MAX_POINTERS) { 159 LOGE("Motion event has invalid pointer count %d; value must be between 1 and %d.", 160 pointerCount, MAX_POINTERS); 161 return false; 162 } 163 BitSet32 pointerIdBits; 164 for (size_t i = 0; i < pointerCount; i++) { 165 int32_t id = pointerProperties[i].id; 166 if (id < 0 || id > MAX_POINTER_ID) { 167 LOGE("Motion event has invalid pointer id %d; value must be between 0 and %d", 168 id, MAX_POINTER_ID); 169 return false; 170 } 171 if (pointerIdBits.hasBit(id)) { 172 LOGE("Motion event has duplicate pointer id %d", id); 173 return false; 174 } 175 pointerIdBits.markBit(id); 176 } 177 return true; 178} 179 180static void scalePointerCoords(const PointerCoords* inCoords, size_t count, float scaleFactor, 181 PointerCoords* outCoords) { 182 for (size_t i = 0; i < count; i++) { 183 outCoords[i] = inCoords[i]; 184 outCoords[i].scale(scaleFactor); 185 } 186} 187 188static void dumpRegion(String8& dump, const SkRegion& region) { 189 if (region.isEmpty()) { 190 dump.append("<empty>"); 191 return; 192 } 193 194 bool first = true; 195 for (SkRegion::Iterator it(region); !it.done(); it.next()) { 196 if (first) { 197 first = false; 198 } else { 199 dump.append("|"); 200 } 201 const SkIRect& rect = it.rect(); 202 dump.appendFormat("[%d,%d][%d,%d]", rect.fLeft, rect.fTop, rect.fRight, rect.fBottom); 203 } 204} 205 206 207// --- InputDispatcher --- 208 209InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy) : 210 mPolicy(policy), 211 mPendingEvent(NULL), mAppSwitchSawKeyDown(false), mAppSwitchDueTime(LONG_LONG_MAX), 212 mNextUnblockedEvent(NULL), 213 mDispatchEnabled(true), mDispatchFrozen(false), mInputFilterEnabled(false), 214 mCurrentInputTargetsValid(false), 215 mInputTargetWaitCause(INPUT_TARGET_WAIT_CAUSE_NONE) { 216 mLooper = new Looper(false); 217 218 mKeyRepeatState.lastKeyEntry = NULL; 219 220 policy->getDispatcherConfiguration(&mConfig); 221 222 mThrottleState.minTimeBetweenEvents = 1000000000LL / mConfig.maxEventsPerSecond; 223 mThrottleState.lastDeviceId = -1; 224 225#if DEBUG_THROTTLING 226 mThrottleState.originalSampleCount = 0; 227 LOGD("Throttling - Max events per second = %d", mConfig.maxEventsPerSecond); 228#endif 229} 230 231InputDispatcher::~InputDispatcher() { 232 { // acquire lock 233 AutoMutex _l(mLock); 234 235 resetKeyRepeatLocked(); 236 releasePendingEventLocked(); 237 drainInboundQueueLocked(); 238 } 239 240 while (mConnectionsByReceiveFd.size() != 0) { 241 unregisterInputChannel(mConnectionsByReceiveFd.valueAt(0)->inputChannel); 242 } 243} 244 245void InputDispatcher::dispatchOnce() { 246 nsecs_t nextWakeupTime = LONG_LONG_MAX; 247 { // acquire lock 248 AutoMutex _l(mLock); 249 dispatchOnceInnerLocked(&nextWakeupTime); 250 251 if (runCommandsLockedInterruptible()) { 252 nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately 253 } 254 } // release lock 255 256 // Wait for callback or timeout or wake. (make sure we round up, not down) 257 nsecs_t currentTime = now(); 258 int timeoutMillis = toMillisecondTimeoutDelay(currentTime, nextWakeupTime); 259 mLooper->pollOnce(timeoutMillis); 260} 261 262void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) { 263 nsecs_t currentTime = now(); 264 265 // Reset the key repeat timer whenever we disallow key events, even if the next event 266 // is not a key. This is to ensure that we abort a key repeat if the device is just coming 267 // out of sleep. 268 if (!mPolicy->isKeyRepeatEnabled()) { 269 resetKeyRepeatLocked(); 270 } 271 272 // If dispatching is frozen, do not process timeouts or try to deliver any new events. 273 if (mDispatchFrozen) { 274#if DEBUG_FOCUS 275 LOGD("Dispatch frozen. Waiting some more."); 276#endif 277 return; 278 } 279 280 // Optimize latency of app switches. 281 // Essentially we start a short timeout when an app switch key (HOME / ENDCALL) has 282 // been pressed. When it expires, we preempt dispatch and drop all other pending events. 283 bool isAppSwitchDue = mAppSwitchDueTime <= currentTime; 284 if (mAppSwitchDueTime < *nextWakeupTime) { 285 *nextWakeupTime = mAppSwitchDueTime; 286 } 287 288 // Ready to start a new event. 289 // If we don't already have a pending event, go grab one. 290 if (! mPendingEvent) { 291 if (mInboundQueue.isEmpty()) { 292 if (isAppSwitchDue) { 293 // The inbound queue is empty so the app switch key we were waiting 294 // for will never arrive. Stop waiting for it. 295 resetPendingAppSwitchLocked(false); 296 isAppSwitchDue = false; 297 } 298 299 // Synthesize a key repeat if appropriate. 300 if (mKeyRepeatState.lastKeyEntry) { 301 if (currentTime >= mKeyRepeatState.nextRepeatTime) { 302 mPendingEvent = synthesizeKeyRepeatLocked(currentTime); 303 } else { 304 if (mKeyRepeatState.nextRepeatTime < *nextWakeupTime) { 305 *nextWakeupTime = mKeyRepeatState.nextRepeatTime; 306 } 307 } 308 } 309 if (! mPendingEvent) { 310 return; 311 } 312 } else { 313 // Inbound queue has at least one entry. 314 EventEntry* entry = mInboundQueue.head; 315 316 // Throttle the entry if it is a move event and there are no 317 // other events behind it in the queue. Due to movement batching, additional 318 // samples may be appended to this event by the time the throttling timeout 319 // expires. 320 // TODO Make this smarter and consider throttling per device independently. 321 if (entry->type == EventEntry::TYPE_MOTION 322 && !isAppSwitchDue 323 && mDispatchEnabled 324 && (entry->policyFlags & POLICY_FLAG_PASS_TO_USER) 325 && !entry->isInjected()) { 326 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry); 327 int32_t deviceId = motionEntry->deviceId; 328 uint32_t source = motionEntry->source; 329 if (! isAppSwitchDue 330 && !motionEntry->next // exactly one event, no successors 331 && (motionEntry->action == AMOTION_EVENT_ACTION_MOVE 332 || motionEntry->action == AMOTION_EVENT_ACTION_HOVER_MOVE) 333 && deviceId == mThrottleState.lastDeviceId 334 && source == mThrottleState.lastSource) { 335 nsecs_t nextTime = mThrottleState.lastEventTime 336 + mThrottleState.minTimeBetweenEvents; 337 if (currentTime < nextTime) { 338 // Throttle it! 339#if DEBUG_THROTTLING 340 LOGD("Throttling - Delaying motion event for " 341 "device %d, source 0x%08x by up to %0.3fms.", 342 deviceId, source, (nextTime - currentTime) * 0.000001); 343#endif 344 if (nextTime < *nextWakeupTime) { 345 *nextWakeupTime = nextTime; 346 } 347 if (mThrottleState.originalSampleCount == 0) { 348 mThrottleState.originalSampleCount = 349 motionEntry->countSamples(); 350 } 351 return; 352 } 353 } 354 355#if DEBUG_THROTTLING 356 if (mThrottleState.originalSampleCount != 0) { 357 uint32_t count = motionEntry->countSamples(); 358 LOGD("Throttling - Motion event sample count grew by %d from %d to %d.", 359 count - mThrottleState.originalSampleCount, 360 mThrottleState.originalSampleCount, count); 361 mThrottleState.originalSampleCount = 0; 362 } 363#endif 364 365 mThrottleState.lastEventTime = currentTime; 366 mThrottleState.lastDeviceId = deviceId; 367 mThrottleState.lastSource = source; 368 } 369 370 mInboundQueue.dequeue(entry); 371 mPendingEvent = entry; 372 } 373 374 // Poke user activity for this event. 375 if (mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER) { 376 pokeUserActivityLocked(mPendingEvent); 377 } 378 } 379 380 // Now we have an event to dispatch. 381 // All events are eventually dequeued and processed this way, even if we intend to drop them. 382 LOG_ASSERT(mPendingEvent != NULL); 383 bool done = false; 384 DropReason dropReason = DROP_REASON_NOT_DROPPED; 385 if (!(mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER)) { 386 dropReason = DROP_REASON_POLICY; 387 } else if (!mDispatchEnabled) { 388 dropReason = DROP_REASON_DISABLED; 389 } 390 391 if (mNextUnblockedEvent == mPendingEvent) { 392 mNextUnblockedEvent = NULL; 393 } 394 395 switch (mPendingEvent->type) { 396 case EventEntry::TYPE_CONFIGURATION_CHANGED: { 397 ConfigurationChangedEntry* typedEntry = 398 static_cast<ConfigurationChangedEntry*>(mPendingEvent); 399 done = dispatchConfigurationChangedLocked(currentTime, typedEntry); 400 dropReason = DROP_REASON_NOT_DROPPED; // configuration changes are never dropped 401 break; 402 } 403 404 case EventEntry::TYPE_DEVICE_RESET: { 405 DeviceResetEntry* typedEntry = 406 static_cast<DeviceResetEntry*>(mPendingEvent); 407 done = dispatchDeviceResetLocked(currentTime, typedEntry); 408 dropReason = DROP_REASON_NOT_DROPPED; // device resets are never dropped 409 break; 410 } 411 412 case EventEntry::TYPE_KEY: { 413 KeyEntry* typedEntry = static_cast<KeyEntry*>(mPendingEvent); 414 if (isAppSwitchDue) { 415 if (isAppSwitchKeyEventLocked(typedEntry)) { 416 resetPendingAppSwitchLocked(true); 417 isAppSwitchDue = false; 418 } else if (dropReason == DROP_REASON_NOT_DROPPED) { 419 dropReason = DROP_REASON_APP_SWITCH; 420 } 421 } 422 if (dropReason == DROP_REASON_NOT_DROPPED 423 && isStaleEventLocked(currentTime, typedEntry)) { 424 dropReason = DROP_REASON_STALE; 425 } 426 if (dropReason == DROP_REASON_NOT_DROPPED && mNextUnblockedEvent) { 427 dropReason = DROP_REASON_BLOCKED; 428 } 429 done = dispatchKeyLocked(currentTime, typedEntry, &dropReason, nextWakeupTime); 430 break; 431 } 432 433 case EventEntry::TYPE_MOTION: { 434 MotionEntry* typedEntry = static_cast<MotionEntry*>(mPendingEvent); 435 if (dropReason == DROP_REASON_NOT_DROPPED && isAppSwitchDue) { 436 dropReason = DROP_REASON_APP_SWITCH; 437 } 438 if (dropReason == DROP_REASON_NOT_DROPPED 439 && isStaleEventLocked(currentTime, typedEntry)) { 440 dropReason = DROP_REASON_STALE; 441 } 442 if (dropReason == DROP_REASON_NOT_DROPPED && mNextUnblockedEvent) { 443 dropReason = DROP_REASON_BLOCKED; 444 } 445 done = dispatchMotionLocked(currentTime, typedEntry, 446 &dropReason, nextWakeupTime); 447 break; 448 } 449 450 default: 451 LOG_ASSERT(false); 452 break; 453 } 454 455 if (done) { 456 if (dropReason != DROP_REASON_NOT_DROPPED) { 457 dropInboundEventLocked(mPendingEvent, dropReason); 458 } 459 460 releasePendingEventLocked(); 461 *nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately 462 } 463} 464 465bool InputDispatcher::enqueueInboundEventLocked(EventEntry* entry) { 466 bool needWake = mInboundQueue.isEmpty(); 467 mInboundQueue.enqueueAtTail(entry); 468 469 switch (entry->type) { 470 case EventEntry::TYPE_KEY: { 471 // Optimize app switch latency. 472 // If the application takes too long to catch up then we drop all events preceding 473 // the app switch key. 474 KeyEntry* keyEntry = static_cast<KeyEntry*>(entry); 475 if (isAppSwitchKeyEventLocked(keyEntry)) { 476 if (keyEntry->action == AKEY_EVENT_ACTION_DOWN) { 477 mAppSwitchSawKeyDown = true; 478 } else if (keyEntry->action == AKEY_EVENT_ACTION_UP) { 479 if (mAppSwitchSawKeyDown) { 480#if DEBUG_APP_SWITCH 481 LOGD("App switch is pending!"); 482#endif 483 mAppSwitchDueTime = keyEntry->eventTime + APP_SWITCH_TIMEOUT; 484 mAppSwitchSawKeyDown = false; 485 needWake = true; 486 } 487 } 488 } 489 break; 490 } 491 492 case EventEntry::TYPE_MOTION: { 493 // Optimize case where the current application is unresponsive and the user 494 // decides to touch a window in a different application. 495 // If the application takes too long to catch up then we drop all events preceding 496 // the touch into the other window. 497 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry); 498 if (motionEntry->action == AMOTION_EVENT_ACTION_DOWN 499 && (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) 500 && mInputTargetWaitCause == INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY 501 && mInputTargetWaitApplicationHandle != NULL) { 502 int32_t x = int32_t(motionEntry->firstSample.pointerCoords[0]. 503 getAxisValue(AMOTION_EVENT_AXIS_X)); 504 int32_t y = int32_t(motionEntry->firstSample.pointerCoords[0]. 505 getAxisValue(AMOTION_EVENT_AXIS_Y)); 506 sp<InputWindowHandle> touchedWindowHandle = findTouchedWindowAtLocked(x, y); 507 if (touchedWindowHandle != NULL 508 && touchedWindowHandle->inputApplicationHandle 509 != mInputTargetWaitApplicationHandle) { 510 // User touched a different application than the one we are waiting on. 511 // Flag the event, and start pruning the input queue. 512 mNextUnblockedEvent = motionEntry; 513 needWake = true; 514 } 515 } 516 break; 517 } 518 } 519 520 return needWake; 521} 522 523sp<InputWindowHandle> InputDispatcher::findTouchedWindowAtLocked(int32_t x, int32_t y) { 524 // Traverse windows from front to back to find touched window. 525 size_t numWindows = mWindowHandles.size(); 526 for (size_t i = 0; i < numWindows; i++) { 527 sp<InputWindowHandle> windowHandle = mWindowHandles.itemAt(i); 528 int32_t flags = windowHandle->layoutParamsFlags; 529 530 if (windowHandle->visible) { 531 if (!(flags & InputWindowHandle::FLAG_NOT_TOUCHABLE)) { 532 bool isTouchModal = (flags & (InputWindowHandle::FLAG_NOT_FOCUSABLE 533 | InputWindowHandle::FLAG_NOT_TOUCH_MODAL)) == 0; 534 if (isTouchModal || windowHandle->touchableRegionContainsPoint(x, y)) { 535 // Found window. 536 return windowHandle; 537 } 538 } 539 } 540 541 if (flags & InputWindowHandle::FLAG_SYSTEM_ERROR) { 542 // Error window is on top but not visible, so touch is dropped. 543 return NULL; 544 } 545 } 546 return NULL; 547} 548 549void InputDispatcher::dropInboundEventLocked(EventEntry* entry, DropReason dropReason) { 550 const char* reason; 551 switch (dropReason) { 552 case DROP_REASON_POLICY: 553#if DEBUG_INBOUND_EVENT_DETAILS 554 LOGD("Dropped event because policy consumed it."); 555#endif 556 reason = "inbound event was dropped because the policy consumed it"; 557 break; 558 case DROP_REASON_DISABLED: 559 LOGI("Dropped event because input dispatch is disabled."); 560 reason = "inbound event was dropped because input dispatch is disabled"; 561 break; 562 case DROP_REASON_APP_SWITCH: 563 LOGI("Dropped event because of pending overdue app switch."); 564 reason = "inbound event was dropped because of pending overdue app switch"; 565 break; 566 case DROP_REASON_BLOCKED: 567 LOGI("Dropped event because the current application is not responding and the user " 568 "has started interacting with a different application."); 569 reason = "inbound event was dropped because the current application is not responding " 570 "and the user has started interacting with a different application"; 571 break; 572 case DROP_REASON_STALE: 573 LOGI("Dropped event because it is stale."); 574 reason = "inbound event was dropped because it is stale"; 575 break; 576 default: 577 LOG_ASSERT(false); 578 return; 579 } 580 581 switch (entry->type) { 582 case EventEntry::TYPE_KEY: { 583 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason); 584 synthesizeCancelationEventsForAllConnectionsLocked(options); 585 break; 586 } 587 case EventEntry::TYPE_MOTION: { 588 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry); 589 if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) { 590 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS, reason); 591 synthesizeCancelationEventsForAllConnectionsLocked(options); 592 } else { 593 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason); 594 synthesizeCancelationEventsForAllConnectionsLocked(options); 595 } 596 break; 597 } 598 } 599} 600 601bool InputDispatcher::isAppSwitchKeyCode(int32_t keyCode) { 602 return keyCode == AKEYCODE_HOME || keyCode == AKEYCODE_ENDCALL; 603} 604 605bool InputDispatcher::isAppSwitchKeyEventLocked(KeyEntry* keyEntry) { 606 return ! (keyEntry->flags & AKEY_EVENT_FLAG_CANCELED) 607 && isAppSwitchKeyCode(keyEntry->keyCode) 608 && (keyEntry->policyFlags & POLICY_FLAG_TRUSTED) 609 && (keyEntry->policyFlags & POLICY_FLAG_PASS_TO_USER); 610} 611 612bool InputDispatcher::isAppSwitchPendingLocked() { 613 return mAppSwitchDueTime != LONG_LONG_MAX; 614} 615 616void InputDispatcher::resetPendingAppSwitchLocked(bool handled) { 617 mAppSwitchDueTime = LONG_LONG_MAX; 618 619#if DEBUG_APP_SWITCH 620 if (handled) { 621 LOGD("App switch has arrived."); 622 } else { 623 LOGD("App switch was abandoned."); 624 } 625#endif 626} 627 628bool InputDispatcher::isStaleEventLocked(nsecs_t currentTime, EventEntry* entry) { 629 return currentTime - entry->eventTime >= STALE_EVENT_TIMEOUT; 630} 631 632bool InputDispatcher::runCommandsLockedInterruptible() { 633 if (mCommandQueue.isEmpty()) { 634 return false; 635 } 636 637 do { 638 CommandEntry* commandEntry = mCommandQueue.dequeueAtHead(); 639 640 Command command = commandEntry->command; 641 (this->*command)(commandEntry); // commands are implicitly 'LockedInterruptible' 642 643 commandEntry->connection.clear(); 644 delete commandEntry; 645 } while (! mCommandQueue.isEmpty()); 646 return true; 647} 648 649InputDispatcher::CommandEntry* InputDispatcher::postCommandLocked(Command command) { 650 CommandEntry* commandEntry = new CommandEntry(command); 651 mCommandQueue.enqueueAtTail(commandEntry); 652 return commandEntry; 653} 654 655void InputDispatcher::drainInboundQueueLocked() { 656 while (! mInboundQueue.isEmpty()) { 657 EventEntry* entry = mInboundQueue.dequeueAtHead(); 658 releaseInboundEventLocked(entry); 659 } 660} 661 662void InputDispatcher::releasePendingEventLocked() { 663 if (mPendingEvent) { 664 releaseInboundEventLocked(mPendingEvent); 665 mPendingEvent = NULL; 666 } 667} 668 669void InputDispatcher::releaseInboundEventLocked(EventEntry* entry) { 670 InjectionState* injectionState = entry->injectionState; 671 if (injectionState && injectionState->injectionResult == INPUT_EVENT_INJECTION_PENDING) { 672#if DEBUG_DISPATCH_CYCLE 673 LOGD("Injected inbound event was dropped."); 674#endif 675 setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_FAILED); 676 } 677 if (entry == mNextUnblockedEvent) { 678 mNextUnblockedEvent = NULL; 679 } 680 entry->release(); 681} 682 683void InputDispatcher::resetKeyRepeatLocked() { 684 if (mKeyRepeatState.lastKeyEntry) { 685 mKeyRepeatState.lastKeyEntry->release(); 686 mKeyRepeatState.lastKeyEntry = NULL; 687 } 688} 689 690InputDispatcher::KeyEntry* InputDispatcher::synthesizeKeyRepeatLocked(nsecs_t currentTime) { 691 KeyEntry* entry = mKeyRepeatState.lastKeyEntry; 692 693 // Reuse the repeated key entry if it is otherwise unreferenced. 694 uint32_t policyFlags = (entry->policyFlags & POLICY_FLAG_RAW_MASK) 695 | POLICY_FLAG_PASS_TO_USER | POLICY_FLAG_TRUSTED; 696 if (entry->refCount == 1) { 697 entry->recycle(); 698 entry->eventTime = currentTime; 699 entry->policyFlags = policyFlags; 700 entry->repeatCount += 1; 701 } else { 702 KeyEntry* newEntry = new KeyEntry(currentTime, 703 entry->deviceId, entry->source, policyFlags, 704 entry->action, entry->flags, entry->keyCode, entry->scanCode, 705 entry->metaState, entry->repeatCount + 1, entry->downTime); 706 707 mKeyRepeatState.lastKeyEntry = newEntry; 708 entry->release(); 709 710 entry = newEntry; 711 } 712 entry->syntheticRepeat = true; 713 714 // Increment reference count since we keep a reference to the event in 715 // mKeyRepeatState.lastKeyEntry in addition to the one we return. 716 entry->refCount += 1; 717 718 mKeyRepeatState.nextRepeatTime = currentTime + mConfig.keyRepeatDelay; 719 return entry; 720} 721 722bool InputDispatcher::dispatchConfigurationChangedLocked( 723 nsecs_t currentTime, ConfigurationChangedEntry* entry) { 724#if DEBUG_OUTBOUND_EVENT_DETAILS 725 LOGD("dispatchConfigurationChanged - eventTime=%lld", entry->eventTime); 726#endif 727 728 // Reset key repeating in case a keyboard device was added or removed or something. 729 resetKeyRepeatLocked(); 730 731 // Enqueue a command to run outside the lock to tell the policy that the configuration changed. 732 CommandEntry* commandEntry = postCommandLocked( 733 & InputDispatcher::doNotifyConfigurationChangedInterruptible); 734 commandEntry->eventTime = entry->eventTime; 735 return true; 736} 737 738bool InputDispatcher::dispatchDeviceResetLocked( 739 nsecs_t currentTime, DeviceResetEntry* entry) { 740#if DEBUG_OUTBOUND_EVENT_DETAILS 741 LOGD("dispatchDeviceReset - eventTime=%lld, deviceId=%d", entry->eventTime, entry->deviceId); 742#endif 743 744 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, 745 "device was reset"); 746 options.deviceId = entry->deviceId; 747 synthesizeCancelationEventsForAllConnectionsLocked(options); 748 return true; 749} 750 751bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, KeyEntry* entry, 752 DropReason* dropReason, nsecs_t* nextWakeupTime) { 753 // Preprocessing. 754 if (! entry->dispatchInProgress) { 755 if (entry->repeatCount == 0 756 && entry->action == AKEY_EVENT_ACTION_DOWN 757 && (entry->policyFlags & POLICY_FLAG_TRUSTED) 758 && (!(entry->policyFlags & POLICY_FLAG_DISABLE_KEY_REPEAT))) { 759 if (mKeyRepeatState.lastKeyEntry 760 && mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode) { 761 // We have seen two identical key downs in a row which indicates that the device 762 // driver is automatically generating key repeats itself. We take note of the 763 // repeat here, but we disable our own next key repeat timer since it is clear that 764 // we will not need to synthesize key repeats ourselves. 765 entry->repeatCount = mKeyRepeatState.lastKeyEntry->repeatCount + 1; 766 resetKeyRepeatLocked(); 767 mKeyRepeatState.nextRepeatTime = LONG_LONG_MAX; // don't generate repeats ourselves 768 } else { 769 // Not a repeat. Save key down state in case we do see a repeat later. 770 resetKeyRepeatLocked(); 771 mKeyRepeatState.nextRepeatTime = entry->eventTime + mConfig.keyRepeatTimeout; 772 } 773 mKeyRepeatState.lastKeyEntry = entry; 774 entry->refCount += 1; 775 } else if (! entry->syntheticRepeat) { 776 resetKeyRepeatLocked(); 777 } 778 779 if (entry->repeatCount == 1) { 780 entry->flags |= AKEY_EVENT_FLAG_LONG_PRESS; 781 } else { 782 entry->flags &= ~AKEY_EVENT_FLAG_LONG_PRESS; 783 } 784 785 entry->dispatchInProgress = true; 786 resetTargetsLocked(); 787 788 logOutboundKeyDetailsLocked("dispatchKey - ", entry); 789 } 790 791 // Give the policy a chance to intercept the key. 792 if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) { 793 if (entry->policyFlags & POLICY_FLAG_PASS_TO_USER) { 794 CommandEntry* commandEntry = postCommandLocked( 795 & InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible); 796 if (mFocusedWindowHandle != NULL) { 797 commandEntry->inputWindowHandle = mFocusedWindowHandle; 798 } 799 commandEntry->keyEntry = entry; 800 entry->refCount += 1; 801 return false; // wait for the command to run 802 } else { 803 entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE; 804 } 805 } else if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_SKIP) { 806 if (*dropReason == DROP_REASON_NOT_DROPPED) { 807 *dropReason = DROP_REASON_POLICY; 808 } 809 } 810 811 // Clean up if dropping the event. 812 if (*dropReason != DROP_REASON_NOT_DROPPED) { 813 resetTargetsLocked(); 814 setInjectionResultLocked(entry, *dropReason == DROP_REASON_POLICY 815 ? INPUT_EVENT_INJECTION_SUCCEEDED : INPUT_EVENT_INJECTION_FAILED); 816 return true; 817 } 818 819 // Identify targets. 820 if (! mCurrentInputTargetsValid) { 821 int32_t injectionResult = findFocusedWindowTargetsLocked(currentTime, 822 entry, nextWakeupTime); 823 if (injectionResult == INPUT_EVENT_INJECTION_PENDING) { 824 return false; 825 } 826 827 setInjectionResultLocked(entry, injectionResult); 828 if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) { 829 return true; 830 } 831 832 addMonitoringTargetsLocked(); 833 commitTargetsLocked(); 834 } 835 836 // Dispatch the key. 837 dispatchEventToCurrentInputTargetsLocked(currentTime, entry, false); 838 return true; 839} 840 841void InputDispatcher::logOutboundKeyDetailsLocked(const char* prefix, const KeyEntry* entry) { 842#if DEBUG_OUTBOUND_EVENT_DETAILS 843 LOGD("%seventTime=%lld, deviceId=%d, source=0x%x, policyFlags=0x%x, " 844 "action=0x%x, flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, " 845 "repeatCount=%d, downTime=%lld", 846 prefix, 847 entry->eventTime, entry->deviceId, entry->source, entry->policyFlags, 848 entry->action, entry->flags, entry->keyCode, entry->scanCode, entry->metaState, 849 entry->repeatCount, entry->downTime); 850#endif 851} 852 853bool InputDispatcher::dispatchMotionLocked( 854 nsecs_t currentTime, MotionEntry* entry, DropReason* dropReason, nsecs_t* nextWakeupTime) { 855 // Preprocessing. 856 if (! entry->dispatchInProgress) { 857 entry->dispatchInProgress = true; 858 resetTargetsLocked(); 859 860 logOutboundMotionDetailsLocked("dispatchMotion - ", entry); 861 } 862 863 // Clean up if dropping the event. 864 if (*dropReason != DROP_REASON_NOT_DROPPED) { 865 resetTargetsLocked(); 866 setInjectionResultLocked(entry, *dropReason == DROP_REASON_POLICY 867 ? INPUT_EVENT_INJECTION_SUCCEEDED : INPUT_EVENT_INJECTION_FAILED); 868 return true; 869 } 870 871 bool isPointerEvent = entry->source & AINPUT_SOURCE_CLASS_POINTER; 872 873 // Identify targets. 874 bool conflictingPointerActions = false; 875 if (! mCurrentInputTargetsValid) { 876 int32_t injectionResult; 877 const MotionSample* splitBatchAfterSample = NULL; 878 if (isPointerEvent) { 879 // Pointer event. (eg. touchscreen) 880 injectionResult = findTouchedWindowTargetsLocked(currentTime, 881 entry, nextWakeupTime, &conflictingPointerActions, &splitBatchAfterSample); 882 } else { 883 // Non touch event. (eg. trackball) 884 injectionResult = findFocusedWindowTargetsLocked(currentTime, 885 entry, nextWakeupTime); 886 } 887 if (injectionResult == INPUT_EVENT_INJECTION_PENDING) { 888 return false; 889 } 890 891 setInjectionResultLocked(entry, injectionResult); 892 if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) { 893 return true; 894 } 895 896 addMonitoringTargetsLocked(); 897 commitTargetsLocked(); 898 899 // Unbatch the event if necessary by splitting it into two parts after the 900 // motion sample indicated by splitBatchAfterSample. 901 if (splitBatchAfterSample && splitBatchAfterSample->next) { 902#if DEBUG_BATCHING 903 uint32_t originalSampleCount = entry->countSamples(); 904#endif 905 MotionSample* nextSample = splitBatchAfterSample->next; 906 MotionEntry* nextEntry = new MotionEntry(nextSample->eventTime, 907 entry->deviceId, entry->source, entry->policyFlags, 908 entry->action, entry->flags, 909 entry->metaState, entry->buttonState, entry->edgeFlags, 910 entry->xPrecision, entry->yPrecision, entry->downTime, 911 entry->pointerCount, entry->pointerProperties, nextSample->pointerCoords); 912 if (nextSample != entry->lastSample) { 913 nextEntry->firstSample.next = nextSample->next; 914 nextEntry->lastSample = entry->lastSample; 915 } 916 delete nextSample; 917 918 entry->lastSample = const_cast<MotionSample*>(splitBatchAfterSample); 919 entry->lastSample->next = NULL; 920 921 if (entry->injectionState) { 922 nextEntry->injectionState = entry->injectionState; 923 entry->injectionState->refCount += 1; 924 } 925 926#if DEBUG_BATCHING 927 LOGD("Split batch of %d samples into two parts, first part has %d samples, " 928 "second part has %d samples.", originalSampleCount, 929 entry->countSamples(), nextEntry->countSamples()); 930#endif 931 932 mInboundQueue.enqueueAtHead(nextEntry); 933 } 934 } 935 936 // Dispatch the motion. 937 if (conflictingPointerActions) { 938 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS, 939 "conflicting pointer actions"); 940 synthesizeCancelationEventsForAllConnectionsLocked(options); 941 } 942 dispatchEventToCurrentInputTargetsLocked(currentTime, entry, false); 943 return true; 944} 945 946 947void InputDispatcher::logOutboundMotionDetailsLocked(const char* prefix, const MotionEntry* entry) { 948#if DEBUG_OUTBOUND_EVENT_DETAILS 949 LOGD("%seventTime=%lld, deviceId=%d, source=0x%x, policyFlags=0x%x, " 950 "action=0x%x, flags=0x%x, " 951 "metaState=0x%x, buttonState=0x%x, " 952 "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%lld", 953 prefix, 954 entry->eventTime, entry->deviceId, entry->source, entry->policyFlags, 955 entry->action, entry->flags, 956 entry->metaState, entry->buttonState, 957 entry->edgeFlags, entry->xPrecision, entry->yPrecision, 958 entry->downTime); 959 960 // Print the most recent sample that we have available, this may change due to batching. 961 size_t sampleCount = 1; 962 const MotionSample* sample = & entry->firstSample; 963 for (; sample->next != NULL; sample = sample->next) { 964 sampleCount += 1; 965 } 966 for (uint32_t i = 0; i < entry->pointerCount; i++) { 967 LOGD(" Pointer %d: id=%d, toolType=%d, " 968 "x=%f, y=%f, pressure=%f, size=%f, " 969 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, " 970 "orientation=%f", 971 i, entry->pointerProperties[i].id, 972 entry->pointerProperties[i].toolType, 973 sample->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X), 974 sample->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y), 975 sample->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE), 976 sample->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE), 977 sample->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR), 978 sample->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR), 979 sample->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR), 980 sample->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR), 981 sample->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION)); 982 } 983 984 // Keep in mind that due to batching, it is possible for the number of samples actually 985 // dispatched to change before the application finally consumed them. 986 if (entry->action == AMOTION_EVENT_ACTION_MOVE) { 987 LOGD(" ... Total movement samples currently batched %d ...", sampleCount); 988 } 989#endif 990} 991 992void InputDispatcher::dispatchEventToCurrentInputTargetsLocked(nsecs_t currentTime, 993 EventEntry* eventEntry, bool resumeWithAppendedMotionSample) { 994#if DEBUG_DISPATCH_CYCLE 995 LOGD("dispatchEventToCurrentInputTargets - " 996 "resumeWithAppendedMotionSample=%s", 997 toString(resumeWithAppendedMotionSample)); 998#endif 999 1000 LOG_ASSERT(eventEntry->dispatchInProgress); // should already have been set to true 1001 1002 pokeUserActivityLocked(eventEntry); 1003 1004 for (size_t i = 0; i < mCurrentInputTargets.size(); i++) { 1005 const InputTarget& inputTarget = mCurrentInputTargets.itemAt(i); 1006 1007 ssize_t connectionIndex = getConnectionIndexLocked(inputTarget.inputChannel); 1008 if (connectionIndex >= 0) { 1009 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex); 1010 prepareDispatchCycleLocked(currentTime, connection, eventEntry, & inputTarget, 1011 resumeWithAppendedMotionSample); 1012 } else { 1013#if DEBUG_FOCUS 1014 LOGD("Dropping event delivery to target with channel '%s' because it " 1015 "is no longer registered with the input dispatcher.", 1016 inputTarget.inputChannel->getName().string()); 1017#endif 1018 } 1019 } 1020} 1021 1022void InputDispatcher::resetTargetsLocked() { 1023 mCurrentInputTargetsValid = false; 1024 mCurrentInputTargets.clear(); 1025 resetANRTimeoutsLocked(); 1026} 1027 1028void InputDispatcher::commitTargetsLocked() { 1029 mCurrentInputTargetsValid = true; 1030} 1031 1032int32_t InputDispatcher::handleTargetsNotReadyLocked(nsecs_t currentTime, 1033 const EventEntry* entry, 1034 const sp<InputApplicationHandle>& applicationHandle, 1035 const sp<InputWindowHandle>& windowHandle, 1036 nsecs_t* nextWakeupTime) { 1037 if (applicationHandle == NULL && windowHandle == NULL) { 1038 if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY) { 1039#if DEBUG_FOCUS 1040 LOGD("Waiting for system to become ready for input."); 1041#endif 1042 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY; 1043 mInputTargetWaitStartTime = currentTime; 1044 mInputTargetWaitTimeoutTime = LONG_LONG_MAX; 1045 mInputTargetWaitTimeoutExpired = false; 1046 mInputTargetWaitApplicationHandle.clear(); 1047 } 1048 } else { 1049 if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) { 1050#if DEBUG_FOCUS 1051 LOGD("Waiting for application to become ready for input: %s", 1052 getApplicationWindowLabelLocked(applicationHandle, windowHandle).string()); 1053#endif 1054 nsecs_t timeout = windowHandle != NULL ? windowHandle->dispatchingTimeout : 1055 applicationHandle != NULL ? 1056 applicationHandle->dispatchingTimeout : DEFAULT_INPUT_DISPATCHING_TIMEOUT; 1057 1058 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY; 1059 mInputTargetWaitStartTime = currentTime; 1060 mInputTargetWaitTimeoutTime = currentTime + timeout; 1061 mInputTargetWaitTimeoutExpired = false; 1062 mInputTargetWaitApplicationHandle.clear(); 1063 1064 if (windowHandle != NULL) { 1065 mInputTargetWaitApplicationHandle = windowHandle->inputApplicationHandle; 1066 } 1067 if (mInputTargetWaitApplicationHandle == NULL && applicationHandle != NULL) { 1068 mInputTargetWaitApplicationHandle = applicationHandle; 1069 } 1070 } 1071 } 1072 1073 if (mInputTargetWaitTimeoutExpired) { 1074 return INPUT_EVENT_INJECTION_TIMED_OUT; 1075 } 1076 1077 if (currentTime >= mInputTargetWaitTimeoutTime) { 1078 onANRLocked(currentTime, applicationHandle, windowHandle, 1079 entry->eventTime, mInputTargetWaitStartTime); 1080 1081 // Force poll loop to wake up immediately on next iteration once we get the 1082 // ANR response back from the policy. 1083 *nextWakeupTime = LONG_LONG_MIN; 1084 return INPUT_EVENT_INJECTION_PENDING; 1085 } else { 1086 // Force poll loop to wake up when timeout is due. 1087 if (mInputTargetWaitTimeoutTime < *nextWakeupTime) { 1088 *nextWakeupTime = mInputTargetWaitTimeoutTime; 1089 } 1090 return INPUT_EVENT_INJECTION_PENDING; 1091 } 1092} 1093 1094void InputDispatcher::resumeAfterTargetsNotReadyTimeoutLocked(nsecs_t newTimeout, 1095 const sp<InputChannel>& inputChannel) { 1096 if (newTimeout > 0) { 1097 // Extend the timeout. 1098 mInputTargetWaitTimeoutTime = now() + newTimeout; 1099 } else { 1100 // Give up. 1101 mInputTargetWaitTimeoutExpired = true; 1102 1103 // Release the touch targets. 1104 mTouchState.reset(); 1105 1106 // Input state will not be realistic. Mark it out of sync. 1107 if (inputChannel.get()) { 1108 ssize_t connectionIndex = getConnectionIndexLocked(inputChannel); 1109 if (connectionIndex >= 0) { 1110 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex); 1111 if (connection->status == Connection::STATUS_NORMAL) { 1112 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, 1113 "application not responding"); 1114 synthesizeCancelationEventsForConnectionLocked(connection, options); 1115 } 1116 } 1117 } 1118 } 1119} 1120 1121nsecs_t InputDispatcher::getTimeSpentWaitingForApplicationLocked( 1122 nsecs_t currentTime) { 1123 if (mInputTargetWaitCause == INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) { 1124 return currentTime - mInputTargetWaitStartTime; 1125 } 1126 return 0; 1127} 1128 1129void InputDispatcher::resetANRTimeoutsLocked() { 1130#if DEBUG_FOCUS 1131 LOGD("Resetting ANR timeouts."); 1132#endif 1133 1134 // Reset input target wait timeout. 1135 mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_NONE; 1136 mInputTargetWaitApplicationHandle.clear(); 1137} 1138 1139int32_t InputDispatcher::findFocusedWindowTargetsLocked(nsecs_t currentTime, 1140 const EventEntry* entry, nsecs_t* nextWakeupTime) { 1141 mCurrentInputTargets.clear(); 1142 1143 int32_t injectionResult; 1144 1145 // If there is no currently focused window and no focused application 1146 // then drop the event. 1147 if (mFocusedWindowHandle == NULL) { 1148 if (mFocusedApplicationHandle != NULL) { 1149#if DEBUG_FOCUS 1150 LOGD("Waiting because there is no focused window but there is a " 1151 "focused application that may eventually add a window: %s.", 1152 getApplicationWindowLabelLocked(mFocusedApplicationHandle, NULL).string()); 1153#endif 1154 injectionResult = handleTargetsNotReadyLocked(currentTime, entry, 1155 mFocusedApplicationHandle, NULL, nextWakeupTime); 1156 goto Unresponsive; 1157 } 1158 1159 LOGI("Dropping event because there is no focused window or focused application."); 1160 injectionResult = INPUT_EVENT_INJECTION_FAILED; 1161 goto Failed; 1162 } 1163 1164 // Check permissions. 1165 if (! checkInjectionPermission(mFocusedWindowHandle, entry->injectionState)) { 1166 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED; 1167 goto Failed; 1168 } 1169 1170 // If the currently focused window is paused then keep waiting. 1171 if (mFocusedWindowHandle->paused) { 1172#if DEBUG_FOCUS 1173 LOGD("Waiting because focused window is paused."); 1174#endif 1175 injectionResult = handleTargetsNotReadyLocked(currentTime, entry, 1176 mFocusedApplicationHandle, mFocusedWindowHandle, nextWakeupTime); 1177 goto Unresponsive; 1178 } 1179 1180 // If the currently focused window is still working on previous events then keep waiting. 1181 if (! isWindowFinishedWithPreviousInputLocked(mFocusedWindowHandle)) { 1182#if DEBUG_FOCUS 1183 LOGD("Waiting because focused window still processing previous input."); 1184#endif 1185 injectionResult = handleTargetsNotReadyLocked(currentTime, entry, 1186 mFocusedApplicationHandle, mFocusedWindowHandle, nextWakeupTime); 1187 goto Unresponsive; 1188 } 1189 1190 // Success! Output targets. 1191 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED; 1192 addWindowTargetLocked(mFocusedWindowHandle, 1193 InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS, BitSet32(0)); 1194 1195 // Done. 1196Failed: 1197Unresponsive: 1198 nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime); 1199 updateDispatchStatisticsLocked(currentTime, entry, 1200 injectionResult, timeSpentWaitingForApplication); 1201#if DEBUG_FOCUS 1202 LOGD("findFocusedWindow finished: injectionResult=%d, " 1203 "timeSpendWaitingForApplication=%0.1fms", 1204 injectionResult, timeSpentWaitingForApplication / 1000000.0); 1205#endif 1206 return injectionResult; 1207} 1208 1209int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime, 1210 const MotionEntry* entry, nsecs_t* nextWakeupTime, bool* outConflictingPointerActions, 1211 const MotionSample** outSplitBatchAfterSample) { 1212 enum InjectionPermission { 1213 INJECTION_PERMISSION_UNKNOWN, 1214 INJECTION_PERMISSION_GRANTED, 1215 INJECTION_PERMISSION_DENIED 1216 }; 1217 1218 mCurrentInputTargets.clear(); 1219 1220 nsecs_t startTime = now(); 1221 1222 // For security reasons, we defer updating the touch state until we are sure that 1223 // event injection will be allowed. 1224 // 1225 // FIXME In the original code, screenWasOff could never be set to true. 1226 // The reason is that the POLICY_FLAG_WOKE_HERE 1227 // and POLICY_FLAG_BRIGHT_HERE flags were set only when preprocessing raw 1228 // EV_KEY, EV_REL and EV_ABS events. As it happens, the touch event was 1229 // actually enqueued using the policyFlags that appeared in the final EV_SYN 1230 // events upon which no preprocessing took place. So policyFlags was always 0. 1231 // In the new native input dispatcher we're a bit more careful about event 1232 // preprocessing so the touches we receive can actually have non-zero policyFlags. 1233 // Unfortunately we obtain undesirable behavior. 1234 // 1235 // Here's what happens: 1236 // 1237 // When the device dims in anticipation of going to sleep, touches 1238 // in windows which have FLAG_TOUCHABLE_WHEN_WAKING cause 1239 // the device to brighten and reset the user activity timer. 1240 // Touches on other windows (such as the launcher window) 1241 // are dropped. Then after a moment, the device goes to sleep. Oops. 1242 // 1243 // Also notice how screenWasOff was being initialized using POLICY_FLAG_BRIGHT_HERE 1244 // instead of POLICY_FLAG_WOKE_HERE... 1245 // 1246 bool screenWasOff = false; // original policy: policyFlags & POLICY_FLAG_BRIGHT_HERE; 1247 1248 int32_t action = entry->action; 1249 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK; 1250 1251 // Update the touch state as needed based on the properties of the touch event. 1252 int32_t injectionResult = INPUT_EVENT_INJECTION_PENDING; 1253 InjectionPermission injectionPermission = INJECTION_PERMISSION_UNKNOWN; 1254 sp<InputWindowHandle> newHoverWindowHandle; 1255 1256 bool isSplit = mTouchState.split; 1257 bool switchedDevice = mTouchState.deviceId >= 0 1258 && (mTouchState.deviceId != entry->deviceId 1259 || mTouchState.source != entry->source); 1260 bool isHoverAction = (maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE 1261 || maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER 1262 || maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT); 1263 bool newGesture = (maskedAction == AMOTION_EVENT_ACTION_DOWN 1264 || maskedAction == AMOTION_EVENT_ACTION_SCROLL 1265 || isHoverAction); 1266 bool wrongDevice = false; 1267 if (newGesture) { 1268 bool down = maskedAction == AMOTION_EVENT_ACTION_DOWN; 1269 if (switchedDevice && mTouchState.down && !down) { 1270#if DEBUG_FOCUS 1271 LOGD("Dropping event because a pointer for a different device is already down."); 1272#endif 1273 mTempTouchState.copyFrom(mTouchState); 1274 injectionResult = INPUT_EVENT_INJECTION_FAILED; 1275 switchedDevice = false; 1276 wrongDevice = true; 1277 goto Failed; 1278 } 1279 mTempTouchState.reset(); 1280 mTempTouchState.down = down; 1281 mTempTouchState.deviceId = entry->deviceId; 1282 mTempTouchState.source = entry->source; 1283 isSplit = false; 1284 } else { 1285 mTempTouchState.copyFrom(mTouchState); 1286 } 1287 1288 if (newGesture || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)) { 1289 /* Case 1: New splittable pointer going down, or need target for hover or scroll. */ 1290 1291 const MotionSample* sample = &entry->firstSample; 1292 int32_t pointerIndex = getMotionEventActionPointerIndex(action); 1293 int32_t x = int32_t(sample->pointerCoords[pointerIndex]. 1294 getAxisValue(AMOTION_EVENT_AXIS_X)); 1295 int32_t y = int32_t(sample->pointerCoords[pointerIndex]. 1296 getAxisValue(AMOTION_EVENT_AXIS_Y)); 1297 sp<InputWindowHandle> newTouchedWindowHandle; 1298 sp<InputWindowHandle> topErrorWindowHandle; 1299 bool isTouchModal = false; 1300 1301 // Traverse windows from front to back to find touched window and outside targets. 1302 size_t numWindows = mWindowHandles.size(); 1303 for (size_t i = 0; i < numWindows; i++) { 1304 sp<InputWindowHandle> windowHandle = mWindowHandles.itemAt(i); 1305 int32_t flags = windowHandle->layoutParamsFlags; 1306 1307 if (flags & InputWindowHandle::FLAG_SYSTEM_ERROR) { 1308 if (topErrorWindowHandle == NULL) { 1309 topErrorWindowHandle = windowHandle; 1310 } 1311 } 1312 1313 if (windowHandle->visible) { 1314 if (! (flags & InputWindowHandle::FLAG_NOT_TOUCHABLE)) { 1315 isTouchModal = (flags & (InputWindowHandle::FLAG_NOT_FOCUSABLE 1316 | InputWindowHandle::FLAG_NOT_TOUCH_MODAL)) == 0; 1317 if (isTouchModal || windowHandle->touchableRegionContainsPoint(x, y)) { 1318 if (! screenWasOff 1319 || (flags & InputWindowHandle::FLAG_TOUCHABLE_WHEN_WAKING)) { 1320 newTouchedWindowHandle = windowHandle; 1321 } 1322 break; // found touched window, exit window loop 1323 } 1324 } 1325 1326 if (maskedAction == AMOTION_EVENT_ACTION_DOWN 1327 && (flags & InputWindowHandle::FLAG_WATCH_OUTSIDE_TOUCH)) { 1328 int32_t outsideTargetFlags = InputTarget::FLAG_DISPATCH_AS_OUTSIDE; 1329 if (isWindowObscuredAtPointLocked(windowHandle, x, y)) { 1330 outsideTargetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED; 1331 } 1332 1333 mTempTouchState.addOrUpdateWindow( 1334 windowHandle, outsideTargetFlags, BitSet32(0)); 1335 } 1336 } 1337 } 1338 1339 // If there is an error window but it is not taking focus (typically because 1340 // it is invisible) then wait for it. Any other focused window may in 1341 // fact be in ANR state. 1342 if (topErrorWindowHandle != NULL && newTouchedWindowHandle != topErrorWindowHandle) { 1343#if DEBUG_FOCUS 1344 LOGD("Waiting because system error window is pending."); 1345#endif 1346 injectionResult = handleTargetsNotReadyLocked(currentTime, entry, 1347 NULL, NULL, nextWakeupTime); 1348 injectionPermission = INJECTION_PERMISSION_UNKNOWN; 1349 goto Unresponsive; 1350 } 1351 1352 // Figure out whether splitting will be allowed for this window. 1353 if (newTouchedWindowHandle != NULL && newTouchedWindowHandle->supportsSplitTouch()) { 1354 // New window supports splitting. 1355 isSplit = true; 1356 } else if (isSplit) { 1357 // New window does not support splitting but we have already split events. 1358 // Assign the pointer to the first foreground window we find. 1359 // (May be NULL which is why we put this code block before the next check.) 1360 newTouchedWindowHandle = mTempTouchState.getFirstForegroundWindowHandle(); 1361 } 1362 1363 // If we did not find a touched window then fail. 1364 if (newTouchedWindowHandle == NULL) { 1365 if (mFocusedApplicationHandle != NULL) { 1366#if DEBUG_FOCUS 1367 LOGD("Waiting because there is no touched window but there is a " 1368 "focused application that may eventually add a new window: %s.", 1369 getApplicationWindowLabelLocked(mFocusedApplicationHandle, NULL).string()); 1370#endif 1371 injectionResult = handleTargetsNotReadyLocked(currentTime, entry, 1372 mFocusedApplicationHandle, NULL, nextWakeupTime); 1373 goto Unresponsive; 1374 } 1375 1376 LOGI("Dropping event because there is no touched window or focused application."); 1377 injectionResult = INPUT_EVENT_INJECTION_FAILED; 1378 goto Failed; 1379 } 1380 1381 // Set target flags. 1382 int32_t targetFlags = InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS; 1383 if (isSplit) { 1384 targetFlags |= InputTarget::FLAG_SPLIT; 1385 } 1386 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) { 1387 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED; 1388 } 1389 1390 // Update hover state. 1391 if (isHoverAction) { 1392 newHoverWindowHandle = newTouchedWindowHandle; 1393 1394 // Ensure all subsequent motion samples are also within the touched window. 1395 // Set *outSplitBatchAfterSample to the sample before the first one that is not 1396 // within the touched window. 1397 if (!isTouchModal) { 1398 while (sample->next) { 1399 if (!newHoverWindowHandle->touchableRegionContainsPoint( 1400 sample->next->pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1401 sample->next->pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y))) { 1402 *outSplitBatchAfterSample = sample; 1403 break; 1404 } 1405 sample = sample->next; 1406 } 1407 } 1408 } else if (maskedAction == AMOTION_EVENT_ACTION_SCROLL) { 1409 newHoverWindowHandle = mLastHoverWindowHandle; 1410 } 1411 1412 // Update the temporary touch state. 1413 BitSet32 pointerIds; 1414 if (isSplit) { 1415 uint32_t pointerId = entry->pointerProperties[pointerIndex].id; 1416 pointerIds.markBit(pointerId); 1417 } 1418 mTempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds); 1419 } else { 1420 /* Case 2: Pointer move, up, cancel or non-splittable pointer down. */ 1421 1422 // If the pointer is not currently down, then ignore the event. 1423 if (! mTempTouchState.down) { 1424#if DEBUG_FOCUS 1425 LOGD("Dropping event because the pointer is not down or we previously " 1426 "dropped the pointer down event."); 1427#endif 1428 injectionResult = INPUT_EVENT_INJECTION_FAILED; 1429 goto Failed; 1430 } 1431 1432 // Check whether touches should slip outside of the current foreground window. 1433 if (maskedAction == AMOTION_EVENT_ACTION_MOVE 1434 && entry->pointerCount == 1 1435 && mTempTouchState.isSlippery()) { 1436 const MotionSample* sample = &entry->firstSample; 1437 int32_t x = int32_t(sample->pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X)); 1438 int32_t y = int32_t(sample->pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y)); 1439 1440 sp<InputWindowHandle> oldTouchedWindowHandle = 1441 mTempTouchState.getFirstForegroundWindowHandle(); 1442 sp<InputWindowHandle> newTouchedWindowHandle = findTouchedWindowAtLocked(x, y); 1443 if (oldTouchedWindowHandle != newTouchedWindowHandle 1444 && newTouchedWindowHandle != NULL) { 1445#if DEBUG_FOCUS 1446 LOGD("Touch is slipping out of window %s into window %s.", 1447 oldTouchedWindowHandle->name.string(), 1448 newTouchedWindowHandle->name.string()); 1449#endif 1450 // Make a slippery exit from the old window. 1451 mTempTouchState.addOrUpdateWindow(oldTouchedWindowHandle, 1452 InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT, BitSet32(0)); 1453 1454 // Make a slippery entrance into the new window. 1455 if (newTouchedWindowHandle->supportsSplitTouch()) { 1456 isSplit = true; 1457 } 1458 1459 int32_t targetFlags = InputTarget::FLAG_FOREGROUND 1460 | InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER; 1461 if (isSplit) { 1462 targetFlags |= InputTarget::FLAG_SPLIT; 1463 } 1464 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) { 1465 targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED; 1466 } 1467 1468 BitSet32 pointerIds; 1469 if (isSplit) { 1470 pointerIds.markBit(entry->pointerProperties[0].id); 1471 } 1472 mTempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds); 1473 1474 // Split the batch here so we send exactly one sample. 1475 *outSplitBatchAfterSample = &entry->firstSample; 1476 } 1477 } 1478 } 1479 1480 if (newHoverWindowHandle != mLastHoverWindowHandle) { 1481 // Split the batch here so we send exactly one sample as part of ENTER or EXIT. 1482 *outSplitBatchAfterSample = &entry->firstSample; 1483 1484 // Let the previous window know that the hover sequence is over. 1485 if (mLastHoverWindowHandle != NULL) { 1486#if DEBUG_HOVER 1487 LOGD("Sending hover exit event to window %s.", mLastHoverWindowHandle->name.string()); 1488#endif 1489 mTempTouchState.addOrUpdateWindow(mLastHoverWindowHandle, 1490 InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT, BitSet32(0)); 1491 } 1492 1493 // Let the new window know that the hover sequence is starting. 1494 if (newHoverWindowHandle != NULL) { 1495#if DEBUG_HOVER 1496 LOGD("Sending hover enter event to window %s.", newHoverWindowHandle->name.string()); 1497#endif 1498 mTempTouchState.addOrUpdateWindow(newHoverWindowHandle, 1499 InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER, BitSet32(0)); 1500 } 1501 } 1502 1503 // Check permission to inject into all touched foreground windows and ensure there 1504 // is at least one touched foreground window. 1505 { 1506 bool haveForegroundWindow = false; 1507 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) { 1508 const TouchedWindow& touchedWindow = mTempTouchState.windows[i]; 1509 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) { 1510 haveForegroundWindow = true; 1511 if (! checkInjectionPermission(touchedWindow.windowHandle, 1512 entry->injectionState)) { 1513 injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED; 1514 injectionPermission = INJECTION_PERMISSION_DENIED; 1515 goto Failed; 1516 } 1517 } 1518 } 1519 if (! haveForegroundWindow) { 1520#if DEBUG_FOCUS 1521 LOGD("Dropping event because there is no touched foreground window to receive it."); 1522#endif 1523 injectionResult = INPUT_EVENT_INJECTION_FAILED; 1524 goto Failed; 1525 } 1526 1527 // Permission granted to injection into all touched foreground windows. 1528 injectionPermission = INJECTION_PERMISSION_GRANTED; 1529 } 1530 1531 // Check whether windows listening for outside touches are owned by the same UID. If it is 1532 // set the policy flag that we will not reveal coordinate information to this window. 1533 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) { 1534 sp<InputWindowHandle> foregroundWindowHandle = 1535 mTempTouchState.getFirstForegroundWindowHandle(); 1536 const int32_t foregroundWindowUid = foregroundWindowHandle->ownerUid; 1537 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) { 1538 const TouchedWindow& touchedWindow = mTempTouchState.windows[i]; 1539 if (touchedWindow.targetFlags & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) { 1540 sp<InputWindowHandle> inputWindowHandle = touchedWindow.windowHandle; 1541 if (inputWindowHandle->ownerUid != foregroundWindowUid) { 1542 mTempTouchState.addOrUpdateWindow(inputWindowHandle, 1543 InputTarget::FLAG_ZERO_COORDS, BitSet32(0)); 1544 } 1545 } 1546 } 1547 } 1548 1549 // Ensure all touched foreground windows are ready for new input. 1550 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) { 1551 const TouchedWindow& touchedWindow = mTempTouchState.windows[i]; 1552 if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) { 1553 // If the touched window is paused then keep waiting. 1554 if (touchedWindow.windowHandle->paused) { 1555#if DEBUG_FOCUS 1556 LOGD("Waiting because touched window is paused."); 1557#endif 1558 injectionResult = handleTargetsNotReadyLocked(currentTime, entry, 1559 NULL, touchedWindow.windowHandle, nextWakeupTime); 1560 goto Unresponsive; 1561 } 1562 1563 // If the touched window is still working on previous events then keep waiting. 1564 if (! isWindowFinishedWithPreviousInputLocked(touchedWindow.windowHandle)) { 1565#if DEBUG_FOCUS 1566 LOGD("Waiting because touched window still processing previous input."); 1567#endif 1568 injectionResult = handleTargetsNotReadyLocked(currentTime, entry, 1569 NULL, touchedWindow.windowHandle, nextWakeupTime); 1570 goto Unresponsive; 1571 } 1572 } 1573 } 1574 1575 // If this is the first pointer going down and the touched window has a wallpaper 1576 // then also add the touched wallpaper windows so they are locked in for the duration 1577 // of the touch gesture. 1578 // We do not collect wallpapers during HOVER_MOVE or SCROLL because the wallpaper 1579 // engine only supports touch events. We would need to add a mechanism similar 1580 // to View.onGenericMotionEvent to enable wallpapers to handle these events. 1581 if (maskedAction == AMOTION_EVENT_ACTION_DOWN) { 1582 sp<InputWindowHandle> foregroundWindowHandle = 1583 mTempTouchState.getFirstForegroundWindowHandle(); 1584 if (foregroundWindowHandle->hasWallpaper) { 1585 for (size_t i = 0; i < mWindowHandles.size(); i++) { 1586 sp<InputWindowHandle> windowHandle = mWindowHandles.itemAt(i); 1587 if (windowHandle->layoutParamsType == InputWindowHandle::TYPE_WALLPAPER) { 1588 mTempTouchState.addOrUpdateWindow(windowHandle, 1589 InputTarget::FLAG_WINDOW_IS_OBSCURED 1590 | InputTarget::FLAG_DISPATCH_AS_IS, 1591 BitSet32(0)); 1592 } 1593 } 1594 } 1595 } 1596 1597 // Success! Output targets. 1598 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED; 1599 1600 for (size_t i = 0; i < mTempTouchState.windows.size(); i++) { 1601 const TouchedWindow& touchedWindow = mTempTouchState.windows.itemAt(i); 1602 addWindowTargetLocked(touchedWindow.windowHandle, touchedWindow.targetFlags, 1603 touchedWindow.pointerIds); 1604 } 1605 1606 // Drop the outside or hover touch windows since we will not care about them 1607 // in the next iteration. 1608 mTempTouchState.filterNonAsIsTouchWindows(); 1609 1610Failed: 1611 // Check injection permission once and for all. 1612 if (injectionPermission == INJECTION_PERMISSION_UNKNOWN) { 1613 if (checkInjectionPermission(NULL, entry->injectionState)) { 1614 injectionPermission = INJECTION_PERMISSION_GRANTED; 1615 } else { 1616 injectionPermission = INJECTION_PERMISSION_DENIED; 1617 } 1618 } 1619 1620 // Update final pieces of touch state if the injector had permission. 1621 if (injectionPermission == INJECTION_PERMISSION_GRANTED) { 1622 if (!wrongDevice) { 1623 if (switchedDevice) { 1624#if DEBUG_FOCUS 1625 LOGD("Conflicting pointer actions: Switched to a different device."); 1626#endif 1627 *outConflictingPointerActions = true; 1628 } 1629 1630 if (isHoverAction) { 1631 // Started hovering, therefore no longer down. 1632 if (mTouchState.down) { 1633#if DEBUG_FOCUS 1634 LOGD("Conflicting pointer actions: Hover received while pointer was down."); 1635#endif 1636 *outConflictingPointerActions = true; 1637 } 1638 mTouchState.reset(); 1639 if (maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER 1640 || maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE) { 1641 mTouchState.deviceId = entry->deviceId; 1642 mTouchState.source = entry->source; 1643 } 1644 } else if (maskedAction == AMOTION_EVENT_ACTION_UP 1645 || maskedAction == AMOTION_EVENT_ACTION_CANCEL) { 1646 // All pointers up or canceled. 1647 mTouchState.reset(); 1648 } else if (maskedAction == AMOTION_EVENT_ACTION_DOWN) { 1649 // First pointer went down. 1650 if (mTouchState.down) { 1651#if DEBUG_FOCUS 1652 LOGD("Conflicting pointer actions: Down received while already down."); 1653#endif 1654 *outConflictingPointerActions = true; 1655 } 1656 mTouchState.copyFrom(mTempTouchState); 1657 } else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) { 1658 // One pointer went up. 1659 if (isSplit) { 1660 int32_t pointerIndex = getMotionEventActionPointerIndex(action); 1661 uint32_t pointerId = entry->pointerProperties[pointerIndex].id; 1662 1663 for (size_t i = 0; i < mTempTouchState.windows.size(); ) { 1664 TouchedWindow& touchedWindow = mTempTouchState.windows.editItemAt(i); 1665 if (touchedWindow.targetFlags & InputTarget::FLAG_SPLIT) { 1666 touchedWindow.pointerIds.clearBit(pointerId); 1667 if (touchedWindow.pointerIds.isEmpty()) { 1668 mTempTouchState.windows.removeAt(i); 1669 continue; 1670 } 1671 } 1672 i += 1; 1673 } 1674 } 1675 mTouchState.copyFrom(mTempTouchState); 1676 } else if (maskedAction == AMOTION_EVENT_ACTION_SCROLL) { 1677 // Discard temporary touch state since it was only valid for this action. 1678 } else { 1679 // Save changes to touch state as-is for all other actions. 1680 mTouchState.copyFrom(mTempTouchState); 1681 } 1682 1683 // Update hover state. 1684 mLastHoverWindowHandle = newHoverWindowHandle; 1685 } 1686 } else { 1687#if DEBUG_FOCUS 1688 LOGD("Not updating touch focus because injection was denied."); 1689#endif 1690 } 1691 1692Unresponsive: 1693 // Reset temporary touch state to ensure we release unnecessary references to input channels. 1694 mTempTouchState.reset(); 1695 1696 nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime); 1697 updateDispatchStatisticsLocked(currentTime, entry, 1698 injectionResult, timeSpentWaitingForApplication); 1699#if DEBUG_FOCUS 1700 LOGD("findTouchedWindow finished: injectionResult=%d, injectionPermission=%d, " 1701 "timeSpentWaitingForApplication=%0.1fms", 1702 injectionResult, injectionPermission, timeSpentWaitingForApplication / 1000000.0); 1703#endif 1704 return injectionResult; 1705} 1706 1707void InputDispatcher::addWindowTargetLocked(const sp<InputWindowHandle>& windowHandle, 1708 int32_t targetFlags, BitSet32 pointerIds) { 1709 mCurrentInputTargets.push(); 1710 1711 InputTarget& target = mCurrentInputTargets.editTop(); 1712 target.inputChannel = windowHandle->inputChannel; 1713 target.flags = targetFlags; 1714 target.xOffset = - windowHandle->frameLeft; 1715 target.yOffset = - windowHandle->frameTop; 1716 target.scaleFactor = windowHandle->scaleFactor; 1717 target.pointerIds = pointerIds; 1718} 1719 1720void InputDispatcher::addMonitoringTargetsLocked() { 1721 for (size_t i = 0; i < mMonitoringChannels.size(); i++) { 1722 mCurrentInputTargets.push(); 1723 1724 InputTarget& target = mCurrentInputTargets.editTop(); 1725 target.inputChannel = mMonitoringChannels[i]; 1726 target.flags = InputTarget::FLAG_DISPATCH_AS_IS; 1727 target.xOffset = 0; 1728 target.yOffset = 0; 1729 target.pointerIds.clear(); 1730 target.scaleFactor = 1.0f; 1731 } 1732} 1733 1734bool InputDispatcher::checkInjectionPermission(const sp<InputWindowHandle>& windowHandle, 1735 const InjectionState* injectionState) { 1736 if (injectionState 1737 && (windowHandle == NULL || windowHandle->ownerUid != injectionState->injectorUid) 1738 && !hasInjectionPermission(injectionState->injectorPid, injectionState->injectorUid)) { 1739 if (windowHandle != NULL) { 1740 LOGW("Permission denied: injecting event from pid %d uid %d to window %s " 1741 "owned by uid %d", 1742 injectionState->injectorPid, injectionState->injectorUid, 1743 windowHandle->name.string(), 1744 windowHandle->ownerUid); 1745 } else { 1746 LOGW("Permission denied: injecting event from pid %d uid %d", 1747 injectionState->injectorPid, injectionState->injectorUid); 1748 } 1749 return false; 1750 } 1751 return true; 1752} 1753 1754bool InputDispatcher::isWindowObscuredAtPointLocked( 1755 const sp<InputWindowHandle>& windowHandle, int32_t x, int32_t y) const { 1756 size_t numWindows = mWindowHandles.size(); 1757 for (size_t i = 0; i < numWindows; i++) { 1758 sp<InputWindowHandle> otherHandle = mWindowHandles.itemAt(i); 1759 if (otherHandle == windowHandle) { 1760 break; 1761 } 1762 if (otherHandle->visible && ! otherHandle->isTrustedOverlay() 1763 && otherHandle->frameContainsPoint(x, y)) { 1764 return true; 1765 } 1766 } 1767 return false; 1768} 1769 1770bool InputDispatcher::isWindowFinishedWithPreviousInputLocked( 1771 const sp<InputWindowHandle>& windowHandle) { 1772 ssize_t connectionIndex = getConnectionIndexLocked(windowHandle->inputChannel); 1773 if (connectionIndex >= 0) { 1774 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex); 1775 return connection->outboundQueue.isEmpty(); 1776 } else { 1777 return true; 1778 } 1779} 1780 1781String8 InputDispatcher::getApplicationWindowLabelLocked( 1782 const sp<InputApplicationHandle>& applicationHandle, 1783 const sp<InputWindowHandle>& windowHandle) { 1784 if (applicationHandle != NULL) { 1785 if (windowHandle != NULL) { 1786 String8 label(applicationHandle->name); 1787 label.append(" - "); 1788 label.append(windowHandle->name); 1789 return label; 1790 } else { 1791 return applicationHandle->name; 1792 } 1793 } else if (windowHandle != NULL) { 1794 return windowHandle->name; 1795 } else { 1796 return String8("<unknown application or window>"); 1797 } 1798} 1799 1800void InputDispatcher::pokeUserActivityLocked(const EventEntry* eventEntry) { 1801 int32_t eventType = POWER_MANAGER_OTHER_EVENT; 1802 switch (eventEntry->type) { 1803 case EventEntry::TYPE_MOTION: { 1804 const MotionEntry* motionEntry = static_cast<const MotionEntry*>(eventEntry); 1805 if (motionEntry->action == AMOTION_EVENT_ACTION_CANCEL) { 1806 return; 1807 } 1808 1809 if (MotionEvent::isTouchEvent(motionEntry->source, motionEntry->action)) { 1810 eventType = POWER_MANAGER_TOUCH_EVENT; 1811 } 1812 break; 1813 } 1814 case EventEntry::TYPE_KEY: { 1815 const KeyEntry* keyEntry = static_cast<const KeyEntry*>(eventEntry); 1816 if (keyEntry->flags & AKEY_EVENT_FLAG_CANCELED) { 1817 return; 1818 } 1819 eventType = POWER_MANAGER_BUTTON_EVENT; 1820 break; 1821 } 1822 } 1823 1824 CommandEntry* commandEntry = postCommandLocked( 1825 & InputDispatcher::doPokeUserActivityLockedInterruptible); 1826 commandEntry->eventTime = eventEntry->eventTime; 1827 commandEntry->userActivityEventType = eventType; 1828} 1829 1830void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime, 1831 const sp<Connection>& connection, EventEntry* eventEntry, const InputTarget* inputTarget, 1832 bool resumeWithAppendedMotionSample) { 1833#if DEBUG_DISPATCH_CYCLE 1834 LOGD("channel '%s' ~ prepareDispatchCycle - flags=%d, " 1835 "xOffset=%f, yOffset=%f, scaleFactor=%f" 1836 "pointerIds=0x%x, " 1837 "resumeWithAppendedMotionSample=%s", 1838 connection->getInputChannelName(), inputTarget->flags, 1839 inputTarget->xOffset, inputTarget->yOffset, 1840 inputTarget->scaleFactor, inputTarget->pointerIds.value, 1841 toString(resumeWithAppendedMotionSample)); 1842#endif 1843 1844 // Make sure we are never called for streaming when splitting across multiple windows. 1845 bool isSplit = inputTarget->flags & InputTarget::FLAG_SPLIT; 1846 LOG_ASSERT(! (resumeWithAppendedMotionSample && isSplit)); 1847 1848 // Skip this event if the connection status is not normal. 1849 // We don't want to enqueue additional outbound events if the connection is broken. 1850 if (connection->status != Connection::STATUS_NORMAL) { 1851#if DEBUG_DISPATCH_CYCLE 1852 LOGD("channel '%s' ~ Dropping event because the channel status is %s", 1853 connection->getInputChannelName(), connection->getStatusLabel()); 1854#endif 1855 return; 1856 } 1857 1858 // Split a motion event if needed. 1859 if (isSplit) { 1860 LOG_ASSERT(eventEntry->type == EventEntry::TYPE_MOTION); 1861 1862 MotionEntry* originalMotionEntry = static_cast<MotionEntry*>(eventEntry); 1863 if (inputTarget->pointerIds.count() != originalMotionEntry->pointerCount) { 1864 MotionEntry* splitMotionEntry = splitMotionEvent( 1865 originalMotionEntry, inputTarget->pointerIds); 1866 if (!splitMotionEntry) { 1867 return; // split event was dropped 1868 } 1869#if DEBUG_FOCUS 1870 LOGD("channel '%s' ~ Split motion event.", 1871 connection->getInputChannelName()); 1872 logOutboundMotionDetailsLocked(" ", splitMotionEntry); 1873#endif 1874 eventEntry = splitMotionEntry; 1875 } 1876 } 1877 1878 // Resume the dispatch cycle with a freshly appended motion sample. 1879 // First we check that the last dispatch entry in the outbound queue is for the same 1880 // motion event to which we appended the motion sample. If we find such a dispatch 1881 // entry, and if it is currently in progress then we try to stream the new sample. 1882 bool wasEmpty = connection->outboundQueue.isEmpty(); 1883 1884 if (! wasEmpty && resumeWithAppendedMotionSample) { 1885 DispatchEntry* motionEventDispatchEntry = 1886 connection->findQueuedDispatchEntryForEvent(eventEntry); 1887 if (motionEventDispatchEntry) { 1888 // If the dispatch entry is not in progress, then we must be busy dispatching an 1889 // earlier event. Not a problem, the motion event is on the outbound queue and will 1890 // be dispatched later. 1891 if (! motionEventDispatchEntry->inProgress) { 1892#if DEBUG_BATCHING 1893 LOGD("channel '%s' ~ Not streaming because the motion event has " 1894 "not yet been dispatched. " 1895 "(Waiting for earlier events to be consumed.)", 1896 connection->getInputChannelName()); 1897#endif 1898 return; 1899 } 1900 1901 // If the dispatch entry is in progress but it already has a tail of pending 1902 // motion samples, then it must mean that the shared memory buffer filled up. 1903 // Not a problem, when this dispatch cycle is finished, we will eventually start 1904 // a new dispatch cycle to process the tail and that tail includes the newly 1905 // appended motion sample. 1906 if (motionEventDispatchEntry->tailMotionSample) { 1907#if DEBUG_BATCHING 1908 LOGD("channel '%s' ~ Not streaming because no new samples can " 1909 "be appended to the motion event in this dispatch cycle. " 1910 "(Waiting for next dispatch cycle to start.)", 1911 connection->getInputChannelName()); 1912#endif 1913 return; 1914 } 1915 1916 // If the motion event was modified in flight, then we cannot stream the sample. 1917 if ((motionEventDispatchEntry->targetFlags & InputTarget::FLAG_DISPATCH_MASK) 1918 != InputTarget::FLAG_DISPATCH_AS_IS) { 1919#if DEBUG_BATCHING 1920 LOGD("channel '%s' ~ Not streaming because the motion event was not " 1921 "being dispatched as-is. " 1922 "(Waiting for next dispatch cycle to start.)", 1923 connection->getInputChannelName()); 1924#endif 1925 return; 1926 } 1927 1928 // The dispatch entry is in progress and is still potentially open for streaming. 1929 // Try to stream the new motion sample. This might fail if the consumer has already 1930 // consumed the motion event (or if the channel is broken). 1931 MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry); 1932 MotionSample* appendedMotionSample = motionEntry->lastSample; 1933 status_t status; 1934 if (motionEventDispatchEntry->scaleFactor == 1.0f) { 1935 status = connection->inputPublisher.appendMotionSample( 1936 appendedMotionSample->eventTime, appendedMotionSample->pointerCoords); 1937 } else { 1938 PointerCoords scaledCoords[MAX_POINTERS]; 1939 for (size_t i = 0; i < motionEntry->pointerCount; i++) { 1940 scaledCoords[i] = appendedMotionSample->pointerCoords[i]; 1941 scaledCoords[i].scale(motionEventDispatchEntry->scaleFactor); 1942 } 1943 status = connection->inputPublisher.appendMotionSample( 1944 appendedMotionSample->eventTime, scaledCoords); 1945 } 1946 if (status == OK) { 1947#if DEBUG_BATCHING 1948 LOGD("channel '%s' ~ Successfully streamed new motion sample.", 1949 connection->getInputChannelName()); 1950#endif 1951 return; 1952 } 1953 1954#if DEBUG_BATCHING 1955 if (status == NO_MEMORY) { 1956 LOGD("channel '%s' ~ Could not append motion sample to currently " 1957 "dispatched move event because the shared memory buffer is full. " 1958 "(Waiting for next dispatch cycle to start.)", 1959 connection->getInputChannelName()); 1960 } else if (status == status_t(FAILED_TRANSACTION)) { 1961 LOGD("channel '%s' ~ Could not append motion sample to currently " 1962 "dispatched move event because the event has already been consumed. " 1963 "(Waiting for next dispatch cycle to start.)", 1964 connection->getInputChannelName()); 1965 } else { 1966 LOGD("channel '%s' ~ Could not append motion sample to currently " 1967 "dispatched move event due to an error, status=%d. " 1968 "(Waiting for next dispatch cycle to start.)", 1969 connection->getInputChannelName(), status); 1970 } 1971#endif 1972 // Failed to stream. Start a new tail of pending motion samples to dispatch 1973 // in the next cycle. 1974 motionEventDispatchEntry->tailMotionSample = appendedMotionSample; 1975 return; 1976 } 1977 } 1978 1979 // Enqueue dispatch entries for the requested modes. 1980 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget, 1981 resumeWithAppendedMotionSample, InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT); 1982 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget, 1983 resumeWithAppendedMotionSample, InputTarget::FLAG_DISPATCH_AS_OUTSIDE); 1984 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget, 1985 resumeWithAppendedMotionSample, InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER); 1986 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget, 1987 resumeWithAppendedMotionSample, InputTarget::FLAG_DISPATCH_AS_IS); 1988 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget, 1989 resumeWithAppendedMotionSample, InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT); 1990 enqueueDispatchEntryLocked(connection, eventEntry, inputTarget, 1991 resumeWithAppendedMotionSample, InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER); 1992 1993 // If the outbound queue was previously empty, start the dispatch cycle going. 1994 if (wasEmpty && !connection->outboundQueue.isEmpty()) { 1995 activateConnectionLocked(connection.get()); 1996 startDispatchCycleLocked(currentTime, connection); 1997 } 1998} 1999 2000void InputDispatcher::enqueueDispatchEntryLocked( 2001 const sp<Connection>& connection, EventEntry* eventEntry, const InputTarget* inputTarget, 2002 bool resumeWithAppendedMotionSample, int32_t dispatchMode) { 2003 int32_t inputTargetFlags = inputTarget->flags; 2004 if (!(inputTargetFlags & dispatchMode)) { 2005 return; 2006 } 2007 inputTargetFlags = (inputTargetFlags & ~InputTarget::FLAG_DISPATCH_MASK) | dispatchMode; 2008 2009 // This is a new event. 2010 // Enqueue a new dispatch entry onto the outbound queue for this connection. 2011 DispatchEntry* dispatchEntry = new DispatchEntry(eventEntry, // increments ref 2012 inputTargetFlags, inputTarget->xOffset, inputTarget->yOffset, 2013 inputTarget->scaleFactor); 2014 if (dispatchEntry->hasForegroundTarget()) { 2015 incrementPendingForegroundDispatchesLocked(eventEntry); 2016 } 2017 2018 // Handle the case where we could not stream a new motion sample because the consumer has 2019 // already consumed the motion event (otherwise the corresponding dispatch entry would 2020 // still be in the outbound queue for this connection). We set the head motion sample 2021 // to the list starting with the newly appended motion sample. 2022 if (resumeWithAppendedMotionSample) { 2023#if DEBUG_BATCHING 2024 LOGD("channel '%s' ~ Preparing a new dispatch cycle for additional motion samples " 2025 "that cannot be streamed because the motion event has already been consumed.", 2026 connection->getInputChannelName()); 2027#endif 2028 MotionSample* appendedMotionSample = static_cast<MotionEntry*>(eventEntry)->lastSample; 2029 dispatchEntry->headMotionSample = appendedMotionSample; 2030 } 2031 2032 // Apply target flags and update the connection's input state. 2033 switch (eventEntry->type) { 2034 case EventEntry::TYPE_KEY: { 2035 KeyEntry* keyEntry = static_cast<KeyEntry*>(eventEntry); 2036 dispatchEntry->resolvedAction = keyEntry->action; 2037 dispatchEntry->resolvedFlags = keyEntry->flags; 2038 2039 if (!connection->inputState.trackKey(keyEntry, 2040 dispatchEntry->resolvedAction, dispatchEntry->resolvedFlags)) { 2041#if DEBUG_DISPATCH_CYCLE 2042 LOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent key event", 2043 connection->getInputChannelName()); 2044#endif 2045 return; // skip the inconsistent event 2046 } 2047 break; 2048 } 2049 2050 case EventEntry::TYPE_MOTION: { 2051 MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry); 2052 if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) { 2053 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_OUTSIDE; 2054 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT) { 2055 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_EXIT; 2056 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER) { 2057 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER; 2058 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT) { 2059 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_CANCEL; 2060 } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER) { 2061 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_DOWN; 2062 } else { 2063 dispatchEntry->resolvedAction = motionEntry->action; 2064 } 2065 if (dispatchEntry->resolvedAction == AMOTION_EVENT_ACTION_HOVER_MOVE 2066 && !connection->inputState.isHovering( 2067 motionEntry->deviceId, motionEntry->source)) { 2068#if DEBUG_DISPATCH_CYCLE 2069 LOGD("channel '%s' ~ enqueueDispatchEntryLocked: filling in missing hover enter event", 2070 connection->getInputChannelName()); 2071#endif 2072 dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER; 2073 } 2074 2075 dispatchEntry->resolvedFlags = motionEntry->flags; 2076 if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) { 2077 dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED; 2078 } 2079 2080 if (!connection->inputState.trackMotion(motionEntry, 2081 dispatchEntry->resolvedAction, dispatchEntry->resolvedFlags)) { 2082#if DEBUG_DISPATCH_CYCLE 2083 LOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent motion event", 2084 connection->getInputChannelName()); 2085#endif 2086 return; // skip the inconsistent event 2087 } 2088 break; 2089 } 2090 } 2091 2092 // Enqueue the dispatch entry. 2093 connection->outboundQueue.enqueueAtTail(dispatchEntry); 2094} 2095 2096void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime, 2097 const sp<Connection>& connection) { 2098#if DEBUG_DISPATCH_CYCLE 2099 LOGD("channel '%s' ~ startDispatchCycle", 2100 connection->getInputChannelName()); 2101#endif 2102 2103 LOG_ASSERT(connection->status == Connection::STATUS_NORMAL); 2104 LOG_ASSERT(! connection->outboundQueue.isEmpty()); 2105 2106 DispatchEntry* dispatchEntry = connection->outboundQueue.head; 2107 LOG_ASSERT(! dispatchEntry->inProgress); 2108 2109 // Mark the dispatch entry as in progress. 2110 dispatchEntry->inProgress = true; 2111 2112 // Publish the event. 2113 status_t status; 2114 EventEntry* eventEntry = dispatchEntry->eventEntry; 2115 switch (eventEntry->type) { 2116 case EventEntry::TYPE_KEY: { 2117 KeyEntry* keyEntry = static_cast<KeyEntry*>(eventEntry); 2118 2119 // Publish the key event. 2120 status = connection->inputPublisher.publishKeyEvent( 2121 keyEntry->deviceId, keyEntry->source, 2122 dispatchEntry->resolvedAction, dispatchEntry->resolvedFlags, 2123 keyEntry->keyCode, keyEntry->scanCode, 2124 keyEntry->metaState, keyEntry->repeatCount, keyEntry->downTime, 2125 keyEntry->eventTime); 2126 2127 if (status) { 2128 LOGE("channel '%s' ~ Could not publish key event, " 2129 "status=%d", connection->getInputChannelName(), status); 2130 abortBrokenDispatchCycleLocked(currentTime, connection); 2131 return; 2132 } 2133 break; 2134 } 2135 2136 case EventEntry::TYPE_MOTION: { 2137 MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry); 2138 2139 // If headMotionSample is non-NULL, then it points to the first new sample that we 2140 // were unable to dispatch during the previous cycle so we resume dispatching from 2141 // that point in the list of motion samples. 2142 // Otherwise, we just start from the first sample of the motion event. 2143 MotionSample* firstMotionSample = dispatchEntry->headMotionSample; 2144 if (! firstMotionSample) { 2145 firstMotionSample = & motionEntry->firstSample; 2146 } 2147 2148 PointerCoords scaledCoords[MAX_POINTERS]; 2149 const PointerCoords* usingCoords = firstMotionSample->pointerCoords; 2150 2151 // Set the X and Y offset depending on the input source. 2152 float xOffset, yOffset, scaleFactor; 2153 if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER 2154 && !(dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS)) { 2155 scaleFactor = dispatchEntry->scaleFactor; 2156 xOffset = dispatchEntry->xOffset * scaleFactor; 2157 yOffset = dispatchEntry->yOffset * scaleFactor; 2158 if (scaleFactor != 1.0f) { 2159 for (size_t i = 0; i < motionEntry->pointerCount; i++) { 2160 scaledCoords[i] = firstMotionSample->pointerCoords[i]; 2161 scaledCoords[i].scale(scaleFactor); 2162 } 2163 usingCoords = scaledCoords; 2164 } 2165 } else { 2166 xOffset = 0.0f; 2167 yOffset = 0.0f; 2168 scaleFactor = 1.0f; 2169 2170 // We don't want the dispatch target to know. 2171 if (dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS) { 2172 for (size_t i = 0; i < motionEntry->pointerCount; i++) { 2173 scaledCoords[i].clear(); 2174 } 2175 usingCoords = scaledCoords; 2176 } 2177 } 2178 2179 // Publish the motion event and the first motion sample. 2180 status = connection->inputPublisher.publishMotionEvent( 2181 motionEntry->deviceId, motionEntry->source, 2182 dispatchEntry->resolvedAction, dispatchEntry->resolvedFlags, 2183 motionEntry->edgeFlags, motionEntry->metaState, motionEntry->buttonState, 2184 xOffset, yOffset, 2185 motionEntry->xPrecision, motionEntry->yPrecision, 2186 motionEntry->downTime, firstMotionSample->eventTime, 2187 motionEntry->pointerCount, motionEntry->pointerProperties, 2188 usingCoords); 2189 2190 if (status) { 2191 LOGE("channel '%s' ~ Could not publish motion event, " 2192 "status=%d", connection->getInputChannelName(), status); 2193 abortBrokenDispatchCycleLocked(currentTime, connection); 2194 return; 2195 } 2196 2197 if (dispatchEntry->resolvedAction == AMOTION_EVENT_ACTION_MOVE 2198 || dispatchEntry->resolvedAction == AMOTION_EVENT_ACTION_HOVER_MOVE) { 2199 // Append additional motion samples. 2200 MotionSample* nextMotionSample = firstMotionSample->next; 2201 for (; nextMotionSample != NULL; nextMotionSample = nextMotionSample->next) { 2202 if (usingCoords == scaledCoords) { 2203 if (!(dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS)) { 2204 for (size_t i = 0; i < motionEntry->pointerCount; i++) { 2205 scaledCoords[i] = nextMotionSample->pointerCoords[i]; 2206 scaledCoords[i].scale(scaleFactor); 2207 } 2208 } 2209 } else { 2210 usingCoords = nextMotionSample->pointerCoords; 2211 } 2212 status = connection->inputPublisher.appendMotionSample( 2213 nextMotionSample->eventTime, usingCoords); 2214 if (status == NO_MEMORY) { 2215#if DEBUG_DISPATCH_CYCLE 2216 LOGD("channel '%s' ~ Shared memory buffer full. Some motion samples will " 2217 "be sent in the next dispatch cycle.", 2218 connection->getInputChannelName()); 2219#endif 2220 break; 2221 } 2222 if (status != OK) { 2223 LOGE("channel '%s' ~ Could not append motion sample " 2224 "for a reason other than out of memory, status=%d", 2225 connection->getInputChannelName(), status); 2226 abortBrokenDispatchCycleLocked(currentTime, connection); 2227 return; 2228 } 2229 } 2230 2231 // Remember the next motion sample that we could not dispatch, in case we ran out 2232 // of space in the shared memory buffer. 2233 dispatchEntry->tailMotionSample = nextMotionSample; 2234 } 2235 break; 2236 } 2237 2238 default: { 2239 LOG_ASSERT(false); 2240 } 2241 } 2242 2243 // Send the dispatch signal. 2244 status = connection->inputPublisher.sendDispatchSignal(); 2245 if (status) { 2246 LOGE("channel '%s' ~ Could not send dispatch signal, status=%d", 2247 connection->getInputChannelName(), status); 2248 abortBrokenDispatchCycleLocked(currentTime, connection); 2249 return; 2250 } 2251 2252 // Record information about the newly started dispatch cycle. 2253 connection->lastEventTime = eventEntry->eventTime; 2254 connection->lastDispatchTime = currentTime; 2255 2256 // Notify other system components. 2257 onDispatchCycleStartedLocked(currentTime, connection); 2258} 2259 2260void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime, 2261 const sp<Connection>& connection, bool handled) { 2262#if DEBUG_DISPATCH_CYCLE 2263 LOGD("channel '%s' ~ finishDispatchCycle - %01.1fms since event, " 2264 "%01.1fms since dispatch, handled=%s", 2265 connection->getInputChannelName(), 2266 connection->getEventLatencyMillis(currentTime), 2267 connection->getDispatchLatencyMillis(currentTime), 2268 toString(handled)); 2269#endif 2270 2271 if (connection->status == Connection::STATUS_BROKEN 2272 || connection->status == Connection::STATUS_ZOMBIE) { 2273 return; 2274 } 2275 2276 // Reset the publisher since the event has been consumed. 2277 // We do this now so that the publisher can release some of its internal resources 2278 // while waiting for the next dispatch cycle to begin. 2279 status_t status = connection->inputPublisher.reset(); 2280 if (status) { 2281 LOGE("channel '%s' ~ Could not reset publisher, status=%d", 2282 connection->getInputChannelName(), status); 2283 abortBrokenDispatchCycleLocked(currentTime, connection); 2284 return; 2285 } 2286 2287 // Notify other system components and prepare to start the next dispatch cycle. 2288 onDispatchCycleFinishedLocked(currentTime, connection, handled); 2289} 2290 2291void InputDispatcher::startNextDispatchCycleLocked(nsecs_t currentTime, 2292 const sp<Connection>& connection) { 2293 // Start the next dispatch cycle for this connection. 2294 while (! connection->outboundQueue.isEmpty()) { 2295 DispatchEntry* dispatchEntry = connection->outboundQueue.head; 2296 if (dispatchEntry->inProgress) { 2297 // Finish or resume current event in progress. 2298 if (dispatchEntry->tailMotionSample) { 2299 // We have a tail of undispatched motion samples. 2300 // Reuse the same DispatchEntry and start a new cycle. 2301 dispatchEntry->inProgress = false; 2302 dispatchEntry->headMotionSample = dispatchEntry->tailMotionSample; 2303 dispatchEntry->tailMotionSample = NULL; 2304 startDispatchCycleLocked(currentTime, connection); 2305 return; 2306 } 2307 // Finished. 2308 connection->outboundQueue.dequeueAtHead(); 2309 if (dispatchEntry->hasForegroundTarget()) { 2310 decrementPendingForegroundDispatchesLocked(dispatchEntry->eventEntry); 2311 } 2312 delete dispatchEntry; 2313 } else { 2314 // If the head is not in progress, then we must have already dequeued the in 2315 // progress event, which means we actually aborted it. 2316 // So just start the next event for this connection. 2317 startDispatchCycleLocked(currentTime, connection); 2318 return; 2319 } 2320 } 2321 2322 // Outbound queue is empty, deactivate the connection. 2323 deactivateConnectionLocked(connection.get()); 2324} 2325 2326void InputDispatcher::abortBrokenDispatchCycleLocked(nsecs_t currentTime, 2327 const sp<Connection>& connection) { 2328#if DEBUG_DISPATCH_CYCLE 2329 LOGD("channel '%s' ~ abortBrokenDispatchCycle", 2330 connection->getInputChannelName()); 2331#endif 2332 2333 // Clear the outbound queue. 2334 drainOutboundQueueLocked(connection.get()); 2335 2336 // The connection appears to be unrecoverably broken. 2337 // Ignore already broken or zombie connections. 2338 if (connection->status == Connection::STATUS_NORMAL) { 2339 connection->status = Connection::STATUS_BROKEN; 2340 2341 // Notify other system components. 2342 onDispatchCycleBrokenLocked(currentTime, connection); 2343 } 2344} 2345 2346void InputDispatcher::drainOutboundQueueLocked(Connection* connection) { 2347 while (! connection->outboundQueue.isEmpty()) { 2348 DispatchEntry* dispatchEntry = connection->outboundQueue.dequeueAtHead(); 2349 if (dispatchEntry->hasForegroundTarget()) { 2350 decrementPendingForegroundDispatchesLocked(dispatchEntry->eventEntry); 2351 } 2352 delete dispatchEntry; 2353 } 2354 2355 deactivateConnectionLocked(connection); 2356} 2357 2358int InputDispatcher::handleReceiveCallback(int receiveFd, int events, void* data) { 2359 InputDispatcher* d = static_cast<InputDispatcher*>(data); 2360 2361 { // acquire lock 2362 AutoMutex _l(d->mLock); 2363 2364 ssize_t connectionIndex = d->mConnectionsByReceiveFd.indexOfKey(receiveFd); 2365 if (connectionIndex < 0) { 2366 LOGE("Received spurious receive callback for unknown input channel. " 2367 "fd=%d, events=0x%x", receiveFd, events); 2368 return 0; // remove the callback 2369 } 2370 2371 nsecs_t currentTime = now(); 2372 2373 sp<Connection> connection = d->mConnectionsByReceiveFd.valueAt(connectionIndex); 2374 if (events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP)) { 2375 LOGE("channel '%s' ~ Consumer closed input channel or an error occurred. " 2376 "events=0x%x", connection->getInputChannelName(), events); 2377 d->abortBrokenDispatchCycleLocked(currentTime, connection); 2378 d->runCommandsLockedInterruptible(); 2379 return 0; // remove the callback 2380 } 2381 2382 if (! (events & ALOOPER_EVENT_INPUT)) { 2383 LOGW("channel '%s' ~ Received spurious callback for unhandled poll event. " 2384 "events=0x%x", connection->getInputChannelName(), events); 2385 return 1; 2386 } 2387 2388 bool handled = false; 2389 status_t status = connection->inputPublisher.receiveFinishedSignal(&handled); 2390 if (status) { 2391 LOGE("channel '%s' ~ Failed to receive finished signal. status=%d", 2392 connection->getInputChannelName(), status); 2393 d->abortBrokenDispatchCycleLocked(currentTime, connection); 2394 d->runCommandsLockedInterruptible(); 2395 return 0; // remove the callback 2396 } 2397 2398 d->finishDispatchCycleLocked(currentTime, connection, handled); 2399 d->runCommandsLockedInterruptible(); 2400 return 1; 2401 } // release lock 2402} 2403 2404void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked( 2405 const CancelationOptions& options) { 2406 for (size_t i = 0; i < mConnectionsByReceiveFd.size(); i++) { 2407 synthesizeCancelationEventsForConnectionLocked( 2408 mConnectionsByReceiveFd.valueAt(i), options); 2409 } 2410} 2411 2412void InputDispatcher::synthesizeCancelationEventsForInputChannelLocked( 2413 const sp<InputChannel>& channel, const CancelationOptions& options) { 2414 ssize_t index = getConnectionIndexLocked(channel); 2415 if (index >= 0) { 2416 synthesizeCancelationEventsForConnectionLocked( 2417 mConnectionsByReceiveFd.valueAt(index), options); 2418 } 2419} 2420 2421void InputDispatcher::synthesizeCancelationEventsForConnectionLocked( 2422 const sp<Connection>& connection, const CancelationOptions& options) { 2423 nsecs_t currentTime = now(); 2424 2425 mTempCancelationEvents.clear(); 2426 connection->inputState.synthesizeCancelationEvents(currentTime, 2427 mTempCancelationEvents, options); 2428 2429 if (! mTempCancelationEvents.isEmpty() 2430 && connection->status != Connection::STATUS_BROKEN) { 2431#if DEBUG_OUTBOUND_EVENT_DETAILS 2432 LOGD("channel '%s' ~ Synthesized %d cancelation events to bring channel back in sync " 2433 "with reality: %s, mode=%d.", 2434 connection->getInputChannelName(), mTempCancelationEvents.size(), 2435 options.reason, options.mode); 2436#endif 2437 for (size_t i = 0; i < mTempCancelationEvents.size(); i++) { 2438 EventEntry* cancelationEventEntry = mTempCancelationEvents.itemAt(i); 2439 switch (cancelationEventEntry->type) { 2440 case EventEntry::TYPE_KEY: 2441 logOutboundKeyDetailsLocked("cancel - ", 2442 static_cast<KeyEntry*>(cancelationEventEntry)); 2443 break; 2444 case EventEntry::TYPE_MOTION: 2445 logOutboundMotionDetailsLocked("cancel - ", 2446 static_cast<MotionEntry*>(cancelationEventEntry)); 2447 break; 2448 } 2449 2450 InputTarget target; 2451 sp<InputWindowHandle> windowHandle = getWindowHandleLocked(connection->inputChannel); 2452 if (windowHandle != NULL) { 2453 target.xOffset = -windowHandle->frameLeft; 2454 target.yOffset = -windowHandle->frameTop; 2455 target.scaleFactor = windowHandle->scaleFactor; 2456 } else { 2457 target.xOffset = 0; 2458 target.yOffset = 0; 2459 target.scaleFactor = 1.0f; 2460 } 2461 target.inputChannel = connection->inputChannel; 2462 target.flags = InputTarget::FLAG_DISPATCH_AS_IS; 2463 2464 enqueueDispatchEntryLocked(connection, cancelationEventEntry, // increments ref 2465 &target, false, InputTarget::FLAG_DISPATCH_AS_IS); 2466 2467 cancelationEventEntry->release(); 2468 } 2469 2470 if (!connection->outboundQueue.head->inProgress) { 2471 startDispatchCycleLocked(currentTime, connection); 2472 } 2473 } 2474} 2475 2476InputDispatcher::MotionEntry* 2477InputDispatcher::splitMotionEvent(const MotionEntry* originalMotionEntry, BitSet32 pointerIds) { 2478 LOG_ASSERT(pointerIds.value != 0); 2479 2480 uint32_t splitPointerIndexMap[MAX_POINTERS]; 2481 PointerProperties splitPointerProperties[MAX_POINTERS]; 2482 PointerCoords splitPointerCoords[MAX_POINTERS]; 2483 2484 uint32_t originalPointerCount = originalMotionEntry->pointerCount; 2485 uint32_t splitPointerCount = 0; 2486 2487 for (uint32_t originalPointerIndex = 0; originalPointerIndex < originalPointerCount; 2488 originalPointerIndex++) { 2489 const PointerProperties& pointerProperties = 2490 originalMotionEntry->pointerProperties[originalPointerIndex]; 2491 uint32_t pointerId = uint32_t(pointerProperties.id); 2492 if (pointerIds.hasBit(pointerId)) { 2493 splitPointerIndexMap[splitPointerCount] = originalPointerIndex; 2494 splitPointerProperties[splitPointerCount].copyFrom(pointerProperties); 2495 splitPointerCoords[splitPointerCount].copyFrom( 2496 originalMotionEntry->firstSample.pointerCoords[originalPointerIndex]); 2497 splitPointerCount += 1; 2498 } 2499 } 2500 2501 if (splitPointerCount != pointerIds.count()) { 2502 // This is bad. We are missing some of the pointers that we expected to deliver. 2503 // Most likely this indicates that we received an ACTION_MOVE events that has 2504 // different pointer ids than we expected based on the previous ACTION_DOWN 2505 // or ACTION_POINTER_DOWN events that caused us to decide to split the pointers 2506 // in this way. 2507 LOGW("Dropping split motion event because the pointer count is %d but " 2508 "we expected there to be %d pointers. This probably means we received " 2509 "a broken sequence of pointer ids from the input device.", 2510 splitPointerCount, pointerIds.count()); 2511 return NULL; 2512 } 2513 2514 int32_t action = originalMotionEntry->action; 2515 int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK; 2516 if (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN 2517 || maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) { 2518 int32_t originalPointerIndex = getMotionEventActionPointerIndex(action); 2519 const PointerProperties& pointerProperties = 2520 originalMotionEntry->pointerProperties[originalPointerIndex]; 2521 uint32_t pointerId = uint32_t(pointerProperties.id); 2522 if (pointerIds.hasBit(pointerId)) { 2523 if (pointerIds.count() == 1) { 2524 // The first/last pointer went down/up. 2525 action = maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN 2526 ? AMOTION_EVENT_ACTION_DOWN : AMOTION_EVENT_ACTION_UP; 2527 } else { 2528 // A secondary pointer went down/up. 2529 uint32_t splitPointerIndex = 0; 2530 while (pointerId != uint32_t(splitPointerProperties[splitPointerIndex].id)) { 2531 splitPointerIndex += 1; 2532 } 2533 action = maskedAction | (splitPointerIndex 2534 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT); 2535 } 2536 } else { 2537 // An unrelated pointer changed. 2538 action = AMOTION_EVENT_ACTION_MOVE; 2539 } 2540 } 2541 2542 MotionEntry* splitMotionEntry = new MotionEntry( 2543 originalMotionEntry->eventTime, 2544 originalMotionEntry->deviceId, 2545 originalMotionEntry->source, 2546 originalMotionEntry->policyFlags, 2547 action, 2548 originalMotionEntry->flags, 2549 originalMotionEntry->metaState, 2550 originalMotionEntry->buttonState, 2551 originalMotionEntry->edgeFlags, 2552 originalMotionEntry->xPrecision, 2553 originalMotionEntry->yPrecision, 2554 originalMotionEntry->downTime, 2555 splitPointerCount, splitPointerProperties, splitPointerCoords); 2556 2557 for (MotionSample* originalMotionSample = originalMotionEntry->firstSample.next; 2558 originalMotionSample != NULL; originalMotionSample = originalMotionSample->next) { 2559 for (uint32_t splitPointerIndex = 0; splitPointerIndex < splitPointerCount; 2560 splitPointerIndex++) { 2561 uint32_t originalPointerIndex = splitPointerIndexMap[splitPointerIndex]; 2562 splitPointerCoords[splitPointerIndex].copyFrom( 2563 originalMotionSample->pointerCoords[originalPointerIndex]); 2564 } 2565 2566 splitMotionEntry->appendSample(originalMotionSample->eventTime, splitPointerCoords); 2567 } 2568 2569 if (originalMotionEntry->injectionState) { 2570 splitMotionEntry->injectionState = originalMotionEntry->injectionState; 2571 splitMotionEntry->injectionState->refCount += 1; 2572 } 2573 2574 return splitMotionEntry; 2575} 2576 2577void InputDispatcher::notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args) { 2578#if DEBUG_INBOUND_EVENT_DETAILS 2579 LOGD("notifyConfigurationChanged - eventTime=%lld", args->eventTime); 2580#endif 2581 2582 bool needWake; 2583 { // acquire lock 2584 AutoMutex _l(mLock); 2585 2586 ConfigurationChangedEntry* newEntry = new ConfigurationChangedEntry(args->eventTime); 2587 needWake = enqueueInboundEventLocked(newEntry); 2588 } // release lock 2589 2590 if (needWake) { 2591 mLooper->wake(); 2592 } 2593} 2594 2595void InputDispatcher::notifyKey(const NotifyKeyArgs* args) { 2596#if DEBUG_INBOUND_EVENT_DETAILS 2597 LOGD("notifyKey - eventTime=%lld, deviceId=%d, source=0x%x, policyFlags=0x%x, action=0x%x, " 2598 "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%lld", 2599 args->eventTime, args->deviceId, args->source, args->policyFlags, 2600 args->action, args->flags, args->keyCode, args->scanCode, 2601 args->metaState, args->downTime); 2602#endif 2603 if (!validateKeyEvent(args->action)) { 2604 return; 2605 } 2606 2607 uint32_t policyFlags = args->policyFlags; 2608 int32_t flags = args->flags; 2609 int32_t metaState = args->metaState; 2610 if ((policyFlags & POLICY_FLAG_VIRTUAL) || (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY)) { 2611 policyFlags |= POLICY_FLAG_VIRTUAL; 2612 flags |= AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY; 2613 } 2614 if (policyFlags & POLICY_FLAG_ALT) { 2615 metaState |= AMETA_ALT_ON | AMETA_ALT_LEFT_ON; 2616 } 2617 if (policyFlags & POLICY_FLAG_ALT_GR) { 2618 metaState |= AMETA_ALT_ON | AMETA_ALT_RIGHT_ON; 2619 } 2620 if (policyFlags & POLICY_FLAG_SHIFT) { 2621 metaState |= AMETA_SHIFT_ON | AMETA_SHIFT_LEFT_ON; 2622 } 2623 if (policyFlags & POLICY_FLAG_CAPS_LOCK) { 2624 metaState |= AMETA_CAPS_LOCK_ON; 2625 } 2626 if (policyFlags & POLICY_FLAG_FUNCTION) { 2627 metaState |= AMETA_FUNCTION_ON; 2628 } 2629 2630 policyFlags |= POLICY_FLAG_TRUSTED; 2631 2632 KeyEvent event; 2633 event.initialize(args->deviceId, args->source, args->action, 2634 flags, args->keyCode, args->scanCode, metaState, 0, 2635 args->downTime, args->eventTime); 2636 2637 mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags); 2638 2639 if (policyFlags & POLICY_FLAG_WOKE_HERE) { 2640 flags |= AKEY_EVENT_FLAG_WOKE_HERE; 2641 } 2642 2643 bool needWake; 2644 { // acquire lock 2645 mLock.lock(); 2646 2647 if (mInputFilterEnabled) { 2648 mLock.unlock(); 2649 2650 policyFlags |= POLICY_FLAG_FILTERED; 2651 if (!mPolicy->filterInputEvent(&event, policyFlags)) { 2652 return; // event was consumed by the filter 2653 } 2654 2655 mLock.lock(); 2656 } 2657 2658 int32_t repeatCount = 0; 2659 KeyEntry* newEntry = new KeyEntry(args->eventTime, 2660 args->deviceId, args->source, policyFlags, 2661 args->action, flags, args->keyCode, args->scanCode, 2662 metaState, repeatCount, args->downTime); 2663 2664 needWake = enqueueInboundEventLocked(newEntry); 2665 mLock.unlock(); 2666 } // release lock 2667 2668 if (needWake) { 2669 mLooper->wake(); 2670 } 2671} 2672 2673void InputDispatcher::notifyMotion(const NotifyMotionArgs* args) { 2674#if DEBUG_INBOUND_EVENT_DETAILS 2675 LOGD("notifyMotion - eventTime=%lld, deviceId=%d, source=0x%x, policyFlags=0x%x, " 2676 "action=0x%x, flags=0x%x, metaState=0x%x, buttonState=0x%x, edgeFlags=0x%x, " 2677 "xPrecision=%f, yPrecision=%f, downTime=%lld", 2678 args->eventTime, args->deviceId, args->source, args->policyFlags, 2679 args->action, args->flags, args->metaState, args->buttonState, 2680 args->edgeFlags, args->xPrecision, args->yPrecision, args->downTime); 2681 for (uint32_t i = 0; i < args->pointerCount; i++) { 2682 LOGD(" Pointer %d: id=%d, toolType=%d, " 2683 "x=%f, y=%f, pressure=%f, size=%f, " 2684 "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, " 2685 "orientation=%f", 2686 i, args->pointerProperties[i].id, 2687 args->pointerProperties[i].toolType, 2688 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X), 2689 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y), 2690 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE), 2691 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE), 2692 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR), 2693 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR), 2694 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR), 2695 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR), 2696 args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION)); 2697 } 2698#endif 2699 if (!validateMotionEvent(args->action, args->pointerCount, args->pointerProperties)) { 2700 return; 2701 } 2702 2703 uint32_t policyFlags = args->policyFlags; 2704 policyFlags |= POLICY_FLAG_TRUSTED; 2705 mPolicy->interceptMotionBeforeQueueing(args->eventTime, /*byref*/ policyFlags); 2706 2707 bool needWake; 2708 { // acquire lock 2709 mLock.lock(); 2710 2711 if (mInputFilterEnabled) { 2712 mLock.unlock(); 2713 2714 MotionEvent event; 2715 event.initialize(args->deviceId, args->source, args->action, args->flags, 2716 args->edgeFlags, args->metaState, args->buttonState, 0, 0, 2717 args->xPrecision, args->yPrecision, 2718 args->downTime, args->eventTime, 2719 args->pointerCount, args->pointerProperties, args->pointerCoords); 2720 2721 policyFlags |= POLICY_FLAG_FILTERED; 2722 if (!mPolicy->filterInputEvent(&event, policyFlags)) { 2723 return; // event was consumed by the filter 2724 } 2725 2726 mLock.lock(); 2727 } 2728 2729 // Attempt batching and streaming of move events. 2730 if (args->action == AMOTION_EVENT_ACTION_MOVE 2731 || args->action == AMOTION_EVENT_ACTION_HOVER_MOVE) { 2732 // BATCHING CASE 2733 // 2734 // Try to append a move sample to the tail of the inbound queue for this device. 2735 // Give up if we encounter a non-move motion event for this device since that 2736 // means we cannot append any new samples until a new motion event has started. 2737 for (EventEntry* entry = mInboundQueue.tail; entry; entry = entry->prev) { 2738 if (entry->type != EventEntry::TYPE_MOTION) { 2739 // Keep looking for motion events. 2740 continue; 2741 } 2742 2743 MotionEntry* motionEntry = static_cast<MotionEntry*>(entry); 2744 if (motionEntry->deviceId != args->deviceId 2745 || motionEntry->source != args->source) { 2746 // Keep looking for this device and source. 2747 continue; 2748 } 2749 2750 if (!motionEntry->canAppendSamples(args->action, 2751 args->pointerCount, args->pointerProperties)) { 2752 // Last motion event in the queue for this device and source is 2753 // not compatible for appending new samples. Stop here. 2754 goto NoBatchingOrStreaming; 2755 } 2756 2757 // Do the batching magic. 2758 batchMotionLocked(motionEntry, args->eventTime, 2759 args->metaState, args->pointerCoords, 2760 "most recent motion event for this device and source in the inbound queue"); 2761 mLock.unlock(); 2762 return; // done! 2763 } 2764 2765 // BATCHING ONTO PENDING EVENT CASE 2766 // 2767 // Try to append a move sample to the currently pending event, if there is one. 2768 // We can do this as long as we are still waiting to find the targets for the 2769 // event. Once the targets are locked-in we can only do streaming. 2770 if (mPendingEvent 2771 && (!mPendingEvent->dispatchInProgress || !mCurrentInputTargetsValid) 2772 && mPendingEvent->type == EventEntry::TYPE_MOTION) { 2773 MotionEntry* motionEntry = static_cast<MotionEntry*>(mPendingEvent); 2774 if (motionEntry->deviceId == args->deviceId 2775 && motionEntry->source == args->source) { 2776 if (!motionEntry->canAppendSamples(args->action, 2777 args->pointerCount, args->pointerProperties)) { 2778 // Pending motion event is for this device and source but it is 2779 // not compatible for appending new samples. Stop here. 2780 goto NoBatchingOrStreaming; 2781 } 2782 2783 // Do the batching magic. 2784 batchMotionLocked(motionEntry, args->eventTime, 2785 args->metaState, args->pointerCoords, 2786 "pending motion event"); 2787 mLock.unlock(); 2788 return; // done! 2789 } 2790 } 2791 2792 // STREAMING CASE 2793 // 2794 // There is no pending motion event (of any kind) for this device in the inbound queue. 2795 // Search the outbound queue for the current foreground targets to find a dispatched 2796 // motion event that is still in progress. If found, then, appen the new sample to 2797 // that event and push it out to all current targets. The logic in 2798 // prepareDispatchCycleLocked takes care of the case where some targets may 2799 // already have consumed the motion event by starting a new dispatch cycle if needed. 2800 if (mCurrentInputTargetsValid) { 2801 for (size_t i = 0; i < mCurrentInputTargets.size(); i++) { 2802 const InputTarget& inputTarget = mCurrentInputTargets[i]; 2803 if ((inputTarget.flags & InputTarget::FLAG_FOREGROUND) == 0) { 2804 // Skip non-foreground targets. We only want to stream if there is at 2805 // least one foreground target whose dispatch is still in progress. 2806 continue; 2807 } 2808 2809 ssize_t connectionIndex = getConnectionIndexLocked(inputTarget.inputChannel); 2810 if (connectionIndex < 0) { 2811 // Connection must no longer be valid. 2812 continue; 2813 } 2814 2815 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex); 2816 if (connection->outboundQueue.isEmpty()) { 2817 // This foreground target has an empty outbound queue. 2818 continue; 2819 } 2820 2821 DispatchEntry* dispatchEntry = connection->outboundQueue.head; 2822 if (! dispatchEntry->inProgress 2823 || dispatchEntry->eventEntry->type != EventEntry::TYPE_MOTION 2824 || dispatchEntry->isSplit()) { 2825 // No motion event is being dispatched, or it is being split across 2826 // windows in which case we cannot stream. 2827 continue; 2828 } 2829 2830 MotionEntry* motionEntry = static_cast<MotionEntry*>( 2831 dispatchEntry->eventEntry); 2832 if (motionEntry->action != args->action 2833 || motionEntry->deviceId != args->deviceId 2834 || motionEntry->source != args->source 2835 || motionEntry->pointerCount != args->pointerCount 2836 || motionEntry->isInjected()) { 2837 // The motion event is not compatible with this move. 2838 continue; 2839 } 2840 2841 if (args->action == AMOTION_EVENT_ACTION_HOVER_MOVE) { 2842 if (mLastHoverWindowHandle == NULL) { 2843#if DEBUG_BATCHING 2844 LOGD("Not streaming hover move because there is no " 2845 "last hovered window."); 2846#endif 2847 goto NoBatchingOrStreaming; 2848 } 2849 2850 sp<InputWindowHandle> hoverWindowHandle = findTouchedWindowAtLocked( 2851 args->pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 2852 args->pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y)); 2853 if (mLastHoverWindowHandle != hoverWindowHandle) { 2854#if DEBUG_BATCHING 2855 LOGD("Not streaming hover move because the last hovered window " 2856 "is '%s' but the currently hovered window is '%s'.", 2857 mLastHoverWindowHandle->name.string(), 2858 hoverWindowHandle != NULL 2859 ? hoverWindowHandle->name.string() : "<null>"); 2860#endif 2861 goto NoBatchingOrStreaming; 2862 } 2863 } 2864 2865 // Hurray! This foreground target is currently dispatching a move event 2866 // that we can stream onto. Append the motion sample and resume dispatch. 2867 motionEntry->appendSample(args->eventTime, args->pointerCoords); 2868#if DEBUG_BATCHING 2869 LOGD("Appended motion sample onto batch for most recently dispatched " 2870 "motion event for this device and source in the outbound queues. " 2871 "Attempting to stream the motion sample."); 2872#endif 2873 nsecs_t currentTime = now(); 2874 dispatchEventToCurrentInputTargetsLocked(currentTime, motionEntry, 2875 true /*resumeWithAppendedMotionSample*/); 2876 2877 runCommandsLockedInterruptible(); 2878 mLock.unlock(); 2879 return; // done! 2880 } 2881 } 2882 2883NoBatchingOrStreaming:; 2884 } 2885 2886 // Just enqueue a new motion event. 2887 MotionEntry* newEntry = new MotionEntry(args->eventTime, 2888 args->deviceId, args->source, policyFlags, 2889 args->action, args->flags, args->metaState, args->buttonState, 2890 args->edgeFlags, args->xPrecision, args->yPrecision, args->downTime, 2891 args->pointerCount, args->pointerProperties, args->pointerCoords); 2892 2893 needWake = enqueueInboundEventLocked(newEntry); 2894 mLock.unlock(); 2895 } // release lock 2896 2897 if (needWake) { 2898 mLooper->wake(); 2899 } 2900} 2901 2902void InputDispatcher::batchMotionLocked(MotionEntry* entry, nsecs_t eventTime, 2903 int32_t metaState, const PointerCoords* pointerCoords, const char* eventDescription) { 2904 // Combine meta states. 2905 entry->metaState |= metaState; 2906 2907 // Coalesce this sample if not enough time has elapsed since the last sample was 2908 // initially appended to the batch. 2909 MotionSample* lastSample = entry->lastSample; 2910 long interval = eventTime - lastSample->eventTimeBeforeCoalescing; 2911 if (interval <= MOTION_SAMPLE_COALESCE_INTERVAL) { 2912 uint32_t pointerCount = entry->pointerCount; 2913 for (uint32_t i = 0; i < pointerCount; i++) { 2914 lastSample->pointerCoords[i].copyFrom(pointerCoords[i]); 2915 } 2916 lastSample->eventTime = eventTime; 2917#if DEBUG_BATCHING 2918 LOGD("Coalesced motion into last sample of batch for %s, events were %0.3f ms apart", 2919 eventDescription, interval * 0.000001f); 2920#endif 2921 return; 2922 } 2923 2924 // Append the sample. 2925 entry->appendSample(eventTime, pointerCoords); 2926#if DEBUG_BATCHING 2927 LOGD("Appended motion sample onto batch for %s, events were %0.3f ms apart", 2928 eventDescription, interval * 0.000001f); 2929#endif 2930} 2931 2932void InputDispatcher::notifySwitch(const NotifySwitchArgs* args) { 2933#if DEBUG_INBOUND_EVENT_DETAILS 2934 LOGD("notifySwitch - eventTime=%lld, policyFlags=0x%x, switchCode=%d, switchValue=%d", 2935 args->eventTime, args->policyFlags, 2936 args->switchCode, args->switchValue); 2937#endif 2938 2939 uint32_t policyFlags = args->policyFlags; 2940 policyFlags |= POLICY_FLAG_TRUSTED; 2941 mPolicy->notifySwitch(args->eventTime, 2942 args->switchCode, args->switchValue, policyFlags); 2943} 2944 2945void InputDispatcher::notifyDeviceReset(const NotifyDeviceResetArgs* args) { 2946#if DEBUG_INBOUND_EVENT_DETAILS 2947 LOGD("notifyDeviceReset - eventTime=%lld, deviceId=%d", 2948 args->eventTime, args->deviceId); 2949#endif 2950 2951 bool needWake; 2952 { // acquire lock 2953 AutoMutex _l(mLock); 2954 2955 DeviceResetEntry* newEntry = new DeviceResetEntry(args->eventTime, args->deviceId); 2956 needWake = enqueueInboundEventLocked(newEntry); 2957 } // release lock 2958 2959 if (needWake) { 2960 mLooper->wake(); 2961 } 2962} 2963 2964int32_t InputDispatcher::injectInputEvent(const InputEvent* event, 2965 int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis, 2966 uint32_t policyFlags) { 2967#if DEBUG_INBOUND_EVENT_DETAILS 2968 LOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, " 2969 "syncMode=%d, timeoutMillis=%d, policyFlags=0x%08x", 2970 event->getType(), injectorPid, injectorUid, syncMode, timeoutMillis, policyFlags); 2971#endif 2972 2973 nsecs_t endTime = now() + milliseconds_to_nanoseconds(timeoutMillis); 2974 2975 policyFlags |= POLICY_FLAG_INJECTED; 2976 if (hasInjectionPermission(injectorPid, injectorUid)) { 2977 policyFlags |= POLICY_FLAG_TRUSTED; 2978 } 2979 2980 EventEntry* injectedEntry; 2981 switch (event->getType()) { 2982 case AINPUT_EVENT_TYPE_KEY: { 2983 const KeyEvent* keyEvent = static_cast<const KeyEvent*>(event); 2984 int32_t action = keyEvent->getAction(); 2985 if (! validateKeyEvent(action)) { 2986 return INPUT_EVENT_INJECTION_FAILED; 2987 } 2988 2989 int32_t flags = keyEvent->getFlags(); 2990 if (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY) { 2991 policyFlags |= POLICY_FLAG_VIRTUAL; 2992 } 2993 2994 if (!(policyFlags & POLICY_FLAG_FILTERED)) { 2995 mPolicy->interceptKeyBeforeQueueing(keyEvent, /*byref*/ policyFlags); 2996 } 2997 2998 if (policyFlags & POLICY_FLAG_WOKE_HERE) { 2999 flags |= AKEY_EVENT_FLAG_WOKE_HERE; 3000 } 3001 3002 mLock.lock(); 3003 injectedEntry = new KeyEntry(keyEvent->getEventTime(), 3004 keyEvent->getDeviceId(), keyEvent->getSource(), 3005 policyFlags, action, flags, 3006 keyEvent->getKeyCode(), keyEvent->getScanCode(), keyEvent->getMetaState(), 3007 keyEvent->getRepeatCount(), keyEvent->getDownTime()); 3008 break; 3009 } 3010 3011 case AINPUT_EVENT_TYPE_MOTION: { 3012 const MotionEvent* motionEvent = static_cast<const MotionEvent*>(event); 3013 int32_t action = motionEvent->getAction(); 3014 size_t pointerCount = motionEvent->getPointerCount(); 3015 const PointerProperties* pointerProperties = motionEvent->getPointerProperties(); 3016 if (! validateMotionEvent(action, pointerCount, pointerProperties)) { 3017 return INPUT_EVENT_INJECTION_FAILED; 3018 } 3019 3020 if (!(policyFlags & POLICY_FLAG_FILTERED)) { 3021 nsecs_t eventTime = motionEvent->getEventTime(); 3022 mPolicy->interceptMotionBeforeQueueing(eventTime, /*byref*/ policyFlags); 3023 } 3024 3025 mLock.lock(); 3026 const nsecs_t* sampleEventTimes = motionEvent->getSampleEventTimes(); 3027 const PointerCoords* samplePointerCoords = motionEvent->getSamplePointerCoords(); 3028 MotionEntry* motionEntry = new MotionEntry(*sampleEventTimes, 3029 motionEvent->getDeviceId(), motionEvent->getSource(), policyFlags, 3030 action, motionEvent->getFlags(), 3031 motionEvent->getMetaState(), motionEvent->getButtonState(), 3032 motionEvent->getEdgeFlags(), 3033 motionEvent->getXPrecision(), motionEvent->getYPrecision(), 3034 motionEvent->getDownTime(), uint32_t(pointerCount), 3035 pointerProperties, samplePointerCoords); 3036 for (size_t i = motionEvent->getHistorySize(); i > 0; i--) { 3037 sampleEventTimes += 1; 3038 samplePointerCoords += pointerCount; 3039 motionEntry->appendSample(*sampleEventTimes, samplePointerCoords); 3040 } 3041 injectedEntry = motionEntry; 3042 break; 3043 } 3044 3045 default: 3046 LOGW("Cannot inject event of type %d", event->getType()); 3047 return INPUT_EVENT_INJECTION_FAILED; 3048 } 3049 3050 InjectionState* injectionState = new InjectionState(injectorPid, injectorUid); 3051 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) { 3052 injectionState->injectionIsAsync = true; 3053 } 3054 3055 injectionState->refCount += 1; 3056 injectedEntry->injectionState = injectionState; 3057 3058 bool needWake = enqueueInboundEventLocked(injectedEntry); 3059 mLock.unlock(); 3060 3061 if (needWake) { 3062 mLooper->wake(); 3063 } 3064 3065 int32_t injectionResult; 3066 { // acquire lock 3067 AutoMutex _l(mLock); 3068 3069 if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) { 3070 injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED; 3071 } else { 3072 for (;;) { 3073 injectionResult = injectionState->injectionResult; 3074 if (injectionResult != INPUT_EVENT_INJECTION_PENDING) { 3075 break; 3076 } 3077 3078 nsecs_t remainingTimeout = endTime - now(); 3079 if (remainingTimeout <= 0) { 3080#if DEBUG_INJECTION 3081 LOGD("injectInputEvent - Timed out waiting for injection result " 3082 "to become available."); 3083#endif 3084 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT; 3085 break; 3086 } 3087 3088 mInjectionResultAvailableCondition.waitRelative(mLock, remainingTimeout); 3089 } 3090 3091 if (injectionResult == INPUT_EVENT_INJECTION_SUCCEEDED 3092 && syncMode == INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISHED) { 3093 while (injectionState->pendingForegroundDispatches != 0) { 3094#if DEBUG_INJECTION 3095 LOGD("injectInputEvent - Waiting for %d pending foreground dispatches.", 3096 injectionState->pendingForegroundDispatches); 3097#endif 3098 nsecs_t remainingTimeout = endTime - now(); 3099 if (remainingTimeout <= 0) { 3100#if DEBUG_INJECTION 3101 LOGD("injectInputEvent - Timed out waiting for pending foreground " 3102 "dispatches to finish."); 3103#endif 3104 injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT; 3105 break; 3106 } 3107 3108 mInjectionSyncFinishedCondition.waitRelative(mLock, remainingTimeout); 3109 } 3110 } 3111 } 3112 3113 injectionState->release(); 3114 } // release lock 3115 3116#if DEBUG_INJECTION 3117 LOGD("injectInputEvent - Finished with result %d. " 3118 "injectorPid=%d, injectorUid=%d", 3119 injectionResult, injectorPid, injectorUid); 3120#endif 3121 3122 return injectionResult; 3123} 3124 3125bool InputDispatcher::hasInjectionPermission(int32_t injectorPid, int32_t injectorUid) { 3126 return injectorUid == 0 3127 || mPolicy->checkInjectEventsPermissionNonReentrant(injectorPid, injectorUid); 3128} 3129 3130void InputDispatcher::setInjectionResultLocked(EventEntry* entry, int32_t injectionResult) { 3131 InjectionState* injectionState = entry->injectionState; 3132 if (injectionState) { 3133#if DEBUG_INJECTION 3134 LOGD("Setting input event injection result to %d. " 3135 "injectorPid=%d, injectorUid=%d", 3136 injectionResult, injectionState->injectorPid, injectionState->injectorUid); 3137#endif 3138 3139 if (injectionState->injectionIsAsync 3140 && !(entry->policyFlags & POLICY_FLAG_FILTERED)) { 3141 // Log the outcome since the injector did not wait for the injection result. 3142 switch (injectionResult) { 3143 case INPUT_EVENT_INJECTION_SUCCEEDED: 3144 LOGV("Asynchronous input event injection succeeded."); 3145 break; 3146 case INPUT_EVENT_INJECTION_FAILED: 3147 LOGW("Asynchronous input event injection failed."); 3148 break; 3149 case INPUT_EVENT_INJECTION_PERMISSION_DENIED: 3150 LOGW("Asynchronous input event injection permission denied."); 3151 break; 3152 case INPUT_EVENT_INJECTION_TIMED_OUT: 3153 LOGW("Asynchronous input event injection timed out."); 3154 break; 3155 } 3156 } 3157 3158 injectionState->injectionResult = injectionResult; 3159 mInjectionResultAvailableCondition.broadcast(); 3160 } 3161} 3162 3163void InputDispatcher::incrementPendingForegroundDispatchesLocked(EventEntry* entry) { 3164 InjectionState* injectionState = entry->injectionState; 3165 if (injectionState) { 3166 injectionState->pendingForegroundDispatches += 1; 3167 } 3168} 3169 3170void InputDispatcher::decrementPendingForegroundDispatchesLocked(EventEntry* entry) { 3171 InjectionState* injectionState = entry->injectionState; 3172 if (injectionState) { 3173 injectionState->pendingForegroundDispatches -= 1; 3174 3175 if (injectionState->pendingForegroundDispatches == 0) { 3176 mInjectionSyncFinishedCondition.broadcast(); 3177 } 3178 } 3179} 3180 3181sp<InputWindowHandle> InputDispatcher::getWindowHandleLocked( 3182 const sp<InputChannel>& inputChannel) const { 3183 size_t numWindows = mWindowHandles.size(); 3184 for (size_t i = 0; i < numWindows; i++) { 3185 const sp<InputWindowHandle>& windowHandle = mWindowHandles.itemAt(i); 3186 if (windowHandle->inputChannel == inputChannel) { 3187 return windowHandle; 3188 } 3189 } 3190 return NULL; 3191} 3192 3193bool InputDispatcher::hasWindowHandleLocked( 3194 const sp<InputWindowHandle>& windowHandle) const { 3195 size_t numWindows = mWindowHandles.size(); 3196 for (size_t i = 0; i < numWindows; i++) { 3197 if (mWindowHandles.itemAt(i) == windowHandle) { 3198 return true; 3199 } 3200 } 3201 return false; 3202} 3203 3204void InputDispatcher::setInputWindows(const Vector<sp<InputWindowHandle> >& inputWindowHandles) { 3205#if DEBUG_FOCUS 3206 LOGD("setInputWindows"); 3207#endif 3208 { // acquire lock 3209 AutoMutex _l(mLock); 3210 3211 mWindowHandles = inputWindowHandles; 3212 3213 sp<InputWindowHandle> newFocusedWindowHandle; 3214 bool foundHoveredWindow = false; 3215 for (size_t i = 0; i < mWindowHandles.size(); i++) { 3216 const sp<InputWindowHandle>& windowHandle = mWindowHandles.itemAt(i); 3217 if (!windowHandle->update() || windowHandle->inputChannel == NULL) { 3218 mWindowHandles.removeAt(i--); 3219 continue; 3220 } 3221 if (windowHandle->hasFocus) { 3222 newFocusedWindowHandle = windowHandle; 3223 } 3224 if (windowHandle == mLastHoverWindowHandle) { 3225 foundHoveredWindow = true; 3226 } 3227 } 3228 3229 if (!foundHoveredWindow) { 3230 mLastHoverWindowHandle = NULL; 3231 } 3232 3233 if (mFocusedWindowHandle != newFocusedWindowHandle) { 3234 if (mFocusedWindowHandle != NULL) { 3235#if DEBUG_FOCUS 3236 LOGD("Focus left window: %s", 3237 mFocusedWindowHandle->name.string()); 3238#endif 3239 if (mFocusedWindowHandle->inputChannel != NULL) { 3240 CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, 3241 "focus left window"); 3242 synthesizeCancelationEventsForInputChannelLocked( 3243 mFocusedWindowHandle->inputChannel, options); 3244 } 3245 } 3246 if (newFocusedWindowHandle != NULL) { 3247#if DEBUG_FOCUS 3248 LOGD("Focus entered window: %s", 3249 newFocusedWindowHandle->name.string()); 3250#endif 3251 } 3252 mFocusedWindowHandle = newFocusedWindowHandle; 3253 } 3254 3255 for (size_t i = 0; i < mTouchState.windows.size(); i++) { 3256 TouchedWindow& touchedWindow = mTouchState.windows.editItemAt(i); 3257 if (!hasWindowHandleLocked(touchedWindow.windowHandle)) { 3258#if DEBUG_FOCUS 3259 LOGD("Touched window was removed: %s", touchedWindow.windowHandle->name.string()); 3260#endif 3261 if (touchedWindow.windowHandle->inputChannel != NULL) { 3262 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS, 3263 "touched window was removed"); 3264 synthesizeCancelationEventsForInputChannelLocked( 3265 touchedWindow.windowHandle->inputChannel, options); 3266 } 3267 mTouchState.windows.removeAt(i--); 3268 } 3269 } 3270 } // release lock 3271 3272 // Wake up poll loop since it may need to make new input dispatching choices. 3273 mLooper->wake(); 3274} 3275 3276void InputDispatcher::setFocusedApplication( 3277 const sp<InputApplicationHandle>& inputApplicationHandle) { 3278#if DEBUG_FOCUS 3279 LOGD("setFocusedApplication"); 3280#endif 3281 { // acquire lock 3282 AutoMutex _l(mLock); 3283 3284 if (inputApplicationHandle != NULL && inputApplicationHandle->update()) { 3285 if (mFocusedApplicationHandle != inputApplicationHandle) { 3286 if (mFocusedApplicationHandle != NULL) { 3287 resetTargetsLocked(); 3288 } 3289 mFocusedApplicationHandle = inputApplicationHandle; 3290 } 3291 } else if (mFocusedApplicationHandle != NULL) { 3292 resetTargetsLocked(); 3293 mFocusedApplicationHandle.clear(); 3294 } 3295 3296#if DEBUG_FOCUS 3297 //logDispatchStateLocked(); 3298#endif 3299 } // release lock 3300 3301 // Wake up poll loop since it may need to make new input dispatching choices. 3302 mLooper->wake(); 3303} 3304 3305void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) { 3306#if DEBUG_FOCUS 3307 LOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen); 3308#endif 3309 3310 bool changed; 3311 { // acquire lock 3312 AutoMutex _l(mLock); 3313 3314 if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) { 3315 if (mDispatchFrozen && !frozen) { 3316 resetANRTimeoutsLocked(); 3317 } 3318 3319 if (mDispatchEnabled && !enabled) { 3320 resetAndDropEverythingLocked("dispatcher is being disabled"); 3321 } 3322 3323 mDispatchEnabled = enabled; 3324 mDispatchFrozen = frozen; 3325 changed = true; 3326 } else { 3327 changed = false; 3328 } 3329 3330#if DEBUG_FOCUS 3331 //logDispatchStateLocked(); 3332#endif 3333 } // release lock 3334 3335 if (changed) { 3336 // Wake up poll loop since it may need to make new input dispatching choices. 3337 mLooper->wake(); 3338 } 3339} 3340 3341void InputDispatcher::setInputFilterEnabled(bool enabled) { 3342#if DEBUG_FOCUS 3343 LOGD("setInputFilterEnabled: enabled=%d", enabled); 3344#endif 3345 3346 { // acquire lock 3347 AutoMutex _l(mLock); 3348 3349 if (mInputFilterEnabled == enabled) { 3350 return; 3351 } 3352 3353 mInputFilterEnabled = enabled; 3354 resetAndDropEverythingLocked("input filter is being enabled or disabled"); 3355 } // release lock 3356 3357 // Wake up poll loop since there might be work to do to drop everything. 3358 mLooper->wake(); 3359} 3360 3361bool InputDispatcher::transferTouchFocus(const sp<InputChannel>& fromChannel, 3362 const sp<InputChannel>& toChannel) { 3363#if DEBUG_FOCUS 3364 LOGD("transferTouchFocus: fromChannel=%s, toChannel=%s", 3365 fromChannel->getName().string(), toChannel->getName().string()); 3366#endif 3367 { // acquire lock 3368 AutoMutex _l(mLock); 3369 3370 sp<InputWindowHandle> fromWindowHandle = getWindowHandleLocked(fromChannel); 3371 sp<InputWindowHandle> toWindowHandle = getWindowHandleLocked(toChannel); 3372 if (fromWindowHandle == NULL || toWindowHandle == NULL) { 3373#if DEBUG_FOCUS 3374 LOGD("Cannot transfer focus because from or to window not found."); 3375#endif 3376 return false; 3377 } 3378 if (fromWindowHandle == toWindowHandle) { 3379#if DEBUG_FOCUS 3380 LOGD("Trivial transfer to same window."); 3381#endif 3382 return true; 3383 } 3384 3385 bool found = false; 3386 for (size_t i = 0; i < mTouchState.windows.size(); i++) { 3387 const TouchedWindow& touchedWindow = mTouchState.windows[i]; 3388 if (touchedWindow.windowHandle == fromWindowHandle) { 3389 int32_t oldTargetFlags = touchedWindow.targetFlags; 3390 BitSet32 pointerIds = touchedWindow.pointerIds; 3391 3392 mTouchState.windows.removeAt(i); 3393 3394 int32_t newTargetFlags = oldTargetFlags 3395 & (InputTarget::FLAG_FOREGROUND 3396 | InputTarget::FLAG_SPLIT | InputTarget::FLAG_DISPATCH_AS_IS); 3397 mTouchState.addOrUpdateWindow(toWindowHandle, newTargetFlags, pointerIds); 3398 3399 found = true; 3400 break; 3401 } 3402 } 3403 3404 if (! found) { 3405#if DEBUG_FOCUS 3406 LOGD("Focus transfer failed because from window did not have focus."); 3407#endif 3408 return false; 3409 } 3410 3411 ssize_t fromConnectionIndex = getConnectionIndexLocked(fromChannel); 3412 ssize_t toConnectionIndex = getConnectionIndexLocked(toChannel); 3413 if (fromConnectionIndex >= 0 && toConnectionIndex >= 0) { 3414 sp<Connection> fromConnection = mConnectionsByReceiveFd.valueAt(fromConnectionIndex); 3415 sp<Connection> toConnection = mConnectionsByReceiveFd.valueAt(toConnectionIndex); 3416 3417 fromConnection->inputState.copyPointerStateTo(toConnection->inputState); 3418 CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS, 3419 "transferring touch focus from this window to another window"); 3420 synthesizeCancelationEventsForConnectionLocked(fromConnection, options); 3421 } 3422 3423#if DEBUG_FOCUS 3424 logDispatchStateLocked(); 3425#endif 3426 } // release lock 3427 3428 // Wake up poll loop since it may need to make new input dispatching choices. 3429 mLooper->wake(); 3430 return true; 3431} 3432 3433void InputDispatcher::resetAndDropEverythingLocked(const char* reason) { 3434#if DEBUG_FOCUS 3435 LOGD("Resetting and dropping all events (%s).", reason); 3436#endif 3437 3438 CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, reason); 3439 synthesizeCancelationEventsForAllConnectionsLocked(options); 3440 3441 resetKeyRepeatLocked(); 3442 releasePendingEventLocked(); 3443 drainInboundQueueLocked(); 3444 resetTargetsLocked(); 3445 3446 mTouchState.reset(); 3447 mLastHoverWindowHandle.clear(); 3448} 3449 3450void InputDispatcher::logDispatchStateLocked() { 3451 String8 dump; 3452 dumpDispatchStateLocked(dump); 3453 3454 char* text = dump.lockBuffer(dump.size()); 3455 char* start = text; 3456 while (*start != '\0') { 3457 char* end = strchr(start, '\n'); 3458 if (*end == '\n') { 3459 *(end++) = '\0'; 3460 } 3461 LOGD("%s", start); 3462 start = end; 3463 } 3464} 3465 3466void InputDispatcher::dumpDispatchStateLocked(String8& dump) { 3467 dump.appendFormat(INDENT "DispatchEnabled: %d\n", mDispatchEnabled); 3468 dump.appendFormat(INDENT "DispatchFrozen: %d\n", mDispatchFrozen); 3469 3470 if (mFocusedApplicationHandle != NULL) { 3471 dump.appendFormat(INDENT "FocusedApplication: name='%s', dispatchingTimeout=%0.3fms\n", 3472 mFocusedApplicationHandle->name.string(), 3473 mFocusedApplicationHandle->dispatchingTimeout / 1000000.0); 3474 } else { 3475 dump.append(INDENT "FocusedApplication: <null>\n"); 3476 } 3477 dump.appendFormat(INDENT "FocusedWindow: name='%s'\n", 3478 mFocusedWindowHandle != NULL ? mFocusedWindowHandle->name.string() : "<null>"); 3479 3480 dump.appendFormat(INDENT "TouchDown: %s\n", toString(mTouchState.down)); 3481 dump.appendFormat(INDENT "TouchSplit: %s\n", toString(mTouchState.split)); 3482 dump.appendFormat(INDENT "TouchDeviceId: %d\n", mTouchState.deviceId); 3483 dump.appendFormat(INDENT "TouchSource: 0x%08x\n", mTouchState.source); 3484 if (!mTouchState.windows.isEmpty()) { 3485 dump.append(INDENT "TouchedWindows:\n"); 3486 for (size_t i = 0; i < mTouchState.windows.size(); i++) { 3487 const TouchedWindow& touchedWindow = mTouchState.windows[i]; 3488 dump.appendFormat(INDENT2 "%d: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n", 3489 i, touchedWindow.windowHandle->name.string(), touchedWindow.pointerIds.value, 3490 touchedWindow.targetFlags); 3491 } 3492 } else { 3493 dump.append(INDENT "TouchedWindows: <none>\n"); 3494 } 3495 3496 if (!mWindowHandles.isEmpty()) { 3497 dump.append(INDENT "Windows:\n"); 3498 for (size_t i = 0; i < mWindowHandles.size(); i++) { 3499 const sp<InputWindowHandle>& windowHandle = mWindowHandles.itemAt(i); 3500 dump.appendFormat(INDENT2 "%d: name='%s', paused=%s, hasFocus=%s, hasWallpaper=%s, " 3501 "visible=%s, canReceiveKeys=%s, flags=0x%08x, type=0x%08x, layer=%d, " 3502 "frame=[%d,%d][%d,%d], scale=%f, " 3503 "touchableRegion=", 3504 i, windowHandle->name.string(), 3505 toString(windowHandle->paused), 3506 toString(windowHandle->hasFocus), 3507 toString(windowHandle->hasWallpaper), 3508 toString(windowHandle->visible), 3509 toString(windowHandle->canReceiveKeys), 3510 windowHandle->layoutParamsFlags, windowHandle->layoutParamsType, 3511 windowHandle->layer, 3512 windowHandle->frameLeft, windowHandle->frameTop, 3513 windowHandle->frameRight, windowHandle->frameBottom, 3514 windowHandle->scaleFactor); 3515 dumpRegion(dump, windowHandle->touchableRegion); 3516 dump.appendFormat(", inputFeatures=0x%08x", windowHandle->inputFeatures); 3517 dump.appendFormat(", ownerPid=%d, ownerUid=%d, dispatchingTimeout=%0.3fms\n", 3518 windowHandle->ownerPid, windowHandle->ownerUid, 3519 windowHandle->dispatchingTimeout / 1000000.0); 3520 } 3521 } else { 3522 dump.append(INDENT "Windows: <none>\n"); 3523 } 3524 3525 if (!mMonitoringChannels.isEmpty()) { 3526 dump.append(INDENT "MonitoringChannels:\n"); 3527 for (size_t i = 0; i < mMonitoringChannels.size(); i++) { 3528 const sp<InputChannel>& channel = mMonitoringChannels[i]; 3529 dump.appendFormat(INDENT2 "%d: '%s'\n", i, channel->getName().string()); 3530 } 3531 } else { 3532 dump.append(INDENT "MonitoringChannels: <none>\n"); 3533 } 3534 3535 dump.appendFormat(INDENT "InboundQueue: length=%u\n", mInboundQueue.count()); 3536 3537 if (!mActiveConnections.isEmpty()) { 3538 dump.append(INDENT "ActiveConnections:\n"); 3539 for (size_t i = 0; i < mActiveConnections.size(); i++) { 3540 const Connection* connection = mActiveConnections[i]; 3541 dump.appendFormat(INDENT2 "%d: '%s', status=%s, outboundQueueLength=%u, " 3542 "inputState.isNeutral=%s\n", 3543 i, connection->getInputChannelName(), connection->getStatusLabel(), 3544 connection->outboundQueue.count(), 3545 toString(connection->inputState.isNeutral())); 3546 } 3547 } else { 3548 dump.append(INDENT "ActiveConnections: <none>\n"); 3549 } 3550 3551 if (isAppSwitchPendingLocked()) { 3552 dump.appendFormat(INDENT "AppSwitch: pending, due in %01.1fms\n", 3553 (mAppSwitchDueTime - now()) / 1000000.0); 3554 } else { 3555 dump.append(INDENT "AppSwitch: not pending\n"); 3556 } 3557} 3558 3559status_t InputDispatcher::registerInputChannel(const sp<InputChannel>& inputChannel, 3560 const sp<InputWindowHandle>& inputWindowHandle, bool monitor) { 3561#if DEBUG_REGISTRATION 3562 LOGD("channel '%s' ~ registerInputChannel - monitor=%s", inputChannel->getName().string(), 3563 toString(monitor)); 3564#endif 3565 3566 { // acquire lock 3567 AutoMutex _l(mLock); 3568 3569 if (getConnectionIndexLocked(inputChannel) >= 0) { 3570 LOGW("Attempted to register already registered input channel '%s'", 3571 inputChannel->getName().string()); 3572 return BAD_VALUE; 3573 } 3574 3575 sp<Connection> connection = new Connection(inputChannel, inputWindowHandle); 3576 status_t status = connection->initialize(); 3577 if (status) { 3578 LOGE("Failed to initialize input publisher for input channel '%s', status=%d", 3579 inputChannel->getName().string(), status); 3580 return status; 3581 } 3582 3583 int32_t receiveFd = inputChannel->getReceivePipeFd(); 3584 mConnectionsByReceiveFd.add(receiveFd, connection); 3585 3586 if (monitor) { 3587 mMonitoringChannels.push(inputChannel); 3588 } 3589 3590 mLooper->addFd(receiveFd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this); 3591 3592 runCommandsLockedInterruptible(); 3593 } // release lock 3594 return OK; 3595} 3596 3597status_t InputDispatcher::unregisterInputChannel(const sp<InputChannel>& inputChannel) { 3598#if DEBUG_REGISTRATION 3599 LOGD("channel '%s' ~ unregisterInputChannel", inputChannel->getName().string()); 3600#endif 3601 3602 { // acquire lock 3603 AutoMutex _l(mLock); 3604 3605 ssize_t connectionIndex = getConnectionIndexLocked(inputChannel); 3606 if (connectionIndex < 0) { 3607 LOGW("Attempted to unregister already unregistered input channel '%s'", 3608 inputChannel->getName().string()); 3609 return BAD_VALUE; 3610 } 3611 3612 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex); 3613 mConnectionsByReceiveFd.removeItemsAt(connectionIndex); 3614 3615 connection->status = Connection::STATUS_ZOMBIE; 3616 3617 for (size_t i = 0; i < mMonitoringChannels.size(); i++) { 3618 if (mMonitoringChannels[i] == inputChannel) { 3619 mMonitoringChannels.removeAt(i); 3620 break; 3621 } 3622 } 3623 3624 mLooper->removeFd(inputChannel->getReceivePipeFd()); 3625 3626 nsecs_t currentTime = now(); 3627 abortBrokenDispatchCycleLocked(currentTime, connection); 3628 3629 runCommandsLockedInterruptible(); 3630 } // release lock 3631 3632 // Wake the poll loop because removing the connection may have changed the current 3633 // synchronization state. 3634 mLooper->wake(); 3635 return OK; 3636} 3637 3638ssize_t InputDispatcher::getConnectionIndexLocked(const sp<InputChannel>& inputChannel) { 3639 ssize_t connectionIndex = mConnectionsByReceiveFd.indexOfKey(inputChannel->getReceivePipeFd()); 3640 if (connectionIndex >= 0) { 3641 sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex); 3642 if (connection->inputChannel.get() == inputChannel.get()) { 3643 return connectionIndex; 3644 } 3645 } 3646 3647 return -1; 3648} 3649 3650void InputDispatcher::activateConnectionLocked(Connection* connection) { 3651 for (size_t i = 0; i < mActiveConnections.size(); i++) { 3652 if (mActiveConnections.itemAt(i) == connection) { 3653 return; 3654 } 3655 } 3656 mActiveConnections.add(connection); 3657} 3658 3659void InputDispatcher::deactivateConnectionLocked(Connection* connection) { 3660 for (size_t i = 0; i < mActiveConnections.size(); i++) { 3661 if (mActiveConnections.itemAt(i) == connection) { 3662 mActiveConnections.removeAt(i); 3663 return; 3664 } 3665 } 3666} 3667 3668void InputDispatcher::onDispatchCycleStartedLocked( 3669 nsecs_t currentTime, const sp<Connection>& connection) { 3670} 3671 3672void InputDispatcher::onDispatchCycleFinishedLocked( 3673 nsecs_t currentTime, const sp<Connection>& connection, bool handled) { 3674 CommandEntry* commandEntry = postCommandLocked( 3675 & InputDispatcher::doDispatchCycleFinishedLockedInterruptible); 3676 commandEntry->connection = connection; 3677 commandEntry->handled = handled; 3678} 3679 3680void InputDispatcher::onDispatchCycleBrokenLocked( 3681 nsecs_t currentTime, const sp<Connection>& connection) { 3682 LOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!", 3683 connection->getInputChannelName()); 3684 3685 CommandEntry* commandEntry = postCommandLocked( 3686 & InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible); 3687 commandEntry->connection = connection; 3688} 3689 3690void InputDispatcher::onANRLocked( 3691 nsecs_t currentTime, const sp<InputApplicationHandle>& applicationHandle, 3692 const sp<InputWindowHandle>& windowHandle, 3693 nsecs_t eventTime, nsecs_t waitStartTime) { 3694 LOGI("Application is not responding: %s. " 3695 "%01.1fms since event, %01.1fms since wait started", 3696 getApplicationWindowLabelLocked(applicationHandle, windowHandle).string(), 3697 (currentTime - eventTime) / 1000000.0, 3698 (currentTime - waitStartTime) / 1000000.0); 3699 3700 CommandEntry* commandEntry = postCommandLocked( 3701 & InputDispatcher::doNotifyANRLockedInterruptible); 3702 commandEntry->inputApplicationHandle = applicationHandle; 3703 commandEntry->inputWindowHandle = windowHandle; 3704} 3705 3706void InputDispatcher::doNotifyConfigurationChangedInterruptible( 3707 CommandEntry* commandEntry) { 3708 mLock.unlock(); 3709 3710 mPolicy->notifyConfigurationChanged(commandEntry->eventTime); 3711 3712 mLock.lock(); 3713} 3714 3715void InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible( 3716 CommandEntry* commandEntry) { 3717 sp<Connection> connection = commandEntry->connection; 3718 3719 if (connection->status != Connection::STATUS_ZOMBIE) { 3720 mLock.unlock(); 3721 3722 mPolicy->notifyInputChannelBroken(connection->inputWindowHandle); 3723 3724 mLock.lock(); 3725 } 3726} 3727 3728void InputDispatcher::doNotifyANRLockedInterruptible( 3729 CommandEntry* commandEntry) { 3730 mLock.unlock(); 3731 3732 nsecs_t newTimeout = mPolicy->notifyANR( 3733 commandEntry->inputApplicationHandle, commandEntry->inputWindowHandle); 3734 3735 mLock.lock(); 3736 3737 resumeAfterTargetsNotReadyTimeoutLocked(newTimeout, 3738 commandEntry->inputWindowHandle != NULL 3739 ? commandEntry->inputWindowHandle->inputChannel : NULL); 3740} 3741 3742void InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible( 3743 CommandEntry* commandEntry) { 3744 KeyEntry* entry = commandEntry->keyEntry; 3745 3746 KeyEvent event; 3747 initializeKeyEvent(&event, entry); 3748 3749 mLock.unlock(); 3750 3751 bool consumed = mPolicy->interceptKeyBeforeDispatching(commandEntry->inputWindowHandle, 3752 &event, entry->policyFlags); 3753 3754 mLock.lock(); 3755 3756 entry->interceptKeyResult = consumed 3757 ? KeyEntry::INTERCEPT_KEY_RESULT_SKIP 3758 : KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE; 3759 entry->release(); 3760} 3761 3762void InputDispatcher::doDispatchCycleFinishedLockedInterruptible( 3763 CommandEntry* commandEntry) { 3764 sp<Connection> connection = commandEntry->connection; 3765 bool handled = commandEntry->handled; 3766 3767 bool skipNext = false; 3768 if (!connection->outboundQueue.isEmpty()) { 3769 DispatchEntry* dispatchEntry = connection->outboundQueue.head; 3770 if (dispatchEntry->inProgress) { 3771 if (dispatchEntry->eventEntry->type == EventEntry::TYPE_KEY) { 3772 KeyEntry* keyEntry = static_cast<KeyEntry*>(dispatchEntry->eventEntry); 3773 skipNext = afterKeyEventLockedInterruptible(connection, 3774 dispatchEntry, keyEntry, handled); 3775 } else if (dispatchEntry->eventEntry->type == EventEntry::TYPE_MOTION) { 3776 MotionEntry* motionEntry = static_cast<MotionEntry*>(dispatchEntry->eventEntry); 3777 skipNext = afterMotionEventLockedInterruptible(connection, 3778 dispatchEntry, motionEntry, handled); 3779 } 3780 } 3781 } 3782 3783 if (!skipNext) { 3784 startNextDispatchCycleLocked(now(), connection); 3785 } 3786} 3787 3788bool InputDispatcher::afterKeyEventLockedInterruptible(const sp<Connection>& connection, 3789 DispatchEntry* dispatchEntry, KeyEntry* keyEntry, bool handled) { 3790 if (!(keyEntry->flags & AKEY_EVENT_FLAG_FALLBACK)) { 3791 // Get the fallback key state. 3792 // Clear it out after dispatching the UP. 3793 int32_t originalKeyCode = keyEntry->keyCode; 3794 int32_t fallbackKeyCode = connection->inputState.getFallbackKey(originalKeyCode); 3795 if (keyEntry->action == AKEY_EVENT_ACTION_UP) { 3796 connection->inputState.removeFallbackKey(originalKeyCode); 3797 } 3798 3799 if (handled || !dispatchEntry->hasForegroundTarget()) { 3800 // If the application handles the original key for which we previously 3801 // generated a fallback or if the window is not a foreground window, 3802 // then cancel the associated fallback key, if any. 3803 if (fallbackKeyCode != -1) { 3804 if (fallbackKeyCode != AKEYCODE_UNKNOWN) { 3805 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS, 3806 "application handled the original non-fallback key " 3807 "or is no longer a foreground target, " 3808 "canceling previously dispatched fallback key"); 3809 options.keyCode = fallbackKeyCode; 3810 synthesizeCancelationEventsForConnectionLocked(connection, options); 3811 } 3812 connection->inputState.removeFallbackKey(originalKeyCode); 3813 } 3814 } else { 3815 // If the application did not handle a non-fallback key, first check 3816 // that we are in a good state to perform unhandled key event processing 3817 // Then ask the policy what to do with it. 3818 bool initialDown = keyEntry->action == AKEY_EVENT_ACTION_DOWN 3819 && keyEntry->repeatCount == 0; 3820 if (fallbackKeyCode == -1 && !initialDown) { 3821#if DEBUG_OUTBOUND_EVENT_DETAILS 3822 LOGD("Unhandled key event: Skipping unhandled key event processing " 3823 "since this is not an initial down. " 3824 "keyCode=%d, action=%d, repeatCount=%d", 3825 originalKeyCode, keyEntry->action, keyEntry->repeatCount); 3826#endif 3827 return false; 3828 } 3829 3830 // Dispatch the unhandled key to the policy. 3831#if DEBUG_OUTBOUND_EVENT_DETAILS 3832 LOGD("Unhandled key event: Asking policy to perform fallback action. " 3833 "keyCode=%d, action=%d, repeatCount=%d", 3834 keyEntry->keyCode, keyEntry->action, keyEntry->repeatCount); 3835#endif 3836 KeyEvent event; 3837 initializeKeyEvent(&event, keyEntry); 3838 3839 mLock.unlock(); 3840 3841 bool fallback = mPolicy->dispatchUnhandledKey(connection->inputWindowHandle, 3842 &event, keyEntry->policyFlags, &event); 3843 3844 mLock.lock(); 3845 3846 if (connection->status != Connection::STATUS_NORMAL) { 3847 connection->inputState.removeFallbackKey(originalKeyCode); 3848 return true; // skip next cycle 3849 } 3850 3851 LOG_ASSERT(connection->outboundQueue.head == dispatchEntry); 3852 3853 // Latch the fallback keycode for this key on an initial down. 3854 // The fallback keycode cannot change at any other point in the lifecycle. 3855 if (initialDown) { 3856 if (fallback) { 3857 fallbackKeyCode = event.getKeyCode(); 3858 } else { 3859 fallbackKeyCode = AKEYCODE_UNKNOWN; 3860 } 3861 connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode); 3862 } 3863 3864 LOG_ASSERT(fallbackKeyCode != -1); 3865 3866 // Cancel the fallback key if the policy decides not to send it anymore. 3867 // We will continue to dispatch the key to the policy but we will no 3868 // longer dispatch a fallback key to the application. 3869 if (fallbackKeyCode != AKEYCODE_UNKNOWN 3870 && (!fallback || fallbackKeyCode != event.getKeyCode())) { 3871#if DEBUG_OUTBOUND_EVENT_DETAILS 3872 if (fallback) { 3873 LOGD("Unhandled key event: Policy requested to send key %d" 3874 "as a fallback for %d, but on the DOWN it had requested " 3875 "to send %d instead. Fallback canceled.", 3876 event.getKeyCode(), originalKeyCode, fallbackKeyCode); 3877 } else { 3878 LOGD("Unhandled key event: Policy did not request fallback for %d," 3879 "but on the DOWN it had requested to send %d. " 3880 "Fallback canceled.", 3881 originalKeyCode, fallbackKeyCode); 3882 } 3883#endif 3884 3885 CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS, 3886 "canceling fallback, policy no longer desires it"); 3887 options.keyCode = fallbackKeyCode; 3888 synthesizeCancelationEventsForConnectionLocked(connection, options); 3889 3890 fallback = false; 3891 fallbackKeyCode = AKEYCODE_UNKNOWN; 3892 if (keyEntry->action != AKEY_EVENT_ACTION_UP) { 3893 connection->inputState.setFallbackKey(originalKeyCode, 3894 fallbackKeyCode); 3895 } 3896 } 3897 3898#if DEBUG_OUTBOUND_EVENT_DETAILS 3899 { 3900 String8 msg; 3901 const KeyedVector<int32_t, int32_t>& fallbackKeys = 3902 connection->inputState.getFallbackKeys(); 3903 for (size_t i = 0; i < fallbackKeys.size(); i++) { 3904 msg.appendFormat(", %d->%d", fallbackKeys.keyAt(i), 3905 fallbackKeys.valueAt(i)); 3906 } 3907 LOGD("Unhandled key event: %d currently tracked fallback keys%s.", 3908 fallbackKeys.size(), msg.string()); 3909 } 3910#endif 3911 3912 if (fallback) { 3913 // Restart the dispatch cycle using the fallback key. 3914 keyEntry->eventTime = event.getEventTime(); 3915 keyEntry->deviceId = event.getDeviceId(); 3916 keyEntry->source = event.getSource(); 3917 keyEntry->flags = event.getFlags() | AKEY_EVENT_FLAG_FALLBACK; 3918 keyEntry->keyCode = fallbackKeyCode; 3919 keyEntry->scanCode = event.getScanCode(); 3920 keyEntry->metaState = event.getMetaState(); 3921 keyEntry->repeatCount = event.getRepeatCount(); 3922 keyEntry->downTime = event.getDownTime(); 3923 keyEntry->syntheticRepeat = false; 3924 3925#if DEBUG_OUTBOUND_EVENT_DETAILS 3926 LOGD("Unhandled key event: Dispatching fallback key. " 3927 "originalKeyCode=%d, fallbackKeyCode=%d, fallbackMetaState=%08x", 3928 originalKeyCode, fallbackKeyCode, keyEntry->metaState); 3929#endif 3930 3931 dispatchEntry->inProgress = false; 3932 startDispatchCycleLocked(now(), connection); 3933 return true; // already started next cycle 3934 } else { 3935#if DEBUG_OUTBOUND_EVENT_DETAILS 3936 LOGD("Unhandled key event: No fallback key."); 3937#endif 3938 } 3939 } 3940 } 3941 return false; 3942} 3943 3944bool InputDispatcher::afterMotionEventLockedInterruptible(const sp<Connection>& connection, 3945 DispatchEntry* dispatchEntry, MotionEntry* motionEntry, bool handled) { 3946 return false; 3947} 3948 3949void InputDispatcher::doPokeUserActivityLockedInterruptible(CommandEntry* commandEntry) { 3950 mLock.unlock(); 3951 3952 mPolicy->pokeUserActivity(commandEntry->eventTime, commandEntry->userActivityEventType); 3953 3954 mLock.lock(); 3955} 3956 3957void InputDispatcher::initializeKeyEvent(KeyEvent* event, const KeyEntry* entry) { 3958 event->initialize(entry->deviceId, entry->source, entry->action, entry->flags, 3959 entry->keyCode, entry->scanCode, entry->metaState, entry->repeatCount, 3960 entry->downTime, entry->eventTime); 3961} 3962 3963void InputDispatcher::updateDispatchStatisticsLocked(nsecs_t currentTime, const EventEntry* entry, 3964 int32_t injectionResult, nsecs_t timeSpentWaitingForApplication) { 3965 // TODO Write some statistics about how long we spend waiting. 3966} 3967 3968void InputDispatcher::dump(String8& dump) { 3969 AutoMutex _l(mLock); 3970 3971 dump.append("Input Dispatcher State:\n"); 3972 dumpDispatchStateLocked(dump); 3973 3974 dump.append(INDENT "Configuration:\n"); 3975 dump.appendFormat(INDENT2 "MaxEventsPerSecond: %d\n", mConfig.maxEventsPerSecond); 3976 dump.appendFormat(INDENT2 "KeyRepeatDelay: %0.1fms\n", mConfig.keyRepeatDelay * 0.000001f); 3977 dump.appendFormat(INDENT2 "KeyRepeatTimeout: %0.1fms\n", mConfig.keyRepeatTimeout * 0.000001f); 3978} 3979 3980void InputDispatcher::monitor() { 3981 // Acquire and release the lock to ensure that the dispatcher has not deadlocked. 3982 mLock.lock(); 3983 mLock.unlock(); 3984} 3985 3986 3987// --- InputDispatcher::Queue --- 3988 3989template <typename T> 3990uint32_t InputDispatcher::Queue<T>::count() const { 3991 uint32_t result = 0; 3992 for (const T* entry = head; entry; entry = entry->next) { 3993 result += 1; 3994 } 3995 return result; 3996} 3997 3998 3999// --- InputDispatcher::InjectionState --- 4000 4001InputDispatcher::InjectionState::InjectionState(int32_t injectorPid, int32_t injectorUid) : 4002 refCount(1), 4003 injectorPid(injectorPid), injectorUid(injectorUid), 4004 injectionResult(INPUT_EVENT_INJECTION_PENDING), injectionIsAsync(false), 4005 pendingForegroundDispatches(0) { 4006} 4007 4008InputDispatcher::InjectionState::~InjectionState() { 4009} 4010 4011void InputDispatcher::InjectionState::release() { 4012 refCount -= 1; 4013 if (refCount == 0) { 4014 delete this; 4015 } else { 4016 LOG_ASSERT(refCount > 0); 4017 } 4018} 4019 4020 4021// --- InputDispatcher::EventEntry --- 4022 4023InputDispatcher::EventEntry::EventEntry(int32_t type, nsecs_t eventTime, uint32_t policyFlags) : 4024 refCount(1), type(type), eventTime(eventTime), policyFlags(policyFlags), 4025 injectionState(NULL), dispatchInProgress(false) { 4026} 4027 4028InputDispatcher::EventEntry::~EventEntry() { 4029 releaseInjectionState(); 4030} 4031 4032void InputDispatcher::EventEntry::release() { 4033 refCount -= 1; 4034 if (refCount == 0) { 4035 delete this; 4036 } else { 4037 LOG_ASSERT(refCount > 0); 4038 } 4039} 4040 4041void InputDispatcher::EventEntry::releaseInjectionState() { 4042 if (injectionState) { 4043 injectionState->release(); 4044 injectionState = NULL; 4045 } 4046} 4047 4048 4049// --- InputDispatcher::ConfigurationChangedEntry --- 4050 4051InputDispatcher::ConfigurationChangedEntry::ConfigurationChangedEntry(nsecs_t eventTime) : 4052 EventEntry(TYPE_CONFIGURATION_CHANGED, eventTime, 0) { 4053} 4054 4055InputDispatcher::ConfigurationChangedEntry::~ConfigurationChangedEntry() { 4056} 4057 4058 4059// --- InputDispatcher::DeviceResetEntry --- 4060 4061InputDispatcher::DeviceResetEntry::DeviceResetEntry(nsecs_t eventTime, int32_t deviceId) : 4062 EventEntry(TYPE_DEVICE_RESET, eventTime, 0), 4063 deviceId(deviceId) { 4064} 4065 4066InputDispatcher::DeviceResetEntry::~DeviceResetEntry() { 4067} 4068 4069 4070// --- InputDispatcher::KeyEntry --- 4071 4072InputDispatcher::KeyEntry::KeyEntry(nsecs_t eventTime, 4073 int32_t deviceId, uint32_t source, uint32_t policyFlags, int32_t action, 4074 int32_t flags, int32_t keyCode, int32_t scanCode, int32_t metaState, 4075 int32_t repeatCount, nsecs_t downTime) : 4076 EventEntry(TYPE_KEY, eventTime, policyFlags), 4077 deviceId(deviceId), source(source), action(action), flags(flags), 4078 keyCode(keyCode), scanCode(scanCode), metaState(metaState), 4079 repeatCount(repeatCount), downTime(downTime), 4080 syntheticRepeat(false), interceptKeyResult(KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) { 4081} 4082 4083InputDispatcher::KeyEntry::~KeyEntry() { 4084} 4085 4086void InputDispatcher::KeyEntry::recycle() { 4087 releaseInjectionState(); 4088 4089 dispatchInProgress = false; 4090 syntheticRepeat = false; 4091 interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN; 4092} 4093 4094 4095// --- InputDispatcher::MotionSample --- 4096 4097InputDispatcher::MotionSample::MotionSample(nsecs_t eventTime, 4098 const PointerCoords* pointerCoords, uint32_t pointerCount) : 4099 next(NULL), eventTime(eventTime), eventTimeBeforeCoalescing(eventTime) { 4100 for (uint32_t i = 0; i < pointerCount; i++) { 4101 this->pointerCoords[i].copyFrom(pointerCoords[i]); 4102 } 4103} 4104 4105 4106// --- InputDispatcher::MotionEntry --- 4107 4108InputDispatcher::MotionEntry::MotionEntry(nsecs_t eventTime, 4109 int32_t deviceId, uint32_t source, uint32_t policyFlags, int32_t action, int32_t flags, 4110 int32_t metaState, int32_t buttonState, 4111 int32_t edgeFlags, float xPrecision, float yPrecision, 4112 nsecs_t downTime, uint32_t pointerCount, 4113 const PointerProperties* pointerProperties, const PointerCoords* pointerCoords) : 4114 EventEntry(TYPE_MOTION, eventTime, policyFlags), 4115 deviceId(deviceId), source(source), action(action), flags(flags), 4116 metaState(metaState), buttonState(buttonState), edgeFlags(edgeFlags), 4117 xPrecision(xPrecision), yPrecision(yPrecision), 4118 downTime(downTime), pointerCount(pointerCount), 4119 firstSample(eventTime, pointerCoords, pointerCount), 4120 lastSample(&firstSample) { 4121 for (uint32_t i = 0; i < pointerCount; i++) { 4122 this->pointerProperties[i].copyFrom(pointerProperties[i]); 4123 } 4124} 4125 4126InputDispatcher::MotionEntry::~MotionEntry() { 4127 for (MotionSample* sample = firstSample.next; sample != NULL; ) { 4128 MotionSample* next = sample->next; 4129 delete sample; 4130 sample = next; 4131 } 4132} 4133 4134uint32_t InputDispatcher::MotionEntry::countSamples() const { 4135 uint32_t count = 1; 4136 for (MotionSample* sample = firstSample.next; sample != NULL; sample = sample->next) { 4137 count += 1; 4138 } 4139 return count; 4140} 4141 4142bool InputDispatcher::MotionEntry::canAppendSamples(int32_t action, uint32_t pointerCount, 4143 const PointerProperties* pointerProperties) const { 4144 if (this->action != action 4145 || this->pointerCount != pointerCount 4146 || this->isInjected()) { 4147 return false; 4148 } 4149 for (uint32_t i = 0; i < pointerCount; i++) { 4150 if (this->pointerProperties[i] != pointerProperties[i]) { 4151 return false; 4152 } 4153 } 4154 return true; 4155} 4156 4157void InputDispatcher::MotionEntry::appendSample( 4158 nsecs_t eventTime, const PointerCoords* pointerCoords) { 4159 MotionSample* sample = new MotionSample(eventTime, pointerCoords, pointerCount); 4160 4161 lastSample->next = sample; 4162 lastSample = sample; 4163} 4164 4165 4166// --- InputDispatcher::DispatchEntry --- 4167 4168InputDispatcher::DispatchEntry::DispatchEntry(EventEntry* eventEntry, 4169 int32_t targetFlags, float xOffset, float yOffset, float scaleFactor) : 4170 eventEntry(eventEntry), targetFlags(targetFlags), 4171 xOffset(xOffset), yOffset(yOffset), scaleFactor(scaleFactor), 4172 inProgress(false), 4173 resolvedAction(0), resolvedFlags(0), 4174 headMotionSample(NULL), tailMotionSample(NULL) { 4175 eventEntry->refCount += 1; 4176} 4177 4178InputDispatcher::DispatchEntry::~DispatchEntry() { 4179 eventEntry->release(); 4180} 4181 4182 4183// --- InputDispatcher::InputState --- 4184 4185InputDispatcher::InputState::InputState() { 4186} 4187 4188InputDispatcher::InputState::~InputState() { 4189} 4190 4191bool InputDispatcher::InputState::isNeutral() const { 4192 return mKeyMementos.isEmpty() && mMotionMementos.isEmpty(); 4193} 4194 4195bool InputDispatcher::InputState::isHovering(int32_t deviceId, uint32_t source) const { 4196 for (size_t i = 0; i < mMotionMementos.size(); i++) { 4197 const MotionMemento& memento = mMotionMementos.itemAt(i); 4198 if (memento.deviceId == deviceId 4199 && memento.source == source 4200 && memento.hovering) { 4201 return true; 4202 } 4203 } 4204 return false; 4205} 4206 4207bool InputDispatcher::InputState::trackKey(const KeyEntry* entry, 4208 int32_t action, int32_t flags) { 4209 switch (action) { 4210 case AKEY_EVENT_ACTION_UP: { 4211 if (entry->flags & AKEY_EVENT_FLAG_FALLBACK) { 4212 for (size_t i = 0; i < mFallbackKeys.size(); ) { 4213 if (mFallbackKeys.valueAt(i) == entry->keyCode) { 4214 mFallbackKeys.removeItemsAt(i); 4215 } else { 4216 i += 1; 4217 } 4218 } 4219 } 4220 ssize_t index = findKeyMemento(entry); 4221 if (index >= 0) { 4222 mKeyMementos.removeAt(index); 4223 return true; 4224 } 4225#if DEBUG_OUTBOUND_EVENT_DETAILS 4226 LOGD("Dropping inconsistent key up event: deviceId=%d, source=%08x, " 4227 "keyCode=%d, scanCode=%d", 4228 entry->deviceId, entry->source, entry->keyCode, entry->scanCode); 4229#endif 4230 return false; 4231 } 4232 4233 case AKEY_EVENT_ACTION_DOWN: { 4234 ssize_t index = findKeyMemento(entry); 4235 if (index >= 0) { 4236 mKeyMementos.removeAt(index); 4237 } 4238 addKeyMemento(entry, flags); 4239 return true; 4240 } 4241 4242 default: 4243 return true; 4244 } 4245} 4246 4247bool InputDispatcher::InputState::trackMotion(const MotionEntry* entry, 4248 int32_t action, int32_t flags) { 4249 int32_t actionMasked = action & AMOTION_EVENT_ACTION_MASK; 4250 switch (actionMasked) { 4251 case AMOTION_EVENT_ACTION_UP: 4252 case AMOTION_EVENT_ACTION_CANCEL: { 4253 ssize_t index = findMotionMemento(entry, false /*hovering*/); 4254 if (index >= 0) { 4255 mMotionMementos.removeAt(index); 4256 return true; 4257 } 4258#if DEBUG_OUTBOUND_EVENT_DETAILS 4259 LOGD("Dropping inconsistent motion up or cancel event: deviceId=%d, source=%08x, " 4260 "actionMasked=%d", 4261 entry->deviceId, entry->source, actionMasked); 4262#endif 4263 return false; 4264 } 4265 4266 case AMOTION_EVENT_ACTION_DOWN: { 4267 ssize_t index = findMotionMemento(entry, false /*hovering*/); 4268 if (index >= 0) { 4269 mMotionMementos.removeAt(index); 4270 } 4271 addMotionMemento(entry, flags, false /*hovering*/); 4272 return true; 4273 } 4274 4275 case AMOTION_EVENT_ACTION_POINTER_UP: 4276 case AMOTION_EVENT_ACTION_POINTER_DOWN: 4277 case AMOTION_EVENT_ACTION_MOVE: { 4278 ssize_t index = findMotionMemento(entry, false /*hovering*/); 4279 if (index >= 0) { 4280 MotionMemento& memento = mMotionMementos.editItemAt(index); 4281 memento.setPointers(entry); 4282 return true; 4283 } 4284 if (actionMasked == AMOTION_EVENT_ACTION_MOVE 4285 && (entry->source & (AINPUT_SOURCE_CLASS_JOYSTICK 4286 | AINPUT_SOURCE_CLASS_NAVIGATION))) { 4287 // Joysticks and trackballs can send MOVE events without corresponding DOWN or UP. 4288 return true; 4289 } 4290#if DEBUG_OUTBOUND_EVENT_DETAILS 4291 LOGD("Dropping inconsistent motion pointer up/down or move event: " 4292 "deviceId=%d, source=%08x, actionMasked=%d", 4293 entry->deviceId, entry->source, actionMasked); 4294#endif 4295 return false; 4296 } 4297 4298 case AMOTION_EVENT_ACTION_HOVER_EXIT: { 4299 ssize_t index = findMotionMemento(entry, true /*hovering*/); 4300 if (index >= 0) { 4301 mMotionMementos.removeAt(index); 4302 return true; 4303 } 4304#if DEBUG_OUTBOUND_EVENT_DETAILS 4305 LOGD("Dropping inconsistent motion hover exit event: deviceId=%d, source=%08x", 4306 entry->deviceId, entry->source); 4307#endif 4308 return false; 4309 } 4310 4311 case AMOTION_EVENT_ACTION_HOVER_ENTER: 4312 case AMOTION_EVENT_ACTION_HOVER_MOVE: { 4313 ssize_t index = findMotionMemento(entry, true /*hovering*/); 4314 if (index >= 0) { 4315 mMotionMementos.removeAt(index); 4316 } 4317 addMotionMemento(entry, flags, true /*hovering*/); 4318 return true; 4319 } 4320 4321 default: 4322 return true; 4323 } 4324} 4325 4326ssize_t InputDispatcher::InputState::findKeyMemento(const KeyEntry* entry) const { 4327 for (size_t i = 0; i < mKeyMementos.size(); i++) { 4328 const KeyMemento& memento = mKeyMementos.itemAt(i); 4329 if (memento.deviceId == entry->deviceId 4330 && memento.source == entry->source 4331 && memento.keyCode == entry->keyCode 4332 && memento.scanCode == entry->scanCode) { 4333 return i; 4334 } 4335 } 4336 return -1; 4337} 4338 4339ssize_t InputDispatcher::InputState::findMotionMemento(const MotionEntry* entry, 4340 bool hovering) const { 4341 for (size_t i = 0; i < mMotionMementos.size(); i++) { 4342 const MotionMemento& memento = mMotionMementos.itemAt(i); 4343 if (memento.deviceId == entry->deviceId 4344 && memento.source == entry->source 4345 && memento.hovering == hovering) { 4346 return i; 4347 } 4348 } 4349 return -1; 4350} 4351 4352void InputDispatcher::InputState::addKeyMemento(const KeyEntry* entry, int32_t flags) { 4353 mKeyMementos.push(); 4354 KeyMemento& memento = mKeyMementos.editTop(); 4355 memento.deviceId = entry->deviceId; 4356 memento.source = entry->source; 4357 memento.keyCode = entry->keyCode; 4358 memento.scanCode = entry->scanCode; 4359 memento.flags = flags; 4360 memento.downTime = entry->downTime; 4361} 4362 4363void InputDispatcher::InputState::addMotionMemento(const MotionEntry* entry, 4364 int32_t flags, bool hovering) { 4365 mMotionMementos.push(); 4366 MotionMemento& memento = mMotionMementos.editTop(); 4367 memento.deviceId = entry->deviceId; 4368 memento.source = entry->source; 4369 memento.flags = flags; 4370 memento.xPrecision = entry->xPrecision; 4371 memento.yPrecision = entry->yPrecision; 4372 memento.downTime = entry->downTime; 4373 memento.setPointers(entry); 4374 memento.hovering = hovering; 4375} 4376 4377void InputDispatcher::InputState::MotionMemento::setPointers(const MotionEntry* entry) { 4378 pointerCount = entry->pointerCount; 4379 for (uint32_t i = 0; i < entry->pointerCount; i++) { 4380 pointerProperties[i].copyFrom(entry->pointerProperties[i]); 4381 pointerCoords[i].copyFrom(entry->lastSample->pointerCoords[i]); 4382 } 4383} 4384 4385void InputDispatcher::InputState::synthesizeCancelationEvents(nsecs_t currentTime, 4386 Vector<EventEntry*>& outEvents, const CancelationOptions& options) { 4387 for (size_t i = 0; i < mKeyMementos.size(); i++) { 4388 const KeyMemento& memento = mKeyMementos.itemAt(i); 4389 if (shouldCancelKey(memento, options)) { 4390 outEvents.push(new KeyEntry(currentTime, 4391 memento.deviceId, memento.source, 0, 4392 AKEY_EVENT_ACTION_UP, memento.flags | AKEY_EVENT_FLAG_CANCELED, 4393 memento.keyCode, memento.scanCode, 0, 0, memento.downTime)); 4394 } 4395 } 4396 4397 for (size_t i = 0; i < mMotionMementos.size(); i++) { 4398 const MotionMemento& memento = mMotionMementos.itemAt(i); 4399 if (shouldCancelMotion(memento, options)) { 4400 outEvents.push(new MotionEntry(currentTime, 4401 memento.deviceId, memento.source, 0, 4402 memento.hovering 4403 ? AMOTION_EVENT_ACTION_HOVER_EXIT 4404 : AMOTION_EVENT_ACTION_CANCEL, 4405 memento.flags, 0, 0, 0, 4406 memento.xPrecision, memento.yPrecision, memento.downTime, 4407 memento.pointerCount, memento.pointerProperties, memento.pointerCoords)); 4408 } 4409 } 4410} 4411 4412void InputDispatcher::InputState::clear() { 4413 mKeyMementos.clear(); 4414 mMotionMementos.clear(); 4415 mFallbackKeys.clear(); 4416} 4417 4418void InputDispatcher::InputState::copyPointerStateTo(InputState& other) const { 4419 for (size_t i = 0; i < mMotionMementos.size(); i++) { 4420 const MotionMemento& memento = mMotionMementos.itemAt(i); 4421 if (memento.source & AINPUT_SOURCE_CLASS_POINTER) { 4422 for (size_t j = 0; j < other.mMotionMementos.size(); ) { 4423 const MotionMemento& otherMemento = other.mMotionMementos.itemAt(j); 4424 if (memento.deviceId == otherMemento.deviceId 4425 && memento.source == otherMemento.source) { 4426 other.mMotionMementos.removeAt(j); 4427 } else { 4428 j += 1; 4429 } 4430 } 4431 other.mMotionMementos.push(memento); 4432 } 4433 } 4434} 4435 4436int32_t InputDispatcher::InputState::getFallbackKey(int32_t originalKeyCode) { 4437 ssize_t index = mFallbackKeys.indexOfKey(originalKeyCode); 4438 return index >= 0 ? mFallbackKeys.valueAt(index) : -1; 4439} 4440 4441void InputDispatcher::InputState::setFallbackKey(int32_t originalKeyCode, 4442 int32_t fallbackKeyCode) { 4443 ssize_t index = mFallbackKeys.indexOfKey(originalKeyCode); 4444 if (index >= 0) { 4445 mFallbackKeys.replaceValueAt(index, fallbackKeyCode); 4446 } else { 4447 mFallbackKeys.add(originalKeyCode, fallbackKeyCode); 4448 } 4449} 4450 4451void InputDispatcher::InputState::removeFallbackKey(int32_t originalKeyCode) { 4452 mFallbackKeys.removeItem(originalKeyCode); 4453} 4454 4455bool InputDispatcher::InputState::shouldCancelKey(const KeyMemento& memento, 4456 const CancelationOptions& options) { 4457 if (options.keyCode != -1 && memento.keyCode != options.keyCode) { 4458 return false; 4459 } 4460 4461 if (options.deviceId != -1 && memento.deviceId != options.deviceId) { 4462 return false; 4463 } 4464 4465 switch (options.mode) { 4466 case CancelationOptions::CANCEL_ALL_EVENTS: 4467 case CancelationOptions::CANCEL_NON_POINTER_EVENTS: 4468 return true; 4469 case CancelationOptions::CANCEL_FALLBACK_EVENTS: 4470 return memento.flags & AKEY_EVENT_FLAG_FALLBACK; 4471 default: 4472 return false; 4473 } 4474} 4475 4476bool InputDispatcher::InputState::shouldCancelMotion(const MotionMemento& memento, 4477 const CancelationOptions& options) { 4478 if (options.deviceId != -1 && memento.deviceId != options.deviceId) { 4479 return false; 4480 } 4481 4482 switch (options.mode) { 4483 case CancelationOptions::CANCEL_ALL_EVENTS: 4484 return true; 4485 case CancelationOptions::CANCEL_POINTER_EVENTS: 4486 return memento.source & AINPUT_SOURCE_CLASS_POINTER; 4487 case CancelationOptions::CANCEL_NON_POINTER_EVENTS: 4488 return !(memento.source & AINPUT_SOURCE_CLASS_POINTER); 4489 default: 4490 return false; 4491 } 4492} 4493 4494 4495// --- InputDispatcher::Connection --- 4496 4497InputDispatcher::Connection::Connection(const sp<InputChannel>& inputChannel, 4498 const sp<InputWindowHandle>& inputWindowHandle) : 4499 status(STATUS_NORMAL), inputChannel(inputChannel), inputWindowHandle(inputWindowHandle), 4500 inputPublisher(inputChannel), 4501 lastEventTime(LONG_LONG_MAX), lastDispatchTime(LONG_LONG_MAX) { 4502} 4503 4504InputDispatcher::Connection::~Connection() { 4505} 4506 4507status_t InputDispatcher::Connection::initialize() { 4508 return inputPublisher.initialize(); 4509} 4510 4511const char* InputDispatcher::Connection::getStatusLabel() const { 4512 switch (status) { 4513 case STATUS_NORMAL: 4514 return "NORMAL"; 4515 4516 case STATUS_BROKEN: 4517 return "BROKEN"; 4518 4519 case STATUS_ZOMBIE: 4520 return "ZOMBIE"; 4521 4522 default: 4523 return "UNKNOWN"; 4524 } 4525} 4526 4527InputDispatcher::DispatchEntry* InputDispatcher::Connection::findQueuedDispatchEntryForEvent( 4528 const EventEntry* eventEntry) const { 4529 for (DispatchEntry* dispatchEntry = outboundQueue.tail; dispatchEntry; 4530 dispatchEntry = dispatchEntry->prev) { 4531 if (dispatchEntry->eventEntry == eventEntry) { 4532 return dispatchEntry; 4533 } 4534 } 4535 return NULL; 4536} 4537 4538 4539// --- InputDispatcher::CommandEntry --- 4540 4541InputDispatcher::CommandEntry::CommandEntry(Command command) : 4542 command(command), eventTime(0), keyEntry(NULL), userActivityEventType(0), handled(false) { 4543} 4544 4545InputDispatcher::CommandEntry::~CommandEntry() { 4546} 4547 4548 4549// --- InputDispatcher::TouchState --- 4550 4551InputDispatcher::TouchState::TouchState() : 4552 down(false), split(false), deviceId(-1), source(0) { 4553} 4554 4555InputDispatcher::TouchState::~TouchState() { 4556} 4557 4558void InputDispatcher::TouchState::reset() { 4559 down = false; 4560 split = false; 4561 deviceId = -1; 4562 source = 0; 4563 windows.clear(); 4564} 4565 4566void InputDispatcher::TouchState::copyFrom(const TouchState& other) { 4567 down = other.down; 4568 split = other.split; 4569 deviceId = other.deviceId; 4570 source = other.source; 4571 windows = other.windows; 4572} 4573 4574void InputDispatcher::TouchState::addOrUpdateWindow(const sp<InputWindowHandle>& windowHandle, 4575 int32_t targetFlags, BitSet32 pointerIds) { 4576 if (targetFlags & InputTarget::FLAG_SPLIT) { 4577 split = true; 4578 } 4579 4580 for (size_t i = 0; i < windows.size(); i++) { 4581 TouchedWindow& touchedWindow = windows.editItemAt(i); 4582 if (touchedWindow.windowHandle == windowHandle) { 4583 touchedWindow.targetFlags |= targetFlags; 4584 if (targetFlags & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT) { 4585 touchedWindow.targetFlags &= ~InputTarget::FLAG_DISPATCH_AS_IS; 4586 } 4587 touchedWindow.pointerIds.value |= pointerIds.value; 4588 return; 4589 } 4590 } 4591 4592 windows.push(); 4593 4594 TouchedWindow& touchedWindow = windows.editTop(); 4595 touchedWindow.windowHandle = windowHandle; 4596 touchedWindow.targetFlags = targetFlags; 4597 touchedWindow.pointerIds = pointerIds; 4598} 4599 4600void InputDispatcher::TouchState::filterNonAsIsTouchWindows() { 4601 for (size_t i = 0 ; i < windows.size(); ) { 4602 TouchedWindow& window = windows.editItemAt(i); 4603 if (window.targetFlags & (InputTarget::FLAG_DISPATCH_AS_IS 4604 | InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER)) { 4605 window.targetFlags &= ~InputTarget::FLAG_DISPATCH_MASK; 4606 window.targetFlags |= InputTarget::FLAG_DISPATCH_AS_IS; 4607 i += 1; 4608 } else { 4609 windows.removeAt(i); 4610 } 4611 } 4612} 4613 4614sp<InputWindowHandle> InputDispatcher::TouchState::getFirstForegroundWindowHandle() const { 4615 for (size_t i = 0; i < windows.size(); i++) { 4616 const TouchedWindow& window = windows.itemAt(i); 4617 if (window.targetFlags & InputTarget::FLAG_FOREGROUND) { 4618 return window.windowHandle; 4619 } 4620 } 4621 return NULL; 4622} 4623 4624bool InputDispatcher::TouchState::isSlippery() const { 4625 // Must have exactly one foreground window. 4626 bool haveSlipperyForegroundWindow = false; 4627 for (size_t i = 0; i < windows.size(); i++) { 4628 const TouchedWindow& window = windows.itemAt(i); 4629 if (window.targetFlags & InputTarget::FLAG_FOREGROUND) { 4630 if (haveSlipperyForegroundWindow || !(window.windowHandle->layoutParamsFlags 4631 & InputWindowHandle::FLAG_SLIPPERY)) { 4632 return false; 4633 } 4634 haveSlipperyForegroundWindow = true; 4635 } 4636 } 4637 return haveSlipperyForegroundWindow; 4638} 4639 4640 4641// --- InputDispatcherThread --- 4642 4643InputDispatcherThread::InputDispatcherThread(const sp<InputDispatcherInterface>& dispatcher) : 4644 Thread(/*canCallJava*/ true), mDispatcher(dispatcher) { 4645} 4646 4647InputDispatcherThread::~InputDispatcherThread() { 4648} 4649 4650bool InputDispatcherThread::threadLoop() { 4651 mDispatcher->dispatchOnce(); 4652 return true; 4653} 4654 4655} // namespace android 4656