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