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