InputDispatcher.cpp revision 8564c8da817a845353d213acd8636b76f567b234
1b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown/*
2b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown * Copyright (C) 2010 The Android Open Source Project
3b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown *
4b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown * Licensed under the Apache License, Version 2.0 (the "License");
5b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown * you may not use this file except in compliance with the License.
6b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown * You may obtain a copy of the License at
7b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown *
8b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown *      http://www.apache.org/licenses/LICENSE-2.0
9b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown *
10b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown * Unless required by applicable law or agreed to in writing, software
11b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown * distributed under the License is distributed on an "AS IS" BASIS,
12b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown * See the License for the specific language governing permissions and
14b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown * limitations under the License.
15b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown */
16b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown
1746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#define LOG_TAG "InputDispatcher"
1846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
1946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown//#define LOG_NDEBUG 0
2046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
2146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown// Log detailed debug messages about each inbound event notification to the dispatcher.
22349703effce5acc53ed96f7ed8556131f0c65e18Jeff Brown#define DEBUG_INBOUND_EVENT_DETAILS 0
2346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
2446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown// Log detailed debug messages about each outbound event processed by the dispatcher.
25349703effce5acc53ed96f7ed8556131f0c65e18Jeff Brown#define DEBUG_OUTBOUND_EVENT_DETAILS 0
2646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
2746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown// Log debug messages about batching.
28349703effce5acc53ed96f7ed8556131f0c65e18Jeff Brown#define DEBUG_BATCHING 0
2946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
3046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown// Log debug messages about the dispatch cycle.
31349703effce5acc53ed96f7ed8556131f0c65e18Jeff Brown#define DEBUG_DISPATCH_CYCLE 0
3246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
339c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown// Log debug messages about registrations.
34349703effce5acc53ed96f7ed8556131f0c65e18Jeff Brown#define DEBUG_REGISTRATION 0
359c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown
3646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown// Log debug messages about performance statistics.
37349703effce5acc53ed96f7ed8556131f0c65e18Jeff Brown#define DEBUG_PERFORMANCE_STATISTICS 0
3846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
397fbdc84e87dd3a0e196b9803bb04495d11e9cb8aJeff Brown// Log debug messages about input event injection.
40349703effce5acc53ed96f7ed8556131f0c65e18Jeff Brown#define DEBUG_INJECTION 0
417fbdc84e87dd3a0e196b9803bb04495d11e9cb8aJeff Brown
42ae9fc03bdccda709101291bbcd3beaa5b6daebfcJeff Brown// Log debug messages about input event throttling.
43ae9fc03bdccda709101291bbcd3beaa5b6daebfcJeff Brown#define DEBUG_THROTTLING 0
44ae9fc03bdccda709101291bbcd3beaa5b6daebfcJeff Brown
45b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown// Log debug messages about input focus tracking.
46b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown#define DEBUG_FOCUS 0
47b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
48b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown// Log debug messages about the app switch latency optimization.
49b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown#define DEBUG_APP_SWITCH 0
50b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
51a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown// Log debug messages about hover events.
52a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown#define DEBUG_HOVER 0
53a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown
54b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown#include "InputDispatcher.h"
55b4ff35df5c04aec71fce7e90a6d6f9ef7180c2adJeff Brown
5646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#include <cutils/log.h>
57b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown#include <ui/PowerManager.h>
5846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
5946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#include <stddef.h>
6046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#include <unistd.h>
6146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#include <errno.h>
6246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#include <limits.h>
6346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
64f2f487183052865d50c004a835360be1728b5a52Jeff Brown#define INDENT "  "
65f2f487183052865d50c004a835360be1728b5a52Jeff Brown#define INDENT2 "    "
66f2f487183052865d50c004a835360be1728b5a52Jeff Brown
6746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownnamespace android {
6846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
69b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown// Default input dispatching timeout if there is no focused application or paused window
70b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown// from which to determine an appropriate dispatching timeout.
71b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brownconst nsecs_t DEFAULT_INPUT_DISPATCHING_TIMEOUT = 5000 * 1000000LL; // 5 sec
72b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
73b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown// Amount of time to allow for all pending events to be processed when an app switch
74b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown// key is on the way.  This is used to preempt input dispatch and drop input events
75b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown// when an application takes too long to respond and the user has pressed an app switch key.
76b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brownconst nsecs_t APP_SWITCH_TIMEOUT = 500 * 1000000LL; // 0.5sec
77b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
78928e054931d357326613c78e62f4d850b7c442ffJeff Brown// Amount of time to allow for an event to be dispatched (measured since its eventTime)
79928e054931d357326613c78e62f4d850b7c442ffJeff Brown// before considering it stale and dropping it.
80928e054931d357326613c78e62f4d850b7c442ffJeff Brownconst nsecs_t STALE_EVENT_TIMEOUT = 10000 * 1000000LL; // 10sec
81928e054931d357326613c78e62f4d850b7c442ffJeff Brown
824e91a180be46c0c7c3bf398d4df4cbe2404216b5Jeff Brown// Motion samples that are received within this amount of time are simply coalesced
834e91a180be46c0c7c3bf398d4df4cbe2404216b5Jeff Brown// when batched instead of being appended.  This is done because some drivers update
844e91a180be46c0c7c3bf398d4df4cbe2404216b5Jeff Brown// the location of pointers one at a time instead of all at once.
854e91a180be46c0c7c3bf398d4df4cbe2404216b5Jeff Brown// For example, when there are 10 fingers down, the input dispatcher may receive 10
864e91a180be46c0c7c3bf398d4df4cbe2404216b5Jeff Brown// samples in quick succession with only one finger's location changed in each sample.
874e91a180be46c0c7c3bf398d4df4cbe2404216b5Jeff Brown//
884e91a180be46c0c7c3bf398d4df4cbe2404216b5Jeff Brown// This value effectively imposes an upper bound on the touch sampling rate.
894e91a180be46c0c7c3bf398d4df4cbe2404216b5Jeff Brown// Touch sensors typically have a 50Hz - 200Hz sampling rate, so we expect distinct
904e91a180be46c0c7c3bf398d4df4cbe2404216b5Jeff Brown// samples to become available 5-20ms apart but individual finger reports can trickle
914e91a180be46c0c7c3bf398d4df4cbe2404216b5Jeff Brown// in over a period of 2-4ms or so.
924e91a180be46c0c7c3bf398d4df4cbe2404216b5Jeff Brown//
934e91a180be46c0c7c3bf398d4df4cbe2404216b5Jeff Brown// Empirical testing shows that a 2ms coalescing interval (500Hz) is not enough,
944e91a180be46c0c7c3bf398d4df4cbe2404216b5Jeff Brown// a 3ms coalescing interval (333Hz) works well most of the time and doesn't introduce
954e91a180be46c0c7c3bf398d4df4cbe2404216b5Jeff Brown// significant quantization noise on current hardware.
964e91a180be46c0c7c3bf398d4df4cbe2404216b5Jeff Brownconst nsecs_t MOTION_SAMPLE_COALESCE_INTERVAL = 3 * 1000000LL; // 3ms, 333Hz
974e91a180be46c0c7c3bf398d4df4cbe2404216b5Jeff Brown
9846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
997fbdc84e87dd3a0e196b9803bb04495d11e9cb8aJeff Brownstatic inline nsecs_t now() {
1007fbdc84e87dd3a0e196b9803bb04495d11e9cb8aJeff Brown    return systemTime(SYSTEM_TIME_MONOTONIC);
1017fbdc84e87dd3a0e196b9803bb04495d11e9cb8aJeff Brown}
1027fbdc84e87dd3a0e196b9803bb04495d11e9cb8aJeff Brown
103b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brownstatic inline const char* toString(bool value) {
104b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    return value ? "true" : "false";
105b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown}
106b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
10701ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brownstatic inline int32_t getMotionEventActionPointerIndex(int32_t action) {
10801ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    return (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK)
10901ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown            >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
11001ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown}
11101ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown
11201ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brownstatic bool isValidKeyAction(int32_t action) {
11301ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    switch (action) {
11401ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    case AKEY_EVENT_ACTION_DOWN:
11501ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    case AKEY_EVENT_ACTION_UP:
11601ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown        return true;
11701ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    default:
11801ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown        return false;
11901ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    }
12001ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown}
12101ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown
12201ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brownstatic bool validateKeyEvent(int32_t action) {
12301ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    if (! isValidKeyAction(action)) {
12401ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown        LOGE("Key event has invalid action code 0x%x", action);
12501ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown        return false;
12601ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    }
12701ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    return true;
12801ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown}
12901ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown
130b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brownstatic bool isValidMotionAction(int32_t action, size_t pointerCount) {
13101ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    switch (action & AMOTION_EVENT_ACTION_MASK) {
13201ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    case AMOTION_EVENT_ACTION_DOWN:
13301ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    case AMOTION_EVENT_ACTION_UP:
13401ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    case AMOTION_EVENT_ACTION_CANCEL:
13501ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    case AMOTION_EVENT_ACTION_MOVE:
13601ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    case AMOTION_EVENT_ACTION_OUTSIDE:
137a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown    case AMOTION_EVENT_ACTION_HOVER_ENTER:
138cc0c159e9b3dd4e0f48da0ce3e33d2c68a651413Jeff Brown    case AMOTION_EVENT_ACTION_HOVER_MOVE:
139a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown    case AMOTION_EVENT_ACTION_HOVER_EXIT:
14033bbfd2232ea9eaae9a9d87a05a95a430f09bd83Jeff Brown    case AMOTION_EVENT_ACTION_SCROLL:
14101ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown        return true;
142b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown    case AMOTION_EVENT_ACTION_POINTER_DOWN:
143b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown    case AMOTION_EVENT_ACTION_POINTER_UP: {
144b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown        int32_t index = getMotionEventActionPointerIndex(action);
145b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown        return index >= 0 && size_t(index) < pointerCount;
146b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown    }
14701ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    default:
14801ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown        return false;
14901ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    }
15001ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown}
15101ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown
15201ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brownstatic bool validateMotionEvent(int32_t action, size_t pointerCount,
153fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        const PointerProperties* pointerProperties) {
154b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown    if (! isValidMotionAction(action, pointerCount)) {
15501ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown        LOGE("Motion event has invalid action code 0x%x", action);
15601ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown        return false;
15701ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    }
15801ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    if (pointerCount < 1 || pointerCount > MAX_POINTERS) {
15901ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown        LOGE("Motion event has invalid pointer count %d; value must be between 1 and %d.",
16001ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown                pointerCount, MAX_POINTERS);
16101ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown        return false;
16201ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    }
163c3db858de9fa152480b9cf53c8c0cb793a280722Jeff Brown    BitSet32 pointerIdBits;
16401ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    for (size_t i = 0; i < pointerCount; i++) {
165fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        int32_t id = pointerProperties[i].id;
166c3db858de9fa152480b9cf53c8c0cb793a280722Jeff Brown        if (id < 0 || id > MAX_POINTER_ID) {
16701ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown            LOGE("Motion event has invalid pointer id %d; value must be between 0 and %d",
168c3db858de9fa152480b9cf53c8c0cb793a280722Jeff Brown                    id, MAX_POINTER_ID);
16901ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown            return false;
17001ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown        }
171c3db858de9fa152480b9cf53c8c0cb793a280722Jeff Brown        if (pointerIdBits.hasBit(id)) {
172c3db858de9fa152480b9cf53c8c0cb793a280722Jeff Brown            LOGE("Motion event has duplicate pointer id %d", id);
173c3db858de9fa152480b9cf53c8c0cb793a280722Jeff Brown            return false;
174c3db858de9fa152480b9cf53c8c0cb793a280722Jeff Brown        }
175c3db858de9fa152480b9cf53c8c0cb793a280722Jeff Brown        pointerIdBits.markBit(id);
17601ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    }
17701ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    return true;
17801ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown}
17901ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown
180fbf097732137a32930d151f7ba6816a5b870c32aJeff Brownstatic void dumpRegion(String8& dump, const SkRegion& region) {
181fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown    if (region.isEmpty()) {
182fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown        dump.append("<empty>");
183fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown        return;
184fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown    }
185fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown
186fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown    bool first = true;
187fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown    for (SkRegion::Iterator it(region); !it.done(); it.next()) {
188fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown        if (first) {
189fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown            first = false;
190fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown        } else {
191fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown            dump.append("|");
192fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown        }
193fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown        const SkIRect& rect = it.rect();
194fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown        dump.appendFormat("[%d,%d][%d,%d]", rect.fLeft, rect.fTop, rect.fRight, rect.fBottom);
195fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown    }
196fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown}
197fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown
198b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
19946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown// --- InputDispatcher ---
20046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
2019c3cda04d969912bc46184f2b326d1db95e0aba5Jeff BrownInputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy) :
202b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    mPolicy(policy),
203928e054931d357326613c78e62f4d850b7c442ffJeff Brown    mPendingEvent(NULL), mAppSwitchSawKeyDown(false), mAppSwitchDueTime(LONG_LONG_MAX),
204928e054931d357326613c78e62f4d850b7c442ffJeff Brown    mNextUnblockedEvent(NULL),
2050029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown    mDispatchEnabled(true), mDispatchFrozen(false), mInputFilterEnabled(false),
206b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    mCurrentInputTargetsValid(false),
2079302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown    mInputTargetWaitCause(INPUT_TARGET_WAIT_CAUSE_NONE) {
2084fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown    mLooper = new Looper(false);
20946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
21046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    mKeyRepeatState.lastKeyEntry = NULL;
2119c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown
212214eaf48878bba00cbd5831871bcbd82632b6e34Jeff Brown    policy->getDispatcherConfiguration(&mConfig);
213214eaf48878bba00cbd5831871bcbd82632b6e34Jeff Brown
214214eaf48878bba00cbd5831871bcbd82632b6e34Jeff Brown    mThrottleState.minTimeBetweenEvents = 1000000000LL / mConfig.maxEventsPerSecond;
215ae9fc03bdccda709101291bbcd3beaa5b6daebfcJeff Brown    mThrottleState.lastDeviceId = -1;
216ae9fc03bdccda709101291bbcd3beaa5b6daebfcJeff Brown
217ae9fc03bdccda709101291bbcd3beaa5b6daebfcJeff Brown#if DEBUG_THROTTLING
218ae9fc03bdccda709101291bbcd3beaa5b6daebfcJeff Brown    mThrottleState.originalSampleCount = 0;
2195baa3a62a97544669fba6d65a11c07f252e654ddSteve Block    ALOGD("Throttling - Max events per second = %d", mConfig.maxEventsPerSecond);
220ae9fc03bdccda709101291bbcd3beaa5b6daebfcJeff Brown#endif
22146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
22246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
22346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff BrownInputDispatcher::~InputDispatcher() {
224b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    { // acquire lock
225b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        AutoMutex _l(mLock);
22646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
227b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        resetKeyRepeatLocked();
22854a1825121d006d4a4dcbbadf4eac9910f44ef8cJeff Brown        releasePendingEventLocked();
229b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        drainInboundQueueLocked();
23046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
23146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
232b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    while (mConnectionsByReceiveFd.size() != 0) {
233b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        unregisterInputChannel(mConnectionsByReceiveFd.valueAt(0)->inputChannel);
23446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
23546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
23646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
23746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownvoid InputDispatcher::dispatchOnce() {
23846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    nsecs_t nextWakeupTime = LONG_LONG_MAX;
23946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    { // acquire lock
24046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        AutoMutex _l(mLock);
241214eaf48878bba00cbd5831871bcbd82632b6e34Jeff Brown        dispatchOnceInnerLocked(&nextWakeupTime);
24246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
243b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        if (runCommandsLockedInterruptible()) {
244b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown            nextWakeupTime = LONG_LONG_MIN;  // force next poll to wake up immediately
245b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        }
246b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    } // release lock
247b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
248b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    // Wait for callback or timeout or wake.  (make sure we round up, not down)
249b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    nsecs_t currentTime = now();
250aa3855d5836d2a2d83baafdf6e40caf90d3dad1cJeff Brown    int timeoutMillis = toMillisecondTimeoutDelay(currentTime, nextWakeupTime);
2514fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown    mLooper->pollOnce(timeoutMillis);
252b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown}
253b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
254214eaf48878bba00cbd5831871bcbd82632b6e34Jeff Brownvoid InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) {
255b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    nsecs_t currentTime = now();
256b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
257b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    // Reset the key repeat timer whenever we disallow key events, even if the next event
258b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    // is not a key.  This is to ensure that we abort a key repeat if the device is just coming
259b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    // out of sleep.
260214eaf48878bba00cbd5831871bcbd82632b6e34Jeff Brown    if (!mPolicy->isKeyRepeatEnabled()) {
261b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        resetKeyRepeatLocked();
262b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    }
263b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
264b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    // If dispatching is frozen, do not process timeouts or try to deliver any new events.
265b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    if (mDispatchFrozen) {
266b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown#if DEBUG_FOCUS
2675baa3a62a97544669fba6d65a11c07f252e654ddSteve Block        ALOGD("Dispatch frozen.  Waiting some more.");
268b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown#endif
269b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        return;
270b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    }
27146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
272b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    // Optimize latency of app switches.
273b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    // Essentially we start a short timeout when an app switch key (HOME / ENDCALL) has
274b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    // been pressed.  When it expires, we preempt dispatch and drop all other pending events.
275b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    bool isAppSwitchDue = mAppSwitchDueTime <= currentTime;
276b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    if (mAppSwitchDueTime < *nextWakeupTime) {
277b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        *nextWakeupTime = mAppSwitchDueTime;
278b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    }
27946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
280b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    // Ready to start a new event.
281b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    // If we don't already have a pending event, go grab one.
282b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    if (! mPendingEvent) {
283b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        if (mInboundQueue.isEmpty()) {
284b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown            if (isAppSwitchDue) {
285b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown                // The inbound queue is empty so the app switch key we were waiting
286b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown                // for will never arrive.  Stop waiting for it.
287b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown                resetPendingAppSwitchLocked(false);
288b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown                isAppSwitchDue = false;
289b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown            }
290b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
291b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown            // Synthesize a key repeat if appropriate.
292b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown            if (mKeyRepeatState.lastKeyEntry) {
293b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown                if (currentTime >= mKeyRepeatState.nextRepeatTime) {
294214eaf48878bba00cbd5831871bcbd82632b6e34Jeff Brown                    mPendingEvent = synthesizeKeyRepeatLocked(currentTime);
295b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown                } else {
296b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown                    if (mKeyRepeatState.nextRepeatTime < *nextWakeupTime) {
297b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown                        *nextWakeupTime = mKeyRepeatState.nextRepeatTime;
29846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown                    }
29946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown                }
300b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown            }
301cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown
302cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown            // Nothing to do if there is no pending event.
303b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown            if (! mPendingEvent) {
304cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown                if (mActiveConnections.isEmpty()) {
305cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown                    dispatchIdleLocked();
306cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown                }
307b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown                return;
308b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown            }
309b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        } else {
310b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown            // Inbound queue has at least one entry.
311ac386073df2514b79a2ca169f4a89f129733002fJeff Brown            EventEntry* entry = mInboundQueue.head;
312b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
313b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown            // Throttle the entry if it is a move event and there are no
314b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown            // other events behind it in the queue.  Due to movement batching, additional
315b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown            // samples may be appended to this event by the time the throttling timeout
316b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown            // expires.
317b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown            // TODO Make this smarter and consider throttling per device independently.
318b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown            if (entry->type == EventEntry::TYPE_MOTION
319b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown                    && !isAppSwitchDue
320b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown                    && mDispatchEnabled
321b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown                    && (entry->policyFlags & POLICY_FLAG_PASS_TO_USER)
322b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown                    && !entry->isInjected()) {
323b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown                MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
324b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown                int32_t deviceId = motionEntry->deviceId;
325b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown                uint32_t source = motionEntry->source;
326b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown                if (! isAppSwitchDue
327ac386073df2514b79a2ca169f4a89f129733002fJeff Brown                        && !motionEntry->next // exactly one event, no successors
328cc0c159e9b3dd4e0f48da0ce3e33d2c68a651413Jeff Brown                        && (motionEntry->action == AMOTION_EVENT_ACTION_MOVE
329cc0c159e9b3dd4e0f48da0ce3e33d2c68a651413Jeff Brown                                || motionEntry->action == AMOTION_EVENT_ACTION_HOVER_MOVE)
330b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown                        && deviceId == mThrottleState.lastDeviceId
331b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown                        && source == mThrottleState.lastSource) {
332b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown                    nsecs_t nextTime = mThrottleState.lastEventTime
333b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown                            + mThrottleState.minTimeBetweenEvents;
334b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown                    if (currentTime < nextTime) {
335b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown                        // Throttle it!
336ae9fc03bdccda709101291bbcd3beaa5b6daebfcJeff Brown#if DEBUG_THROTTLING
3375baa3a62a97544669fba6d65a11c07f252e654ddSteve Block                        ALOGD("Throttling - Delaying motion event for "
3389065504a63d6bf37bf621191fda1d1fe4da76ee3Jeff Brown                                "device %d, source 0x%08x by up to %0.3fms.",
339b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown                                deviceId, source, (nextTime - currentTime) * 0.000001);
340ae9fc03bdccda709101291bbcd3beaa5b6daebfcJeff Brown#endif
341b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown                        if (nextTime < *nextWakeupTime) {
342b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown                            *nextWakeupTime = nextTime;
343ae9fc03bdccda709101291bbcd3beaa5b6daebfcJeff Brown                        }
344b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown                        if (mThrottleState.originalSampleCount == 0) {
345b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown                            mThrottleState.originalSampleCount =
346b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown                                    motionEntry->countSamples();
347b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown                        }
348b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown                        return;
349ae9fc03bdccda709101291bbcd3beaa5b6daebfcJeff Brown                    }
350b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown                }
351ae9fc03bdccda709101291bbcd3beaa5b6daebfcJeff Brown
352ae9fc03bdccda709101291bbcd3beaa5b6daebfcJeff Brown#if DEBUG_THROTTLING
353b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown                if (mThrottleState.originalSampleCount != 0) {
354b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown                    uint32_t count = motionEntry->countSamples();
3555baa3a62a97544669fba6d65a11c07f252e654ddSteve Block                    ALOGD("Throttling - Motion event sample count grew by %d from %d to %d.",
356b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown                            count - mThrottleState.originalSampleCount,
357b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown                            mThrottleState.originalSampleCount, count);
358b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown                    mThrottleState.originalSampleCount = 0;
359b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown                }
360ae9fc03bdccda709101291bbcd3beaa5b6daebfcJeff Brown#endif
361ae9fc03bdccda709101291bbcd3beaa5b6daebfcJeff Brown
362f634ded277f246bd9568e9b7dcad40790767c6abmakarand.karvekar                mThrottleState.lastEventTime = currentTime;
363b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown                mThrottleState.lastDeviceId = deviceId;
364b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown                mThrottleState.lastSource = source;
365b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown            }
366ae9fc03bdccda709101291bbcd3beaa5b6daebfcJeff Brown
367b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown            mInboundQueue.dequeue(entry);
368b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown            mPendingEvent = entry;
369b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        }
370e2fe69edc009a0e0348e5351cf83062224e011acJeff Brown
371e2fe69edc009a0e0348e5351cf83062224e011acJeff Brown        // Poke user activity for this event.
372e2fe69edc009a0e0348e5351cf83062224e011acJeff Brown        if (mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER) {
373e2fe69edc009a0e0348e5351cf83062224e011acJeff Brown            pokeUserActivityLocked(mPendingEvent);
374e2fe69edc009a0e0348e5351cf83062224e011acJeff Brown        }
375b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    }
37646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
377b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    // Now we have an event to dispatch.
378928e054931d357326613c78e62f4d850b7c442ffJeff Brown    // All events are eventually dequeued and processed this way, even if we intend to drop them.
379b6110c2de0cd7950360aeb2c248a44e4ea5f33f5Jeff Brown    LOG_ASSERT(mPendingEvent != NULL);
38054a1825121d006d4a4dcbbadf4eac9910f44ef8cJeff Brown    bool done = false;
381b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown    DropReason dropReason = DROP_REASON_NOT_DROPPED;
382b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown    if (!(mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER)) {
383b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown        dropReason = DROP_REASON_POLICY;
384b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown    } else if (!mDispatchEnabled) {
385b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown        dropReason = DROP_REASON_DISABLED;
386b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown    }
387928e054931d357326613c78e62f4d850b7c442ffJeff Brown
388928e054931d357326613c78e62f4d850b7c442ffJeff Brown    if (mNextUnblockedEvent == mPendingEvent) {
389928e054931d357326613c78e62f4d850b7c442ffJeff Brown        mNextUnblockedEvent = NULL;
390928e054931d357326613c78e62f4d850b7c442ffJeff Brown    }
391928e054931d357326613c78e62f4d850b7c442ffJeff Brown
392b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    switch (mPendingEvent->type) {
393b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    case EventEntry::TYPE_CONFIGURATION_CHANGED: {
394b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        ConfigurationChangedEntry* typedEntry =
395b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown                static_cast<ConfigurationChangedEntry*>(mPendingEvent);
39654a1825121d006d4a4dcbbadf4eac9910f44ef8cJeff Brown        done = dispatchConfigurationChangedLocked(currentTime, typedEntry);
397b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown        dropReason = DROP_REASON_NOT_DROPPED; // configuration changes are never dropped
398b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        break;
399b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    }
40046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
40165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    case EventEntry::TYPE_DEVICE_RESET: {
40265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        DeviceResetEntry* typedEntry =
40365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown                static_cast<DeviceResetEntry*>(mPendingEvent);
40465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        done = dispatchDeviceResetLocked(currentTime, typedEntry);
40565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        dropReason = DROP_REASON_NOT_DROPPED; // device resets are never dropped
40665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        break;
40765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    }
40865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
409b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    case EventEntry::TYPE_KEY: {
410b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        KeyEntry* typedEntry = static_cast<KeyEntry*>(mPendingEvent);
411b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown        if (isAppSwitchDue) {
412b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown            if (isAppSwitchKeyEventLocked(typedEntry)) {
413b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown                resetPendingAppSwitchLocked(true);
414b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown                isAppSwitchDue = false;
415b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown            } else if (dropReason == DROP_REASON_NOT_DROPPED) {
416b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown                dropReason = DROP_REASON_APP_SWITCH;
417b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown            }
418b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        }
419928e054931d357326613c78e62f4d850b7c442ffJeff Brown        if (dropReason == DROP_REASON_NOT_DROPPED
420928e054931d357326613c78e62f4d850b7c442ffJeff Brown                && isStaleEventLocked(currentTime, typedEntry)) {
421928e054931d357326613c78e62f4d850b7c442ffJeff Brown            dropReason = DROP_REASON_STALE;
422928e054931d357326613c78e62f4d850b7c442ffJeff Brown        }
423928e054931d357326613c78e62f4d850b7c442ffJeff Brown        if (dropReason == DROP_REASON_NOT_DROPPED && mNextUnblockedEvent) {
424928e054931d357326613c78e62f4d850b7c442ffJeff Brown            dropReason = DROP_REASON_BLOCKED;
425928e054931d357326613c78e62f4d850b7c442ffJeff Brown        }
426214eaf48878bba00cbd5831871bcbd82632b6e34Jeff Brown        done = dispatchKeyLocked(currentTime, typedEntry, &dropReason, nextWakeupTime);
427b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        break;
428b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    }
42946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
430b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    case EventEntry::TYPE_MOTION: {
431b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        MotionEntry* typedEntry = static_cast<MotionEntry*>(mPendingEvent);
432b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown        if (dropReason == DROP_REASON_NOT_DROPPED && isAppSwitchDue) {
433b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown            dropReason = DROP_REASON_APP_SWITCH;
434b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        }
435928e054931d357326613c78e62f4d850b7c442ffJeff Brown        if (dropReason == DROP_REASON_NOT_DROPPED
436928e054931d357326613c78e62f4d850b7c442ffJeff Brown                && isStaleEventLocked(currentTime, typedEntry)) {
437928e054931d357326613c78e62f4d850b7c442ffJeff Brown            dropReason = DROP_REASON_STALE;
438928e054931d357326613c78e62f4d850b7c442ffJeff Brown        }
439928e054931d357326613c78e62f4d850b7c442ffJeff Brown        if (dropReason == DROP_REASON_NOT_DROPPED && mNextUnblockedEvent) {
440928e054931d357326613c78e62f4d850b7c442ffJeff Brown            dropReason = DROP_REASON_BLOCKED;
441928e054931d357326613c78e62f4d850b7c442ffJeff Brown        }
442b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown        done = dispatchMotionLocked(currentTime, typedEntry,
443e20c9e0264190f94324197a8271cf03811a4ca58Jeff Brown                &dropReason, nextWakeupTime);
444b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        break;
445b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    }
4469c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown
447b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    default:
448b6110c2de0cd7950360aeb2c248a44e4ea5f33f5Jeff Brown        LOG_ASSERT(false);
449b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        break;
450b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    }
451ae9fc03bdccda709101291bbcd3beaa5b6daebfcJeff Brown
45254a1825121d006d4a4dcbbadf4eac9910f44ef8cJeff Brown    if (done) {
453b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown        if (dropReason != DROP_REASON_NOT_DROPPED) {
454b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown            dropInboundEventLocked(mPendingEvent, dropReason);
455b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown        }
456b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown
45754a1825121d006d4a4dcbbadf4eac9910f44ef8cJeff Brown        releasePendingEventLocked();
458b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        *nextWakeupTime = LONG_LONG_MIN;  // force next poll to wake up immediately
459b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    }
460b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown}
4619c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown
462cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brownvoid InputDispatcher::dispatchIdleLocked() {
463cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown#if DEBUG_FOCUS
4645baa3a62a97544669fba6d65a11c07f252e654ddSteve Block    ALOGD("Dispatcher idle.  There are no pending events or active connections.");
465cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown#endif
466cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown
467cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown    // Reset targets when idle, to release input channels and other resources
468cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown    // they are holding onto.
469cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown    resetTargetsLocked();
470cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown}
471cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown
472b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brownbool InputDispatcher::enqueueInboundEventLocked(EventEntry* entry) {
473b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    bool needWake = mInboundQueue.isEmpty();
474b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    mInboundQueue.enqueueAtTail(entry);
47546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
476b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    switch (entry->type) {
477b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown    case EventEntry::TYPE_KEY: {
478928e054931d357326613c78e62f4d850b7c442ffJeff Brown        // Optimize app switch latency.
479928e054931d357326613c78e62f4d850b7c442ffJeff Brown        // If the application takes too long to catch up then we drop all events preceding
480928e054931d357326613c78e62f4d850b7c442ffJeff Brown        // the app switch key.
481b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown        KeyEntry* keyEntry = static_cast<KeyEntry*>(entry);
482b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown        if (isAppSwitchKeyEventLocked(keyEntry)) {
483b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown            if (keyEntry->action == AKEY_EVENT_ACTION_DOWN) {
484b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown                mAppSwitchSawKeyDown = true;
485b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown            } else if (keyEntry->action == AKEY_EVENT_ACTION_UP) {
486b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown                if (mAppSwitchSawKeyDown) {
487b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown#if DEBUG_APP_SWITCH
4885baa3a62a97544669fba6d65a11c07f252e654ddSteve Block                    ALOGD("App switch is pending!");
489b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown#endif
490b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown                    mAppSwitchDueTime = keyEntry->eventTime + APP_SWITCH_TIMEOUT;
491b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown                    mAppSwitchSawKeyDown = false;
492b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown                    needWake = true;
493b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown                }
494b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown            }
495b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown        }
496b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        break;
4979c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown    }
498928e054931d357326613c78e62f4d850b7c442ffJeff Brown
499928e054931d357326613c78e62f4d850b7c442ffJeff Brown    case EventEntry::TYPE_MOTION: {
500928e054931d357326613c78e62f4d850b7c442ffJeff Brown        // Optimize case where the current application is unresponsive and the user
501928e054931d357326613c78e62f4d850b7c442ffJeff Brown        // decides to touch a window in a different application.
502928e054931d357326613c78e62f4d850b7c442ffJeff Brown        // If the application takes too long to catch up then we drop all events preceding
503928e054931d357326613c78e62f4d850b7c442ffJeff Brown        // the touch into the other window.
504928e054931d357326613c78e62f4d850b7c442ffJeff Brown        MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
50533bbfd2232ea9eaae9a9d87a05a95a430f09bd83Jeff Brown        if (motionEntry->action == AMOTION_EVENT_ACTION_DOWN
506928e054931d357326613c78e62f4d850b7c442ffJeff Brown                && (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER)
507928e054931d357326613c78e62f4d850b7c442ffJeff Brown                && mInputTargetWaitCause == INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY
5089302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown                && mInputTargetWaitApplicationHandle != NULL) {
50991c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            int32_t x = int32_t(motionEntry->firstSample.pointerCoords[0].
510ebbd5d14ad3b1e762d9fcfa026e19413cc857e05Jeff Brown                    getAxisValue(AMOTION_EVENT_AXIS_X));
51191c69ab01539f7ba28708f41ec1835cc2920d0a0Jeff Brown            int32_t y = int32_t(motionEntry->firstSample.pointerCoords[0].
512ebbd5d14ad3b1e762d9fcfa026e19413cc857e05Jeff Brown                    getAxisValue(AMOTION_EVENT_AXIS_Y));
5139302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown            sp<InputWindowHandle> touchedWindowHandle = findTouchedWindowAtLocked(x, y);
5149302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown            if (touchedWindowHandle != NULL
5159302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown                    && touchedWindowHandle->inputApplicationHandle
5169302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown                            != mInputTargetWaitApplicationHandle) {
517928e054931d357326613c78e62f4d850b7c442ffJeff Brown                // User touched a different application than the one we are waiting on.
518928e054931d357326613c78e62f4d850b7c442ffJeff Brown                // Flag the event, and start pruning the input queue.
519928e054931d357326613c78e62f4d850b7c442ffJeff Brown                mNextUnblockedEvent = motionEntry;
520928e054931d357326613c78e62f4d850b7c442ffJeff Brown                needWake = true;
521928e054931d357326613c78e62f4d850b7c442ffJeff Brown            }
522928e054931d357326613c78e62f4d850b7c442ffJeff Brown        }
523928e054931d357326613c78e62f4d850b7c442ffJeff Brown        break;
524928e054931d357326613c78e62f4d850b7c442ffJeff Brown    }
525b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown    }
5269c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown
527b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    return needWake;
528b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown}
529b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
5309302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brownsp<InputWindowHandle> InputDispatcher::findTouchedWindowAtLocked(int32_t x, int32_t y) {
531928e054931d357326613c78e62f4d850b7c442ffJeff Brown    // Traverse windows from front to back to find touched window.
5329302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown    size_t numWindows = mWindowHandles.size();
533928e054931d357326613c78e62f4d850b7c442ffJeff Brown    for (size_t i = 0; i < numWindows; i++) {
5349302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown        sp<InputWindowHandle> windowHandle = mWindowHandles.itemAt(i);
535cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown        const InputWindowInfo* windowInfo = windowHandle->getInfo();
536cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown        int32_t flags = windowInfo->layoutParamsFlags;
537cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown
538cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown        if (windowInfo->visible) {
539cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown            if (!(flags & InputWindowInfo::FLAG_NOT_TOUCHABLE)) {
540cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown                bool isTouchModal = (flags & (InputWindowInfo::FLAG_NOT_FOCUSABLE
541cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown                        | InputWindowInfo::FLAG_NOT_TOUCH_MODAL)) == 0;
542cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown                if (isTouchModal || windowInfo->touchableRegionContainsPoint(x, y)) {
543928e054931d357326613c78e62f4d850b7c442ffJeff Brown                    // Found window.
5449302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown                    return windowHandle;
545928e054931d357326613c78e62f4d850b7c442ffJeff Brown                }
546928e054931d357326613c78e62f4d850b7c442ffJeff Brown            }
547928e054931d357326613c78e62f4d850b7c442ffJeff Brown        }
548928e054931d357326613c78e62f4d850b7c442ffJeff Brown
549cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown        if (flags & InputWindowInfo::FLAG_SYSTEM_ERROR) {
550928e054931d357326613c78e62f4d850b7c442ffJeff Brown            // Error window is on top but not visible, so touch is dropped.
551928e054931d357326613c78e62f4d850b7c442ffJeff Brown            return NULL;
552928e054931d357326613c78e62f4d850b7c442ffJeff Brown        }
553928e054931d357326613c78e62f4d850b7c442ffJeff Brown    }
554928e054931d357326613c78e62f4d850b7c442ffJeff Brown    return NULL;
555928e054931d357326613c78e62f4d850b7c442ffJeff Brown}
556928e054931d357326613c78e62f4d850b7c442ffJeff Brown
557b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brownvoid InputDispatcher::dropInboundEventLocked(EventEntry* entry, DropReason dropReason) {
558b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown    const char* reason;
559b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown    switch (dropReason) {
560b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown    case DROP_REASON_POLICY:
561e20c9e0264190f94324197a8271cf03811a4ca58Jeff Brown#if DEBUG_INBOUND_EVENT_DETAILS
5625baa3a62a97544669fba6d65a11c07f252e654ddSteve Block        ALOGD("Dropped event because policy consumed it.");
563e20c9e0264190f94324197a8271cf03811a4ca58Jeff Brown#endif
5643122e4488aa0749cbec9890ace22c366e35350c3Jeff Brown        reason = "inbound event was dropped because the policy consumed it";
565b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown        break;
566b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown    case DROP_REASON_DISABLED:
5676215d3ff4b5dfa52a5d8b9a42e343051f31066a5Steve Block        ALOGI("Dropped event because input dispatch is disabled.");
568b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown        reason = "inbound event was dropped because input dispatch is disabled";
569b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown        break;
570b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown    case DROP_REASON_APP_SWITCH:
5716215d3ff4b5dfa52a5d8b9a42e343051f31066a5Steve Block        ALOGI("Dropped event because of pending overdue app switch.");
572b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown        reason = "inbound event was dropped because of pending overdue app switch";
573b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown        break;
574928e054931d357326613c78e62f4d850b7c442ffJeff Brown    case DROP_REASON_BLOCKED:
5756215d3ff4b5dfa52a5d8b9a42e343051f31066a5Steve Block        ALOGI("Dropped event because the current application is not responding and the user "
5768134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown                "has started interacting with a different application.");
577928e054931d357326613c78e62f4d850b7c442ffJeff Brown        reason = "inbound event was dropped because the current application is not responding "
5788134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown                "and the user has started interacting with a different application";
579928e054931d357326613c78e62f4d850b7c442ffJeff Brown        break;
580928e054931d357326613c78e62f4d850b7c442ffJeff Brown    case DROP_REASON_STALE:
5816215d3ff4b5dfa52a5d8b9a42e343051f31066a5Steve Block        ALOGI("Dropped event because it is stale.");
582928e054931d357326613c78e62f4d850b7c442ffJeff Brown        reason = "inbound event was dropped because it is stale";
583928e054931d357326613c78e62f4d850b7c442ffJeff Brown        break;
584b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown    default:
585b6110c2de0cd7950360aeb2c248a44e4ea5f33f5Jeff Brown        LOG_ASSERT(false);
586b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown        return;
587b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown    }
588b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown
589b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown    switch (entry->type) {
590da3d5a91b6b311ed77f2707d4456c1f18b84d73bJeff Brown    case EventEntry::TYPE_KEY: {
591da3d5a91b6b311ed77f2707d4456c1f18b84d73bJeff Brown        CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
592da3d5a91b6b311ed77f2707d4456c1f18b84d73bJeff Brown        synthesizeCancelationEventsForAllConnectionsLocked(options);
593b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown        break;
594da3d5a91b6b311ed77f2707d4456c1f18b84d73bJeff Brown    }
595b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown    case EventEntry::TYPE_MOTION: {
596b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown        MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
597b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown        if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) {
598da3d5a91b6b311ed77f2707d4456c1f18b84d73bJeff Brown            CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS, reason);
599da3d5a91b6b311ed77f2707d4456c1f18b84d73bJeff Brown            synthesizeCancelationEventsForAllConnectionsLocked(options);
600b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown        } else {
601da3d5a91b6b311ed77f2707d4456c1f18b84d73bJeff Brown            CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
602da3d5a91b6b311ed77f2707d4456c1f18b84d73bJeff Brown            synthesizeCancelationEventsForAllConnectionsLocked(options);
603b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown        }
604b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown        break;
605b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown    }
606b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown    }
607b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown}
608b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown
609b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brownbool InputDispatcher::isAppSwitchKeyCode(int32_t keyCode) {
610b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    return keyCode == AKEYCODE_HOME || keyCode == AKEYCODE_ENDCALL;
611b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown}
612b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
613b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brownbool InputDispatcher::isAppSwitchKeyEventLocked(KeyEntry* keyEntry) {
614b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown    return ! (keyEntry->flags & AKEY_EVENT_FLAG_CANCELED)
615b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown            && isAppSwitchKeyCode(keyEntry->keyCode)
616e20c9e0264190f94324197a8271cf03811a4ca58Jeff Brown            && (keyEntry->policyFlags & POLICY_FLAG_TRUSTED)
617b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown            && (keyEntry->policyFlags & POLICY_FLAG_PASS_TO_USER);
618b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown}
619b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
620b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brownbool InputDispatcher::isAppSwitchPendingLocked() {
621b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown    return mAppSwitchDueTime != LONG_LONG_MAX;
622b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown}
623b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
624b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brownvoid InputDispatcher::resetPendingAppSwitchLocked(bool handled) {
625b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    mAppSwitchDueTime = LONG_LONG_MAX;
626b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
627b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown#if DEBUG_APP_SWITCH
628b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    if (handled) {
6295baa3a62a97544669fba6d65a11c07f252e654ddSteve Block        ALOGD("App switch has arrived.");
630b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    } else {
6315baa3a62a97544669fba6d65a11c07f252e654ddSteve Block        ALOGD("App switch was abandoned.");
632b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    }
633b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown#endif
63446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
63546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
636928e054931d357326613c78e62f4d850b7c442ffJeff Brownbool InputDispatcher::isStaleEventLocked(nsecs_t currentTime, EventEntry* entry) {
637928e054931d357326613c78e62f4d850b7c442ffJeff Brown    return currentTime - entry->eventTime >= STALE_EVENT_TIMEOUT;
638928e054931d357326613c78e62f4d850b7c442ffJeff Brown}
639928e054931d357326613c78e62f4d850b7c442ffJeff Brown
6409c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brownbool InputDispatcher::runCommandsLockedInterruptible() {
6419c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown    if (mCommandQueue.isEmpty()) {
6429c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown        return false;
6439c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown    }
6449c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown
6459c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown    do {
6469c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown        CommandEntry* commandEntry = mCommandQueue.dequeueAtHead();
6479c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown
6489c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown        Command command = commandEntry->command;
6499c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown        (this->*command)(commandEntry); // commands are implicitly 'LockedInterruptible'
6509c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown
6517fbdc84e87dd3a0e196b9803bb04495d11e9cb8aJeff Brown        commandEntry->connection.clear();
652ac386073df2514b79a2ca169f4a89f129733002fJeff Brown        delete commandEntry;
6539c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown    } while (! mCommandQueue.isEmpty());
6549c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown    return true;
6559c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown}
6569c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown
6579c3cda04d969912bc46184f2b326d1db95e0aba5Jeff BrownInputDispatcher::CommandEntry* InputDispatcher::postCommandLocked(Command command) {
658ac386073df2514b79a2ca169f4a89f129733002fJeff Brown    CommandEntry* commandEntry = new CommandEntry(command);
6599c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown    mCommandQueue.enqueueAtTail(commandEntry);
6609c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown    return commandEntry;
6619c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown}
6629c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown
663b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brownvoid InputDispatcher::drainInboundQueueLocked() {
664b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    while (! mInboundQueue.isEmpty()) {
665b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        EventEntry* entry = mInboundQueue.dequeueAtHead();
66654a1825121d006d4a4dcbbadf4eac9910f44ef8cJeff Brown        releaseInboundEventLocked(entry);
667b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    }
668b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown}
6699c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown
67054a1825121d006d4a4dcbbadf4eac9910f44ef8cJeff Brownvoid InputDispatcher::releasePendingEventLocked() {
671b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    if (mPendingEvent) {
67254a1825121d006d4a4dcbbadf4eac9910f44ef8cJeff Brown        releaseInboundEventLocked(mPendingEvent);
673b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        mPendingEvent = NULL;
674b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    }
67546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
67646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
67754a1825121d006d4a4dcbbadf4eac9910f44ef8cJeff Brownvoid InputDispatcher::releaseInboundEventLocked(EventEntry* entry) {
67801ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    InjectionState* injectionState = entry->injectionState;
67901ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    if (injectionState && injectionState->injectionResult == INPUT_EVENT_INJECTION_PENDING) {
680b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown#if DEBUG_DISPATCH_CYCLE
6815baa3a62a97544669fba6d65a11c07f252e654ddSteve Block        ALOGD("Injected inbound event was dropped.");
68246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#endif
683b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_FAILED);
68446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
685abb4d446a10b2defd342b1a2fa6462b52b82cdefJeff Brown    if (entry == mNextUnblockedEvent) {
686abb4d446a10b2defd342b1a2fa6462b52b82cdefJeff Brown        mNextUnblockedEvent = NULL;
687abb4d446a10b2defd342b1a2fa6462b52b82cdefJeff Brown    }
688ac386073df2514b79a2ca169f4a89f129733002fJeff Brown    entry->release();
689b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown}
69046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
691b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brownvoid InputDispatcher::resetKeyRepeatLocked() {
692b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    if (mKeyRepeatState.lastKeyEntry) {
693ac386073df2514b79a2ca169f4a89f129733002fJeff Brown        mKeyRepeatState.lastKeyEntry->release();
694b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        mKeyRepeatState.lastKeyEntry = NULL;
695b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    }
696b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown}
697b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
698214eaf48878bba00cbd5831871bcbd82632b6e34Jeff BrownInputDispatcher::KeyEntry* InputDispatcher::synthesizeKeyRepeatLocked(nsecs_t currentTime) {
699349703effce5acc53ed96f7ed8556131f0c65e18Jeff Brown    KeyEntry* entry = mKeyRepeatState.lastKeyEntry;
700349703effce5acc53ed96f7ed8556131f0c65e18Jeff Brown
701349703effce5acc53ed96f7ed8556131f0c65e18Jeff Brown    // Reuse the repeated key entry if it is otherwise unreferenced.
702e20c9e0264190f94324197a8271cf03811a4ca58Jeff Brown    uint32_t policyFlags = (entry->policyFlags & POLICY_FLAG_RAW_MASK)
703e20c9e0264190f94324197a8271cf03811a4ca58Jeff Brown            | POLICY_FLAG_PASS_TO_USER | POLICY_FLAG_TRUSTED;
70446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    if (entry->refCount == 1) {
705ac386073df2514b79a2ca169f4a89f129733002fJeff Brown        entry->recycle();
7067fbdc84e87dd3a0e196b9803bb04495d11e9cb8aJeff Brown        entry->eventTime = currentTime;
7077fbdc84e87dd3a0e196b9803bb04495d11e9cb8aJeff Brown        entry->policyFlags = policyFlags;
70846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        entry->repeatCount += 1;
70946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    } else {
710ac386073df2514b79a2ca169f4a89f129733002fJeff Brown        KeyEntry* newEntry = new KeyEntry(currentTime,
711c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown                entry->deviceId, entry->source, policyFlags,
7127fbdc84e87dd3a0e196b9803bb04495d11e9cb8aJeff Brown                entry->action, entry->flags, entry->keyCode, entry->scanCode,
71300fa7bdd69f0868fd17ea7c881c771d785b2fbbdJeff Brown                entry->metaState, entry->repeatCount + 1, entry->downTime);
71446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
71546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        mKeyRepeatState.lastKeyEntry = newEntry;
716ac386073df2514b79a2ca169f4a89f129733002fJeff Brown        entry->release();
71746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
71846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        entry = newEntry;
71946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
720b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    entry->syntheticRepeat = true;
721b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
722b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    // Increment reference count since we keep a reference to the event in
723b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    // mKeyRepeatState.lastKeyEntry in addition to the one we return.
724b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    entry->refCount += 1;
72546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
726214eaf48878bba00cbd5831871bcbd82632b6e34Jeff Brown    mKeyRepeatState.nextRepeatTime = currentTime + mConfig.keyRepeatDelay;
727b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    return entry;
728b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown}
729b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
730b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brownbool InputDispatcher::dispatchConfigurationChangedLocked(
731b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        nsecs_t currentTime, ConfigurationChangedEntry* entry) {
732b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown#if DEBUG_OUTBOUND_EVENT_DETAILS
7335baa3a62a97544669fba6d65a11c07f252e654ddSteve Block    ALOGD("dispatchConfigurationChanged - eventTime=%lld", entry->eventTime);
734b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown#endif
735b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
736b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    // Reset key repeating in case a keyboard device was added or removed or something.
737b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    resetKeyRepeatLocked();
738b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
739b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    // Enqueue a command to run outside the lock to tell the policy that the configuration changed.
740b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    CommandEntry* commandEntry = postCommandLocked(
741b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown            & InputDispatcher::doNotifyConfigurationChangedInterruptible);
742b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    commandEntry->eventTime = entry->eventTime;
743b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    return true;
744b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown}
74546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
74665fd251c3913fc921468a3dad190810db19eb9dfJeff Brownbool InputDispatcher::dispatchDeviceResetLocked(
74765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        nsecs_t currentTime, DeviceResetEntry* entry) {
74865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown#if DEBUG_OUTBOUND_EVENT_DETAILS
7495baa3a62a97544669fba6d65a11c07f252e654ddSteve Block    ALOGD("dispatchDeviceReset - eventTime=%lld, deviceId=%d", entry->eventTime, entry->deviceId);
75065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown#endif
75165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
75265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS,
75365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            "device was reset");
75465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    options.deviceId = entry->deviceId;
75565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    synthesizeCancelationEventsForAllConnectionsLocked(options);
75665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    return true;
75765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown}
75865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
759214eaf48878bba00cbd5831871bcbd82632b6e34Jeff Brownbool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, KeyEntry* entry,
760e20c9e0264190f94324197a8271cf03811a4ca58Jeff Brown        DropReason* dropReason, nsecs_t* nextWakeupTime) {
761b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    // Preprocessing.
762b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    if (! entry->dispatchInProgress) {
763b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        if (entry->repeatCount == 0
764b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown                && entry->action == AKEY_EVENT_ACTION_DOWN
765e20c9e0264190f94324197a8271cf03811a4ca58Jeff Brown                && (entry->policyFlags & POLICY_FLAG_TRUSTED)
7660029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown                && (!(entry->policyFlags & POLICY_FLAG_DISABLE_KEY_REPEAT))) {
767b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown            if (mKeyRepeatState.lastKeyEntry
768b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown                    && mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode) {
769b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown                // We have seen two identical key downs in a row which indicates that the device
770b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown                // driver is automatically generating key repeats itself.  We take note of the
771b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown                // repeat here, but we disable our own next key repeat timer since it is clear that
772b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown                // we will not need to synthesize key repeats ourselves.
773b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown                entry->repeatCount = mKeyRepeatState.lastKeyEntry->repeatCount + 1;
774b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown                resetKeyRepeatLocked();
775b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown                mKeyRepeatState.nextRepeatTime = LONG_LONG_MAX; // don't generate repeats ourselves
776b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown            } else {
777b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown                // Not a repeat.  Save key down state in case we do see a repeat later.
778b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown                resetKeyRepeatLocked();
779214eaf48878bba00cbd5831871bcbd82632b6e34Jeff Brown                mKeyRepeatState.nextRepeatTime = entry->eventTime + mConfig.keyRepeatTimeout;
780b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown            }
781b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown            mKeyRepeatState.lastKeyEntry = entry;
782b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown            entry->refCount += 1;
783b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        } else if (! entry->syntheticRepeat) {
784b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown            resetKeyRepeatLocked();
785b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        }
786b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
787e2e012683d6f35f5eedfd0c39167ea78e32e2650Jeff Brown        if (entry->repeatCount == 1) {
788e2e012683d6f35f5eedfd0c39167ea78e32e2650Jeff Brown            entry->flags |= AKEY_EVENT_FLAG_LONG_PRESS;
789e2e012683d6f35f5eedfd0c39167ea78e32e2650Jeff Brown        } else {
790e2e012683d6f35f5eedfd0c39167ea78e32e2650Jeff Brown            entry->flags &= ~AKEY_EVENT_FLAG_LONG_PRESS;
791e2e012683d6f35f5eedfd0c39167ea78e32e2650Jeff Brown        }
792e2e012683d6f35f5eedfd0c39167ea78e32e2650Jeff Brown
793b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        entry->dispatchInProgress = true;
79454a1825121d006d4a4dcbbadf4eac9910f44ef8cJeff Brown        resetTargetsLocked();
795e46a0a4693405eb8bbaa069c4e234a6976b48244Jeff Brown
796e46a0a4693405eb8bbaa069c4e234a6976b48244Jeff Brown        logOutboundKeyDetailsLocked("dispatchKey - ", entry);
797e46a0a4693405eb8bbaa069c4e234a6976b48244Jeff Brown    }
798e46a0a4693405eb8bbaa069c4e234a6976b48244Jeff Brown
799905805ad7ce18a386076fff99264f821bbad9f83Jeff Brown    // Handle case where the policy asked us to try again later last time.
800905805ad7ce18a386076fff99264f821bbad9f83Jeff Brown    if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER) {
801905805ad7ce18a386076fff99264f821bbad9f83Jeff Brown        if (currentTime < entry->interceptKeyWakeupTime) {
802905805ad7ce18a386076fff99264f821bbad9f83Jeff Brown            if (entry->interceptKeyWakeupTime < *nextWakeupTime) {
803905805ad7ce18a386076fff99264f821bbad9f83Jeff Brown                *nextWakeupTime = entry->interceptKeyWakeupTime;
804905805ad7ce18a386076fff99264f821bbad9f83Jeff Brown            }
805905805ad7ce18a386076fff99264f821bbad9f83Jeff Brown            return false; // wait until next wakeup
806905805ad7ce18a386076fff99264f821bbad9f83Jeff Brown        }
807905805ad7ce18a386076fff99264f821bbad9f83Jeff Brown        entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
808905805ad7ce18a386076fff99264f821bbad9f83Jeff Brown        entry->interceptKeyWakeupTime = 0;
809905805ad7ce18a386076fff99264f821bbad9f83Jeff Brown    }
810905805ad7ce18a386076fff99264f821bbad9f83Jeff Brown
811e46a0a4693405eb8bbaa069c4e234a6976b48244Jeff Brown    // Give the policy a chance to intercept the key.
812e46a0a4693405eb8bbaa069c4e234a6976b48244Jeff Brown    if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) {
813e46a0a4693405eb8bbaa069c4e234a6976b48244Jeff Brown        if (entry->policyFlags & POLICY_FLAG_PASS_TO_USER) {
814e46a0a4693405eb8bbaa069c4e234a6976b48244Jeff Brown            CommandEntry* commandEntry = postCommandLocked(
815e46a0a4693405eb8bbaa069c4e234a6976b48244Jeff Brown                    & InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible);
8169302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown            if (mFocusedWindowHandle != NULL) {
8179302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown                commandEntry->inputWindowHandle = mFocusedWindowHandle;
818e46a0a4693405eb8bbaa069c4e234a6976b48244Jeff Brown            }
819e46a0a4693405eb8bbaa069c4e234a6976b48244Jeff Brown            commandEntry->keyEntry = entry;
820e46a0a4693405eb8bbaa069c4e234a6976b48244Jeff Brown            entry->refCount += 1;
821e46a0a4693405eb8bbaa069c4e234a6976b48244Jeff Brown            return false; // wait for the command to run
822e46a0a4693405eb8bbaa069c4e234a6976b48244Jeff Brown        } else {
823e46a0a4693405eb8bbaa069c4e234a6976b48244Jeff Brown            entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
824e46a0a4693405eb8bbaa069c4e234a6976b48244Jeff Brown        }
825e46a0a4693405eb8bbaa069c4e234a6976b48244Jeff Brown    } else if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_SKIP) {
826e46a0a4693405eb8bbaa069c4e234a6976b48244Jeff Brown        if (*dropReason == DROP_REASON_NOT_DROPPED) {
827e46a0a4693405eb8bbaa069c4e234a6976b48244Jeff Brown            *dropReason = DROP_REASON_POLICY;
828e46a0a4693405eb8bbaa069c4e234a6976b48244Jeff Brown        }
829e46a0a4693405eb8bbaa069c4e234a6976b48244Jeff Brown    }
830e46a0a4693405eb8bbaa069c4e234a6976b48244Jeff Brown
831e46a0a4693405eb8bbaa069c4e234a6976b48244Jeff Brown    // Clean up if dropping the event.
832e46a0a4693405eb8bbaa069c4e234a6976b48244Jeff Brown    if (*dropReason != DROP_REASON_NOT_DROPPED) {
833e46a0a4693405eb8bbaa069c4e234a6976b48244Jeff Brown        resetTargetsLocked();
834e46a0a4693405eb8bbaa069c4e234a6976b48244Jeff Brown        setInjectionResultLocked(entry, *dropReason == DROP_REASON_POLICY
835e46a0a4693405eb8bbaa069c4e234a6976b48244Jeff Brown                ? INPUT_EVENT_INJECTION_SUCCEEDED : INPUT_EVENT_INJECTION_FAILED);
836e46a0a4693405eb8bbaa069c4e234a6976b48244Jeff Brown        return true;
837b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    }
838b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
839b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    // Identify targets.
840b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    if (! mCurrentInputTargetsValid) {
84101ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown        int32_t injectionResult = findFocusedWindowTargetsLocked(currentTime,
84201ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown                entry, nextWakeupTime);
843b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
844b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown            return false;
845b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        }
846b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
847b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        setInjectionResultLocked(entry, injectionResult);
848b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
849b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown            return true;
850b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        }
851b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
852b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        addMonitoringTargetsLocked();
85301ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown        commitTargetsLocked();
854b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    }
855b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
856b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    // Dispatch the key.
857b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    dispatchEventToCurrentInputTargetsLocked(currentTime, entry, false);
858b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    return true;
859b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown}
860b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
861b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brownvoid InputDispatcher::logOutboundKeyDetailsLocked(const char* prefix, const KeyEntry* entry) {
86246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#if DEBUG_OUTBOUND_EVENT_DETAILS
8635baa3a62a97544669fba6d65a11c07f252e654ddSteve Block    ALOGD("%seventTime=%lld, deviceId=%d, source=0x%x, policyFlags=0x%x, "
86446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            "action=0x%x, flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, "
865e46a0a4693405eb8bbaa069c4e234a6976b48244Jeff Brown            "repeatCount=%d, downTime=%lld",
866b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown            prefix,
867c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown            entry->eventTime, entry->deviceId, entry->source, entry->policyFlags,
86846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            entry->action, entry->flags, entry->keyCode, entry->scanCode, entry->metaState,
869e46a0a4693405eb8bbaa069c4e234a6976b48244Jeff Brown            entry->repeatCount, entry->downTime);
87046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#endif
871b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown}
872b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
873b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brownbool InputDispatcher::dispatchMotionLocked(
874e20c9e0264190f94324197a8271cf03811a4ca58Jeff Brown        nsecs_t currentTime, MotionEntry* entry, DropReason* dropReason, nsecs_t* nextWakeupTime) {
875e46a0a4693405eb8bbaa069c4e234a6976b48244Jeff Brown    // Preprocessing.
876e46a0a4693405eb8bbaa069c4e234a6976b48244Jeff Brown    if (! entry->dispatchInProgress) {
877e46a0a4693405eb8bbaa069c4e234a6976b48244Jeff Brown        entry->dispatchInProgress = true;
878e46a0a4693405eb8bbaa069c4e234a6976b48244Jeff Brown        resetTargetsLocked();
879e46a0a4693405eb8bbaa069c4e234a6976b48244Jeff Brown
880e46a0a4693405eb8bbaa069c4e234a6976b48244Jeff Brown        logOutboundMotionDetailsLocked("dispatchMotion - ", entry);
881e46a0a4693405eb8bbaa069c4e234a6976b48244Jeff Brown    }
882e46a0a4693405eb8bbaa069c4e234a6976b48244Jeff Brown
88354a1825121d006d4a4dcbbadf4eac9910f44ef8cJeff Brown    // Clean up if dropping the event.
884e20c9e0264190f94324197a8271cf03811a4ca58Jeff Brown    if (*dropReason != DROP_REASON_NOT_DROPPED) {
88554a1825121d006d4a4dcbbadf4eac9910f44ef8cJeff Brown        resetTargetsLocked();
8863122e4488aa0749cbec9890ace22c366e35350c3Jeff Brown        setInjectionResultLocked(entry, *dropReason == DROP_REASON_POLICY
8873122e4488aa0749cbec9890ace22c366e35350c3Jeff Brown                ? INPUT_EVENT_INJECTION_SUCCEEDED : INPUT_EVENT_INJECTION_FAILED);
88854a1825121d006d4a4dcbbadf4eac9910f44ef8cJeff Brown        return true;
88954a1825121d006d4a4dcbbadf4eac9910f44ef8cJeff Brown    }
89054a1825121d006d4a4dcbbadf4eac9910f44ef8cJeff Brown
891b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    bool isPointerEvent = entry->source & AINPUT_SOURCE_CLASS_POINTER;
892b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
893b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    // Identify targets.
894cc0c159e9b3dd4e0f48da0ce3e33d2c68a651413Jeff Brown    bool conflictingPointerActions = false;
895b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    if (! mCurrentInputTargetsValid) {
896b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        int32_t injectionResult;
897a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown        const MotionSample* splitBatchAfterSample = NULL;
898b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        if (isPointerEvent) {
899b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown            // Pointer event.  (eg. touchscreen)
90001ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown            injectionResult = findTouchedWindowTargetsLocked(currentTime,
901a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown                    entry, nextWakeupTime, &conflictingPointerActions, &splitBatchAfterSample);
902b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        } else {
903b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown            // Non touch event.  (eg. trackball)
90401ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown            injectionResult = findFocusedWindowTargetsLocked(currentTime,
90501ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown                    entry, nextWakeupTime);
906b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        }
907b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
908b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown            return false;
909b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        }
91046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
911b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        setInjectionResultLocked(entry, injectionResult);
912b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
913b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown            return true;
914b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        }
915b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
916b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        addMonitoringTargetsLocked();
91701ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown        commitTargetsLocked();
918a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown
919a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown        // Unbatch the event if necessary by splitting it into two parts after the
920a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown        // motion sample indicated by splitBatchAfterSample.
921a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown        if (splitBatchAfterSample && splitBatchAfterSample->next) {
922a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown#if DEBUG_BATCHING
923a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown            uint32_t originalSampleCount = entry->countSamples();
924a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown#endif
925a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown            MotionSample* nextSample = splitBatchAfterSample->next;
926ac386073df2514b79a2ca169f4a89f129733002fJeff Brown            MotionEntry* nextEntry = new MotionEntry(nextSample->eventTime,
927a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown                    entry->deviceId, entry->source, entry->policyFlags,
928fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                    entry->action, entry->flags,
929fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                    entry->metaState, entry->buttonState, entry->edgeFlags,
930a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown                    entry->xPrecision, entry->yPrecision, entry->downTime,
931fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                    entry->pointerCount, entry->pointerProperties, nextSample->pointerCoords);
932a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown            if (nextSample != entry->lastSample) {
933a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown                nextEntry->firstSample.next = nextSample->next;
934a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown                nextEntry->lastSample = entry->lastSample;
935a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown            }
936ac386073df2514b79a2ca169f4a89f129733002fJeff Brown            delete nextSample;
937a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown
938a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown            entry->lastSample = const_cast<MotionSample*>(splitBatchAfterSample);
939a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown            entry->lastSample->next = NULL;
940a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown
941a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown            if (entry->injectionState) {
942a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown                nextEntry->injectionState = entry->injectionState;
943a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown                entry->injectionState->refCount += 1;
944a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown            }
945a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown
946a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown#if DEBUG_BATCHING
9475baa3a62a97544669fba6d65a11c07f252e654ddSteve Block            ALOGD("Split batch of %d samples into two parts, first part has %d samples, "
948a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown                    "second part has %d samples.", originalSampleCount,
949a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown                    entry->countSamples(), nextEntry->countSamples());
950a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown#endif
951a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown
952a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown            mInboundQueue.enqueueAtHead(nextEntry);
953a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown        }
954b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    }
955b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
956b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    // Dispatch the motion.
957cc0c159e9b3dd4e0f48da0ce3e33d2c68a651413Jeff Brown    if (conflictingPointerActions) {
958da3d5a91b6b311ed77f2707d4456c1f18b84d73bJeff Brown        CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
959da3d5a91b6b311ed77f2707d4456c1f18b84d73bJeff Brown                "conflicting pointer actions");
960da3d5a91b6b311ed77f2707d4456c1f18b84d73bJeff Brown        synthesizeCancelationEventsForAllConnectionsLocked(options);
961cc0c159e9b3dd4e0f48da0ce3e33d2c68a651413Jeff Brown    }
962b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    dispatchEventToCurrentInputTargetsLocked(currentTime, entry, false);
963b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    return true;
96446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
96546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
966b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
967b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brownvoid InputDispatcher::logOutboundMotionDetailsLocked(const char* prefix, const MotionEntry* entry) {
96846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#if DEBUG_OUTBOUND_EVENT_DETAILS
9695baa3a62a97544669fba6d65a11c07f252e654ddSteve Block    ALOGD("%seventTime=%lld, deviceId=%d, source=0x%x, policyFlags=0x%x, "
97085a3176704b5bfbeece9bd928369fbb76eec7dc6Jeff Brown            "action=0x%x, flags=0x%x, "
971fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            "metaState=0x%x, buttonState=0x%x, "
972fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%lld",
973b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown            prefix,
97485a3176704b5bfbeece9bd928369fbb76eec7dc6Jeff Brown            entry->eventTime, entry->deviceId, entry->source, entry->policyFlags,
97585a3176704b5bfbeece9bd928369fbb76eec7dc6Jeff Brown            entry->action, entry->flags,
976fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            entry->metaState, entry->buttonState,
977fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            entry->edgeFlags, entry->xPrecision, entry->yPrecision,
97846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            entry->downTime);
97946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
98046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    // Print the most recent sample that we have available, this may change due to batching.
98146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    size_t sampleCount = 1;
982b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    const MotionSample* sample = & entry->firstSample;
98346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    for (; sample->next != NULL; sample = sample->next) {
98446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        sampleCount += 1;
98546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
98646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    for (uint32_t i = 0; i < entry->pointerCount; i++) {
9875baa3a62a97544669fba6d65a11c07f252e654ddSteve Block        ALOGD("  Pointer %d: id=%d, toolType=%d, "
988fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                "x=%f, y=%f, pressure=%f, size=%f, "
98985a3176704b5bfbeece9bd928369fbb76eec7dc6Jeff Brown                "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
9908d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                "orientation=%f",
991fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                i, entry->pointerProperties[i].id,
992fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                entry->pointerProperties[i].toolType,
993ebbd5d14ad3b1e762d9fcfa026e19413cc857e05Jeff Brown                sample->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
994ebbd5d14ad3b1e762d9fcfa026e19413cc857e05Jeff Brown                sample->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
995ebbd5d14ad3b1e762d9fcfa026e19413cc857e05Jeff Brown                sample->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
996ebbd5d14ad3b1e762d9fcfa026e19413cc857e05Jeff Brown                sample->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
997ebbd5d14ad3b1e762d9fcfa026e19413cc857e05Jeff Brown                sample->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
998ebbd5d14ad3b1e762d9fcfa026e19413cc857e05Jeff Brown                sample->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
999ebbd5d14ad3b1e762d9fcfa026e19413cc857e05Jeff Brown                sample->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
1000ebbd5d14ad3b1e762d9fcfa026e19413cc857e05Jeff Brown                sample->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
1001ebbd5d14ad3b1e762d9fcfa026e19413cc857e05Jeff Brown                sample->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
100246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
100346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
100446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    // Keep in mind that due to batching, it is possible for the number of samples actually
100546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    // dispatched to change before the application finally consumed them.
1006c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown    if (entry->action == AMOTION_EVENT_ACTION_MOVE) {
10075baa3a62a97544669fba6d65a11c07f252e654ddSteve Block        ALOGD("  ... Total movement samples currently batched %d ...", sampleCount);
100846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
100946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#endif
101046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
101146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
1012b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brownvoid InputDispatcher::dispatchEventToCurrentInputTargetsLocked(nsecs_t currentTime,
1013b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        EventEntry* eventEntry, bool resumeWithAppendedMotionSample) {
101446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#if DEBUG_DISPATCH_CYCLE
10155baa3a62a97544669fba6d65a11c07f252e654ddSteve Block    ALOGD("dispatchEventToCurrentInputTargets - "
1016b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown            "resumeWithAppendedMotionSample=%s",
1017b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown            toString(resumeWithAppendedMotionSample));
101846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#endif
101946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
1020b6110c2de0cd7950360aeb2c248a44e4ea5f33f5Jeff Brown    LOG_ASSERT(eventEntry->dispatchInProgress); // should already have been set to true
10219c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown
1022e2fe69edc009a0e0348e5351cf83062224e011acJeff Brown    pokeUserActivityLocked(eventEntry);
1023e2fe69edc009a0e0348e5351cf83062224e011acJeff Brown
1024b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    for (size_t i = 0; i < mCurrentInputTargets.size(); i++) {
1025b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        const InputTarget& inputTarget = mCurrentInputTargets.itemAt(i);
102646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
1027519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown        ssize_t connectionIndex = getConnectionIndexLocked(inputTarget.inputChannel);
1028b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        if (connectionIndex >= 0) {
1029b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown            sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
1030b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown            prepareDispatchCycleLocked(currentTime, connection, eventEntry, & inputTarget,
1031b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown                    resumeWithAppendedMotionSample);
1032b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        } else {
1033b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown#if DEBUG_FOCUS
10345baa3a62a97544669fba6d65a11c07f252e654ddSteve Block            ALOGD("Dropping event delivery to target with channel '%s' because it "
1035b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown                    "is no longer registered with the input dispatcher.",
1036b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown                    inputTarget.inputChannel->getName().string());
1037b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown#endif
1038b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        }
1039b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    }
1040b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown}
1041b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
104254a1825121d006d4a4dcbbadf4eac9910f44ef8cJeff Brownvoid InputDispatcher::resetTargetsLocked() {
1043b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    mCurrentInputTargetsValid = false;
104446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    mCurrentInputTargets.clear();
10455ea29ab7efa9a9ae22345f15a7cb9be3c5e1bbf5Jeff Brown    resetANRTimeoutsLocked();
1046b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown}
104746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
104801ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brownvoid InputDispatcher::commitTargetsLocked() {
10499c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown    mCurrentInputTargetsValid = true;
1050b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown}
1051b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
1052b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brownint32_t InputDispatcher::handleTargetsNotReadyLocked(nsecs_t currentTime,
10539302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown        const EventEntry* entry,
10549302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown        const sp<InputApplicationHandle>& applicationHandle,
10559302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown        const sp<InputWindowHandle>& windowHandle,
1056b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        nsecs_t* nextWakeupTime) {
10579302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown    if (applicationHandle == NULL && windowHandle == NULL) {
1058b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY) {
1059b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown#if DEBUG_FOCUS
10605baa3a62a97544669fba6d65a11c07f252e654ddSteve Block            ALOGD("Waiting for system to become ready for input.");
1061b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown#endif
1062b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown            mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY;
1063b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown            mInputTargetWaitStartTime = currentTime;
1064b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown            mInputTargetWaitTimeoutTime = LONG_LONG_MAX;
1065b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown            mInputTargetWaitTimeoutExpired = false;
10669302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown            mInputTargetWaitApplicationHandle.clear();
1067b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        }
1068b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    } else {
1069b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
1070b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown#if DEBUG_FOCUS
10715baa3a62a97544669fba6d65a11c07f252e654ddSteve Block            ALOGD("Waiting for application to become ready for input: %s",
10729302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown                    getApplicationWindowLabelLocked(applicationHandle, windowHandle).string());
1073b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown#endif
1074cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown            nsecs_t timeout;
1075cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown            if (windowHandle != NULL) {
1076cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown                timeout = windowHandle->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
1077cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown            } else if (applicationHandle != NULL) {
1078cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown                timeout = applicationHandle->getDispatchingTimeout(
1079cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown                        DEFAULT_INPUT_DISPATCHING_TIMEOUT);
1080cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown            } else {
1081cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown                timeout = DEFAULT_INPUT_DISPATCHING_TIMEOUT;
1082cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown            }
1083b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
1084b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown            mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY;
1085b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown            mInputTargetWaitStartTime = currentTime;
1086b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown            mInputTargetWaitTimeoutTime = currentTime + timeout;
1087b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown            mInputTargetWaitTimeoutExpired = false;
10889302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown            mInputTargetWaitApplicationHandle.clear();
1089928e054931d357326613c78e62f4d850b7c442ffJeff Brown
10909302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown            if (windowHandle != NULL) {
10919302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown                mInputTargetWaitApplicationHandle = windowHandle->inputApplicationHandle;
1092928e054931d357326613c78e62f4d850b7c442ffJeff Brown            }
10939302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown            if (mInputTargetWaitApplicationHandle == NULL && applicationHandle != NULL) {
10949302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown                mInputTargetWaitApplicationHandle = applicationHandle;
1095928e054931d357326613c78e62f4d850b7c442ffJeff Brown            }
1096b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        }
1097b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    }
1098b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
1099b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    if (mInputTargetWaitTimeoutExpired) {
1100b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        return INPUT_EVENT_INJECTION_TIMED_OUT;
1101b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    }
1102b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
1103b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    if (currentTime >= mInputTargetWaitTimeoutTime) {
11049302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown        onANRLocked(currentTime, applicationHandle, windowHandle,
11059302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown                entry->eventTime, mInputTargetWaitStartTime);
11069c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown
1107b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        // Force poll loop to wake up immediately on next iteration once we get the
1108b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        // ANR response back from the policy.
1109b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        *nextWakeupTime = LONG_LONG_MIN;
1110b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        return INPUT_EVENT_INJECTION_PENDING;
1111b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    } else {
1112b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        // Force poll loop to wake up when timeout is due.
1113b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        if (mInputTargetWaitTimeoutTime < *nextWakeupTime) {
1114b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown            *nextWakeupTime = mInputTargetWaitTimeoutTime;
1115b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        }
1116b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        return INPUT_EVENT_INJECTION_PENDING;
1117b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    }
1118b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown}
11197fbdc84e87dd3a0e196b9803bb04495d11e9cb8aJeff Brown
1120519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brownvoid InputDispatcher::resumeAfterTargetsNotReadyTimeoutLocked(nsecs_t newTimeout,
1121519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown        const sp<InputChannel>& inputChannel) {
1122b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    if (newTimeout > 0) {
1123b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        // Extend the timeout.
1124b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        mInputTargetWaitTimeoutTime = now() + newTimeout;
1125b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    } else {
1126b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        // Give up.
1127b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        mInputTargetWaitTimeoutExpired = true;
1128519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown
112901ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown        // Release the touch targets.
113001ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown        mTouchState.reset();
11312a95c2a9ec703b9d19b750cb854fb4ec4899e205Jeff Brown
1132519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown        // Input state will not be realistic.  Mark it out of sync.
1133dc3e00563ee6400936e3cb82405bb94df0b35078Jeff Brown        if (inputChannel.get()) {
1134dc3e00563ee6400936e3cb82405bb94df0b35078Jeff Brown            ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
1135dc3e00563ee6400936e3cb82405bb94df0b35078Jeff Brown            if (connectionIndex >= 0) {
1136dc3e00563ee6400936e3cb82405bb94df0b35078Jeff Brown                sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
113700045a7e6fbed88f3325d2bbb048dc96a082078cJeff Brown                if (connection->status == Connection::STATUS_NORMAL) {
1138da3d5a91b6b311ed77f2707d4456c1f18b84d73bJeff Brown                    CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS,
113900045a7e6fbed88f3325d2bbb048dc96a082078cJeff Brown                            "application not responding");
1140da3d5a91b6b311ed77f2707d4456c1f18b84d73bJeff Brown                    synthesizeCancelationEventsForConnectionLocked(connection, options);
114100045a7e6fbed88f3325d2bbb048dc96a082078cJeff Brown                }
1142dc3e00563ee6400936e3cb82405bb94df0b35078Jeff Brown            }
1143519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown        }
1144349703effce5acc53ed96f7ed8556131f0c65e18Jeff Brown    }
114546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
114646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
1147519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brownnsecs_t InputDispatcher::getTimeSpentWaitingForApplicationLocked(
1148b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        nsecs_t currentTime) {
1149b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    if (mInputTargetWaitCause == INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
1150b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        return currentTime - mInputTargetWaitStartTime;
1151b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    }
1152b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    return 0;
1153b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown}
1154b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
1155b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brownvoid InputDispatcher::resetANRTimeoutsLocked() {
1156b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown#if DEBUG_FOCUS
11575baa3a62a97544669fba6d65a11c07f252e654ddSteve Block        ALOGD("Resetting ANR timeouts.");
115846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#endif
115946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
1160b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    // Reset input target wait timeout.
1161b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_NONE;
11625ea29ab7efa9a9ae22345f15a7cb9be3c5e1bbf5Jeff Brown    mInputTargetWaitApplicationHandle.clear();
1163b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown}
116446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
116501ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brownint32_t InputDispatcher::findFocusedWindowTargetsLocked(nsecs_t currentTime,
116601ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown        const EventEntry* entry, nsecs_t* nextWakeupTime) {
116746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    mCurrentInputTargets.clear();
116846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
1169b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    int32_t injectionResult;
11709c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown
1171b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    // If there is no currently focused window and no focused application
1172b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    // then drop the event.
11739302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown    if (mFocusedWindowHandle == NULL) {
11749302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown        if (mFocusedApplicationHandle != NULL) {
1175b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown#if DEBUG_FOCUS
11765baa3a62a97544669fba6d65a11c07f252e654ddSteve Block            ALOGD("Waiting because there is no focused window but there is a "
1177519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown                    "focused application that may eventually add a window: %s.",
11789302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown                    getApplicationWindowLabelLocked(mFocusedApplicationHandle, NULL).string());
1179b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown#endif
1180b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown            injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
11819302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown                    mFocusedApplicationHandle, NULL, nextWakeupTime);
1182b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown            goto Unresponsive;
1183b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        }
11847fbdc84e87dd3a0e196b9803bb04495d11e9cb8aJeff Brown
11856215d3ff4b5dfa52a5d8b9a42e343051f31066a5Steve Block        ALOGI("Dropping event because there is no focused window or focused application.");
1186b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        injectionResult = INPUT_EVENT_INJECTION_FAILED;
1187b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        goto Failed;
1188349703effce5acc53ed96f7ed8556131f0c65e18Jeff Brown    }
1189b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
1190b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    // Check permissions.
11919302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown    if (! checkInjectionPermission(mFocusedWindowHandle, entry->injectionState)) {
1192b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
1193b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        goto Failed;
1194b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    }
1195b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
1196b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    // If the currently focused window is paused then keep waiting.
1197cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown    if (mFocusedWindowHandle->getInfo()->paused) {
1198b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown#if DEBUG_FOCUS
11995baa3a62a97544669fba6d65a11c07f252e654ddSteve Block        ALOGD("Waiting because focused window is paused.");
1200b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown#endif
1201b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
12029302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown                mFocusedApplicationHandle, mFocusedWindowHandle, nextWakeupTime);
1203b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        goto Unresponsive;
1204b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    }
1205b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
1206519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown    // If the currently focused window is still working on previous events then keep waiting.
12079302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown    if (! isWindowFinishedWithPreviousInputLocked(mFocusedWindowHandle)) {
1208519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown#if DEBUG_FOCUS
12095baa3a62a97544669fba6d65a11c07f252e654ddSteve Block        ALOGD("Waiting because focused window still processing previous input.");
1210519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown#endif
1211519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown        injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
12129302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown                mFocusedApplicationHandle, mFocusedWindowHandle, nextWakeupTime);
1213519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown        goto Unresponsive;
1214519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown    }
1215519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown
1216b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    // Success!  Output targets.
1217b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
12189302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown    addWindowTargetLocked(mFocusedWindowHandle,
1219a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown            InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS, BitSet32(0));
1220b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
1221b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    // Done.
1222b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff BrownFailed:
1223b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff BrownUnresponsive:
1224519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown    nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
1225519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown    updateDispatchStatisticsLocked(currentTime, entry,
1226519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown            injectionResult, timeSpentWaitingForApplication);
1227b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown#if DEBUG_FOCUS
12285baa3a62a97544669fba6d65a11c07f252e654ddSteve Block    ALOGD("findFocusedWindow finished: injectionResult=%d, "
1229519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown            "timeSpendWaitingForApplication=%0.1fms",
1230519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown            injectionResult, timeSpentWaitingForApplication / 1000000.0);
1231b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown#endif
1232b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    return injectionResult;
123346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
123446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
123501ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brownint32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,
1236a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown        const MotionEntry* entry, nsecs_t* nextWakeupTime, bool* outConflictingPointerActions,
1237a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown        const MotionSample** outSplitBatchAfterSample) {
1238b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    enum InjectionPermission {
1239b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        INJECTION_PERMISSION_UNKNOWN,
1240b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        INJECTION_PERMISSION_GRANTED,
1241b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        INJECTION_PERMISSION_DENIED
1242b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    };
1243b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
1244b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    mCurrentInputTargets.clear();
1245b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
1246b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    nsecs_t startTime = now();
1247b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
1248b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    // For security reasons, we defer updating the touch state until we are sure that
1249b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    // event injection will be allowed.
1250b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    //
1251b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    // FIXME In the original code, screenWasOff could never be set to true.
1252b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    //       The reason is that the POLICY_FLAG_WOKE_HERE
1253b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    //       and POLICY_FLAG_BRIGHT_HERE flags were set only when preprocessing raw
1254b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    //       EV_KEY, EV_REL and EV_ABS events.  As it happens, the touch event was
1255b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    //       actually enqueued using the policyFlags that appeared in the final EV_SYN
1256b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    //       events upon which no preprocessing took place.  So policyFlags was always 0.
1257b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    //       In the new native input dispatcher we're a bit more careful about event
1258b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    //       preprocessing so the touches we receive can actually have non-zero policyFlags.
1259b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    //       Unfortunately we obtain undesirable behavior.
1260b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    //
1261b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    //       Here's what happens:
1262b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    //
1263b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    //       When the device dims in anticipation of going to sleep, touches
1264b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    //       in windows which have FLAG_TOUCHABLE_WHEN_WAKING cause
1265b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    //       the device to brighten and reset the user activity timer.
1266b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    //       Touches on other windows (such as the launcher window)
1267b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    //       are dropped.  Then after a moment, the device goes to sleep.  Oops.
1268b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    //
1269b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    //       Also notice how screenWasOff was being initialized using POLICY_FLAG_BRIGHT_HERE
1270b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    //       instead of POLICY_FLAG_WOKE_HERE...
1271b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    //
1272b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    bool screenWasOff = false; // original policy: policyFlags & POLICY_FLAG_BRIGHT_HERE;
1273b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
1274b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    int32_t action = entry->action;
127501ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
1276b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
1277b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    // Update the touch state as needed based on the properties of the touch event.
127801ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    int32_t injectionResult = INPUT_EVENT_INJECTION_PENDING;
127901ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    InjectionPermission injectionPermission = INJECTION_PERMISSION_UNKNOWN;
12809302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown    sp<InputWindowHandle> newHoverWindowHandle;
1281cc0c159e9b3dd4e0f48da0ce3e33d2c68a651413Jeff Brown
1282cc0c159e9b3dd4e0f48da0ce3e33d2c68a651413Jeff Brown    bool isSplit = mTouchState.split;
12832717eff2ac04bed60e5fd577bcb8ec1ea7c2ccdeJeff Brown    bool switchedDevice = mTouchState.deviceId >= 0
12842717eff2ac04bed60e5fd577bcb8ec1ea7c2ccdeJeff Brown            && (mTouchState.deviceId != entry->deviceId
12852717eff2ac04bed60e5fd577bcb8ec1ea7c2ccdeJeff Brown                    || mTouchState.source != entry->source);
1286a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown    bool isHoverAction = (maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE
1287a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown            || maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER
1288a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown            || maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT);
1289a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown    bool newGesture = (maskedAction == AMOTION_EVENT_ACTION_DOWN
1290a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown            || maskedAction == AMOTION_EVENT_ACTION_SCROLL
1291a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown            || isHoverAction);
12928134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown    bool wrongDevice = false;
1293a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown    if (newGesture) {
1294cc0c159e9b3dd4e0f48da0ce3e33d2c68a651413Jeff Brown        bool down = maskedAction == AMOTION_EVENT_ACTION_DOWN;
12958134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        if (switchedDevice && mTouchState.down && !down) {
12968134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown#if DEBUG_FOCUS
12975baa3a62a97544669fba6d65a11c07f252e654ddSteve Block            ALOGD("Dropping event because a pointer for a different device is already down.");
12988134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown#endif
1299cc0c159e9b3dd4e0f48da0ce3e33d2c68a651413Jeff Brown            mTempTouchState.copyFrom(mTouchState);
13008134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown            injectionResult = INPUT_EVENT_INJECTION_FAILED;
13018134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown            switchedDevice = false;
13028134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown            wrongDevice = true;
13038134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown            goto Failed;
1304cc0c159e9b3dd4e0f48da0ce3e33d2c68a651413Jeff Brown        }
13058134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        mTempTouchState.reset();
13068134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        mTempTouchState.down = down;
13078134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        mTempTouchState.deviceId = entry->deviceId;
13088134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        mTempTouchState.source = entry->source;
13098134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        isSplit = false;
131001ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    } else {
131101ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown        mTempTouchState.copyFrom(mTouchState);
1312cc0c159e9b3dd4e0f48da0ce3e33d2c68a651413Jeff Brown    }
1313b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
1314a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown    if (newGesture || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)) {
131533bbfd2232ea9eaae9a9d87a05a95a430f09bd83Jeff Brown        /* Case 1: New splittable pointer going down, or need target for hover or scroll. */
1316b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
1317a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown        const MotionSample* sample = &entry->firstSample;
131801ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown        int32_t pointerIndex = getMotionEventActionPointerIndex(action);
1319a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown        int32_t x = int32_t(sample->pointerCoords[pointerIndex].
1320ebbd5d14ad3b1e762d9fcfa026e19413cc857e05Jeff Brown                getAxisValue(AMOTION_EVENT_AXIS_X));
1321a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown        int32_t y = int32_t(sample->pointerCoords[pointerIndex].
1322ebbd5d14ad3b1e762d9fcfa026e19413cc857e05Jeff Brown                getAxisValue(AMOTION_EVENT_AXIS_Y));
13239302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown        sp<InputWindowHandle> newTouchedWindowHandle;
13249302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown        sp<InputWindowHandle> topErrorWindowHandle;
1325a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown        bool isTouchModal = false;
1326b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
1327b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        // Traverse windows from front to back to find touched window and outside targets.
13289302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown        size_t numWindows = mWindowHandles.size();
1329b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        for (size_t i = 0; i < numWindows; i++) {
13309302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown            sp<InputWindowHandle> windowHandle = mWindowHandles.itemAt(i);
1331cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown            const InputWindowInfo* windowInfo = windowHandle->getInfo();
1332cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown            int32_t flags = windowInfo->layoutParamsFlags;
1333b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
1334cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown            if (flags & InputWindowInfo::FLAG_SYSTEM_ERROR) {
13359302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown                if (topErrorWindowHandle == NULL) {
13369302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown                    topErrorWindowHandle = windowHandle;
1337b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown                }
1338b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown            }
1339b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
1340cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown            if (windowInfo->visible) {
1341cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown                if (! (flags & InputWindowInfo::FLAG_NOT_TOUCHABLE)) {
1342cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown                    isTouchModal = (flags & (InputWindowInfo::FLAG_NOT_FOCUSABLE
1343cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown                            | InputWindowInfo::FLAG_NOT_TOUCH_MODAL)) == 0;
1344cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown                    if (isTouchModal || windowInfo->touchableRegionContainsPoint(x, y)) {
13459302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown                        if (! screenWasOff
1346cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown                                || (flags & InputWindowInfo::FLAG_TOUCHABLE_WHEN_WAKING)) {
13479302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown                            newTouchedWindowHandle = windowHandle;
1348b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown                        }
1349b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown                        break; // found touched window, exit window loop
1350b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown                    }
1351b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown                }
1352b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
135301ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown                if (maskedAction == AMOTION_EVENT_ACTION_DOWN
1354cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown                        && (flags & InputWindowInfo::FLAG_WATCH_OUTSIDE_TOUCH)) {
1355a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown                    int32_t outsideTargetFlags = InputTarget::FLAG_DISPATCH_AS_OUTSIDE;
13569302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown                    if (isWindowObscuredAtPointLocked(windowHandle, x, y)) {
135719dfc83c376d8f5ff3b128ee4c675790cffbc02dJeff Brown                        outsideTargetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
135819dfc83c376d8f5ff3b128ee4c675790cffbc02dJeff Brown                    }
135919dfc83c376d8f5ff3b128ee4c675790cffbc02dJeff Brown
13609302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown                    mTempTouchState.addOrUpdateWindow(
13619302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown                            windowHandle, outsideTargetFlags, BitSet32(0));
1362b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown                }
1363b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown            }
1364b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        }
1365b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
1366b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        // If there is an error window but it is not taking focus (typically because
1367b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        // it is invisible) then wait for it.  Any other focused window may in
1368b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        // fact be in ANR state.
13699302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown        if (topErrorWindowHandle != NULL && newTouchedWindowHandle != topErrorWindowHandle) {
1370b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown#if DEBUG_FOCUS
13715baa3a62a97544669fba6d65a11c07f252e654ddSteve Block            ALOGD("Waiting because system error window is pending.");
137246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#endif
1373b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown            injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
1374b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown                    NULL, NULL, nextWakeupTime);
1375b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown            injectionPermission = INJECTION_PERMISSION_UNKNOWN;
1376b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown            goto Unresponsive;
1377b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        }
137846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
137901ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown        // Figure out whether splitting will be allowed for this window.
1380cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown        if (newTouchedWindowHandle != NULL
1381cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown                && newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
138201ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown            // New window supports splitting.
138301ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown            isSplit = true;
138401ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown        } else if (isSplit) {
138501ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown            // New window does not support splitting but we have already split events.
138601ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown            // Assign the pointer to the first foreground window we find.
138701ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown            // (May be NULL which is why we put this code block before the next check.)
13889302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown            newTouchedWindowHandle = mTempTouchState.getFirstForegroundWindowHandle();
138901ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown        }
139001ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown
1391b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        // If we did not find a touched window then fail.
13929302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown        if (newTouchedWindowHandle == NULL) {
13939302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown            if (mFocusedApplicationHandle != NULL) {
1394b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown#if DEBUG_FOCUS
13955baa3a62a97544669fba6d65a11c07f252e654ddSteve Block                ALOGD("Waiting because there is no touched window but there is a "
1396519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown                        "focused application that may eventually add a new window: %s.",
13979302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown                        getApplicationWindowLabelLocked(mFocusedApplicationHandle, NULL).string());
1398b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown#endif
1399b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown                injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
14009302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown                        mFocusedApplicationHandle, NULL, nextWakeupTime);
1401b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown                goto Unresponsive;
1402b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown            }
14039c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown
14046215d3ff4b5dfa52a5d8b9a42e343051f31066a5Steve Block            ALOGI("Dropping event because there is no touched window or focused application.");
1405b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown            injectionResult = INPUT_EVENT_INJECTION_FAILED;
1406b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown            goto Failed;
1407b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        }
1408b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
140919dfc83c376d8f5ff3b128ee4c675790cffbc02dJeff Brown        // Set target flags.
1410a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown        int32_t targetFlags = InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS;
141119dfc83c376d8f5ff3b128ee4c675790cffbc02dJeff Brown        if (isSplit) {
141219dfc83c376d8f5ff3b128ee4c675790cffbc02dJeff Brown            targetFlags |= InputTarget::FLAG_SPLIT;
141319dfc83c376d8f5ff3b128ee4c675790cffbc02dJeff Brown        }
14149302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown        if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
141519dfc83c376d8f5ff3b128ee4c675790cffbc02dJeff Brown            targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
141619dfc83c376d8f5ff3b128ee4c675790cffbc02dJeff Brown        }
141719dfc83c376d8f5ff3b128ee4c675790cffbc02dJeff Brown
1418a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown        // Update hover state.
1419a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown        if (isHoverAction) {
14209302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown            newHoverWindowHandle = newTouchedWindowHandle;
1421a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown
1422a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown            // Ensure all subsequent motion samples are also within the touched window.
1423a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown            // Set *outSplitBatchAfterSample to the sample before the first one that is not
1424a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown            // within the touched window.
1425a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown            if (!isTouchModal) {
1426a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown                while (sample->next) {
1427cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown                    if (!newHoverWindowHandle->getInfo()->touchableRegionContainsPoint(
1428a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown                            sample->next->pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X),
1429a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown                            sample->next->pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y))) {
1430a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown                        *outSplitBatchAfterSample = sample;
1431a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown                        break;
1432a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown                    }
1433a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown                    sample = sample->next;
1434a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown                }
1435a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown            }
1436a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown        } else if (maskedAction == AMOTION_EVENT_ACTION_SCROLL) {
14379302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown            newHoverWindowHandle = mLastHoverWindowHandle;
1438a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown        }
1439a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown
144001ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown        // Update the temporary touch state.
144101ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown        BitSet32 pointerIds;
144201ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown        if (isSplit) {
1443fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            uint32_t pointerId = entry->pointerProperties[pointerIndex].id;
144401ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown            pointerIds.markBit(pointerId);
1445b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        }
14469302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown        mTempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
1447b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    } else {
144801ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown        /* Case 2: Pointer move, up, cancel or non-splittable pointer down. */
1449b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
1450b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        // If the pointer is not currently down, then ignore the event.
145101ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown        if (! mTempTouchState.down) {
1452a2cc28d732577dd48a02de637c635e9764400248Jeff Brown#if DEBUG_FOCUS
14535baa3a62a97544669fba6d65a11c07f252e654ddSteve Block            ALOGD("Dropping event because the pointer is not down or we previously "
145476860e3fe73a791b1b04f33d78b908eb3163b4b2Jeff Brown                    "dropped the pointer down event.");
145576860e3fe73a791b1b04f33d78b908eb3163b4b2Jeff Brown#endif
1456b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown            injectionResult = INPUT_EVENT_INJECTION_FAILED;
1457b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown            goto Failed;
1458b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        }
145998db5fabdad86dca379740d8050697950b9f026cJeff Brown
146098db5fabdad86dca379740d8050697950b9f026cJeff Brown        // Check whether touches should slip outside of the current foreground window.
146198db5fabdad86dca379740d8050697950b9f026cJeff Brown        if (maskedAction == AMOTION_EVENT_ACTION_MOVE
146298db5fabdad86dca379740d8050697950b9f026cJeff Brown                && entry->pointerCount == 1
146398db5fabdad86dca379740d8050697950b9f026cJeff Brown                && mTempTouchState.isSlippery()) {
146498db5fabdad86dca379740d8050697950b9f026cJeff Brown            const MotionSample* sample = &entry->firstSample;
146598db5fabdad86dca379740d8050697950b9f026cJeff Brown            int32_t x = int32_t(sample->pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
146698db5fabdad86dca379740d8050697950b9f026cJeff Brown            int32_t y = int32_t(sample->pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
146798db5fabdad86dca379740d8050697950b9f026cJeff Brown
14689302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown            sp<InputWindowHandle> oldTouchedWindowHandle =
14699302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown                    mTempTouchState.getFirstForegroundWindowHandle();
14709302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown            sp<InputWindowHandle> newTouchedWindowHandle = findTouchedWindowAtLocked(x, y);
14719302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown            if (oldTouchedWindowHandle != newTouchedWindowHandle
14729302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown                    && newTouchedWindowHandle != NULL) {
147398db5fabdad86dca379740d8050697950b9f026cJeff Brown#if DEBUG_FOCUS
14745baa3a62a97544669fba6d65a11c07f252e654ddSteve Block                ALOGD("Touch is slipping out of window %s into window %s.",
1475cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown                        oldTouchedWindowHandle->getName().string(),
1476cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown                        newTouchedWindowHandle->getName().string());
147798db5fabdad86dca379740d8050697950b9f026cJeff Brown#endif
147898db5fabdad86dca379740d8050697950b9f026cJeff Brown                // Make a slippery exit from the old window.
14799302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown                mTempTouchState.addOrUpdateWindow(oldTouchedWindowHandle,
148098db5fabdad86dca379740d8050697950b9f026cJeff Brown                        InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT, BitSet32(0));
148198db5fabdad86dca379740d8050697950b9f026cJeff Brown
148298db5fabdad86dca379740d8050697950b9f026cJeff Brown                // Make a slippery entrance into the new window.
1483cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown                if (newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
148498db5fabdad86dca379740d8050697950b9f026cJeff Brown                    isSplit = true;
148598db5fabdad86dca379740d8050697950b9f026cJeff Brown                }
148698db5fabdad86dca379740d8050697950b9f026cJeff Brown
148798db5fabdad86dca379740d8050697950b9f026cJeff Brown                int32_t targetFlags = InputTarget::FLAG_FOREGROUND
148898db5fabdad86dca379740d8050697950b9f026cJeff Brown                        | InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER;
148998db5fabdad86dca379740d8050697950b9f026cJeff Brown                if (isSplit) {
149098db5fabdad86dca379740d8050697950b9f026cJeff Brown                    targetFlags |= InputTarget::FLAG_SPLIT;
149198db5fabdad86dca379740d8050697950b9f026cJeff Brown                }
14929302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown                if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
149398db5fabdad86dca379740d8050697950b9f026cJeff Brown                    targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
149498db5fabdad86dca379740d8050697950b9f026cJeff Brown                }
149598db5fabdad86dca379740d8050697950b9f026cJeff Brown
149698db5fabdad86dca379740d8050697950b9f026cJeff Brown                BitSet32 pointerIds;
149798db5fabdad86dca379740d8050697950b9f026cJeff Brown                if (isSplit) {
149898db5fabdad86dca379740d8050697950b9f026cJeff Brown                    pointerIds.markBit(entry->pointerProperties[0].id);
149998db5fabdad86dca379740d8050697950b9f026cJeff Brown                }
15009302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown                mTempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
150198db5fabdad86dca379740d8050697950b9f026cJeff Brown
150298db5fabdad86dca379740d8050697950b9f026cJeff Brown                // Split the batch here so we send exactly one sample.
150398db5fabdad86dca379740d8050697950b9f026cJeff Brown                *outSplitBatchAfterSample = &entry->firstSample;
150498db5fabdad86dca379740d8050697950b9f026cJeff Brown            }
150598db5fabdad86dca379740d8050697950b9f026cJeff Brown        }
150601ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    }
1507b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
15089302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown    if (newHoverWindowHandle != mLastHoverWindowHandle) {
1509a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown        // Split the batch here so we send exactly one sample as part of ENTER or EXIT.
1510a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown        *outSplitBatchAfterSample = &entry->firstSample;
1511a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown
1512a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown        // Let the previous window know that the hover sequence is over.
15139302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown        if (mLastHoverWindowHandle != NULL) {
1514a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown#if DEBUG_HOVER
15155baa3a62a97544669fba6d65a11c07f252e654ddSteve Block            ALOGD("Sending hover exit event to window %s.",
1516cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown                    mLastHoverWindowHandle->getName().string());
1517a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown#endif
15189302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown            mTempTouchState.addOrUpdateWindow(mLastHoverWindowHandle,
1519a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown                    InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT, BitSet32(0));
1520a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown        }
1521a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown
1522a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown        // Let the new window know that the hover sequence is starting.
15239302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown        if (newHoverWindowHandle != NULL) {
1524a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown#if DEBUG_HOVER
15255baa3a62a97544669fba6d65a11c07f252e654ddSteve Block            ALOGD("Sending hover enter event to window %s.",
1526cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown                    newHoverWindowHandle->getName().string());
1527a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown#endif
15289302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown            mTempTouchState.addOrUpdateWindow(newHoverWindowHandle,
1529a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown                    InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER, BitSet32(0));
1530a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown        }
1531a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown    }
1532a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown
153301ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    // Check permission to inject into all touched foreground windows and ensure there
153401ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    // is at least one touched foreground window.
153501ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    {
153601ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown        bool haveForegroundWindow = false;
153701ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown        for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
153801ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown            const TouchedWindow& touchedWindow = mTempTouchState.windows[i];
153901ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown            if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
154001ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown                haveForegroundWindow = true;
15419302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown                if (! checkInjectionPermission(touchedWindow.windowHandle,
15429302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown                        entry->injectionState)) {
154301ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown                    injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
154401ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown                    injectionPermission = INJECTION_PERMISSION_DENIED;
154501ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown                    goto Failed;
154601ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown                }
154701ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown            }
154801ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown        }
154901ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown        if (! haveForegroundWindow) {
1550a2cc28d732577dd48a02de637c635e9764400248Jeff Brown#if DEBUG_FOCUS
15515baa3a62a97544669fba6d65a11c07f252e654ddSteve Block            ALOGD("Dropping event because there is no touched foreground window to receive it.");
1552b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown#endif
1553b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown            injectionResult = INPUT_EVENT_INJECTION_FAILED;
1554b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown            goto Failed;
1555b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        }
1556b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
155701ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown        // Permission granted to injection into all touched foreground windows.
155801ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown        injectionPermission = INJECTION_PERMISSION_GRANTED;
155901ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    }
156001ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown
15617a9db181a64e0e752a447c6408639bbb33c412fcKenny Root    // Check whether windows listening for outside touches are owned by the same UID. If it is
15627a9db181a64e0e752a447c6408639bbb33c412fcKenny Root    // set the policy flag that we will not reveal coordinate information to this window.
15637a9db181a64e0e752a447c6408639bbb33c412fcKenny Root    if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
15649302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown        sp<InputWindowHandle> foregroundWindowHandle =
15659302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown                mTempTouchState.getFirstForegroundWindowHandle();
1566cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown        const int32_t foregroundWindowUid = foregroundWindowHandle->getInfo()->ownerUid;
15677a9db181a64e0e752a447c6408639bbb33c412fcKenny Root        for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
15687a9db181a64e0e752a447c6408639bbb33c412fcKenny Root            const TouchedWindow& touchedWindow = mTempTouchState.windows[i];
15697a9db181a64e0e752a447c6408639bbb33c412fcKenny Root            if (touchedWindow.targetFlags & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
15709302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown                sp<InputWindowHandle> inputWindowHandle = touchedWindow.windowHandle;
1571cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown                if (inputWindowHandle->getInfo()->ownerUid != foregroundWindowUid) {
15729302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown                    mTempTouchState.addOrUpdateWindow(inputWindowHandle,
15737a9db181a64e0e752a447c6408639bbb33c412fcKenny Root                            InputTarget::FLAG_ZERO_COORDS, BitSet32(0));
15747a9db181a64e0e752a447c6408639bbb33c412fcKenny Root                }
15757a9db181a64e0e752a447c6408639bbb33c412fcKenny Root            }
15767a9db181a64e0e752a447c6408639bbb33c412fcKenny Root        }
15777a9db181a64e0e752a447c6408639bbb33c412fcKenny Root    }
15787a9db181a64e0e752a447c6408639bbb33c412fcKenny Root
157901ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    // Ensure all touched foreground windows are ready for new input.
158001ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
158101ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown        const TouchedWindow& touchedWindow = mTempTouchState.windows[i];
158201ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown        if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
158301ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown            // If the touched window is paused then keep waiting.
1584cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown            if (touchedWindow.windowHandle->getInfo()->paused) {
1585a2cc28d732577dd48a02de637c635e9764400248Jeff Brown#if DEBUG_FOCUS
15865baa3a62a97544669fba6d65a11c07f252e654ddSteve Block                ALOGD("Waiting because touched window is paused.");
1587b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown#endif
158801ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown                injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
15899302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown                        NULL, touchedWindow.windowHandle, nextWakeupTime);
159001ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown                goto Unresponsive;
159101ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown            }
1592519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown
159301ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown            // If the touched window is still working on previous events then keep waiting.
15949302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown            if (! isWindowFinishedWithPreviousInputLocked(touchedWindow.windowHandle)) {
1595519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown#if DEBUG_FOCUS
15965baa3a62a97544669fba6d65a11c07f252e654ddSteve Block                ALOGD("Waiting because touched window still processing previous input.");
1597519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown#endif
159801ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown                injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
15999302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown                        NULL, touchedWindow.windowHandle, nextWakeupTime);
160001ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown                goto Unresponsive;
160101ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown            }
1602519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown        }
1603b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    }
1604b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
160501ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    // If this is the first pointer going down and the touched window has a wallpaper
160601ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    // then also add the touched wallpaper windows so they are locked in for the duration
160701ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    // of the touch gesture.
160833bbfd2232ea9eaae9a9d87a05a95a430f09bd83Jeff Brown    // We do not collect wallpapers during HOVER_MOVE or SCROLL because the wallpaper
160933bbfd2232ea9eaae9a9d87a05a95a430f09bd83Jeff Brown    // engine only supports touch events.  We would need to add a mechanism similar
161033bbfd2232ea9eaae9a9d87a05a95a430f09bd83Jeff Brown    // to View.onGenericMotionEvent to enable wallpapers to handle these events.
161133bbfd2232ea9eaae9a9d87a05a95a430f09bd83Jeff Brown    if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
16129302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown        sp<InputWindowHandle> foregroundWindowHandle =
16139302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown                mTempTouchState.getFirstForegroundWindowHandle();
1614cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown        if (foregroundWindowHandle->getInfo()->hasWallpaper) {
16159302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown            for (size_t i = 0; i < mWindowHandles.size(); i++) {
16169302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown                sp<InputWindowHandle> windowHandle = mWindowHandles.itemAt(i);
1617cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown                if (windowHandle->getInfo()->layoutParamsType
1618cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown                        == InputWindowInfo::TYPE_WALLPAPER) {
16199302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown                    mTempTouchState.addOrUpdateWindow(windowHandle,
1620a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown                            InputTarget::FLAG_WINDOW_IS_OBSCURED
1621a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown                                    | InputTarget::FLAG_DISPATCH_AS_IS,
1622a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown                            BitSet32(0));
162301ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown                }
1624b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown            }
1625b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        }
162601ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    }
1627b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
162801ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    // Success!  Output targets.
162901ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
163001ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown
163101ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
163201ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown        const TouchedWindow& touchedWindow = mTempTouchState.windows.itemAt(i);
16339302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown        addWindowTargetLocked(touchedWindow.windowHandle, touchedWindow.targetFlags,
163401ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown                touchedWindow.pointerIds);
163501ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    }
163601ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown
1637a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown    // Drop the outside or hover touch windows since we will not care about them
1638a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown    // in the next iteration.
1639a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown    mTempTouchState.filterNonAsIsTouchWindows();
164001ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown
1641b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff BrownFailed:
1642b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    // Check injection permission once and for all.
1643b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    if (injectionPermission == INJECTION_PERMISSION_UNKNOWN) {
164401ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown        if (checkInjectionPermission(NULL, entry->injectionState)) {
1645b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown            injectionPermission = INJECTION_PERMISSION_GRANTED;
164646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        } else {
1647b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown            injectionPermission = INJECTION_PERMISSION_DENIED;
1648b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        }
1649b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    }
1650b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
1651b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    // Update final pieces of touch state if the injector had permission.
1652b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    if (injectionPermission == INJECTION_PERMISSION_GRANTED) {
165395712850665492af670824abdba77f0944d984d1Jeff Brown        if (!wrongDevice) {
16548134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown            if (switchedDevice) {
16558134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown#if DEBUG_FOCUS
16565baa3a62a97544669fba6d65a11c07f252e654ddSteve Block                ALOGD("Conflicting pointer actions: Switched to a different device.");
16578134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown#endif
16588134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown                *outConflictingPointerActions = true;
16598134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown            }
16608134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown
16618134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown            if (isHoverAction) {
16628134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown                // Started hovering, therefore no longer down.
16638134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown                if (mTouchState.down) {
16648134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown#if DEBUG_FOCUS
16655baa3a62a97544669fba6d65a11c07f252e654ddSteve Block                    ALOGD("Conflicting pointer actions: Hover received while pointer was down.");
16668134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown#endif
16678134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown                    *outConflictingPointerActions = true;
16688134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown                }
16698134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown                mTouchState.reset();
16708134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown                if (maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER
16718134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown                        || maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE) {
16728134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown                    mTouchState.deviceId = entry->deviceId;
16738134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown                    mTouchState.source = entry->source;
16748134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown                }
16758134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown            } else if (maskedAction == AMOTION_EVENT_ACTION_UP
16768134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown                    || maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
167795712850665492af670824abdba77f0944d984d1Jeff Brown                // All pointers up or canceled.
167833bbfd2232ea9eaae9a9d87a05a95a430f09bd83Jeff Brown                mTouchState.reset();
167995712850665492af670824abdba77f0944d984d1Jeff Brown            } else if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
168095712850665492af670824abdba77f0944d984d1Jeff Brown                // First pointer went down.
168195712850665492af670824abdba77f0944d984d1Jeff Brown                if (mTouchState.down) {
1682b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown#if DEBUG_FOCUS
16835baa3a62a97544669fba6d65a11c07f252e654ddSteve Block                    ALOGD("Conflicting pointer actions: Down received while already down.");
1684b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown#endif
16858134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown                    *outConflictingPointerActions = true;
168695712850665492af670824abdba77f0944d984d1Jeff Brown                }
168733bbfd2232ea9eaae9a9d87a05a95a430f09bd83Jeff Brown                mTouchState.copyFrom(mTempTouchState);
168895712850665492af670824abdba77f0944d984d1Jeff Brown            } else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
168995712850665492af670824abdba77f0944d984d1Jeff Brown                // One pointer went up.
169095712850665492af670824abdba77f0944d984d1Jeff Brown                if (isSplit) {
169195712850665492af670824abdba77f0944d984d1Jeff Brown                    int32_t pointerIndex = getMotionEventActionPointerIndex(action);
1692fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                    uint32_t pointerId = entry->pointerProperties[pointerIndex].id;
169395712850665492af670824abdba77f0944d984d1Jeff Brown
169495712850665492af670824abdba77f0944d984d1Jeff Brown                    for (size_t i = 0; i < mTempTouchState.windows.size(); ) {
169595712850665492af670824abdba77f0944d984d1Jeff Brown                        TouchedWindow& touchedWindow = mTempTouchState.windows.editItemAt(i);
169695712850665492af670824abdba77f0944d984d1Jeff Brown                        if (touchedWindow.targetFlags & InputTarget::FLAG_SPLIT) {
169795712850665492af670824abdba77f0944d984d1Jeff Brown                            touchedWindow.pointerIds.clearBit(pointerId);
169895712850665492af670824abdba77f0944d984d1Jeff Brown                            if (touchedWindow.pointerIds.isEmpty()) {
169995712850665492af670824abdba77f0944d984d1Jeff Brown                                mTempTouchState.windows.removeAt(i);
170095712850665492af670824abdba77f0944d984d1Jeff Brown                                continue;
170195712850665492af670824abdba77f0944d984d1Jeff Brown                            }
170201ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown                        }
170395712850665492af670824abdba77f0944d984d1Jeff Brown                        i += 1;
170401ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown                    }
170501ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown                }
170633bbfd2232ea9eaae9a9d87a05a95a430f09bd83Jeff Brown                mTouchState.copyFrom(mTempTouchState);
170733bbfd2232ea9eaae9a9d87a05a95a430f09bd83Jeff Brown            } else if (maskedAction == AMOTION_EVENT_ACTION_SCROLL) {
170833bbfd2232ea9eaae9a9d87a05a95a430f09bd83Jeff Brown                // Discard temporary touch state since it was only valid for this action.
170933bbfd2232ea9eaae9a9d87a05a95a430f09bd83Jeff Brown            } else {
171033bbfd2232ea9eaae9a9d87a05a95a430f09bd83Jeff Brown                // Save changes to touch state as-is for all other actions.
171133bbfd2232ea9eaae9a9d87a05a95a430f09bd83Jeff Brown                mTouchState.copyFrom(mTempTouchState);
1712b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown            }
1713a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown
1714a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown            // Update hover state.
17159302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown            mLastHoverWindowHandle = newHoverWindowHandle;
171695712850665492af670824abdba77f0944d984d1Jeff Brown        }
1717b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    } else {
171801ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown#if DEBUG_FOCUS
17195baa3a62a97544669fba6d65a11c07f252e654ddSteve Block        ALOGD("Not updating touch focus because injection was denied.");
172001ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown#endif
1721b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    }
1722b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
1723b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff BrownUnresponsive:
1724120a4594855951ed5eb185fdfc19bf98efef3ba2Jeff Brown    // Reset temporary touch state to ensure we release unnecessary references to input channels.
1725120a4594855951ed5eb185fdfc19bf98efef3ba2Jeff Brown    mTempTouchState.reset();
1726120a4594855951ed5eb185fdfc19bf98efef3ba2Jeff Brown
1727519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown    nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
1728519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown    updateDispatchStatisticsLocked(currentTime, entry,
1729519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown            injectionResult, timeSpentWaitingForApplication);
1730b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown#if DEBUG_FOCUS
17315baa3a62a97544669fba6d65a11c07f252e654ddSteve Block    ALOGD("findTouchedWindow finished: injectionResult=%d, injectionPermission=%d, "
173201ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown            "timeSpentWaitingForApplication=%0.1fms",
1733519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown            injectionResult, injectionPermission, timeSpentWaitingForApplication / 1000000.0);
1734b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown#endif
1735b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    return injectionResult;
1736b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown}
1737b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
17389302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brownvoid InputDispatcher::addWindowTargetLocked(const sp<InputWindowHandle>& windowHandle,
17399302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown        int32_t targetFlags, BitSet32 pointerIds) {
1740b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    mCurrentInputTargets.push();
1741b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
1742cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown    const InputWindowInfo* windowInfo = windowHandle->getInfo();
1743b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    InputTarget& target = mCurrentInputTargets.editTop();
1744cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown    target.inputChannel = windowInfo->inputChannel;
1745b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    target.flags = targetFlags;
1746cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown    target.xOffset = - windowInfo->frameLeft;
1747cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown    target.yOffset = - windowInfo->frameTop;
1748cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown    target.scaleFactor = windowInfo->scaleFactor;
174901ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    target.pointerIds = pointerIds;
1750b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown}
1751b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
1752b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brownvoid InputDispatcher::addMonitoringTargetsLocked() {
1753b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
1754b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        mCurrentInputTargets.push();
1755b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
1756b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        InputTarget& target = mCurrentInputTargets.editTop();
1757b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        target.inputChannel = mMonitoringChannels[i];
1758b6110c2de0cd7950360aeb2c248a44e4ea5f33f5Jeff Brown        target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
1759b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        target.xOffset = 0;
1760b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        target.yOffset = 0;
1761b6110c2de0cd7950360aeb2c248a44e4ea5f33f5Jeff Brown        target.pointerIds.clear();
1762e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn        target.scaleFactor = 1.0f;
1763b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    }
1764b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown}
1765b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
17669302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brownbool InputDispatcher::checkInjectionPermission(const sp<InputWindowHandle>& windowHandle,
176701ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown        const InjectionState* injectionState) {
176801ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    if (injectionState
1769cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown            && (windowHandle == NULL
1770cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown                    || windowHandle->getInfo()->ownerUid != injectionState->injectorUid)
1771b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown            && !hasInjectionPermission(injectionState->injectorPid, injectionState->injectorUid)) {
17729302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown        if (windowHandle != NULL) {
17738564c8da817a845353d213acd8636b76f567b234Steve Block            ALOGW("Permission denied: injecting event from pid %d uid %d to window %s "
17749302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown                    "owned by uid %d",
1775b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown                    injectionState->injectorPid, injectionState->injectorUid,
1776cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown                    windowHandle->getName().string(),
1777cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown                    windowHandle->getInfo()->ownerUid);
1778b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown        } else {
17798564c8da817a845353d213acd8636b76f567b234Steve Block            ALOGW("Permission denied: injecting event from pid %d uid %d",
1780b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown                    injectionState->injectorPid, injectionState->injectorUid);
1781b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        }
1782b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown        return false;
1783b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    }
1784b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    return true;
1785b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown}
1786b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
178719dfc83c376d8f5ff3b128ee4c675790cffbc02dJeff Brownbool InputDispatcher::isWindowObscuredAtPointLocked(
17889302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown        const sp<InputWindowHandle>& windowHandle, int32_t x, int32_t y) const {
17899302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown    size_t numWindows = mWindowHandles.size();
1790b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    for (size_t i = 0; i < numWindows; i++) {
17919302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown        sp<InputWindowHandle> otherHandle = mWindowHandles.itemAt(i);
17929302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown        if (otherHandle == windowHandle) {
1793b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown            break;
1794b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        }
1795cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown
1796cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown        const InputWindowInfo* otherInfo = otherHandle->getInfo();
1797cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown        if (otherInfo->visible && ! otherInfo->isTrustedOverlay()
1798cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown                && otherInfo->frameContainsPoint(x, y)) {
1799b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown            return true;
180046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        }
180146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
1802b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    return false;
1803b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown}
1804b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
18059302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brownbool InputDispatcher::isWindowFinishedWithPreviousInputLocked(
18069302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown        const sp<InputWindowHandle>& windowHandle) {
1807cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown    ssize_t connectionIndex = getConnectionIndexLocked(windowHandle->getInputChannel());
1808519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown    if (connectionIndex >= 0) {
1809519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown        sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
1810519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown        return connection->outboundQueue.isEmpty();
1811519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown    } else {
1812519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown        return true;
1813519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown    }
1814519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown}
1815519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown
18169302c8796fc4dcda08d4bd1e11733848fd4fafafJeff BrownString8 InputDispatcher::getApplicationWindowLabelLocked(
18179302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown        const sp<InputApplicationHandle>& applicationHandle,
18189302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown        const sp<InputWindowHandle>& windowHandle) {
18199302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown    if (applicationHandle != NULL) {
18209302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown        if (windowHandle != NULL) {
1821cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown            String8 label(applicationHandle->getName());
1822519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown            label.append(" - ");
1823cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown            label.append(windowHandle->getName());
1824519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown            return label;
1825519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown        } else {
1826cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown            return applicationHandle->getName();
1827519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown        }
18289302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown    } else if (windowHandle != NULL) {
1829cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown        return windowHandle->getName();
1830519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown    } else {
1831519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown        return String8("<unknown application or window>");
1832519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown    }
1833519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown}
1834519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown
1835e2fe69edc009a0e0348e5351cf83062224e011acJeff Brownvoid InputDispatcher::pokeUserActivityLocked(const EventEntry* eventEntry) {
183656194ebec6212e229f4ccdaa4b187166d20013efJeff Brown    int32_t eventType = POWER_MANAGER_OTHER_EVENT;
18374d396052deb54399cbadbeb8abd873df6f3af342Jeff Brown    switch (eventEntry->type) {
18384d396052deb54399cbadbeb8abd873df6f3af342Jeff Brown    case EventEntry::TYPE_MOTION: {
1839e2fe69edc009a0e0348e5351cf83062224e011acJeff Brown        const MotionEntry* motionEntry = static_cast<const MotionEntry*>(eventEntry);
18404d396052deb54399cbadbeb8abd873df6f3af342Jeff Brown        if (motionEntry->action == AMOTION_EVENT_ACTION_CANCEL) {
18414d396052deb54399cbadbeb8abd873df6f3af342Jeff Brown            return;
18424d396052deb54399cbadbeb8abd873df6f3af342Jeff Brown        }
18434d396052deb54399cbadbeb8abd873df6f3af342Jeff Brown
184456194ebec6212e229f4ccdaa4b187166d20013efJeff Brown        if (MotionEvent::isTouchEvent(motionEntry->source, motionEntry->action)) {
18451a542c7b8ed0be049869a12d1e01e2604d052ac2Joe Onorato            eventType = POWER_MANAGER_TOUCH_EVENT;
184601ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown        }
18474d396052deb54399cbadbeb8abd873df6f3af342Jeff Brown        break;
18484d396052deb54399cbadbeb8abd873df6f3af342Jeff Brown    }
18494d396052deb54399cbadbeb8abd873df6f3af342Jeff Brown    case EventEntry::TYPE_KEY: {
18504d396052deb54399cbadbeb8abd873df6f3af342Jeff Brown        const KeyEntry* keyEntry = static_cast<const KeyEntry*>(eventEntry);
18514d396052deb54399cbadbeb8abd873df6f3af342Jeff Brown        if (keyEntry->flags & AKEY_EVENT_FLAG_CANCELED) {
18524d396052deb54399cbadbeb8abd873df6f3af342Jeff Brown            return;
18534d396052deb54399cbadbeb8abd873df6f3af342Jeff Brown        }
185456194ebec6212e229f4ccdaa4b187166d20013efJeff Brown        eventType = POWER_MANAGER_BUTTON_EVENT;
18554d396052deb54399cbadbeb8abd873df6f3af342Jeff Brown        break;
18564d396052deb54399cbadbeb8abd873df6f3af342Jeff Brown    }
185701ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    }
185801ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown
1859b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    CommandEntry* commandEntry = postCommandLocked(
1860b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown            & InputDispatcher::doPokeUserActivityLockedInterruptible);
1861e2fe69edc009a0e0348e5351cf83062224e011acJeff Brown    commandEntry->eventTime = eventEntry->eventTime;
1862b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    commandEntry->userActivityEventType = eventType;
186346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
186446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
18657fbdc84e87dd3a0e196b9803bb04495d11e9cb8aJeff Brownvoid InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
18667fbdc84e87dd3a0e196b9803bb04495d11e9cb8aJeff Brown        const sp<Connection>& connection, EventEntry* eventEntry, const InputTarget* inputTarget,
186746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        bool resumeWithAppendedMotionSample) {
186846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#if DEBUG_DISPATCH_CYCLE
18695baa3a62a97544669fba6d65a11c07f252e654ddSteve Block    ALOGD("channel '%s' ~ prepareDispatchCycle - flags=0x%08x, "
18709cc695c5796cf93b414fd7627eb049b7b57d15beJeff Brown            "xOffset=%f, yOffset=%f, scaleFactor=%f, "
187183c09685f2e62bc3cf7e71bc61d903f4b9ccaeb4Jeff Brown            "pointerIds=0x%x, "
187201ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown            "resumeWithAppendedMotionSample=%s",
1873519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown            connection->getInputChannelName(), inputTarget->flags,
187446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            inputTarget->xOffset, inputTarget->yOffset,
1875e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn            inputTarget->scaleFactor, inputTarget->pointerIds.value,
1876b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown            toString(resumeWithAppendedMotionSample));
187746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#endif
187846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
187901ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    // Make sure we are never called for streaming when splitting across multiple windows.
188001ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    bool isSplit = inputTarget->flags & InputTarget::FLAG_SPLIT;
1881b6110c2de0cd7950360aeb2c248a44e4ea5f33f5Jeff Brown    LOG_ASSERT(! (resumeWithAppendedMotionSample && isSplit));
188201ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown
188346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    // Skip this event if the connection status is not normal.
1884519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown    // We don't want to enqueue additional outbound events if the connection is broken.
188546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    if (connection->status != Connection::STATUS_NORMAL) {
1886b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown#if DEBUG_DISPATCH_CYCLE
18875baa3a62a97544669fba6d65a11c07f252e654ddSteve Block        ALOGD("channel '%s' ~ Dropping event because the channel status is %s",
1888b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown                connection->getInputChannelName(), connection->getStatusLabel());
1889b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown#endif
189046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        return;
189146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
189246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
189301ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    // Split a motion event if needed.
189401ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    if (isSplit) {
1895b6110c2de0cd7950360aeb2c248a44e4ea5f33f5Jeff Brown        LOG_ASSERT(eventEntry->type == EventEntry::TYPE_MOTION);
189601ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown
189701ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown        MotionEntry* originalMotionEntry = static_cast<MotionEntry*>(eventEntry);
189801ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown        if (inputTarget->pointerIds.count() != originalMotionEntry->pointerCount) {
189901ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown            MotionEntry* splitMotionEntry = splitMotionEvent(
190001ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown                    originalMotionEntry, inputTarget->pointerIds);
190158a2da843f2f22f406df8df1f011738eb8b7fcb1Jeff Brown            if (!splitMotionEntry) {
190258a2da843f2f22f406df8df1f011738eb8b7fcb1Jeff Brown                return; // split event was dropped
190358a2da843f2f22f406df8df1f011738eb8b7fcb1Jeff Brown            }
190401ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown#if DEBUG_FOCUS
19055baa3a62a97544669fba6d65a11c07f252e654ddSteve Block            ALOGD("channel '%s' ~ Split motion event.",
190601ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown                    connection->getInputChannelName());
190701ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown            logOutboundMotionDetailsLocked("  ", splitMotionEntry);
190801ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown#endif
190901ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown            eventEntry = splitMotionEntry;
191001ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown        }
191101ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    }
191201ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown
191346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    // Resume the dispatch cycle with a freshly appended motion sample.
191446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    // First we check that the last dispatch entry in the outbound queue is for the same
191546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    // motion event to which we appended the motion sample.  If we find such a dispatch
191646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    // entry, and if it is currently in progress then we try to stream the new sample.
191746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    bool wasEmpty = connection->outboundQueue.isEmpty();
191846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
191946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    if (! wasEmpty && resumeWithAppendedMotionSample) {
192046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        DispatchEntry* motionEventDispatchEntry =
192146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown                connection->findQueuedDispatchEntryForEvent(eventEntry);
192246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        if (motionEventDispatchEntry) {
192346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            // If the dispatch entry is not in progress, then we must be busy dispatching an
192446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            // earlier event.  Not a problem, the motion event is on the outbound queue and will
192546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            // be dispatched later.
192646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            if (! motionEventDispatchEntry->inProgress) {
192746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#if DEBUG_BATCHING
19285baa3a62a97544669fba6d65a11c07f252e654ddSteve Block                ALOGD("channel '%s' ~ Not streaming because the motion event has "
192946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown                        "not yet been dispatched.  "
193046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown                        "(Waiting for earlier events to be consumed.)",
193146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown                        connection->getInputChannelName());
193246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#endif
193346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown                return;
193446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            }
193546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
193646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            // If the dispatch entry is in progress but it already has a tail of pending
193746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            // motion samples, then it must mean that the shared memory buffer filled up.
193846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            // Not a problem, when this dispatch cycle is finished, we will eventually start
193946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            // a new dispatch cycle to process the tail and that tail includes the newly
194046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            // appended motion sample.
194146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            if (motionEventDispatchEntry->tailMotionSample) {
194246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#if DEBUG_BATCHING
19435baa3a62a97544669fba6d65a11c07f252e654ddSteve Block                ALOGD("channel '%s' ~ Not streaming because no new samples can "
194446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown                        "be appended to the motion event in this dispatch cycle.  "
194546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown                        "(Waiting for next dispatch cycle to start.)",
194646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown                        connection->getInputChannelName());
194746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#endif
194846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown                return;
194946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            }
195046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
19518134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown            // If the motion event was modified in flight, then we cannot stream the sample.
19528134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown            if ((motionEventDispatchEntry->targetFlags & InputTarget::FLAG_DISPATCH_MASK)
19538134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown                    != InputTarget::FLAG_DISPATCH_AS_IS) {
19548134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown#if DEBUG_BATCHING
19555baa3a62a97544669fba6d65a11c07f252e654ddSteve Block                ALOGD("channel '%s' ~ Not streaming because the motion event was not "
19568134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown                        "being dispatched as-is.  "
19578134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown                        "(Waiting for next dispatch cycle to start.)",
19588134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown                        connection->getInputChannelName());
19598134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown#endif
19608134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown                return;
19618134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown            }
19628134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown
196346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            // The dispatch entry is in progress and is still potentially open for streaming.
196446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            // Try to stream the new motion sample.  This might fail if the consumer has already
196546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            // consumed the motion event (or if the channel is broken).
196601ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown            MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
196701ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown            MotionSample* appendedMotionSample = motionEntry->lastSample;
1968e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn            status_t status;
1969e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn            if (motionEventDispatchEntry->scaleFactor == 1.0f) {
1970e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn                status = connection->inputPublisher.appendMotionSample(
1971e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn                        appendedMotionSample->eventTime, appendedMotionSample->pointerCoords);
1972e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn            } else {
1973e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn                PointerCoords scaledCoords[MAX_POINTERS];
1974e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn                for (size_t i = 0; i < motionEntry->pointerCount; i++) {
1975e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn                    scaledCoords[i] = appendedMotionSample->pointerCoords[i];
1976e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn                    scaledCoords[i].scale(motionEventDispatchEntry->scaleFactor);
1977e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn                }
1978e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn                status = connection->inputPublisher.appendMotionSample(
1979e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn                        appendedMotionSample->eventTime, scaledCoords);
1980e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn            }
198146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            if (status == OK) {
198246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#if DEBUG_BATCHING
19835baa3a62a97544669fba6d65a11c07f252e654ddSteve Block                ALOGD("channel '%s' ~ Successfully streamed new motion sample.",
198446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown                        connection->getInputChannelName());
198546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#endif
198646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown                return;
198746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            }
198846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
198946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#if DEBUG_BATCHING
199046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            if (status == NO_MEMORY) {
19915baa3a62a97544669fba6d65a11c07f252e654ddSteve Block                ALOGD("channel '%s' ~ Could not append motion sample to currently "
199246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown                        "dispatched move event because the shared memory buffer is full.  "
199346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown                        "(Waiting for next dispatch cycle to start.)",
199446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown                        connection->getInputChannelName());
199546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            } else if (status == status_t(FAILED_TRANSACTION)) {
19965baa3a62a97544669fba6d65a11c07f252e654ddSteve Block                ALOGD("channel '%s' ~ Could not append motion sample to currently "
1997349703effce5acc53ed96f7ed8556131f0c65e18Jeff Brown                        "dispatched move event because the event has already been consumed.  "
199846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown                        "(Waiting for next dispatch cycle to start.)",
199946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown                        connection->getInputChannelName());
200046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            } else {
20015baa3a62a97544669fba6d65a11c07f252e654ddSteve Block                ALOGD("channel '%s' ~ Could not append motion sample to currently "
200246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown                        "dispatched move event due to an error, status=%d.  "
200346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown                        "(Waiting for next dispatch cycle to start.)",
200446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown                        connection->getInputChannelName(), status);
200546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            }
200646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#endif
200746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            // Failed to stream.  Start a new tail of pending motion samples to dispatch
200846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            // in the next cycle.
200946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            motionEventDispatchEntry->tailMotionSample = appendedMotionSample;
201046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            return;
201146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        }
201246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
201346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
2014a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown    // Enqueue dispatch entries for the requested modes.
2015a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown    enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
2016a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown            resumeWithAppendedMotionSample, InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT);
2017a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown    enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
2018a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown            resumeWithAppendedMotionSample, InputTarget::FLAG_DISPATCH_AS_OUTSIDE);
2019a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown    enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
2020a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown            resumeWithAppendedMotionSample, InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER);
2021a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown    enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
2022a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown            resumeWithAppendedMotionSample, InputTarget::FLAG_DISPATCH_AS_IS);
202398db5fabdad86dca379740d8050697950b9f026cJeff Brown    enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
202498db5fabdad86dca379740d8050697950b9f026cJeff Brown            resumeWithAppendedMotionSample, InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT);
202598db5fabdad86dca379740d8050697950b9f026cJeff Brown    enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
202698db5fabdad86dca379740d8050697950b9f026cJeff Brown            resumeWithAppendedMotionSample, InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER);
2027a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown
2028a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown    // If the outbound queue was previously empty, start the dispatch cycle going.
2029b6110c2de0cd7950360aeb2c248a44e4ea5f33f5Jeff Brown    if (wasEmpty && !connection->outboundQueue.isEmpty()) {
2030a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown        activateConnectionLocked(connection.get());
2031a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown        startDispatchCycleLocked(currentTime, connection);
2032a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown    }
2033a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown}
2034a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown
2035a032cc008618b83ecbbede537517d1e7998e3264Jeff Brownvoid InputDispatcher::enqueueDispatchEntryLocked(
2036a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown        const sp<Connection>& connection, EventEntry* eventEntry, const InputTarget* inputTarget,
2037a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown        bool resumeWithAppendedMotionSample, int32_t dispatchMode) {
2038a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown    int32_t inputTargetFlags = inputTarget->flags;
2039a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown    if (!(inputTargetFlags & dispatchMode)) {
2040a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown        return;
2041a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown    }
2042a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown    inputTargetFlags = (inputTargetFlags & ~InputTarget::FLAG_DISPATCH_MASK) | dispatchMode;
2043a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown
204446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    // This is a new event.
204546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    // Enqueue a new dispatch entry onto the outbound queue for this connection.
2046ac386073df2514b79a2ca169f4a89f129733002fJeff Brown    DispatchEntry* dispatchEntry = new DispatchEntry(eventEntry, // increments ref
2047aa9d84c37e05f696ec158dac98ce38cf41e18314Dianne Hackborn            inputTargetFlags, inputTarget->xOffset, inputTarget->yOffset,
2048e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn            inputTarget->scaleFactor);
2049519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown    if (dispatchEntry->hasForegroundTarget()) {
205001ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown        incrementPendingForegroundDispatchesLocked(eventEntry);
20516ec402b5ae33c8927694d8522b4cc6a5c8ba974eJeff Brown    }
20526ec402b5ae33c8927694d8522b4cc6a5c8ba974eJeff Brown
205346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    // Handle the case where we could not stream a new motion sample because the consumer has
205446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    // already consumed the motion event (otherwise the corresponding dispatch entry would
205546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    // still be in the outbound queue for this connection).  We set the head motion sample
205646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    // to the list starting with the newly appended motion sample.
205746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    if (resumeWithAppendedMotionSample) {
205846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#if DEBUG_BATCHING
20595baa3a62a97544669fba6d65a11c07f252e654ddSteve Block        ALOGD("channel '%s' ~ Preparing a new dispatch cycle for additional motion samples "
206046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown                "that cannot be streamed because the motion event has already been consumed.",
206146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown                connection->getInputChannelName());
206246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#endif
206346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        MotionSample* appendedMotionSample = static_cast<MotionEntry*>(eventEntry)->lastSample;
206446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        dispatchEntry->headMotionSample = appendedMotionSample;
206546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
206646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
20678134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown    // Apply target flags and update the connection's input state.
20688134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown    switch (eventEntry->type) {
20698134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown    case EventEntry::TYPE_KEY: {
20708134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        KeyEntry* keyEntry = static_cast<KeyEntry*>(eventEntry);
20718134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        dispatchEntry->resolvedAction = keyEntry->action;
20728134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        dispatchEntry->resolvedFlags = keyEntry->flags;
20738134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown
20748134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        if (!connection->inputState.trackKey(keyEntry,
20758134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown                dispatchEntry->resolvedAction, dispatchEntry->resolvedFlags)) {
20768134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown#if DEBUG_DISPATCH_CYCLE
20775baa3a62a97544669fba6d65a11c07f252e654ddSteve Block            ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent key event",
20788134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown                    connection->getInputChannelName());
20798134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown#endif
20808134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown            return; // skip the inconsistent event
20818134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        }
20828134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        break;
20838134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown    }
20848134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown
20858134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown    case EventEntry::TYPE_MOTION: {
20868134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
20878134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
20888134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown            dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_OUTSIDE;
20898134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT) {
20908134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown            dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_EXIT;
20918134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER) {
20928134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown            dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
20938134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT) {
20948134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown            dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_CANCEL;
20958134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER) {
20968134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown            dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_DOWN;
20978134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        } else {
20988134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown            dispatchEntry->resolvedAction = motionEntry->action;
20998134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        }
21008134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        if (dispatchEntry->resolvedAction == AMOTION_EVENT_ACTION_HOVER_MOVE
21018134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown                && !connection->inputState.isHovering(
21028134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown                        motionEntry->deviceId, motionEntry->source)) {
21038134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown#if DEBUG_DISPATCH_CYCLE
21045baa3a62a97544669fba6d65a11c07f252e654ddSteve Block        ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: filling in missing hover enter event",
21058134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown                connection->getInputChannelName());
21068134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown#endif
21078134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown            dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
21088134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        }
21098134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown
21108134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        dispatchEntry->resolvedFlags = motionEntry->flags;
21118134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) {
21128134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown            dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
21138134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        }
21148134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown
21158134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        if (!connection->inputState.trackMotion(motionEntry,
21168134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown                dispatchEntry->resolvedAction, dispatchEntry->resolvedFlags)) {
21178134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown#if DEBUG_DISPATCH_CYCLE
21185baa3a62a97544669fba6d65a11c07f252e654ddSteve Block            ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent motion event",
21198134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown                    connection->getInputChannelName());
21208134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown#endif
21218134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown            return; // skip the inconsistent event
21228134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        }
21238134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        break;
21248134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown    }
21258134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown    }
21268134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown
212746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    // Enqueue the dispatch entry.
212846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    connection->outboundQueue.enqueueAtTail(dispatchEntry);
212946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
213046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
21317fbdc84e87dd3a0e196b9803bb04495d11e9cb8aJeff Brownvoid InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
2132519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown        const sp<Connection>& connection) {
213346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#if DEBUG_DISPATCH_CYCLE
21345baa3a62a97544669fba6d65a11c07f252e654ddSteve Block    ALOGD("channel '%s' ~ startDispatchCycle",
213546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            connection->getInputChannelName());
213646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#endif
213746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
2138b6110c2de0cd7950360aeb2c248a44e4ea5f33f5Jeff Brown    LOG_ASSERT(connection->status == Connection::STATUS_NORMAL);
2139b6110c2de0cd7950360aeb2c248a44e4ea5f33f5Jeff Brown    LOG_ASSERT(! connection->outboundQueue.isEmpty());
214046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
2141ac386073df2514b79a2ca169f4a89f129733002fJeff Brown    DispatchEntry* dispatchEntry = connection->outboundQueue.head;
2142b6110c2de0cd7950360aeb2c248a44e4ea5f33f5Jeff Brown    LOG_ASSERT(! dispatchEntry->inProgress);
214346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
2144b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    // Mark the dispatch entry as in progress.
2145b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    dispatchEntry->inProgress = true;
2146b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
214746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    // Publish the event.
214846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    status_t status;
2149a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown    EventEntry* eventEntry = dispatchEntry->eventEntry;
215001ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    switch (eventEntry->type) {
215146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    case EventEntry::TYPE_KEY: {
215201ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown        KeyEntry* keyEntry = static_cast<KeyEntry*>(eventEntry);
215346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
215446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        // Publish the key event.
21558134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        status = connection->inputPublisher.publishKeyEvent(
21568134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown                keyEntry->deviceId, keyEntry->source,
21578134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown                dispatchEntry->resolvedAction, dispatchEntry->resolvedFlags,
21588134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown                keyEntry->keyCode, keyEntry->scanCode,
215946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown                keyEntry->metaState, keyEntry->repeatCount, keyEntry->downTime,
216046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown                keyEntry->eventTime);
216146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
216246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        if (status) {
216346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            LOGE("channel '%s' ~ Could not publish key event, "
216446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown                    "status=%d", connection->getInputChannelName(), status);
2165cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown            abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
216646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            return;
216746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        }
216846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        break;
216946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
217046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
217146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    case EventEntry::TYPE_MOTION: {
217201ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown        MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
217346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
217446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        // If headMotionSample is non-NULL, then it points to the first new sample that we
217546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        // were unable to dispatch during the previous cycle so we resume dispatching from
217646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        // that point in the list of motion samples.
217746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        // Otherwise, we just start from the first sample of the motion event.
217846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        MotionSample* firstMotionSample = dispatchEntry->headMotionSample;
217946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        if (! firstMotionSample) {
218046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            firstMotionSample = & motionEntry->firstSample;
218146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        }
218246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
2183e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn        PointerCoords scaledCoords[MAX_POINTERS];
2184e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn        const PointerCoords* usingCoords = firstMotionSample->pointerCoords;
2185e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn
2186d3616592fe1b315b589766c4b74ce728fc4968f5Jeff Brown        // Set the X and Y offset depending on the input source.
2187e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn        float xOffset, yOffset, scaleFactor;
21887a9db181a64e0e752a447c6408639bbb33c412fcKenny Root        if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER
21897a9db181a64e0e752a447c6408639bbb33c412fcKenny Root                && !(dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS)) {
2190e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn            scaleFactor = dispatchEntry->scaleFactor;
2191e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn            xOffset = dispatchEntry->xOffset * scaleFactor;
2192e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn            yOffset = dispatchEntry->yOffset * scaleFactor;
2193e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn            if (scaleFactor != 1.0f) {
2194e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn                for (size_t i = 0; i < motionEntry->pointerCount; i++) {
2195e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn                    scaledCoords[i] = firstMotionSample->pointerCoords[i];
2196e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn                    scaledCoords[i].scale(scaleFactor);
2197e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn                }
2198e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn                usingCoords = scaledCoords;
2199e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn            }
2200d3616592fe1b315b589766c4b74ce728fc4968f5Jeff Brown        } else {
2201d3616592fe1b315b589766c4b74ce728fc4968f5Jeff Brown            xOffset = 0.0f;
2202d3616592fe1b315b589766c4b74ce728fc4968f5Jeff Brown            yOffset = 0.0f;
2203e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn            scaleFactor = 1.0f;
22047a9db181a64e0e752a447c6408639bbb33c412fcKenny Root
22057a9db181a64e0e752a447c6408639bbb33c412fcKenny Root            // We don't want the dispatch target to know.
22067a9db181a64e0e752a447c6408639bbb33c412fcKenny Root            if (dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS) {
22077a9db181a64e0e752a447c6408639bbb33c412fcKenny Root                for (size_t i = 0; i < motionEntry->pointerCount; i++) {
22087a9db181a64e0e752a447c6408639bbb33c412fcKenny Root                    scaledCoords[i].clear();
22097a9db181a64e0e752a447c6408639bbb33c412fcKenny Root                }
22107a9db181a64e0e752a447c6408639bbb33c412fcKenny Root                usingCoords = scaledCoords;
22117a9db181a64e0e752a447c6408639bbb33c412fcKenny Root            }
2212d3616592fe1b315b589766c4b74ce728fc4968f5Jeff Brown        }
2213d3616592fe1b315b589766c4b74ce728fc4968f5Jeff Brown
221446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        // Publish the motion event and the first motion sample.
22158134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        status = connection->inputPublisher.publishMotionEvent(
22168134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown                motionEntry->deviceId, motionEntry->source,
22178134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown                dispatchEntry->resolvedAction, dispatchEntry->resolvedFlags,
22188134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown                motionEntry->edgeFlags, motionEntry->metaState, motionEntry->buttonState,
2219fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                xOffset, yOffset,
2220fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                motionEntry->xPrecision, motionEntry->yPrecision,
222146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown                motionEntry->downTime, firstMotionSample->eventTime,
2222fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                motionEntry->pointerCount, motionEntry->pointerProperties,
2223fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                usingCoords);
222446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
222546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        if (status) {
222646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            LOGE("channel '%s' ~ Could not publish motion event, "
222746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown                    "status=%d", connection->getInputChannelName(), status);
2228cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown            abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
222946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            return;
223046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        }
223146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
22328134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        if (dispatchEntry->resolvedAction == AMOTION_EVENT_ACTION_MOVE
22338134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown                || dispatchEntry->resolvedAction == AMOTION_EVENT_ACTION_HOVER_MOVE) {
2234a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown            // Append additional motion samples.
2235a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown            MotionSample* nextMotionSample = firstMotionSample->next;
2236a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown            for (; nextMotionSample != NULL; nextMotionSample = nextMotionSample->next) {
2237fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                if (usingCoords == scaledCoords) {
22387a9db181a64e0e752a447c6408639bbb33c412fcKenny Root                    if (!(dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS)) {
22397a9db181a64e0e752a447c6408639bbb33c412fcKenny Root                        for (size_t i = 0; i < motionEntry->pointerCount; i++) {
22407a9db181a64e0e752a447c6408639bbb33c412fcKenny Root                            scaledCoords[i] = nextMotionSample->pointerCoords[i];
22417a9db181a64e0e752a447c6408639bbb33c412fcKenny Root                            scaledCoords[i].scale(scaleFactor);
22427a9db181a64e0e752a447c6408639bbb33c412fcKenny Root                        }
22432ba3e80f942d35695310f8dde8c16d9687447e47Dianne Hackborn                    }
22442ba3e80f942d35695310f8dde8c16d9687447e47Dianne Hackborn                } else {
22452ba3e80f942d35695310f8dde8c16d9687447e47Dianne Hackborn                    usingCoords = nextMotionSample->pointerCoords;
2246e7d25b74b0f5c8ad32225c7a3e98a0d1717eb7c7Dianne Hackborn                }
2247a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown                status = connection->inputPublisher.appendMotionSample(
2248aa9d84c37e05f696ec158dac98ce38cf41e18314Dianne Hackborn                        nextMotionSample->eventTime, usingCoords);
2249a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown                if (status == NO_MEMORY) {
225046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#if DEBUG_DISPATCH_CYCLE
22515baa3a62a97544669fba6d65a11c07f252e654ddSteve Block                    ALOGD("channel '%s' ~ Shared memory buffer full.  Some motion samples will "
225246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown                            "be sent in the next dispatch cycle.",
225346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown                            connection->getInputChannelName());
225446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#endif
2255a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown                    break;
2256a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown                }
2257a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown                if (status != OK) {
2258a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown                    LOGE("channel '%s' ~ Could not append motion sample "
2259a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown                            "for a reason other than out of memory, status=%d",
2260a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown                            connection->getInputChannelName(), status);
2261cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown                    abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
2262a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown                    return;
2263a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown                }
226446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            }
226546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
2266a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown            // Remember the next motion sample that we could not dispatch, in case we ran out
2267a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown            // of space in the shared memory buffer.
2268a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown            dispatchEntry->tailMotionSample = nextMotionSample;
2269a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown        }
227046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        break;
227146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
227246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
227346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    default: {
2274b6110c2de0cd7950360aeb2c248a44e4ea5f33f5Jeff Brown        LOG_ASSERT(false);
227546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
227646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
227746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
227846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    // Send the dispatch signal.
227946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    status = connection->inputPublisher.sendDispatchSignal();
228046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    if (status) {
228146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        LOGE("channel '%s' ~ Could not send dispatch signal, status=%d",
228246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown                connection->getInputChannelName(), status);
2283cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown        abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
228446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        return;
228546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
228646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
228746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    // Record information about the newly started dispatch cycle.
228801ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    connection->lastEventTime = eventEntry->eventTime;
228946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    connection->lastDispatchTime = currentTime;
229046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
229146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    // Notify other system components.
229246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    onDispatchCycleStartedLocked(currentTime, connection);
229346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
229446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
22957fbdc84e87dd3a0e196b9803bb04495d11e9cb8aJeff Brownvoid InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
22963915bb845b032dc184dba5e60970b803390ca3edJeff Brown        const sp<Connection>& connection, bool handled) {
229746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#if DEBUG_DISPATCH_CYCLE
22985baa3a62a97544669fba6d65a11c07f252e654ddSteve Block    ALOGD("channel '%s' ~ finishDispatchCycle - %01.1fms since event, "
22993915bb845b032dc184dba5e60970b803390ca3edJeff Brown            "%01.1fms since dispatch, handled=%s",
230046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            connection->getInputChannelName(),
230146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            connection->getEventLatencyMillis(currentTime),
23023915bb845b032dc184dba5e60970b803390ca3edJeff Brown            connection->getDispatchLatencyMillis(currentTime),
23033915bb845b032dc184dba5e60970b803390ca3edJeff Brown            toString(handled));
230446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#endif
230546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
23069c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown    if (connection->status == Connection::STATUS_BROKEN
23079c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown            || connection->status == Connection::STATUS_ZOMBIE) {
230846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        return;
230946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
231046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
231146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    // Reset the publisher since the event has been consumed.
231246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    // We do this now so that the publisher can release some of its internal resources
231346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    // while waiting for the next dispatch cycle to begin.
231446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    status_t status = connection->inputPublisher.reset();
231546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    if (status) {
231646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        LOGE("channel '%s' ~ Could not reset publisher, status=%d",
231746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown                connection->getInputChannelName(), status);
2318cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown        abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
231946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        return;
232046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
232146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
23223915bb845b032dc184dba5e60970b803390ca3edJeff Brown    // Notify other system components and prepare to start the next dispatch cycle.
23233915bb845b032dc184dba5e60970b803390ca3edJeff Brown    onDispatchCycleFinishedLocked(currentTime, connection, handled);
2324b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown}
2325b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
2326b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brownvoid InputDispatcher::startNextDispatchCycleLocked(nsecs_t currentTime,
2327b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        const sp<Connection>& connection) {
232846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    // Start the next dispatch cycle for this connection.
232946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    while (! connection->outboundQueue.isEmpty()) {
2330ac386073df2514b79a2ca169f4a89f129733002fJeff Brown        DispatchEntry* dispatchEntry = connection->outboundQueue.head;
233146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        if (dispatchEntry->inProgress) {
233246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown             // Finish or resume current event in progress.
233346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            if (dispatchEntry->tailMotionSample) {
233446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown                // We have a tail of undispatched motion samples.
233546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown                // Reuse the same DispatchEntry and start a new cycle.
233646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown                dispatchEntry->inProgress = false;
233746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown                dispatchEntry->headMotionSample = dispatchEntry->tailMotionSample;
233846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown                dispatchEntry->tailMotionSample = NULL;
2339519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown                startDispatchCycleLocked(currentTime, connection);
234046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown                return;
234146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            }
234246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            // Finished.
234346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            connection->outboundQueue.dequeueAtHead();
2344519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown            if (dispatchEntry->hasForegroundTarget()) {
2345519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown                decrementPendingForegroundDispatchesLocked(dispatchEntry->eventEntry);
23466ec402b5ae33c8927694d8522b4cc6a5c8ba974eJeff Brown            }
2347ac386073df2514b79a2ca169f4a89f129733002fJeff Brown            delete dispatchEntry;
234846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        } else {
234946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            // If the head is not in progress, then we must have already dequeued the in
2350519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown            // progress event, which means we actually aborted it.
235146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            // So just start the next event for this connection.
2352519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown            startDispatchCycleLocked(currentTime, connection);
235346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            return;
235446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        }
235546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
235646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
235746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    // Outbound queue is empty, deactivate the connection.
23587fbdc84e87dd3a0e196b9803bb04495d11e9cb8aJeff Brown    deactivateConnectionLocked(connection.get());
235946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
236046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
2361b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brownvoid InputDispatcher::abortBrokenDispatchCycleLocked(nsecs_t currentTime,
2362cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown        const sp<Connection>& connection, bool notify) {
236346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#if DEBUG_DISPATCH_CYCLE
23645baa3a62a97544669fba6d65a11c07f252e654ddSteve Block    ALOGD("channel '%s' ~ abortBrokenDispatchCycle - notify=%s",
2365cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown            connection->getInputChannelName(), toString(notify));
236646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#endif
236746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
2368b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    // Clear the outbound queue.
2369519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown    drainOutboundQueueLocked(connection.get());
237046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
2371b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown    // The connection appears to be unrecoverably broken.
23729c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown    // Ignore already broken or zombie connections.
2373b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown    if (connection->status == Connection::STATUS_NORMAL) {
2374b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown        connection->status = Connection::STATUS_BROKEN;
237546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
2376cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown        if (notify) {
2377cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown            // Notify other system components.
2378cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown            onDispatchCycleBrokenLocked(currentTime, connection);
2379cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown        }
238046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
238146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
238246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
2383519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brownvoid InputDispatcher::drainOutboundQueueLocked(Connection* connection) {
2384519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown    while (! connection->outboundQueue.isEmpty()) {
2385519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown        DispatchEntry* dispatchEntry = connection->outboundQueue.dequeueAtHead();
2386519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown        if (dispatchEntry->hasForegroundTarget()) {
2387519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown            decrementPendingForegroundDispatchesLocked(dispatchEntry->eventEntry);
2388b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        }
2389ac386073df2514b79a2ca169f4a89f129733002fJeff Brown        delete dispatchEntry;
2390b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    }
2391b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
2392519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown    deactivateConnectionLocked(connection);
2393b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown}
2394b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
23954fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brownint InputDispatcher::handleReceiveCallback(int receiveFd, int events, void* data) {
239646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    InputDispatcher* d = static_cast<InputDispatcher*>(data);
239746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
239846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    { // acquire lock
239946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        AutoMutex _l(d->mLock);
240046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
240146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        ssize_t connectionIndex = d->mConnectionsByReceiveFd.indexOfKey(receiveFd);
240246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        if (connectionIndex < 0) {
240346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            LOGE("Received spurious receive callback for unknown input channel.  "
240446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown                    "fd=%d, events=0x%x", receiveFd, events);
24054fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown            return 0; // remove the callback
240646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        }
240746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
2408cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown        bool notify;
240946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        sp<Connection> connection = d->mConnectionsByReceiveFd.valueAt(connectionIndex);
2410cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown        if (!(events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP))) {
2411cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown            if (!(events & ALOOPER_EVENT_INPUT)) {
24128564c8da817a845353d213acd8636b76f567b234Steve Block                ALOGW("channel '%s' ~ Received spurious callback for unhandled poll event.  "
2413cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown                        "events=0x%x", connection->getInputChannelName(), events);
2414cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown                return 1;
2415cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown            }
241646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
2417cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown            bool handled = false;
2418cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown            status_t status = connection->inputPublisher.receiveFinishedSignal(&handled);
2419cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown            if (!status) {
2420cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown                nsecs_t currentTime = now();
2421cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown                d->finishDispatchCycleLocked(currentTime, connection, handled);
2422cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown                d->runCommandsLockedInterruptible();
2423cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown                return 1;
2424cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown            }
242546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
242646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            LOGE("channel '%s' ~ Failed to receive finished signal.  status=%d",
242746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown                    connection->getInputChannelName(), status);
2428cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown            notify = true;
2429cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown        } else {
2430cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown            // Monitor channels are never explicitly unregistered.
2431cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown            // We do it automatically when the remote endpoint is closed so don't warn
2432cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown            // about them.
2433cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown            notify = !connection->monitor;
2434cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown            if (notify) {
24358564c8da817a845353d213acd8636b76f567b234Steve Block                ALOGW("channel '%s' ~ Consumer closed input channel or an error occurred.  "
2436cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown                        "events=0x%x", connection->getInputChannelName(), events);
2437cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown            }
243846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        }
243946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
2440cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown        // Unregister the channel.
2441cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown        d->unregisterInputChannelLocked(connection->inputChannel, notify);
2442cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown        return 0; // remove the callback
244346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    } // release lock
244446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
244546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
2446b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brownvoid InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked(
2447da3d5a91b6b311ed77f2707d4456c1f18b84d73bJeff Brown        const CancelationOptions& options) {
2448b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown    for (size_t i = 0; i < mConnectionsByReceiveFd.size(); i++) {
2449b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown        synthesizeCancelationEventsForConnectionLocked(
2450da3d5a91b6b311ed77f2707d4456c1f18b84d73bJeff Brown                mConnectionsByReceiveFd.valueAt(i), options);
2451b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown    }
2452b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown}
2453b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown
2454b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brownvoid InputDispatcher::synthesizeCancelationEventsForInputChannelLocked(
2455da3d5a91b6b311ed77f2707d4456c1f18b84d73bJeff Brown        const sp<InputChannel>& channel, const CancelationOptions& options) {
2456b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown    ssize_t index = getConnectionIndexLocked(channel);
2457b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown    if (index >= 0) {
2458b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown        synthesizeCancelationEventsForConnectionLocked(
2459da3d5a91b6b311ed77f2707d4456c1f18b84d73bJeff Brown                mConnectionsByReceiveFd.valueAt(index), options);
2460b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown    }
2461b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown}
2462b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown
2463b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brownvoid InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
2464da3d5a91b6b311ed77f2707d4456c1f18b84d73bJeff Brown        const sp<Connection>& connection, const CancelationOptions& options) {
2465b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown    nsecs_t currentTime = now();
2466b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown
2467b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown    mTempCancelationEvents.clear();
2468ac386073df2514b79a2ca169f4a89f129733002fJeff Brown    connection->inputState.synthesizeCancelationEvents(currentTime,
2469b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown            mTempCancelationEvents, options);
2470b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown
2471b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown    if (! mTempCancelationEvents.isEmpty()
2472b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown            && connection->status != Connection::STATUS_BROKEN) {
2473b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown#if DEBUG_OUTBOUND_EVENT_DETAILS
24745baa3a62a97544669fba6d65a11c07f252e654ddSteve Block        ALOGD("channel '%s' ~ Synthesized %d cancelation events to bring channel back in sync "
2475da3d5a91b6b311ed77f2707d4456c1f18b84d73bJeff Brown                "with reality: %s, mode=%d.",
2476da3d5a91b6b311ed77f2707d4456c1f18b84d73bJeff Brown                connection->getInputChannelName(), mTempCancelationEvents.size(),
2477da3d5a91b6b311ed77f2707d4456c1f18b84d73bJeff Brown                options.reason, options.mode);
2478b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown#endif
2479b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown        for (size_t i = 0; i < mTempCancelationEvents.size(); i++) {
2480b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown            EventEntry* cancelationEventEntry = mTempCancelationEvents.itemAt(i);
2481b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown            switch (cancelationEventEntry->type) {
2482b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown            case EventEntry::TYPE_KEY:
2483b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown                logOutboundKeyDetailsLocked("cancel - ",
2484b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown                        static_cast<KeyEntry*>(cancelationEventEntry));
2485b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown                break;
2486b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown            case EventEntry::TYPE_MOTION:
2487b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown                logOutboundMotionDetailsLocked("cancel - ",
2488b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown                        static_cast<MotionEntry*>(cancelationEventEntry));
2489b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown                break;
2490b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown            }
2491b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown
24928134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown            InputTarget target;
24939302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown            sp<InputWindowHandle> windowHandle = getWindowHandleLocked(connection->inputChannel);
24949302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown            if (windowHandle != NULL) {
2495cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown                const InputWindowInfo* windowInfo = windowHandle->getInfo();
2496cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown                target.xOffset = -windowInfo->frameLeft;
2497cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown                target.yOffset = -windowInfo->frameTop;
2498cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown                target.scaleFactor = windowInfo->scaleFactor;
2499b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown            } else {
25008134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown                target.xOffset = 0;
25018134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown                target.yOffset = 0;
25028134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown                target.scaleFactor = 1.0f;
2503b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown            }
25048134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown            target.inputChannel = connection->inputChannel;
25058134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown            target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
2506b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown
25078134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown            enqueueDispatchEntryLocked(connection, cancelationEventEntry, // increments ref
25088134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown                    &target, false, InputTarget::FLAG_DISPATCH_AS_IS);
2509b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown
2510ac386073df2514b79a2ca169f4a89f129733002fJeff Brown            cancelationEventEntry->release();
2511b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown        }
2512b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown
2513ac386073df2514b79a2ca169f4a89f129733002fJeff Brown        if (!connection->outboundQueue.head->inProgress) {
2514b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown            startDispatchCycleLocked(currentTime, connection);
2515b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown        }
2516b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown    }
2517b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown}
2518b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown
251901ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff BrownInputDispatcher::MotionEntry*
252001ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff BrownInputDispatcher::splitMotionEvent(const MotionEntry* originalMotionEntry, BitSet32 pointerIds) {
2521b6110c2de0cd7950360aeb2c248a44e4ea5f33f5Jeff Brown    LOG_ASSERT(pointerIds.value != 0);
252201ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown
252301ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    uint32_t splitPointerIndexMap[MAX_POINTERS];
2524fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    PointerProperties splitPointerProperties[MAX_POINTERS];
252501ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    PointerCoords splitPointerCoords[MAX_POINTERS];
252601ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown
252701ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    uint32_t originalPointerCount = originalMotionEntry->pointerCount;
252801ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    uint32_t splitPointerCount = 0;
252901ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown
253001ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    for (uint32_t originalPointerIndex = 0; originalPointerIndex < originalPointerCount;
253101ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown            originalPointerIndex++) {
2532fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        const PointerProperties& pointerProperties =
2533fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                originalMotionEntry->pointerProperties[originalPointerIndex];
2534fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        uint32_t pointerId = uint32_t(pointerProperties.id);
253501ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown        if (pointerIds.hasBit(pointerId)) {
253601ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown            splitPointerIndexMap[splitPointerCount] = originalPointerIndex;
2537fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            splitPointerProperties[splitPointerCount].copyFrom(pointerProperties);
2538ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            splitPointerCoords[splitPointerCount].copyFrom(
2539ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                    originalMotionEntry->firstSample.pointerCoords[originalPointerIndex]);
254001ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown            splitPointerCount += 1;
254101ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown        }
254201ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    }
254358a2da843f2f22f406df8df1f011738eb8b7fcb1Jeff Brown
254458a2da843f2f22f406df8df1f011738eb8b7fcb1Jeff Brown    if (splitPointerCount != pointerIds.count()) {
254558a2da843f2f22f406df8df1f011738eb8b7fcb1Jeff Brown        // This is bad.  We are missing some of the pointers that we expected to deliver.
254658a2da843f2f22f406df8df1f011738eb8b7fcb1Jeff Brown        // Most likely this indicates that we received an ACTION_MOVE events that has
254758a2da843f2f22f406df8df1f011738eb8b7fcb1Jeff Brown        // different pointer ids than we expected based on the previous ACTION_DOWN
254858a2da843f2f22f406df8df1f011738eb8b7fcb1Jeff Brown        // or ACTION_POINTER_DOWN events that caused us to decide to split the pointers
254958a2da843f2f22f406df8df1f011738eb8b7fcb1Jeff Brown        // in this way.
25508564c8da817a845353d213acd8636b76f567b234Steve Block        ALOGW("Dropping split motion event because the pointer count is %d but "
255158a2da843f2f22f406df8df1f011738eb8b7fcb1Jeff Brown                "we expected there to be %d pointers.  This probably means we received "
255258a2da843f2f22f406df8df1f011738eb8b7fcb1Jeff Brown                "a broken sequence of pointer ids from the input device.",
255358a2da843f2f22f406df8df1f011738eb8b7fcb1Jeff Brown                splitPointerCount, pointerIds.count());
255458a2da843f2f22f406df8df1f011738eb8b7fcb1Jeff Brown        return NULL;
255558a2da843f2f22f406df8df1f011738eb8b7fcb1Jeff Brown    }
255601ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown
255701ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    int32_t action = originalMotionEntry->action;
255801ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
255901ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    if (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
256001ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown            || maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
256101ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown        int32_t originalPointerIndex = getMotionEventActionPointerIndex(action);
2562fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        const PointerProperties& pointerProperties =
2563fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                originalMotionEntry->pointerProperties[originalPointerIndex];
2564fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        uint32_t pointerId = uint32_t(pointerProperties.id);
256501ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown        if (pointerIds.hasBit(pointerId)) {
256601ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown            if (pointerIds.count() == 1) {
256701ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown                // The first/last pointer went down/up.
256801ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown                action = maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
256901ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown                        ? AMOTION_EVENT_ACTION_DOWN : AMOTION_EVENT_ACTION_UP;
25709a01d0519fa56fa75864cb96045c6ee832a39ff4Jeff Brown            } else {
25719a01d0519fa56fa75864cb96045c6ee832a39ff4Jeff Brown                // A secondary pointer went down/up.
25729a01d0519fa56fa75864cb96045c6ee832a39ff4Jeff Brown                uint32_t splitPointerIndex = 0;
2573fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                while (pointerId != uint32_t(splitPointerProperties[splitPointerIndex].id)) {
25749a01d0519fa56fa75864cb96045c6ee832a39ff4Jeff Brown                    splitPointerIndex += 1;
25759a01d0519fa56fa75864cb96045c6ee832a39ff4Jeff Brown                }
25769a01d0519fa56fa75864cb96045c6ee832a39ff4Jeff Brown                action = maskedAction | (splitPointerIndex
25779a01d0519fa56fa75864cb96045c6ee832a39ff4Jeff Brown                        << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
257801ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown            }
257901ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown        } else {
258001ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown            // An unrelated pointer changed.
258101ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown            action = AMOTION_EVENT_ACTION_MOVE;
258201ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown        }
258301ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    }
258401ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown
2585ac386073df2514b79a2ca169f4a89f129733002fJeff Brown    MotionEntry* splitMotionEntry = new MotionEntry(
258601ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown            originalMotionEntry->eventTime,
258701ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown            originalMotionEntry->deviceId,
258801ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown            originalMotionEntry->source,
258901ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown            originalMotionEntry->policyFlags,
259001ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown            action,
259101ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown            originalMotionEntry->flags,
259201ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown            originalMotionEntry->metaState,
2593fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            originalMotionEntry->buttonState,
259401ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown            originalMotionEntry->edgeFlags,
259501ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown            originalMotionEntry->xPrecision,
259601ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown            originalMotionEntry->yPrecision,
259701ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown            originalMotionEntry->downTime,
2598fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            splitPointerCount, splitPointerProperties, splitPointerCoords);
259901ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown
260001ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    for (MotionSample* originalMotionSample = originalMotionEntry->firstSample.next;
260101ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown            originalMotionSample != NULL; originalMotionSample = originalMotionSample->next) {
260201ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown        for (uint32_t splitPointerIndex = 0; splitPointerIndex < splitPointerCount;
260301ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown                splitPointerIndex++) {
260401ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown            uint32_t originalPointerIndex = splitPointerIndexMap[splitPointerIndex];
2605ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown            splitPointerCoords[splitPointerIndex].copyFrom(
2606ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown                    originalMotionSample->pointerCoords[originalPointerIndex]);
260701ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown        }
260801ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown
2609ac386073df2514b79a2ca169f4a89f129733002fJeff Brown        splitMotionEntry->appendSample(originalMotionSample->eventTime, splitPointerCoords);
261001ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    }
261101ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown
2612a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown    if (originalMotionEntry->injectionState) {
2613a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown        splitMotionEntry->injectionState = originalMotionEntry->injectionState;
2614a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown        splitMotionEntry->injectionState->refCount += 1;
2615a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown    }
2616a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown
261701ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    return splitMotionEntry;
261801ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown}
261901ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown
2620be1aa8250cee7819c49741e819e81659d1d03823Jeff Brownvoid InputDispatcher::notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args) {
262146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#if DEBUG_INBOUND_EVENT_DETAILS
26225baa3a62a97544669fba6d65a11c07f252e654ddSteve Block    ALOGD("notifyConfigurationChanged - eventTime=%lld", args->eventTime);
2623b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown#endif
262446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
2625b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    bool needWake;
2626b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    { // acquire lock
2627b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        AutoMutex _l(mLock);
2628b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
2629be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        ConfigurationChangedEntry* newEntry = new ConfigurationChangedEntry(args->eventTime);
2630b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        needWake = enqueueInboundEventLocked(newEntry);
263146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    } // release lock
2632b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
2633b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    if (needWake) {
26344fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown        mLooper->wake();
2635b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    }
263646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
263746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
2638be1aa8250cee7819c49741e819e81659d1d03823Jeff Brownvoid InputDispatcher::notifyKey(const NotifyKeyArgs* args) {
263946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#if DEBUG_INBOUND_EVENT_DETAILS
26405baa3a62a97544669fba6d65a11c07f252e654ddSteve Block    ALOGD("notifyKey - eventTime=%lld, deviceId=%d, source=0x%x, policyFlags=0x%x, action=0x%x, "
264146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%lld",
2642be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            args->eventTime, args->deviceId, args->source, args->policyFlags,
2643be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            args->action, args->flags, args->keyCode, args->scanCode,
2644be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            args->metaState, args->downTime);
264546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#endif
2646be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    if (!validateKeyEvent(args->action)) {
264701ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown        return;
264801ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    }
264946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
2650be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    uint32_t policyFlags = args->policyFlags;
2651be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    int32_t flags = args->flags;
2652be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    int32_t metaState = args->metaState;
26531f2451007c660091b7b090c1ea332f9044515d2dJeff Brown    if ((policyFlags & POLICY_FLAG_VIRTUAL) || (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY)) {
26541f2451007c660091b7b090c1ea332f9044515d2dJeff Brown        policyFlags |= POLICY_FLAG_VIRTUAL;
26551f2451007c660091b7b090c1ea332f9044515d2dJeff Brown        flags |= AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
26561f2451007c660091b7b090c1ea332f9044515d2dJeff Brown    }
2657924c4d47774fa7d8a5ce659d12291ef7df82ee05Jeff Brown    if (policyFlags & POLICY_FLAG_ALT) {
2658924c4d47774fa7d8a5ce659d12291ef7df82ee05Jeff Brown        metaState |= AMETA_ALT_ON | AMETA_ALT_LEFT_ON;
2659924c4d47774fa7d8a5ce659d12291ef7df82ee05Jeff Brown    }
2660924c4d47774fa7d8a5ce659d12291ef7df82ee05Jeff Brown    if (policyFlags & POLICY_FLAG_ALT_GR) {
2661924c4d47774fa7d8a5ce659d12291ef7df82ee05Jeff Brown        metaState |= AMETA_ALT_ON | AMETA_ALT_RIGHT_ON;
2662924c4d47774fa7d8a5ce659d12291ef7df82ee05Jeff Brown    }
2663924c4d47774fa7d8a5ce659d12291ef7df82ee05Jeff Brown    if (policyFlags & POLICY_FLAG_SHIFT) {
2664924c4d47774fa7d8a5ce659d12291ef7df82ee05Jeff Brown        metaState |= AMETA_SHIFT_ON | AMETA_SHIFT_LEFT_ON;
2665924c4d47774fa7d8a5ce659d12291ef7df82ee05Jeff Brown    }
2666924c4d47774fa7d8a5ce659d12291ef7df82ee05Jeff Brown    if (policyFlags & POLICY_FLAG_CAPS_LOCK) {
2667924c4d47774fa7d8a5ce659d12291ef7df82ee05Jeff Brown        metaState |= AMETA_CAPS_LOCK_ON;
2668924c4d47774fa7d8a5ce659d12291ef7df82ee05Jeff Brown    }
2669924c4d47774fa7d8a5ce659d12291ef7df82ee05Jeff Brown    if (policyFlags & POLICY_FLAG_FUNCTION) {
2670924c4d47774fa7d8a5ce659d12291ef7df82ee05Jeff Brown        metaState |= AMETA_FUNCTION_ON;
2671924c4d47774fa7d8a5ce659d12291ef7df82ee05Jeff Brown    }
26721f2451007c660091b7b090c1ea332f9044515d2dJeff Brown
2673e20c9e0264190f94324197a8271cf03811a4ca58Jeff Brown    policyFlags |= POLICY_FLAG_TRUSTED;
26741f2451007c660091b7b090c1ea332f9044515d2dJeff Brown
26751f2451007c660091b7b090c1ea332f9044515d2dJeff Brown    KeyEvent event;
2676be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    event.initialize(args->deviceId, args->source, args->action,
2677be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            flags, args->keyCode, args->scanCode, metaState, 0,
2678be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            args->downTime, args->eventTime);
26791f2451007c660091b7b090c1ea332f9044515d2dJeff Brown
26801f2451007c660091b7b090c1ea332f9044515d2dJeff Brown    mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags);
26811f2451007c660091b7b090c1ea332f9044515d2dJeff Brown
26821f2451007c660091b7b090c1ea332f9044515d2dJeff Brown    if (policyFlags & POLICY_FLAG_WOKE_HERE) {
26831f2451007c660091b7b090c1ea332f9044515d2dJeff Brown        flags |= AKEY_EVENT_FLAG_WOKE_HERE;
26841f2451007c660091b7b090c1ea332f9044515d2dJeff Brown    }
2685b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown
2686b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    bool needWake;
268746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    { // acquire lock
26880029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown        mLock.lock();
26890029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown
26900029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown        if (mInputFilterEnabled) {
26910029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown            mLock.unlock();
26920029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown
26930029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown            policyFlags |= POLICY_FLAG_FILTERED;
26940029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown            if (!mPolicy->filterInputEvent(&event, policyFlags)) {
26950029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown                return; // event was consumed by the filter
26960029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown            }
26970029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown
26980029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown            mLock.lock();
26990029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown        }
270046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
27017fbdc84e87dd3a0e196b9803bb04495d11e9cb8aJeff Brown        int32_t repeatCount = 0;
2702be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        KeyEntry* newEntry = new KeyEntry(args->eventTime,
2703be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                args->deviceId, args->source, policyFlags,
2704be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                args->action, flags, args->keyCode, args->scanCode,
2705be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                metaState, repeatCount, args->downTime);
270646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
2707b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        needWake = enqueueInboundEventLocked(newEntry);
27080029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown        mLock.unlock();
270946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    } // release lock
271046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
2711b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    if (needWake) {
27124fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown        mLooper->wake();
271346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
271446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
271546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
2716be1aa8250cee7819c49741e819e81659d1d03823Jeff Brownvoid InputDispatcher::notifyMotion(const NotifyMotionArgs* args) {
271746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#if DEBUG_INBOUND_EVENT_DETAILS
27185baa3a62a97544669fba6d65a11c07f252e654ddSteve Block    ALOGD("notifyMotion - eventTime=%lld, deviceId=%d, source=0x%x, policyFlags=0x%x, "
2719fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            "action=0x%x, flags=0x%x, metaState=0x%x, buttonState=0x%x, edgeFlags=0x%x, "
272085a3176704b5bfbeece9bd928369fbb76eec7dc6Jeff Brown            "xPrecision=%f, yPrecision=%f, downTime=%lld",
2721be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            args->eventTime, args->deviceId, args->source, args->policyFlags,
2722be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            args->action, args->flags, args->metaState, args->buttonState,
2723be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            args->edgeFlags, args->xPrecision, args->yPrecision, args->downTime);
2724be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    for (uint32_t i = 0; i < args->pointerCount; i++) {
27255baa3a62a97544669fba6d65a11c07f252e654ddSteve Block        ALOGD("  Pointer %d: id=%d, toolType=%d, "
2726fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                "x=%f, y=%f, pressure=%f, size=%f, "
272785a3176704b5bfbeece9bd928369fbb76eec7dc6Jeff Brown                "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
27288d60866e2100db70ecf0502c14768a384514d7e9Jeff Brown                "orientation=%f",
2729be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                i, args->pointerProperties[i].id,
2730be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                args->pointerProperties[i].toolType,
2731be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
2732be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
2733be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
2734be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
2735be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
2736be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
2737be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
2738be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
2739be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
2740be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    }
2741be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown#endif
2742be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    if (!validateMotionEvent(args->action, args->pointerCount, args->pointerProperties)) {
274301ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown        return;
274401ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    }
274546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
2746be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    uint32_t policyFlags = args->policyFlags;
2747e20c9e0264190f94324197a8271cf03811a4ca58Jeff Brown    policyFlags |= POLICY_FLAG_TRUSTED;
2748be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    mPolicy->interceptMotionBeforeQueueing(args->eventTime, /*byref*/ policyFlags);
2749b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown
2750b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    bool needWake;
275146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    { // acquire lock
27520029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown        mLock.lock();
27530029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown
27540029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown        if (mInputFilterEnabled) {
27550029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown            mLock.unlock();
27560029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown
27570029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown            MotionEvent event;
2758be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            event.initialize(args->deviceId, args->source, args->action, args->flags,
2759be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    args->edgeFlags, args->metaState, args->buttonState, 0, 0,
2760be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    args->xPrecision, args->yPrecision,
2761be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    args->downTime, args->eventTime,
2762be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    args->pointerCount, args->pointerProperties, args->pointerCoords);
27630029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown
27640029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown            policyFlags |= POLICY_FLAG_FILTERED;
27650029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown            if (!mPolicy->filterInputEvent(&event, policyFlags)) {
27660029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown                return; // event was consumed by the filter
27670029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown            }
27680029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown
27690029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown            mLock.lock();
27700029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown        }
277146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
277246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        // Attempt batching and streaming of move events.
2773be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        if (args->action == AMOTION_EVENT_ACTION_MOVE
2774be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                || args->action == AMOTION_EVENT_ACTION_HOVER_MOVE) {
277546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            // BATCHING CASE
277646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            //
277746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            // Try to append a move sample to the tail of the inbound queue for this device.
277846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            // Give up if we encounter a non-move motion event for this device since that
277946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            // means we cannot append any new samples until a new motion event has started.
2780ac386073df2514b79a2ca169f4a89f129733002fJeff Brown            for (EventEntry* entry = mInboundQueue.tail; entry; entry = entry->prev) {
278146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown                if (entry->type != EventEntry::TYPE_MOTION) {
278246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown                    // Keep looking for motion events.
278346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown                    continue;
278446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown                }
278546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
278646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown                MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
2787be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                if (motionEntry->deviceId != args->deviceId
2788be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                        || motionEntry->source != args->source) {
2789efd3266b719eed5f1b217021c0a9e76e4b274b06Jeff Brown                    // Keep looking for this device and source.
279046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown                    continue;
279146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown                }
279246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
2793be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                if (!motionEntry->canAppendSamples(args->action,
2794be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                        args->pointerCount, args->pointerProperties)) {
2795efd3266b719eed5f1b217021c0a9e76e4b274b06Jeff Brown                    // Last motion event in the queue for this device and source is
2796efd3266b719eed5f1b217021c0a9e76e4b274b06Jeff Brown                    // not compatible for appending new samples.  Stop here.
279746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown                    goto NoBatchingOrStreaming;
279846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown                }
279946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
28009c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown                // Do the batching magic.
2801be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                batchMotionLocked(motionEntry, args->eventTime,
2802be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                        args->metaState, args->pointerCoords,
28034e91a180be46c0c7c3bf398d4df4cbe2404216b5Jeff Brown                        "most recent motion event for this device and source in the inbound queue");
28040029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown                mLock.unlock();
28059c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown                return; // done!
280646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            }
280746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
2808f6989da7c7727ad433b75ad2c8d8d23c2651f70bJeff Brown            // BATCHING ONTO PENDING EVENT CASE
2809f6989da7c7727ad433b75ad2c8d8d23c2651f70bJeff Brown            //
2810f6989da7c7727ad433b75ad2c8d8d23c2651f70bJeff Brown            // Try to append a move sample to the currently pending event, if there is one.
2811f6989da7c7727ad433b75ad2c8d8d23c2651f70bJeff Brown            // We can do this as long as we are still waiting to find the targets for the
2812f6989da7c7727ad433b75ad2c8d8d23c2651f70bJeff Brown            // event.  Once the targets are locked-in we can only do streaming.
2813f6989da7c7727ad433b75ad2c8d8d23c2651f70bJeff Brown            if (mPendingEvent
2814f6989da7c7727ad433b75ad2c8d8d23c2651f70bJeff Brown                    && (!mPendingEvent->dispatchInProgress || !mCurrentInputTargetsValid)
2815f6989da7c7727ad433b75ad2c8d8d23c2651f70bJeff Brown                    && mPendingEvent->type == EventEntry::TYPE_MOTION) {
2816f6989da7c7727ad433b75ad2c8d8d23c2651f70bJeff Brown                MotionEntry* motionEntry = static_cast<MotionEntry*>(mPendingEvent);
2817be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                if (motionEntry->deviceId == args->deviceId
2818be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                        && motionEntry->source == args->source) {
2819be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    if (!motionEntry->canAppendSamples(args->action,
2820be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                            args->pointerCount, args->pointerProperties)) {
28214e91a180be46c0c7c3bf398d4df4cbe2404216b5Jeff Brown                        // Pending motion event is for this device and source but it is
28224e91a180be46c0c7c3bf398d4df4cbe2404216b5Jeff Brown                        // not compatible for appending new samples.  Stop here.
2823f6989da7c7727ad433b75ad2c8d8d23c2651f70bJeff Brown                        goto NoBatchingOrStreaming;
2824f6989da7c7727ad433b75ad2c8d8d23c2651f70bJeff Brown                    }
2825f6989da7c7727ad433b75ad2c8d8d23c2651f70bJeff Brown
2826f6989da7c7727ad433b75ad2c8d8d23c2651f70bJeff Brown                    // Do the batching magic.
2827be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    batchMotionLocked(motionEntry, args->eventTime,
2828be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                            args->metaState, args->pointerCoords,
28294e91a180be46c0c7c3bf398d4df4cbe2404216b5Jeff Brown                            "pending motion event");
2830f6989da7c7727ad433b75ad2c8d8d23c2651f70bJeff Brown                    mLock.unlock();
2831f6989da7c7727ad433b75ad2c8d8d23c2651f70bJeff Brown                    return; // done!
2832f6989da7c7727ad433b75ad2c8d8d23c2651f70bJeff Brown                }
2833f6989da7c7727ad433b75ad2c8d8d23c2651f70bJeff Brown            }
2834f6989da7c7727ad433b75ad2c8d8d23c2651f70bJeff Brown
283546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            // STREAMING CASE
283646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            //
283746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            // There is no pending motion event (of any kind) for this device in the inbound queue.
2838519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown            // Search the outbound queue for the current foreground targets to find a dispatched
2839519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown            // motion event that is still in progress.  If found, then, appen the new sample to
2840519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown            // that event and push it out to all current targets.  The logic in
2841519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown            // prepareDispatchCycleLocked takes care of the case where some targets may
2842519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown            // already have consumed the motion event by starting a new dispatch cycle if needed.
28439c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown            if (mCurrentInputTargetsValid) {
2844519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown                for (size_t i = 0; i < mCurrentInputTargets.size(); i++) {
2845519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown                    const InputTarget& inputTarget = mCurrentInputTargets[i];
2846519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown                    if ((inputTarget.flags & InputTarget::FLAG_FOREGROUND) == 0) {
2847519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown                        // Skip non-foreground targets.  We only want to stream if there is at
2848519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown                        // least one foreground target whose dispatch is still in progress.
2849519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown                        continue;
2850519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown                    }
2851519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown
2852519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown                    ssize_t connectionIndex = getConnectionIndexLocked(inputTarget.inputChannel);
2853519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown                    if (connectionIndex < 0) {
2854519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown                        // Connection must no longer be valid.
2855519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown                        continue;
2856519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown                    }
2857519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown
2858519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown                    sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
2859519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown                    if (connection->outboundQueue.isEmpty()) {
2860519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown                        // This foreground target has an empty outbound queue.
2861519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown                        continue;
286246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown                    }
2863519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown
2864ac386073df2514b79a2ca169f4a89f129733002fJeff Brown                    DispatchEntry* dispatchEntry = connection->outboundQueue.head;
2865519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown                    if (! dispatchEntry->inProgress
286601ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown                            || dispatchEntry->eventEntry->type != EventEntry::TYPE_MOTION
286701ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown                            || dispatchEntry->isSplit()) {
286801ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown                        // No motion event is being dispatched, or it is being split across
286901ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown                        // windows in which case we cannot stream.
2870519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown                        continue;
2871519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown                    }
2872519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown
2873519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown                    MotionEntry* motionEntry = static_cast<MotionEntry*>(
2874519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown                            dispatchEntry->eventEntry);
2875be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    if (motionEntry->action != args->action
2876be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                            || motionEntry->deviceId != args->deviceId
2877be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                            || motionEntry->source != args->source
2878be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                            || motionEntry->pointerCount != args->pointerCount
2879519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown                            || motionEntry->isInjected()) {
2880519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown                        // The motion event is not compatible with this move.
2881519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown                        continue;
2882519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown                    }
2883519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown
2884be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    if (args->action == AMOTION_EVENT_ACTION_HOVER_MOVE) {
28859302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown                        if (mLastHoverWindowHandle == NULL) {
2886a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown#if DEBUG_BATCHING
28875baa3a62a97544669fba6d65a11c07f252e654ddSteve Block                            ALOGD("Not streaming hover move because there is no "
2888a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown                                    "last hovered window.");
2889a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown#endif
2890a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown                            goto NoBatchingOrStreaming;
2891a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown                        }
2892a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown
28939302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown                        sp<InputWindowHandle> hoverWindowHandle = findTouchedWindowAtLocked(
2894be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                                args->pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X),
2895be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                                args->pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
28969302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown                        if (mLastHoverWindowHandle != hoverWindowHandle) {
2897a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown#if DEBUG_BATCHING
28985baa3a62a97544669fba6d65a11c07f252e654ddSteve Block                            ALOGD("Not streaming hover move because the last hovered window "
2899a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown                                    "is '%s' but the currently hovered window is '%s'.",
2900cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown                                    mLastHoverWindowHandle->getName().string(),
29019302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown                                    hoverWindowHandle != NULL
2902cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown                                            ? hoverWindowHandle->getName().string() : "<null>");
2903a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown#endif
2904a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown                            goto NoBatchingOrStreaming;
2905a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown                        }
2906a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown                    }
2907a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown
2908519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown                    // Hurray!  This foreground target is currently dispatching a move event
2909519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown                    // that we can stream onto.  Append the motion sample and resume dispatch.
2910be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                    motionEntry->appendSample(args->eventTime, args->pointerCoords);
2911519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown#if DEBUG_BATCHING
29125baa3a62a97544669fba6d65a11c07f252e654ddSteve Block                    ALOGD("Appended motion sample onto batch for most recently dispatched "
29134e91a180be46c0c7c3bf398d4df4cbe2404216b5Jeff Brown                            "motion event for this device and source in the outbound queues.  "
2914519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown                            "Attempting to stream the motion sample.");
2915519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown#endif
2916519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown                    nsecs_t currentTime = now();
2917519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown                    dispatchEventToCurrentInputTargetsLocked(currentTime, motionEntry,
2918519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown                            true /*resumeWithAppendedMotionSample*/);
2919519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown
2920519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown                    runCommandsLockedInterruptible();
29210029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown                    mLock.unlock();
2922519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown                    return; // done!
292346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown                }
292446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            }
292546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
292646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff BrownNoBatchingOrStreaming:;
292746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        }
292846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
292946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        // Just enqueue a new motion event.
2930be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown        MotionEntry* newEntry = new MotionEntry(args->eventTime,
2931be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                args->deviceId, args->source, policyFlags,
2932be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                args->action, args->flags, args->metaState, args->buttonState,
2933be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                args->edgeFlags, args->xPrecision, args->yPrecision, args->downTime,
2934be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown                args->pointerCount, args->pointerProperties, args->pointerCoords);
293546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
2936b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        needWake = enqueueInboundEventLocked(newEntry);
29370029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown        mLock.unlock();
293846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    } // release lock
293946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
2940b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    if (needWake) {
29414fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown        mLooper->wake();
294246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
294346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
294446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
29454e91a180be46c0c7c3bf398d4df4cbe2404216b5Jeff Brownvoid InputDispatcher::batchMotionLocked(MotionEntry* entry, nsecs_t eventTime,
29464e91a180be46c0c7c3bf398d4df4cbe2404216b5Jeff Brown        int32_t metaState, const PointerCoords* pointerCoords, const char* eventDescription) {
29474e91a180be46c0c7c3bf398d4df4cbe2404216b5Jeff Brown    // Combine meta states.
29484e91a180be46c0c7c3bf398d4df4cbe2404216b5Jeff Brown    entry->metaState |= metaState;
29494e91a180be46c0c7c3bf398d4df4cbe2404216b5Jeff Brown
29504e91a180be46c0c7c3bf398d4df4cbe2404216b5Jeff Brown    // Coalesce this sample if not enough time has elapsed since the last sample was
29514e91a180be46c0c7c3bf398d4df4cbe2404216b5Jeff Brown    // initially appended to the batch.
29524e91a180be46c0c7c3bf398d4df4cbe2404216b5Jeff Brown    MotionSample* lastSample = entry->lastSample;
29534e91a180be46c0c7c3bf398d4df4cbe2404216b5Jeff Brown    long interval = eventTime - lastSample->eventTimeBeforeCoalescing;
29544e91a180be46c0c7c3bf398d4df4cbe2404216b5Jeff Brown    if (interval <= MOTION_SAMPLE_COALESCE_INTERVAL) {
29554e91a180be46c0c7c3bf398d4df4cbe2404216b5Jeff Brown        uint32_t pointerCount = entry->pointerCount;
29564e91a180be46c0c7c3bf398d4df4cbe2404216b5Jeff Brown        for (uint32_t i = 0; i < pointerCount; i++) {
29574e91a180be46c0c7c3bf398d4df4cbe2404216b5Jeff Brown            lastSample->pointerCoords[i].copyFrom(pointerCoords[i]);
29584e91a180be46c0c7c3bf398d4df4cbe2404216b5Jeff Brown        }
29594e91a180be46c0c7c3bf398d4df4cbe2404216b5Jeff Brown        lastSample->eventTime = eventTime;
29604e91a180be46c0c7c3bf398d4df4cbe2404216b5Jeff Brown#if DEBUG_BATCHING
29615baa3a62a97544669fba6d65a11c07f252e654ddSteve Block        ALOGD("Coalesced motion into last sample of batch for %s, events were %0.3f ms apart",
29624e91a180be46c0c7c3bf398d4df4cbe2404216b5Jeff Brown                eventDescription, interval * 0.000001f);
29634e91a180be46c0c7c3bf398d4df4cbe2404216b5Jeff Brown#endif
29644e91a180be46c0c7c3bf398d4df4cbe2404216b5Jeff Brown        return;
29654e91a180be46c0c7c3bf398d4df4cbe2404216b5Jeff Brown    }
29664e91a180be46c0c7c3bf398d4df4cbe2404216b5Jeff Brown
29674e91a180be46c0c7c3bf398d4df4cbe2404216b5Jeff Brown    // Append the sample.
2968ac386073df2514b79a2ca169f4a89f129733002fJeff Brown    entry->appendSample(eventTime, pointerCoords);
29694e91a180be46c0c7c3bf398d4df4cbe2404216b5Jeff Brown#if DEBUG_BATCHING
29705baa3a62a97544669fba6d65a11c07f252e654ddSteve Block    ALOGD("Appended motion sample onto batch for %s, events were %0.3f ms apart",
29714e91a180be46c0c7c3bf398d4df4cbe2404216b5Jeff Brown            eventDescription, interval * 0.000001f);
29724e91a180be46c0c7c3bf398d4df4cbe2404216b5Jeff Brown#endif
29734e91a180be46c0c7c3bf398d4df4cbe2404216b5Jeff Brown}
29744e91a180be46c0c7c3bf398d4df4cbe2404216b5Jeff Brown
2975be1aa8250cee7819c49741e819e81659d1d03823Jeff Brownvoid InputDispatcher::notifySwitch(const NotifySwitchArgs* args) {
2976b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown#if DEBUG_INBOUND_EVENT_DETAILS
29775baa3a62a97544669fba6d65a11c07f252e654ddSteve Block    ALOGD("notifySwitch - eventTime=%lld, policyFlags=0x%x, switchCode=%d, switchValue=%d",
2978be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            args->eventTime, args->policyFlags,
2979be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            args->switchCode, args->switchValue);
2980b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown#endif
2981b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown
2982be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    uint32_t policyFlags = args->policyFlags;
2983e20c9e0264190f94324197a8271cf03811a4ca58Jeff Brown    policyFlags |= POLICY_FLAG_TRUSTED;
2984be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown    mPolicy->notifySwitch(args->eventTime,
2985be1aa8250cee7819c49741e819e81659d1d03823Jeff Brown            args->switchCode, args->switchValue, policyFlags);
2986b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown}
2987b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown
298865fd251c3913fc921468a3dad190810db19eb9dfJeff Brownvoid InputDispatcher::notifyDeviceReset(const NotifyDeviceResetArgs* args) {
298965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown#if DEBUG_INBOUND_EVENT_DETAILS
29905baa3a62a97544669fba6d65a11c07f252e654ddSteve Block    ALOGD("notifyDeviceReset - eventTime=%lld, deviceId=%d",
299165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown            args->eventTime, args->deviceId);
299265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown#endif
299365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
299465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    bool needWake;
299565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    { // acquire lock
299665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        AutoMutex _l(mLock);
299765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
299865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        DeviceResetEntry* newEntry = new DeviceResetEntry(args->eventTime, args->deviceId);
299965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        needWake = enqueueInboundEventLocked(newEntry);
300065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    } // release lock
300165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
300265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    if (needWake) {
300365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        mLooper->wake();
300465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    }
300565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown}
300665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
30077fbdc84e87dd3a0e196b9803bb04495d11e9cb8aJeff Brownint32_t InputDispatcher::injectInputEvent(const InputEvent* event,
30080029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown        int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis,
30090029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown        uint32_t policyFlags) {
30107fbdc84e87dd3a0e196b9803bb04495d11e9cb8aJeff Brown#if DEBUG_INBOUND_EVENT_DETAILS
30115baa3a62a97544669fba6d65a11c07f252e654ddSteve Block    ALOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, "
30120029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown            "syncMode=%d, timeoutMillis=%d, policyFlags=0x%08x",
30130029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown            event->getType(), injectorPid, injectorUid, syncMode, timeoutMillis, policyFlags);
30147fbdc84e87dd3a0e196b9803bb04495d11e9cb8aJeff Brown#endif
30157fbdc84e87dd3a0e196b9803bb04495d11e9cb8aJeff Brown
30167fbdc84e87dd3a0e196b9803bb04495d11e9cb8aJeff Brown    nsecs_t endTime = now() + milliseconds_to_nanoseconds(timeoutMillis);
3017e20c9e0264190f94324197a8271cf03811a4ca58Jeff Brown
30180029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown    policyFlags |= POLICY_FLAG_INJECTED;
3019e20c9e0264190f94324197a8271cf03811a4ca58Jeff Brown    if (hasInjectionPermission(injectorPid, injectorUid)) {
3020e20c9e0264190f94324197a8271cf03811a4ca58Jeff Brown        policyFlags |= POLICY_FLAG_TRUSTED;
3021e20c9e0264190f94324197a8271cf03811a4ca58Jeff Brown    }
30227fbdc84e87dd3a0e196b9803bb04495d11e9cb8aJeff Brown
3023b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown    EventEntry* injectedEntry;
3024b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown    switch (event->getType()) {
3025b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown    case AINPUT_EVENT_TYPE_KEY: {
3026b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown        const KeyEvent* keyEvent = static_cast<const KeyEvent*>(event);
3027b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown        int32_t action = keyEvent->getAction();
3028b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown        if (! validateKeyEvent(action)) {
3029b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown            return INPUT_EVENT_INJECTION_FAILED;
3030b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown        }
3031b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown
3032b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown        int32_t flags = keyEvent->getFlags();
30331f2451007c660091b7b090c1ea332f9044515d2dJeff Brown        if (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY) {
30341f2451007c660091b7b090c1ea332f9044515d2dJeff Brown            policyFlags |= POLICY_FLAG_VIRTUAL;
30351f2451007c660091b7b090c1ea332f9044515d2dJeff Brown        }
30361f2451007c660091b7b090c1ea332f9044515d2dJeff Brown
30370029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown        if (!(policyFlags & POLICY_FLAG_FILTERED)) {
30380029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown            mPolicy->interceptKeyBeforeQueueing(keyEvent, /*byref*/ policyFlags);
30390029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown        }
30401f2451007c660091b7b090c1ea332f9044515d2dJeff Brown
30411f2451007c660091b7b090c1ea332f9044515d2dJeff Brown        if (policyFlags & POLICY_FLAG_WOKE_HERE) {
30421f2451007c660091b7b090c1ea332f9044515d2dJeff Brown            flags |= AKEY_EVENT_FLAG_WOKE_HERE;
30431f2451007c660091b7b090c1ea332f9044515d2dJeff Brown        }
30447fbdc84e87dd3a0e196b9803bb04495d11e9cb8aJeff Brown
3045b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown        mLock.lock();
3046ac386073df2514b79a2ca169f4a89f129733002fJeff Brown        injectedEntry = new KeyEntry(keyEvent->getEventTime(),
30471f2451007c660091b7b090c1ea332f9044515d2dJeff Brown                keyEvent->getDeviceId(), keyEvent->getSource(),
30481f2451007c660091b7b090c1ea332f9044515d2dJeff Brown                policyFlags, action, flags,
30491f2451007c660091b7b090c1ea332f9044515d2dJeff Brown                keyEvent->getKeyCode(), keyEvent->getScanCode(), keyEvent->getMetaState(),
3050b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown                keyEvent->getRepeatCount(), keyEvent->getDownTime());
3051b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown        break;
3052b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown    }
3053b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown
3054b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown    case AINPUT_EVENT_TYPE_MOTION: {
3055b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown        const MotionEvent* motionEvent = static_cast<const MotionEvent*>(event);
3056b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown        int32_t action = motionEvent->getAction();
3057b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown        size_t pointerCount = motionEvent->getPointerCount();
3058fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        const PointerProperties* pointerProperties = motionEvent->getPointerProperties();
3059fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        if (! validateMotionEvent(action, pointerCount, pointerProperties)) {
3060b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown            return INPUT_EVENT_INJECTION_FAILED;
3061b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        }
3062b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
30630029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown        if (!(policyFlags & POLICY_FLAG_FILTERED)) {
30640029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown            nsecs_t eventTime = motionEvent->getEventTime();
30650029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown            mPolicy->interceptMotionBeforeQueueing(eventTime, /*byref*/ policyFlags);
30660029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown        }
3067b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown
3068b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown        mLock.lock();
3069b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown        const nsecs_t* sampleEventTimes = motionEvent->getSampleEventTimes();
3070b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown        const PointerCoords* samplePointerCoords = motionEvent->getSamplePointerCoords();
3071ac386073df2514b79a2ca169f4a89f129733002fJeff Brown        MotionEntry* motionEntry = new MotionEntry(*sampleEventTimes,
3072b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown                motionEvent->getDeviceId(), motionEvent->getSource(), policyFlags,
3073b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown                action, motionEvent->getFlags(),
3074fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                motionEvent->getMetaState(), motionEvent->getButtonState(),
3075fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                motionEvent->getEdgeFlags(),
3076b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown                motionEvent->getXPrecision(), motionEvent->getYPrecision(),
3077b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown                motionEvent->getDownTime(), uint32_t(pointerCount),
3078fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                pointerProperties, samplePointerCoords);
3079b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown        for (size_t i = motionEvent->getHistorySize(); i > 0; i--) {
3080b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown            sampleEventTimes += 1;
3081b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown            samplePointerCoords += pointerCount;
3082ac386073df2514b79a2ca169f4a89f129733002fJeff Brown            motionEntry->appendSample(*sampleEventTimes, samplePointerCoords);
30836ec402b5ae33c8927694d8522b4cc6a5c8ba974eJeff Brown        }
3084b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown        injectedEntry = motionEntry;
3085b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown        break;
3086b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown    }
30876ec402b5ae33c8927694d8522b4cc6a5c8ba974eJeff Brown
3088b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown    default:
30898564c8da817a845353d213acd8636b76f567b234Steve Block        ALOGW("Cannot inject event of type %d", event->getType());
3090b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown        return INPUT_EVENT_INJECTION_FAILED;
3091b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown    }
309201ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown
3093ac386073df2514b79a2ca169f4a89f129733002fJeff Brown    InjectionState* injectionState = new InjectionState(injectorPid, injectorUid);
3094b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown    if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
3095b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown        injectionState->injectionIsAsync = true;
3096b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown    }
3097b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown
3098b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown    injectionState->refCount += 1;
3099b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown    injectedEntry->injectionState = injectionState;
3100b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown
3101b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown    bool needWake = enqueueInboundEventLocked(injectedEntry);
3102b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown    mLock.unlock();
31037fbdc84e87dd3a0e196b9803bb04495d11e9cb8aJeff Brown
3104b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    if (needWake) {
31054fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown        mLooper->wake();
31067fbdc84e87dd3a0e196b9803bb04495d11e9cb8aJeff Brown    }
31077fbdc84e87dd3a0e196b9803bb04495d11e9cb8aJeff Brown
31087fbdc84e87dd3a0e196b9803bb04495d11e9cb8aJeff Brown    int32_t injectionResult;
31097fbdc84e87dd3a0e196b9803bb04495d11e9cb8aJeff Brown    { // acquire lock
31107fbdc84e87dd3a0e196b9803bb04495d11e9cb8aJeff Brown        AutoMutex _l(mLock);
31117fbdc84e87dd3a0e196b9803bb04495d11e9cb8aJeff Brown
31126ec402b5ae33c8927694d8522b4cc6a5c8ba974eJeff Brown        if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
31136ec402b5ae33c8927694d8522b4cc6a5c8ba974eJeff Brown            injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
31146ec402b5ae33c8927694d8522b4cc6a5c8ba974eJeff Brown        } else {
31156ec402b5ae33c8927694d8522b4cc6a5c8ba974eJeff Brown            for (;;) {
311601ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown                injectionResult = injectionState->injectionResult;
31176ec402b5ae33c8927694d8522b4cc6a5c8ba974eJeff Brown                if (injectionResult != INPUT_EVENT_INJECTION_PENDING) {
31186ec402b5ae33c8927694d8522b4cc6a5c8ba974eJeff Brown                    break;
31196ec402b5ae33c8927694d8522b4cc6a5c8ba974eJeff Brown                }
31207fbdc84e87dd3a0e196b9803bb04495d11e9cb8aJeff Brown
31217fbdc84e87dd3a0e196b9803bb04495d11e9cb8aJeff Brown                nsecs_t remainingTimeout = endTime - now();
31227fbdc84e87dd3a0e196b9803bb04495d11e9cb8aJeff Brown                if (remainingTimeout <= 0) {
31236ec402b5ae33c8927694d8522b4cc6a5c8ba974eJeff Brown#if DEBUG_INJECTION
31245baa3a62a97544669fba6d65a11c07f252e654ddSteve Block                    ALOGD("injectInputEvent - Timed out waiting for injection result "
31256ec402b5ae33c8927694d8522b4cc6a5c8ba974eJeff Brown                            "to become available.");
31266ec402b5ae33c8927694d8522b4cc6a5c8ba974eJeff Brown#endif
31277fbdc84e87dd3a0e196b9803bb04495d11e9cb8aJeff Brown                    injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
31287fbdc84e87dd3a0e196b9803bb04495d11e9cb8aJeff Brown                    break;
31297fbdc84e87dd3a0e196b9803bb04495d11e9cb8aJeff Brown                }
31307fbdc84e87dd3a0e196b9803bb04495d11e9cb8aJeff Brown
31316ec402b5ae33c8927694d8522b4cc6a5c8ba974eJeff Brown                mInjectionResultAvailableCondition.waitRelative(mLock, remainingTimeout);
31326ec402b5ae33c8927694d8522b4cc6a5c8ba974eJeff Brown            }
31336ec402b5ae33c8927694d8522b4cc6a5c8ba974eJeff Brown
31346ec402b5ae33c8927694d8522b4cc6a5c8ba974eJeff Brown            if (injectionResult == INPUT_EVENT_INJECTION_SUCCEEDED
31356ec402b5ae33c8927694d8522b4cc6a5c8ba974eJeff Brown                    && syncMode == INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISHED) {
313601ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown                while (injectionState->pendingForegroundDispatches != 0) {
31376ec402b5ae33c8927694d8522b4cc6a5c8ba974eJeff Brown#if DEBUG_INJECTION
31385baa3a62a97544669fba6d65a11c07f252e654ddSteve Block                    ALOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
313901ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown                            injectionState->pendingForegroundDispatches);
31406ec402b5ae33c8927694d8522b4cc6a5c8ba974eJeff Brown#endif
31416ec402b5ae33c8927694d8522b4cc6a5c8ba974eJeff Brown                    nsecs_t remainingTimeout = endTime - now();
31426ec402b5ae33c8927694d8522b4cc6a5c8ba974eJeff Brown                    if (remainingTimeout <= 0) {
31436ec402b5ae33c8927694d8522b4cc6a5c8ba974eJeff Brown#if DEBUG_INJECTION
31445baa3a62a97544669fba6d65a11c07f252e654ddSteve Block                    ALOGD("injectInputEvent - Timed out waiting for pending foreground "
31456ec402b5ae33c8927694d8522b4cc6a5c8ba974eJeff Brown                            "dispatches to finish.");
31466ec402b5ae33c8927694d8522b4cc6a5c8ba974eJeff Brown#endif
31476ec402b5ae33c8927694d8522b4cc6a5c8ba974eJeff Brown                        injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
31486ec402b5ae33c8927694d8522b4cc6a5c8ba974eJeff Brown                        break;
31496ec402b5ae33c8927694d8522b4cc6a5c8ba974eJeff Brown                    }
31506ec402b5ae33c8927694d8522b4cc6a5c8ba974eJeff Brown
31516ec402b5ae33c8927694d8522b4cc6a5c8ba974eJeff Brown                    mInjectionSyncFinishedCondition.waitRelative(mLock, remainingTimeout);
31526ec402b5ae33c8927694d8522b4cc6a5c8ba974eJeff Brown                }
31537fbdc84e87dd3a0e196b9803bb04495d11e9cb8aJeff Brown            }
31547fbdc84e87dd3a0e196b9803bb04495d11e9cb8aJeff Brown        }
31557fbdc84e87dd3a0e196b9803bb04495d11e9cb8aJeff Brown
3156ac386073df2514b79a2ca169f4a89f129733002fJeff Brown        injectionState->release();
31577fbdc84e87dd3a0e196b9803bb04495d11e9cb8aJeff Brown    } // release lock
31587fbdc84e87dd3a0e196b9803bb04495d11e9cb8aJeff Brown
31596ec402b5ae33c8927694d8522b4cc6a5c8ba974eJeff Brown#if DEBUG_INJECTION
31605baa3a62a97544669fba6d65a11c07f252e654ddSteve Block    ALOGD("injectInputEvent - Finished with result %d.  "
31616ec402b5ae33c8927694d8522b4cc6a5c8ba974eJeff Brown            "injectorPid=%d, injectorUid=%d",
31626ec402b5ae33c8927694d8522b4cc6a5c8ba974eJeff Brown            injectionResult, injectorPid, injectorUid);
31636ec402b5ae33c8927694d8522b4cc6a5c8ba974eJeff Brown#endif
31646ec402b5ae33c8927694d8522b4cc6a5c8ba974eJeff Brown
31657fbdc84e87dd3a0e196b9803bb04495d11e9cb8aJeff Brown    return injectionResult;
31667fbdc84e87dd3a0e196b9803bb04495d11e9cb8aJeff Brown}
31677fbdc84e87dd3a0e196b9803bb04495d11e9cb8aJeff Brown
3168b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brownbool InputDispatcher::hasInjectionPermission(int32_t injectorPid, int32_t injectorUid) {
3169b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown    return injectorUid == 0
3170b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown            || mPolicy->checkInjectEventsPermissionNonReentrant(injectorPid, injectorUid);
3171b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown}
3172b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown
31737fbdc84e87dd3a0e196b9803bb04495d11e9cb8aJeff Brownvoid InputDispatcher::setInjectionResultLocked(EventEntry* entry, int32_t injectionResult) {
317401ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    InjectionState* injectionState = entry->injectionState;
317501ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    if (injectionState) {
31767fbdc84e87dd3a0e196b9803bb04495d11e9cb8aJeff Brown#if DEBUG_INJECTION
31775baa3a62a97544669fba6d65a11c07f252e654ddSteve Block        ALOGD("Setting input event injection result to %d.  "
31787fbdc84e87dd3a0e196b9803bb04495d11e9cb8aJeff Brown                "injectorPid=%d, injectorUid=%d",
317901ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown                 injectionResult, injectionState->injectorPid, injectionState->injectorUid);
31807fbdc84e87dd3a0e196b9803bb04495d11e9cb8aJeff Brown#endif
31817fbdc84e87dd3a0e196b9803bb04495d11e9cb8aJeff Brown
31820029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown        if (injectionState->injectionIsAsync
31830029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown                && !(entry->policyFlags & POLICY_FLAG_FILTERED)) {
31846ec402b5ae33c8927694d8522b4cc6a5c8ba974eJeff Brown            // Log the outcome since the injector did not wait for the injection result.
31856ec402b5ae33c8927694d8522b4cc6a5c8ba974eJeff Brown            switch (injectionResult) {
31866ec402b5ae33c8927694d8522b4cc6a5c8ba974eJeff Brown            case INPUT_EVENT_INJECTION_SUCCEEDED:
318771f2cf116aab893e224056c38ab146bd1538dd3eSteve Block                ALOGV("Asynchronous input event injection succeeded.");
31886ec402b5ae33c8927694d8522b4cc6a5c8ba974eJeff Brown                break;
31896ec402b5ae33c8927694d8522b4cc6a5c8ba974eJeff Brown            case INPUT_EVENT_INJECTION_FAILED:
31908564c8da817a845353d213acd8636b76f567b234Steve Block                ALOGW("Asynchronous input event injection failed.");
31916ec402b5ae33c8927694d8522b4cc6a5c8ba974eJeff Brown                break;
31926ec402b5ae33c8927694d8522b4cc6a5c8ba974eJeff Brown            case INPUT_EVENT_INJECTION_PERMISSION_DENIED:
31938564c8da817a845353d213acd8636b76f567b234Steve Block                ALOGW("Asynchronous input event injection permission denied.");
31946ec402b5ae33c8927694d8522b4cc6a5c8ba974eJeff Brown                break;
31956ec402b5ae33c8927694d8522b4cc6a5c8ba974eJeff Brown            case INPUT_EVENT_INJECTION_TIMED_OUT:
31968564c8da817a845353d213acd8636b76f567b234Steve Block                ALOGW("Asynchronous input event injection timed out.");
31976ec402b5ae33c8927694d8522b4cc6a5c8ba974eJeff Brown                break;
31986ec402b5ae33c8927694d8522b4cc6a5c8ba974eJeff Brown            }
31996ec402b5ae33c8927694d8522b4cc6a5c8ba974eJeff Brown        }
32006ec402b5ae33c8927694d8522b4cc6a5c8ba974eJeff Brown
320101ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown        injectionState->injectionResult = injectionResult;
32027fbdc84e87dd3a0e196b9803bb04495d11e9cb8aJeff Brown        mInjectionResultAvailableCondition.broadcast();
32037fbdc84e87dd3a0e196b9803bb04495d11e9cb8aJeff Brown    }
32047fbdc84e87dd3a0e196b9803bb04495d11e9cb8aJeff Brown}
32057fbdc84e87dd3a0e196b9803bb04495d11e9cb8aJeff Brown
320601ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brownvoid InputDispatcher::incrementPendingForegroundDispatchesLocked(EventEntry* entry) {
320701ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    InjectionState* injectionState = entry->injectionState;
320801ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    if (injectionState) {
320901ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown        injectionState->pendingForegroundDispatches += 1;
32106ec402b5ae33c8927694d8522b4cc6a5c8ba974eJeff Brown    }
32117fbdc84e87dd3a0e196b9803bb04495d11e9cb8aJeff Brown}
32127fbdc84e87dd3a0e196b9803bb04495d11e9cb8aJeff Brown
321301ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brownvoid InputDispatcher::decrementPendingForegroundDispatchesLocked(EventEntry* entry) {
321401ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    InjectionState* injectionState = entry->injectionState;
321501ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    if (injectionState) {
321601ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown        injectionState->pendingForegroundDispatches -= 1;
3217b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
321801ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown        if (injectionState->pendingForegroundDispatches == 0) {
321901ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown            mInjectionSyncFinishedCondition.broadcast();
322001ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown        }
3221b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    }
3222b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown}
3223b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
32249302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brownsp<InputWindowHandle> InputDispatcher::getWindowHandleLocked(
32259302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown        const sp<InputChannel>& inputChannel) const {
32269302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown    size_t numWindows = mWindowHandles.size();
32279302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown    for (size_t i = 0; i < numWindows; i++) {
32289302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown        const sp<InputWindowHandle>& windowHandle = mWindowHandles.itemAt(i);
3229cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown        if (windowHandle->getInputChannel() == inputChannel) {
32309302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown            return windowHandle;
323101ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown        }
323201ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    }
323301ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    return NULL;
323401ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown}
323501ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown
32369302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brownbool InputDispatcher::hasWindowHandleLocked(
32379302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown        const sp<InputWindowHandle>& windowHandle) const {
32389302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown    size_t numWindows = mWindowHandles.size();
32399302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown    for (size_t i = 0; i < numWindows; i++) {
32409302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown        if (mWindowHandles.itemAt(i) == windowHandle) {
32419302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown            return true;
32429302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown        }
32439302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown    }
32449302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown    return false;
32459302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown}
32469302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown
32479302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brownvoid InputDispatcher::setInputWindows(const Vector<sp<InputWindowHandle> >& inputWindowHandles) {
3248b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown#if DEBUG_FOCUS
32495baa3a62a97544669fba6d65a11c07f252e654ddSteve Block    ALOGD("setInputWindows");
3250b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown#endif
3251b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    { // acquire lock
3252b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        AutoMutex _l(mLock);
3253b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
3254cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown        Vector<sp<InputWindowHandle> > oldWindowHandles = mWindowHandles;
32559302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown        mWindowHandles = inputWindowHandles;
3256b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
32579302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown        sp<InputWindowHandle> newFocusedWindowHandle;
32589302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown        bool foundHoveredWindow = false;
32599302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown        for (size_t i = 0; i < mWindowHandles.size(); i++) {
32609302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown            const sp<InputWindowHandle>& windowHandle = mWindowHandles.itemAt(i);
3261cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown            if (!windowHandle->updateInfo() || windowHandle->getInputChannel() == NULL) {
32629302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown                mWindowHandles.removeAt(i--);
32639302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown                continue;
3264b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown            }
3265cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown            if (windowHandle->getInfo()->hasFocus) {
32669302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown                newFocusedWindowHandle = windowHandle;
32679302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown            }
32689302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown            if (windowHandle == mLastHoverWindowHandle) {
32699302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown                foundHoveredWindow = true;
32709302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown            }
32719302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown        }
32729302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown
32739302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown        if (!foundHoveredWindow) {
32749302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown            mLastHoverWindowHandle = NULL;
327501ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown        }
3276b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
32779302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown        if (mFocusedWindowHandle != newFocusedWindowHandle) {
32789302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown            if (mFocusedWindowHandle != NULL) {
3279b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown#if DEBUG_FOCUS
32805baa3a62a97544669fba6d65a11c07f252e654ddSteve Block                ALOGD("Focus left window: %s",
3281cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown                        mFocusedWindowHandle->getName().string());
3282b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown#endif
3283cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown                sp<InputChannel> focusedInputChannel = mFocusedWindowHandle->getInputChannel();
3284cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown                if (focusedInputChannel != NULL) {
3285d9be36c897680361da2daadba9bbc9da3c16329bChristopher Tate                    CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
3286d9be36c897680361da2daadba9bbc9da3c16329bChristopher Tate                            "focus left window");
3287d9be36c897680361da2daadba9bbc9da3c16329bChristopher Tate                    synthesizeCancelationEventsForInputChannelLocked(
3288cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown                            focusedInputChannel, options);
3289d9be36c897680361da2daadba9bbc9da3c16329bChristopher Tate                }
3290b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown            }
32919302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown            if (newFocusedWindowHandle != NULL) {
3292b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown#if DEBUG_FOCUS
32935baa3a62a97544669fba6d65a11c07f252e654ddSteve Block                ALOGD("Focus entered window: %s",
3294cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown                        newFocusedWindowHandle->getName().string());
3295b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown#endif
32969302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown            }
32979302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown            mFocusedWindowHandle = newFocusedWindowHandle;
3298b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown        }
3299b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown
33009302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown        for (size_t i = 0; i < mTouchState.windows.size(); i++) {
330101ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown            TouchedWindow& touchedWindow = mTouchState.windows.editItemAt(i);
33029302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown            if (!hasWindowHandleLocked(touchedWindow.windowHandle)) {
3303b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown#if DEBUG_FOCUS
33045baa3a62a97544669fba6d65a11c07f252e654ddSteve Block                ALOGD("Touched window was removed: %s",
3305cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown                        touchedWindow.windowHandle->getName().string());
3306b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown#endif
3307cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown                sp<InputChannel> touchedInputChannel =
3308cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown                        touchedWindow.windowHandle->getInputChannel();
3309cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown                if (touchedInputChannel != NULL) {
3310d9be36c897680361da2daadba9bbc9da3c16329bChristopher Tate                    CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
3311d9be36c897680361da2daadba9bbc9da3c16329bChristopher Tate                            "touched window was removed");
3312d9be36c897680361da2daadba9bbc9da3c16329bChristopher Tate                    synthesizeCancelationEventsForInputChannelLocked(
3313cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown                            touchedInputChannel, options);
3314d9be36c897680361da2daadba9bbc9da3c16329bChristopher Tate                }
33159302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown                mTouchState.windows.removeAt(i--);
3316b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown            }
3317b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        }
3318cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown
3319cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown        // Release information for windows that are no longer present.
3320cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown        // This ensures that unused input channels are released promptly.
3321cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown        // Otherwise, they might stick around until the window handle is destroyed
3322cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown        // which might not happen until the next GC.
3323cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown        for (size_t i = 0; i < oldWindowHandles.size(); i++) {
3324cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown            const sp<InputWindowHandle>& oldWindowHandle = oldWindowHandles.itemAt(i);
3325cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown            if (!hasWindowHandleLocked(oldWindowHandle)) {
3326cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown#if DEBUG_FOCUS
33275baa3a62a97544669fba6d65a11c07f252e654ddSteve Block                ALOGD("Window went away: %s", oldWindowHandle->getName().string());
3328cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown#endif
3329cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown                oldWindowHandle->releaseInfo();
3330cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown            }
3331cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown        }
3332b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    } // release lock
3333b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
3334b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    // Wake up poll loop since it may need to make new input dispatching choices.
33354fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown    mLooper->wake();
3336b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown}
3337b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
33389302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brownvoid InputDispatcher::setFocusedApplication(
33399302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown        const sp<InputApplicationHandle>& inputApplicationHandle) {
3340b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown#if DEBUG_FOCUS
33415baa3a62a97544669fba6d65a11c07f252e654ddSteve Block    ALOGD("setFocusedApplication");
3342b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown#endif
3343b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    { // acquire lock
3344b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        AutoMutex _l(mLock);
3345b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
3346cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown        if (inputApplicationHandle != NULL && inputApplicationHandle->updateInfo()) {
33475ea29ab7efa9a9ae22345f15a7cb9be3c5e1bbf5Jeff Brown            if (mFocusedApplicationHandle != inputApplicationHandle) {
33485ea29ab7efa9a9ae22345f15a7cb9be3c5e1bbf5Jeff Brown                if (mFocusedApplicationHandle != NULL) {
33495ea29ab7efa9a9ae22345f15a7cb9be3c5e1bbf5Jeff Brown                    resetTargetsLocked();
3350cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown                    mFocusedApplicationHandle->releaseInfo();
33515ea29ab7efa9a9ae22345f15a7cb9be3c5e1bbf5Jeff Brown                }
33525ea29ab7efa9a9ae22345f15a7cb9be3c5e1bbf5Jeff Brown                mFocusedApplicationHandle = inputApplicationHandle;
33535ea29ab7efa9a9ae22345f15a7cb9be3c5e1bbf5Jeff Brown            }
33545ea29ab7efa9a9ae22345f15a7cb9be3c5e1bbf5Jeff Brown        } else if (mFocusedApplicationHandle != NULL) {
33555ea29ab7efa9a9ae22345f15a7cb9be3c5e1bbf5Jeff Brown            resetTargetsLocked();
3356cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown            mFocusedApplicationHandle->releaseInfo();
33579302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown            mFocusedApplicationHandle.clear();
3358b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        }
3359b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
3360b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown#if DEBUG_FOCUS
3361b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown        //logDispatchStateLocked();
3362b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown#endif
3363b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    } // release lock
3364b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
3365b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    // Wake up poll loop since it may need to make new input dispatching choices.
33664fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown    mLooper->wake();
3367b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown}
3368b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
3369b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brownvoid InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
3370b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown#if DEBUG_FOCUS
33715baa3a62a97544669fba6d65a11c07f252e654ddSteve Block    ALOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
3372349703effce5acc53ed96f7ed8556131f0c65e18Jeff Brown#endif
3373349703effce5acc53ed96f7ed8556131f0c65e18Jeff Brown
3374b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    bool changed;
3375349703effce5acc53ed96f7ed8556131f0c65e18Jeff Brown    { // acquire lock
3376349703effce5acc53ed96f7ed8556131f0c65e18Jeff Brown        AutoMutex _l(mLock);
3377349703effce5acc53ed96f7ed8556131f0c65e18Jeff Brown
3378b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
3379120a4594855951ed5eb185fdfc19bf98efef3ba2Jeff Brown            if (mDispatchFrozen && !frozen) {
3380b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown                resetANRTimeoutsLocked();
3381349703effce5acc53ed96f7ed8556131f0c65e18Jeff Brown            }
3382b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
3383120a4594855951ed5eb185fdfc19bf98efef3ba2Jeff Brown            if (mDispatchEnabled && !enabled) {
3384120a4594855951ed5eb185fdfc19bf98efef3ba2Jeff Brown                resetAndDropEverythingLocked("dispatcher is being disabled");
3385120a4594855951ed5eb185fdfc19bf98efef3ba2Jeff Brown            }
3386120a4594855951ed5eb185fdfc19bf98efef3ba2Jeff Brown
3387b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown            mDispatchEnabled = enabled;
3388b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown            mDispatchFrozen = frozen;
3389b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown            changed = true;
3390b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        } else {
3391b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown            changed = false;
3392349703effce5acc53ed96f7ed8556131f0c65e18Jeff Brown        }
3393b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
3394b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown#if DEBUG_FOCUS
3395b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown        //logDispatchStateLocked();
3396b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown#endif
3397b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    } // release lock
3398b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
3399b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    if (changed) {
3400b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        // Wake up poll loop since it may need to make new input dispatching choices.
34014fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown        mLooper->wake();
3402b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    }
3403b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown}
3404b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
34050029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brownvoid InputDispatcher::setInputFilterEnabled(bool enabled) {
34060029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown#if DEBUG_FOCUS
34075baa3a62a97544669fba6d65a11c07f252e654ddSteve Block    ALOGD("setInputFilterEnabled: enabled=%d", enabled);
34080029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown#endif
34090029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown
34100029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown    { // acquire lock
34110029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown        AutoMutex _l(mLock);
34120029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown
34130029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown        if (mInputFilterEnabled == enabled) {
34140029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown            return;
34150029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown        }
34160029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown
34170029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown        mInputFilterEnabled = enabled;
34180029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown        resetAndDropEverythingLocked("input filter is being enabled or disabled");
34190029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown    } // release lock
34200029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown
34210029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown    // Wake up poll loop since there might be work to do to drop everything.
34220029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown    mLooper->wake();
34230029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown}
34240029c66203ab9ded4342976bf7a17bb63af8c44aJeff Brown
3425e65041225ec0bbc3d67a3b70cdc6d598a5760043Jeff Brownbool InputDispatcher::transferTouchFocus(const sp<InputChannel>& fromChannel,
3426e65041225ec0bbc3d67a3b70cdc6d598a5760043Jeff Brown        const sp<InputChannel>& toChannel) {
3427e65041225ec0bbc3d67a3b70cdc6d598a5760043Jeff Brown#if DEBUG_FOCUS
34285baa3a62a97544669fba6d65a11c07f252e654ddSteve Block    ALOGD("transferTouchFocus: fromChannel=%s, toChannel=%s",
3429e65041225ec0bbc3d67a3b70cdc6d598a5760043Jeff Brown            fromChannel->getName().string(), toChannel->getName().string());
3430e65041225ec0bbc3d67a3b70cdc6d598a5760043Jeff Brown#endif
3431e65041225ec0bbc3d67a3b70cdc6d598a5760043Jeff Brown    { // acquire lock
3432e65041225ec0bbc3d67a3b70cdc6d598a5760043Jeff Brown        AutoMutex _l(mLock);
3433e65041225ec0bbc3d67a3b70cdc6d598a5760043Jeff Brown
34349302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown        sp<InputWindowHandle> fromWindowHandle = getWindowHandleLocked(fromChannel);
34359302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown        sp<InputWindowHandle> toWindowHandle = getWindowHandleLocked(toChannel);
34369302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown        if (fromWindowHandle == NULL || toWindowHandle == NULL) {
3437e65041225ec0bbc3d67a3b70cdc6d598a5760043Jeff Brown#if DEBUG_FOCUS
34385baa3a62a97544669fba6d65a11c07f252e654ddSteve Block            ALOGD("Cannot transfer focus because from or to window not found.");
3439e65041225ec0bbc3d67a3b70cdc6d598a5760043Jeff Brown#endif
3440e65041225ec0bbc3d67a3b70cdc6d598a5760043Jeff Brown            return false;
3441e65041225ec0bbc3d67a3b70cdc6d598a5760043Jeff Brown        }
34429302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown        if (fromWindowHandle == toWindowHandle) {
3443e65041225ec0bbc3d67a3b70cdc6d598a5760043Jeff Brown#if DEBUG_FOCUS
34445baa3a62a97544669fba6d65a11c07f252e654ddSteve Block            ALOGD("Trivial transfer to same window.");
3445e65041225ec0bbc3d67a3b70cdc6d598a5760043Jeff Brown#endif
3446e65041225ec0bbc3d67a3b70cdc6d598a5760043Jeff Brown            return true;
3447e65041225ec0bbc3d67a3b70cdc6d598a5760043Jeff Brown        }
3448e65041225ec0bbc3d67a3b70cdc6d598a5760043Jeff Brown
3449e65041225ec0bbc3d67a3b70cdc6d598a5760043Jeff Brown        bool found = false;
3450e65041225ec0bbc3d67a3b70cdc6d598a5760043Jeff Brown        for (size_t i = 0; i < mTouchState.windows.size(); i++) {
3451e65041225ec0bbc3d67a3b70cdc6d598a5760043Jeff Brown            const TouchedWindow& touchedWindow = mTouchState.windows[i];
34529302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown            if (touchedWindow.windowHandle == fromWindowHandle) {
3453e65041225ec0bbc3d67a3b70cdc6d598a5760043Jeff Brown                int32_t oldTargetFlags = touchedWindow.targetFlags;
3454e65041225ec0bbc3d67a3b70cdc6d598a5760043Jeff Brown                BitSet32 pointerIds = touchedWindow.pointerIds;
3455e65041225ec0bbc3d67a3b70cdc6d598a5760043Jeff Brown
3456e65041225ec0bbc3d67a3b70cdc6d598a5760043Jeff Brown                mTouchState.windows.removeAt(i);
3457e65041225ec0bbc3d67a3b70cdc6d598a5760043Jeff Brown
345846e75294d540fe807d78aec2582ae02cc38c7d42Jeff Brown                int32_t newTargetFlags = oldTargetFlags
3459a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown                        & (InputTarget::FLAG_FOREGROUND
3460a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown                                | InputTarget::FLAG_SPLIT | InputTarget::FLAG_DISPATCH_AS_IS);
34619302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown                mTouchState.addOrUpdateWindow(toWindowHandle, newTargetFlags, pointerIds);
3462e65041225ec0bbc3d67a3b70cdc6d598a5760043Jeff Brown
3463e65041225ec0bbc3d67a3b70cdc6d598a5760043Jeff Brown                found = true;
3464e65041225ec0bbc3d67a3b70cdc6d598a5760043Jeff Brown                break;
3465e65041225ec0bbc3d67a3b70cdc6d598a5760043Jeff Brown            }
3466e65041225ec0bbc3d67a3b70cdc6d598a5760043Jeff Brown        }
3467e65041225ec0bbc3d67a3b70cdc6d598a5760043Jeff Brown
3468e65041225ec0bbc3d67a3b70cdc6d598a5760043Jeff Brown        if (! found) {
3469e65041225ec0bbc3d67a3b70cdc6d598a5760043Jeff Brown#if DEBUG_FOCUS
34705baa3a62a97544669fba6d65a11c07f252e654ddSteve Block            ALOGD("Focus transfer failed because from window did not have focus.");
3471e65041225ec0bbc3d67a3b70cdc6d598a5760043Jeff Brown#endif
3472e65041225ec0bbc3d67a3b70cdc6d598a5760043Jeff Brown            return false;
3473e65041225ec0bbc3d67a3b70cdc6d598a5760043Jeff Brown        }
3474e65041225ec0bbc3d67a3b70cdc6d598a5760043Jeff Brown
34759c9f1a3ba1bc19754e4d38cb27a537d4dfedc0feJeff Brown        ssize_t fromConnectionIndex = getConnectionIndexLocked(fromChannel);
34769c9f1a3ba1bc19754e4d38cb27a537d4dfedc0feJeff Brown        ssize_t toConnectionIndex = getConnectionIndexLocked(toChannel);
34779c9f1a3ba1bc19754e4d38cb27a537d4dfedc0feJeff Brown        if (fromConnectionIndex >= 0 && toConnectionIndex >= 0) {
34789c9f1a3ba1bc19754e4d38cb27a537d4dfedc0feJeff Brown            sp<Connection> fromConnection = mConnectionsByReceiveFd.valueAt(fromConnectionIndex);
34799c9f1a3ba1bc19754e4d38cb27a537d4dfedc0feJeff Brown            sp<Connection> toConnection = mConnectionsByReceiveFd.valueAt(toConnectionIndex);
34809c9f1a3ba1bc19754e4d38cb27a537d4dfedc0feJeff Brown
34819c9f1a3ba1bc19754e4d38cb27a537d4dfedc0feJeff Brown            fromConnection->inputState.copyPointerStateTo(toConnection->inputState);
3482da3d5a91b6b311ed77f2707d4456c1f18b84d73bJeff Brown            CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
34839c9f1a3ba1bc19754e4d38cb27a537d4dfedc0feJeff Brown                    "transferring touch focus from this window to another window");
3484da3d5a91b6b311ed77f2707d4456c1f18b84d73bJeff Brown            synthesizeCancelationEventsForConnectionLocked(fromConnection, options);
34859c9f1a3ba1bc19754e4d38cb27a537d4dfedc0feJeff Brown        }
34869c9f1a3ba1bc19754e4d38cb27a537d4dfedc0feJeff Brown
3487e65041225ec0bbc3d67a3b70cdc6d598a5760043Jeff Brown#if DEBUG_FOCUS
3488e65041225ec0bbc3d67a3b70cdc6d598a5760043Jeff Brown        logDispatchStateLocked();
3489e65041225ec0bbc3d67a3b70cdc6d598a5760043Jeff Brown#endif
3490e65041225ec0bbc3d67a3b70cdc6d598a5760043Jeff Brown    } // release lock
3491e65041225ec0bbc3d67a3b70cdc6d598a5760043Jeff Brown
3492e65041225ec0bbc3d67a3b70cdc6d598a5760043Jeff Brown    // Wake up poll loop since it may need to make new input dispatching choices.
3493e65041225ec0bbc3d67a3b70cdc6d598a5760043Jeff Brown    mLooper->wake();
3494e65041225ec0bbc3d67a3b70cdc6d598a5760043Jeff Brown    return true;
3495e65041225ec0bbc3d67a3b70cdc6d598a5760043Jeff Brown}
3496e65041225ec0bbc3d67a3b70cdc6d598a5760043Jeff Brown
3497120a4594855951ed5eb185fdfc19bf98efef3ba2Jeff Brownvoid InputDispatcher::resetAndDropEverythingLocked(const char* reason) {
3498120a4594855951ed5eb185fdfc19bf98efef3ba2Jeff Brown#if DEBUG_FOCUS
34995baa3a62a97544669fba6d65a11c07f252e654ddSteve Block    ALOGD("Resetting and dropping all events (%s).", reason);
3500120a4594855951ed5eb185fdfc19bf98efef3ba2Jeff Brown#endif
3501120a4594855951ed5eb185fdfc19bf98efef3ba2Jeff Brown
3502da3d5a91b6b311ed77f2707d4456c1f18b84d73bJeff Brown    CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, reason);
3503da3d5a91b6b311ed77f2707d4456c1f18b84d73bJeff Brown    synthesizeCancelationEventsForAllConnectionsLocked(options);
3504120a4594855951ed5eb185fdfc19bf98efef3ba2Jeff Brown
3505120a4594855951ed5eb185fdfc19bf98efef3ba2Jeff Brown    resetKeyRepeatLocked();
3506120a4594855951ed5eb185fdfc19bf98efef3ba2Jeff Brown    releasePendingEventLocked();
3507120a4594855951ed5eb185fdfc19bf98efef3ba2Jeff Brown    drainInboundQueueLocked();
3508120a4594855951ed5eb185fdfc19bf98efef3ba2Jeff Brown    resetTargetsLocked();
3509120a4594855951ed5eb185fdfc19bf98efef3ba2Jeff Brown
3510120a4594855951ed5eb185fdfc19bf98efef3ba2Jeff Brown    mTouchState.reset();
35119302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown    mLastHoverWindowHandle.clear();
3512120a4594855951ed5eb185fdfc19bf98efef3ba2Jeff Brown}
3513120a4594855951ed5eb185fdfc19bf98efef3ba2Jeff Brown
3514b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brownvoid InputDispatcher::logDispatchStateLocked() {
3515b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    String8 dump;
3516b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    dumpDispatchStateLocked(dump);
35172a95c2a9ec703b9d19b750cb854fb4ec4899e205Jeff Brown
35182a95c2a9ec703b9d19b750cb854fb4ec4899e205Jeff Brown    char* text = dump.lockBuffer(dump.size());
35192a95c2a9ec703b9d19b750cb854fb4ec4899e205Jeff Brown    char* start = text;
35202a95c2a9ec703b9d19b750cb854fb4ec4899e205Jeff Brown    while (*start != '\0') {
35212a95c2a9ec703b9d19b750cb854fb4ec4899e205Jeff Brown        char* end = strchr(start, '\n');
35222a95c2a9ec703b9d19b750cb854fb4ec4899e205Jeff Brown        if (*end == '\n') {
35232a95c2a9ec703b9d19b750cb854fb4ec4899e205Jeff Brown            *(end++) = '\0';
35242a95c2a9ec703b9d19b750cb854fb4ec4899e205Jeff Brown        }
35255baa3a62a97544669fba6d65a11c07f252e654ddSteve Block        ALOGD("%s", start);
35262a95c2a9ec703b9d19b750cb854fb4ec4899e205Jeff Brown        start = end;
35272a95c2a9ec703b9d19b750cb854fb4ec4899e205Jeff Brown    }
3528b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown}
3529b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
3530b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brownvoid InputDispatcher::dumpDispatchStateLocked(String8& dump) {
3531f2f487183052865d50c004a835360be1728b5a52Jeff Brown    dump.appendFormat(INDENT "DispatchEnabled: %d\n", mDispatchEnabled);
3532f2f487183052865d50c004a835360be1728b5a52Jeff Brown    dump.appendFormat(INDENT "DispatchFrozen: %d\n", mDispatchFrozen);
3533b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
35349302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown    if (mFocusedApplicationHandle != NULL) {
3535f2f487183052865d50c004a835360be1728b5a52Jeff Brown        dump.appendFormat(INDENT "FocusedApplication: name='%s', dispatchingTimeout=%0.3fms\n",
3536cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown                mFocusedApplicationHandle->getName().string(),
3537cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown                mFocusedApplicationHandle->getDispatchingTimeout(
3538cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown                        DEFAULT_INPUT_DISPATCHING_TIMEOUT) / 1000000.0);
3539b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    } else {
3540f2f487183052865d50c004a835360be1728b5a52Jeff Brown        dump.append(INDENT "FocusedApplication: <null>\n");
3541b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    }
3542f2f487183052865d50c004a835360be1728b5a52Jeff Brown    dump.appendFormat(INDENT "FocusedWindow: name='%s'\n",
3543cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown            mFocusedWindowHandle != NULL ? mFocusedWindowHandle->getName().string() : "<null>");
3544f2f487183052865d50c004a835360be1728b5a52Jeff Brown
3545f2f487183052865d50c004a835360be1728b5a52Jeff Brown    dump.appendFormat(INDENT "TouchDown: %s\n", toString(mTouchState.down));
3546f2f487183052865d50c004a835360be1728b5a52Jeff Brown    dump.appendFormat(INDENT "TouchSplit: %s\n", toString(mTouchState.split));
354795712850665492af670824abdba77f0944d984d1Jeff Brown    dump.appendFormat(INDENT "TouchDeviceId: %d\n", mTouchState.deviceId);
354858a2da843f2f22f406df8df1f011738eb8b7fcb1Jeff Brown    dump.appendFormat(INDENT "TouchSource: 0x%08x\n", mTouchState.source);
3549f2f487183052865d50c004a835360be1728b5a52Jeff Brown    if (!mTouchState.windows.isEmpty()) {
3550f2f487183052865d50c004a835360be1728b5a52Jeff Brown        dump.append(INDENT "TouchedWindows:\n");
3551f2f487183052865d50c004a835360be1728b5a52Jeff Brown        for (size_t i = 0; i < mTouchState.windows.size(); i++) {
3552f2f487183052865d50c004a835360be1728b5a52Jeff Brown            const TouchedWindow& touchedWindow = mTouchState.windows[i];
3553f2f487183052865d50c004a835360be1728b5a52Jeff Brown            dump.appendFormat(INDENT2 "%d: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n",
3554cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown                    i, touchedWindow.windowHandle->getName().string(),
3555cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown                    touchedWindow.pointerIds.value,
3556f2f487183052865d50c004a835360be1728b5a52Jeff Brown                    touchedWindow.targetFlags);
3557f2f487183052865d50c004a835360be1728b5a52Jeff Brown        }
3558f2f487183052865d50c004a835360be1728b5a52Jeff Brown    } else {
3559f2f487183052865d50c004a835360be1728b5a52Jeff Brown        dump.append(INDENT "TouchedWindows: <none>\n");
3560f2f487183052865d50c004a835360be1728b5a52Jeff Brown    }
3561f2f487183052865d50c004a835360be1728b5a52Jeff Brown
35629302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown    if (!mWindowHandles.isEmpty()) {
3563f2f487183052865d50c004a835360be1728b5a52Jeff Brown        dump.append(INDENT "Windows:\n");
35649302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown        for (size_t i = 0; i < mWindowHandles.size(); i++) {
35659302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown            const sp<InputWindowHandle>& windowHandle = mWindowHandles.itemAt(i);
3566cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown            const InputWindowInfo* windowInfo = windowHandle->getInfo();
3567cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown
3568f2f487183052865d50c004a835360be1728b5a52Jeff Brown            dump.appendFormat(INDENT2 "%d: name='%s', paused=%s, hasFocus=%s, hasWallpaper=%s, "
3569f2f487183052865d50c004a835360be1728b5a52Jeff Brown                    "visible=%s, canReceiveKeys=%s, flags=0x%08x, type=0x%08x, layer=%d, "
3570e2515eebf42c763c0a2d9f873a153711778cfc17Dianne Hackborn                    "frame=[%d,%d][%d,%d], scale=%f, "
3571fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown                    "touchableRegion=",
3572cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown                    i, windowInfo->name.string(),
3573cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown                    toString(windowInfo->paused),
3574cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown                    toString(windowInfo->hasFocus),
3575cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown                    toString(windowInfo->hasWallpaper),
3576cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown                    toString(windowInfo->visible),
3577cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown                    toString(windowInfo->canReceiveKeys),
3578cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown                    windowInfo->layoutParamsFlags, windowInfo->layoutParamsType,
3579cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown                    windowInfo->layer,
3580cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown                    windowInfo->frameLeft, windowInfo->frameTop,
3581cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown                    windowInfo->frameRight, windowInfo->frameBottom,
3582cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown                    windowInfo->scaleFactor);
3583cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown            dumpRegion(dump, windowInfo->touchableRegion);
3584cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown            dump.appendFormat(", inputFeatures=0x%08x", windowInfo->inputFeatures);
3585fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown            dump.appendFormat(", ownerPid=%d, ownerUid=%d, dispatchingTimeout=%0.3fms\n",
3586cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown                    windowInfo->ownerPid, windowInfo->ownerUid,
3587cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown                    windowInfo->dispatchingTimeout / 1000000.0);
3588f2f487183052865d50c004a835360be1728b5a52Jeff Brown        }
3589f2f487183052865d50c004a835360be1728b5a52Jeff Brown    } else {
3590f2f487183052865d50c004a835360be1728b5a52Jeff Brown        dump.append(INDENT "Windows: <none>\n");
3591b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    }
3592b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
3593f2f487183052865d50c004a835360be1728b5a52Jeff Brown    if (!mMonitoringChannels.isEmpty()) {
3594f2f487183052865d50c004a835360be1728b5a52Jeff Brown        dump.append(INDENT "MonitoringChannels:\n");
3595f2f487183052865d50c004a835360be1728b5a52Jeff Brown        for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
3596f2f487183052865d50c004a835360be1728b5a52Jeff Brown            const sp<InputChannel>& channel = mMonitoringChannels[i];
3597f2f487183052865d50c004a835360be1728b5a52Jeff Brown            dump.appendFormat(INDENT2 "%d: '%s'\n", i, channel->getName().string());
3598f2f487183052865d50c004a835360be1728b5a52Jeff Brown        }
3599f2f487183052865d50c004a835360be1728b5a52Jeff Brown    } else {
3600f2f487183052865d50c004a835360be1728b5a52Jeff Brown        dump.append(INDENT "MonitoringChannels: <none>\n");
3601b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    }
3602b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
3603f2f487183052865d50c004a835360be1728b5a52Jeff Brown    dump.appendFormat(INDENT "InboundQueue: length=%u\n", mInboundQueue.count());
3604519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown
3605f2f487183052865d50c004a835360be1728b5a52Jeff Brown    if (!mActiveConnections.isEmpty()) {
3606f2f487183052865d50c004a835360be1728b5a52Jeff Brown        dump.append(INDENT "ActiveConnections:\n");
3607f2f487183052865d50c004a835360be1728b5a52Jeff Brown        for (size_t i = 0; i < mActiveConnections.size(); i++) {
3608f2f487183052865d50c004a835360be1728b5a52Jeff Brown            const Connection* connection = mActiveConnections[i];
360976860e3fe73a791b1b04f33d78b908eb3163b4b2Jeff Brown            dump.appendFormat(INDENT2 "%d: '%s', status=%s, outboundQueueLength=%u, "
3610b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown                    "inputState.isNeutral=%s\n",
3611f2f487183052865d50c004a835360be1728b5a52Jeff Brown                    i, connection->getInputChannelName(), connection->getStatusLabel(),
3612f2f487183052865d50c004a835360be1728b5a52Jeff Brown                    connection->outboundQueue.count(),
3613b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown                    toString(connection->inputState.isNeutral()));
3614f2f487183052865d50c004a835360be1728b5a52Jeff Brown        }
3615f2f487183052865d50c004a835360be1728b5a52Jeff Brown    } else {
3616f2f487183052865d50c004a835360be1728b5a52Jeff Brown        dump.append(INDENT "ActiveConnections: <none>\n");
3617b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    }
3618b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
3619b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    if (isAppSwitchPendingLocked()) {
3620f2f487183052865d50c004a835360be1728b5a52Jeff Brown        dump.appendFormat(INDENT "AppSwitch: pending, due in %01.1fms\n",
3621b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown                (mAppSwitchDueTime - now()) / 1000000.0);
3622b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    } else {
3623f2f487183052865d50c004a835360be1728b5a52Jeff Brown        dump.append(INDENT "AppSwitch: not pending\n");
3624b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    }
3625b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown}
3626b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
3627928e054931d357326613c78e62f4d850b7c442ffJeff Brownstatus_t InputDispatcher::registerInputChannel(const sp<InputChannel>& inputChannel,
3628928e054931d357326613c78e62f4d850b7c442ffJeff Brown        const sp<InputWindowHandle>& inputWindowHandle, bool monitor) {
36299c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown#if DEBUG_REGISTRATION
36305baa3a62a97544669fba6d65a11c07f252e654ddSteve Block    ALOGD("channel '%s' ~ registerInputChannel - monitor=%s", inputChannel->getName().string(),
3631b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown            toString(monitor));
36329c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown#endif
36339c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown
363446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    { // acquire lock
363546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        AutoMutex _l(mLock);
363646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
3637519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown        if (getConnectionIndexLocked(inputChannel) >= 0) {
36388564c8da817a845353d213acd8636b76f567b234Steve Block            ALOGW("Attempted to register already registered input channel '%s'",
363946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown                    inputChannel->getName().string());
364046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            return BAD_VALUE;
364146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        }
364246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
3643cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown        sp<Connection> connection = new Connection(inputChannel, inputWindowHandle, monitor);
364446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        status_t status = connection->initialize();
364546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        if (status) {
364646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            LOGE("Failed to initialize input publisher for input channel '%s', status=%d",
364746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown                    inputChannel->getName().string(), status);
364846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            return status;
364946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        }
365046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
36512cbecea4c9627d95377fc3e3b8a319116cee7febJeff Brown        int32_t receiveFd = inputChannel->getReceivePipeFd();
365246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        mConnectionsByReceiveFd.add(receiveFd, connection);
36539c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown
3654b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        if (monitor) {
3655b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown            mMonitoringChannels.push(inputChannel);
3656b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        }
3657b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
36584fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown        mLooper->addFd(receiveFd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
36592cbecea4c9627d95377fc3e3b8a319116cee7febJeff Brown
36609c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown        runCommandsLockedInterruptible();
366146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    } // release lock
366246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    return OK;
366346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
366446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
366546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownstatus_t InputDispatcher::unregisterInputChannel(const sp<InputChannel>& inputChannel) {
36669c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown#if DEBUG_REGISTRATION
36675baa3a62a97544669fba6d65a11c07f252e654ddSteve Block    ALOGD("channel '%s' ~ unregisterInputChannel", inputChannel->getName().string());
36689c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown#endif
36699c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown
367046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    { // acquire lock
367146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        AutoMutex _l(mLock);
367246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
3673cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown        status_t status = unregisterInputChannelLocked(inputChannel, false /*notify*/);
3674cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown        if (status) {
3675cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown            return status;
367646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        }
3677cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown    } // release lock
367846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
3679cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown    // Wake the poll loop because removing the connection may have changed the current
3680cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown    // synchronization state.
3681cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown    mLooper->wake();
3682cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown    return OK;
3683cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown}
368446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
3685cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brownstatus_t InputDispatcher::unregisterInputChannelLocked(const sp<InputChannel>& inputChannel,
3686cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown        bool notify) {
3687cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown    ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
3688cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown    if (connectionIndex < 0) {
36898564c8da817a845353d213acd8636b76f567b234Steve Block        ALOGW("Attempted to unregister already unregistered input channel '%s'",
3690cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown                inputChannel->getName().string());
3691cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown        return BAD_VALUE;
3692cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown    }
369346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
3694cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown    sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
3695cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown    mConnectionsByReceiveFd.removeItemsAt(connectionIndex);
3696b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
3697cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown    if (connection->monitor) {
3698cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown        removeMonitorChannelLocked(inputChannel);
3699cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown    }
37002cbecea4c9627d95377fc3e3b8a319116cee7febJeff Brown
3701cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown    mLooper->removeFd(inputChannel->getReceivePipeFd());
37029c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown
3703cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown    nsecs_t currentTime = now();
3704cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown    abortBrokenDispatchCycleLocked(currentTime, connection, notify);
370546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
3706cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown    runCommandsLockedInterruptible();
3707cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown
3708cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown    connection->status = Connection::STATUS_ZOMBIE;
370946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    return OK;
371046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
371146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
3712cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brownvoid InputDispatcher::removeMonitorChannelLocked(const sp<InputChannel>& inputChannel) {
3713cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown    for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
3714cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown         if (mMonitoringChannels[i] == inputChannel) {
3715cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown             mMonitoringChannels.removeAt(i);
3716cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown             break;
3717cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown         }
3718cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown    }
3719cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown}
3720cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown
3721519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brownssize_t InputDispatcher::getConnectionIndexLocked(const sp<InputChannel>& inputChannel) {
37222cbecea4c9627d95377fc3e3b8a319116cee7febJeff Brown    ssize_t connectionIndex = mConnectionsByReceiveFd.indexOfKey(inputChannel->getReceivePipeFd());
37232cbecea4c9627d95377fc3e3b8a319116cee7febJeff Brown    if (connectionIndex >= 0) {
37242cbecea4c9627d95377fc3e3b8a319116cee7febJeff Brown        sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
37252cbecea4c9627d95377fc3e3b8a319116cee7febJeff Brown        if (connection->inputChannel.get() == inputChannel.get()) {
37262cbecea4c9627d95377fc3e3b8a319116cee7febJeff Brown            return connectionIndex;
37272cbecea4c9627d95377fc3e3b8a319116cee7febJeff Brown        }
37282cbecea4c9627d95377fc3e3b8a319116cee7febJeff Brown    }
37292cbecea4c9627d95377fc3e3b8a319116cee7febJeff Brown
37302cbecea4c9627d95377fc3e3b8a319116cee7febJeff Brown    return -1;
37312cbecea4c9627d95377fc3e3b8a319116cee7febJeff Brown}
37322cbecea4c9627d95377fc3e3b8a319116cee7febJeff Brown
373346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownvoid InputDispatcher::activateConnectionLocked(Connection* connection) {
373446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    for (size_t i = 0; i < mActiveConnections.size(); i++) {
373546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        if (mActiveConnections.itemAt(i) == connection) {
373646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            return;
373746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        }
373846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
373946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    mActiveConnections.add(connection);
374046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
374146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
374246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownvoid InputDispatcher::deactivateConnectionLocked(Connection* connection) {
374346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    for (size_t i = 0; i < mActiveConnections.size(); i++) {
374446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        if (mActiveConnections.itemAt(i) == connection) {
374546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            mActiveConnections.removeAt(i);
374646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            return;
374746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        }
374846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
374946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
375046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
37519c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brownvoid InputDispatcher::onDispatchCycleStartedLocked(
37527fbdc84e87dd3a0e196b9803bb04495d11e9cb8aJeff Brown        nsecs_t currentTime, const sp<Connection>& connection) {
375346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
375446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
37559c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brownvoid InputDispatcher::onDispatchCycleFinishedLocked(
37563915bb845b032dc184dba5e60970b803390ca3edJeff Brown        nsecs_t currentTime, const sp<Connection>& connection, bool handled) {
37573915bb845b032dc184dba5e60970b803390ca3edJeff Brown    CommandEntry* commandEntry = postCommandLocked(
37583915bb845b032dc184dba5e60970b803390ca3edJeff Brown            & InputDispatcher::doDispatchCycleFinishedLockedInterruptible);
37593915bb845b032dc184dba5e60970b803390ca3edJeff Brown    commandEntry->connection = connection;
37603915bb845b032dc184dba5e60970b803390ca3edJeff Brown    commandEntry->handled = handled;
376146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
376246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
37639c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brownvoid InputDispatcher::onDispatchCycleBrokenLocked(
37647fbdc84e87dd3a0e196b9803bb04495d11e9cb8aJeff Brown        nsecs_t currentTime, const sp<Connection>& connection) {
376546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    LOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
376646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            connection->getInputChannelName());
376746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
37689c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown    CommandEntry* commandEntry = postCommandLocked(
37699c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown            & InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible);
37707fbdc84e87dd3a0e196b9803bb04495d11e9cb8aJeff Brown    commandEntry->connection = connection;
377146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
377246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
3773519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brownvoid InputDispatcher::onANRLocked(
37749302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown        nsecs_t currentTime, const sp<InputApplicationHandle>& applicationHandle,
37759302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown        const sp<InputWindowHandle>& windowHandle,
3776519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown        nsecs_t eventTime, nsecs_t waitStartTime) {
37776215d3ff4b5dfa52a5d8b9a42e343051f31066a5Steve Block    ALOGI("Application is not responding: %s.  "
3778519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown            "%01.1fms since event, %01.1fms since wait started",
37799302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown            getApplicationWindowLabelLocked(applicationHandle, windowHandle).string(),
3780519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown            (currentTime - eventTime) / 1000000.0,
3781519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown            (currentTime - waitStartTime) / 1000000.0);
3782519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown
3783519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown    CommandEntry* commandEntry = postCommandLocked(
3784519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown            & InputDispatcher::doNotifyANRLockedInterruptible);
37859302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown    commandEntry->inputApplicationHandle = applicationHandle;
37869302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown    commandEntry->inputWindowHandle = windowHandle;
3787519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown}
3788519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown
3789b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brownvoid InputDispatcher::doNotifyConfigurationChangedInterruptible(
3790b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        CommandEntry* commandEntry) {
3791b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    mLock.unlock();
3792b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
3793b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    mPolicy->notifyConfigurationChanged(commandEntry->eventTime);
3794b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
3795b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    mLock.lock();
3796b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown}
3797b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
37989c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brownvoid InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible(
37999c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown        CommandEntry* commandEntry) {
38007fbdc84e87dd3a0e196b9803bb04495d11e9cb8aJeff Brown    sp<Connection> connection = commandEntry->connection;
38019c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown
38027fbdc84e87dd3a0e196b9803bb04495d11e9cb8aJeff Brown    if (connection->status != Connection::STATUS_ZOMBIE) {
38037fbdc84e87dd3a0e196b9803bb04495d11e9cb8aJeff Brown        mLock.unlock();
38049c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown
3805928e054931d357326613c78e62f4d850b7c442ffJeff Brown        mPolicy->notifyInputChannelBroken(connection->inputWindowHandle);
38067fbdc84e87dd3a0e196b9803bb04495d11e9cb8aJeff Brown
38077fbdc84e87dd3a0e196b9803bb04495d11e9cb8aJeff Brown        mLock.lock();
38087fbdc84e87dd3a0e196b9803bb04495d11e9cb8aJeff Brown    }
38099c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown}
38109c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown
3811519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brownvoid InputDispatcher::doNotifyANRLockedInterruptible(
38129c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown        CommandEntry* commandEntry) {
3813519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown    mLock.unlock();
38149c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown
3815519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown    nsecs_t newTimeout = mPolicy->notifyANR(
3816928e054931d357326613c78e62f4d850b7c442ffJeff Brown            commandEntry->inputApplicationHandle, commandEntry->inputWindowHandle);
38179c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown
3818519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown    mLock.lock();
38197fbdc84e87dd3a0e196b9803bb04495d11e9cb8aJeff Brown
38209302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown    resumeAfterTargetsNotReadyTimeoutLocked(newTimeout,
38219302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown            commandEntry->inputWindowHandle != NULL
3822cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown                    ? commandEntry->inputWindowHandle->getInputChannel() : NULL);
38239c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown}
38249c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown
3825b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brownvoid InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible(
3826b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        CommandEntry* commandEntry) {
3827b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    KeyEntry* entry = commandEntry->keyEntry;
38281f2451007c660091b7b090c1ea332f9044515d2dJeff Brown
38291f2451007c660091b7b090c1ea332f9044515d2dJeff Brown    KeyEvent event;
38301f2451007c660091b7b090c1ea332f9044515d2dJeff Brown    initializeKeyEvent(&event, entry);
3831b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
3832b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    mLock.unlock();
3833b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
3834905805ad7ce18a386076fff99264f821bbad9f83Jeff Brown    nsecs_t delay = mPolicy->interceptKeyBeforeDispatching(commandEntry->inputWindowHandle,
38351f2451007c660091b7b090c1ea332f9044515d2dJeff Brown            &event, entry->policyFlags);
3836b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
3837b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    mLock.lock();
3838b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
3839905805ad7ce18a386076fff99264f821bbad9f83Jeff Brown    if (delay < 0) {
3840905805ad7ce18a386076fff99264f821bbad9f83Jeff Brown        entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_SKIP;
3841905805ad7ce18a386076fff99264f821bbad9f83Jeff Brown    } else if (!delay) {
3842905805ad7ce18a386076fff99264f821bbad9f83Jeff Brown        entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
3843905805ad7ce18a386076fff99264f821bbad9f83Jeff Brown    } else {
3844905805ad7ce18a386076fff99264f821bbad9f83Jeff Brown        entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER;
3845905805ad7ce18a386076fff99264f821bbad9f83Jeff Brown        entry->interceptKeyWakeupTime = now() + delay;
3846905805ad7ce18a386076fff99264f821bbad9f83Jeff Brown    }
3847ac386073df2514b79a2ca169f4a89f129733002fJeff Brown    entry->release();
3848b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown}
3849b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
38503915bb845b032dc184dba5e60970b803390ca3edJeff Brownvoid InputDispatcher::doDispatchCycleFinishedLockedInterruptible(
38513915bb845b032dc184dba5e60970b803390ca3edJeff Brown        CommandEntry* commandEntry) {
38523915bb845b032dc184dba5e60970b803390ca3edJeff Brown    sp<Connection> connection = commandEntry->connection;
38533915bb845b032dc184dba5e60970b803390ca3edJeff Brown    bool handled = commandEntry->handled;
38543915bb845b032dc184dba5e60970b803390ca3edJeff Brown
3855fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    bool skipNext = false;
385649ed71db425c5054e3ad9526496a7e116c89556bJeff Brown    if (!connection->outboundQueue.isEmpty()) {
3857ac386073df2514b79a2ca169f4a89f129733002fJeff Brown        DispatchEntry* dispatchEntry = connection->outboundQueue.head;
3858fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        if (dispatchEntry->inProgress) {
3859fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            if (dispatchEntry->eventEntry->type == EventEntry::TYPE_KEY) {
3860fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                KeyEntry* keyEntry = static_cast<KeyEntry*>(dispatchEntry->eventEntry);
3861fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                skipNext = afterKeyEventLockedInterruptible(connection,
3862fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                        dispatchEntry, keyEntry, handled);
3863fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            } else if (dispatchEntry->eventEntry->type == EventEntry::TYPE_MOTION) {
3864fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                MotionEntry* motionEntry = static_cast<MotionEntry*>(dispatchEntry->eventEntry);
3865fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                skipNext = afterMotionEventLockedInterruptible(connection,
3866fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                        dispatchEntry, motionEntry, handled);
3867fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            }
3868fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        }
3869fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    }
3870da3d5a91b6b311ed77f2707d4456c1f18b84d73bJeff Brown
3871fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    if (!skipNext) {
3872fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        startNextDispatchCycleLocked(now(), connection);
3873fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    }
3874fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown}
3875fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown
3876fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brownbool InputDispatcher::afterKeyEventLockedInterruptible(const sp<Connection>& connection,
3877fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        DispatchEntry* dispatchEntry, KeyEntry* keyEntry, bool handled) {
3878fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    if (!(keyEntry->flags & AKEY_EVENT_FLAG_FALLBACK)) {
3879fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        // Get the fallback key state.
3880fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        // Clear it out after dispatching the UP.
3881fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        int32_t originalKeyCode = keyEntry->keyCode;
3882fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        int32_t fallbackKeyCode = connection->inputState.getFallbackKey(originalKeyCode);
3883fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        if (keyEntry->action == AKEY_EVENT_ACTION_UP) {
3884fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            connection->inputState.removeFallbackKey(originalKeyCode);
3885fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        }
3886fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown
3887fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        if (handled || !dispatchEntry->hasForegroundTarget()) {
3888fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            // If the application handles the original key for which we previously
3889fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            // generated a fallback or if the window is not a foreground window,
3890fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            // then cancel the associated fallback key, if any.
3891fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            if (fallbackKeyCode != -1) {
3892fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                if (fallbackKeyCode != AKEYCODE_UNKNOWN) {
3893fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                    CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
3894fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                            "application handled the original non-fallback key "
3895fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                            "or is no longer a foreground target, "
3896fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                            "canceling previously dispatched fallback key");
3897fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                    options.keyCode = fallbackKeyCode;
3898fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                    synthesizeCancelationEventsForConnectionLocked(connection, options);
3899fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                }
3900fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                connection->inputState.removeFallbackKey(originalKeyCode);
3901fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            }
3902fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        } else {
3903fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            // If the application did not handle a non-fallback key, first check
3904fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            // that we are in a good state to perform unhandled key event processing
3905fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            // Then ask the policy what to do with it.
3906fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            bool initialDown = keyEntry->action == AKEY_EVENT_ACTION_DOWN
3907fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                    && keyEntry->repeatCount == 0;
3908fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            if (fallbackKeyCode == -1 && !initialDown) {
3909bfaf3b91709ef35e0d5901b186edd7c2a9729161Jeff Brown#if DEBUG_OUTBOUND_EVENT_DETAILS
39105baa3a62a97544669fba6d65a11c07f252e654ddSteve Block                ALOGD("Unhandled key event: Skipping unhandled key event processing "
3911fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                        "since this is not an initial down.  "
3912fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                        "keyCode=%d, action=%d, repeatCount=%d",
3913fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                        originalKeyCode, keyEntry->action, keyEntry->repeatCount);
3914bfaf3b91709ef35e0d5901b186edd7c2a9729161Jeff Brown#endif
3915fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                return false;
3916fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            }
3917bfaf3b91709ef35e0d5901b186edd7c2a9729161Jeff Brown
3918fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            // Dispatch the unhandled key to the policy.
3919bfaf3b91709ef35e0d5901b186edd7c2a9729161Jeff Brown#if DEBUG_OUTBOUND_EVENT_DETAILS
39205baa3a62a97544669fba6d65a11c07f252e654ddSteve Block            ALOGD("Unhandled key event: Asking policy to perform fallback action.  "
3921fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                    "keyCode=%d, action=%d, repeatCount=%d",
3922fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                    keyEntry->keyCode, keyEntry->action, keyEntry->repeatCount);
3923bfaf3b91709ef35e0d5901b186edd7c2a9729161Jeff Brown#endif
3924fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            KeyEvent event;
3925fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            initializeKeyEvent(&event, keyEntry);
392649ed71db425c5054e3ad9526496a7e116c89556bJeff Brown
3927fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            mLock.unlock();
392849ed71db425c5054e3ad9526496a7e116c89556bJeff Brown
3929fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            bool fallback = mPolicy->dispatchUnhandledKey(connection->inputWindowHandle,
3930fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                    &event, keyEntry->policyFlags, &event);
393149ed71db425c5054e3ad9526496a7e116c89556bJeff Brown
3932fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            mLock.lock();
393349ed71db425c5054e3ad9526496a7e116c89556bJeff Brown
3934fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            if (connection->status != Connection::STATUS_NORMAL) {
3935fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                connection->inputState.removeFallbackKey(originalKeyCode);
3936fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                return true; // skip next cycle
3937fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            }
393800045a7e6fbed88f3325d2bbb048dc96a082078cJeff Brown
3939ac386073df2514b79a2ca169f4a89f129733002fJeff Brown            LOG_ASSERT(connection->outboundQueue.head == dispatchEntry);
394000045a7e6fbed88f3325d2bbb048dc96a082078cJeff Brown
3941fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            // Latch the fallback keycode for this key on an initial down.
3942fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            // The fallback keycode cannot change at any other point in the lifecycle.
3943fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            if (initialDown) {
3944fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                if (fallback) {
3945fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                    fallbackKeyCode = event.getKeyCode();
3946fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                } else {
3947fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                    fallbackKeyCode = AKEYCODE_UNKNOWN;
3948fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                }
3949fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
3950fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            }
3951da3d5a91b6b311ed77f2707d4456c1f18b84d73bJeff Brown
3952fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            LOG_ASSERT(fallbackKeyCode != -1);
3953da3d5a91b6b311ed77f2707d4456c1f18b84d73bJeff Brown
3954fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            // Cancel the fallback key if the policy decides not to send it anymore.
3955fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            // We will continue to dispatch the key to the policy but we will no
3956fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            // longer dispatch a fallback key to the application.
3957fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            if (fallbackKeyCode != AKEYCODE_UNKNOWN
3958fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                    && (!fallback || fallbackKeyCode != event.getKeyCode())) {
3959da3d5a91b6b311ed77f2707d4456c1f18b84d73bJeff Brown#if DEBUG_OUTBOUND_EVENT_DETAILS
3960fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                if (fallback) {
39615baa3a62a97544669fba6d65a11c07f252e654ddSteve Block                    ALOGD("Unhandled key event: Policy requested to send key %d"
3962fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                            "as a fallback for %d, but on the DOWN it had requested "
3963fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                            "to send %d instead.  Fallback canceled.",
3964fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                            event.getKeyCode(), originalKeyCode, fallbackKeyCode);
3965fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                } else {
39665baa3a62a97544669fba6d65a11c07f252e654ddSteve Block                    ALOGD("Unhandled key event: Policy did not request fallback for %d,"
3967fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                            "but on the DOWN it had requested to send %d.  "
3968fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                            "Fallback canceled.",
3969fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                            originalKeyCode, fallbackKeyCode);
3970fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                }
3971da3d5a91b6b311ed77f2707d4456c1f18b84d73bJeff Brown#endif
3972da3d5a91b6b311ed77f2707d4456c1f18b84d73bJeff Brown
3973fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
3974fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                        "canceling fallback, policy no longer desires it");
3975fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                options.keyCode = fallbackKeyCode;
3976fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                synthesizeCancelationEventsForConnectionLocked(connection, options);
3977da3d5a91b6b311ed77f2707d4456c1f18b84d73bJeff Brown
3978fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                fallback = false;
3979fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                fallbackKeyCode = AKEYCODE_UNKNOWN;
3980fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                if (keyEntry->action != AKEY_EVENT_ACTION_UP) {
3981fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                    connection->inputState.setFallbackKey(originalKeyCode,
3982fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                            fallbackKeyCode);
3983fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                }
3984fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            }
3985da3d5a91b6b311ed77f2707d4456c1f18b84d73bJeff Brown
3986da3d5a91b6b311ed77f2707d4456c1f18b84d73bJeff Brown#if DEBUG_OUTBOUND_EVENT_DETAILS
3987fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            {
3988fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                String8 msg;
3989fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                const KeyedVector<int32_t, int32_t>& fallbackKeys =
3990fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                        connection->inputState.getFallbackKeys();
3991fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                for (size_t i = 0; i < fallbackKeys.size(); i++) {
3992fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                    msg.appendFormat(", %d->%d", fallbackKeys.keyAt(i),
3993fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                            fallbackKeys.valueAt(i));
3994fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                }
39955baa3a62a97544669fba6d65a11c07f252e654ddSteve Block                ALOGD("Unhandled key event: %d currently tracked fallback keys%s.",
3996fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                        fallbackKeys.size(), msg.string());
3997fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            }
3998da3d5a91b6b311ed77f2707d4456c1f18b84d73bJeff Brown#endif
3999da3d5a91b6b311ed77f2707d4456c1f18b84d73bJeff Brown
4000fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            if (fallback) {
4001fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                // Restart the dispatch cycle using the fallback key.
4002fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                keyEntry->eventTime = event.getEventTime();
4003fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                keyEntry->deviceId = event.getDeviceId();
4004fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                keyEntry->source = event.getSource();
4005fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                keyEntry->flags = event.getFlags() | AKEY_EVENT_FLAG_FALLBACK;
4006fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                keyEntry->keyCode = fallbackKeyCode;
4007fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                keyEntry->scanCode = event.getScanCode();
4008fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                keyEntry->metaState = event.getMetaState();
4009fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                keyEntry->repeatCount = event.getRepeatCount();
4010fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                keyEntry->downTime = event.getDownTime();
4011fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                keyEntry->syntheticRepeat = false;
401249ed71db425c5054e3ad9526496a7e116c89556bJeff Brown
4013bfaf3b91709ef35e0d5901b186edd7c2a9729161Jeff Brown#if DEBUG_OUTBOUND_EVENT_DETAILS
40145baa3a62a97544669fba6d65a11c07f252e654ddSteve Block                ALOGD("Unhandled key event: Dispatching fallback key.  "
4015fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                        "originalKeyCode=%d, fallbackKeyCode=%d, fallbackMetaState=%08x",
4016fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                        originalKeyCode, fallbackKeyCode, keyEntry->metaState);
4017bfaf3b91709ef35e0d5901b186edd7c2a9729161Jeff Brown#endif
4018bfaf3b91709ef35e0d5901b186edd7c2a9729161Jeff Brown
4019fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                dispatchEntry->inProgress = false;
4020fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                startDispatchCycleLocked(now(), connection);
4021fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                return true; // already started next cycle
4022fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown            } else {
4023da3d5a91b6b311ed77f2707d4456c1f18b84d73bJeff Brown#if DEBUG_OUTBOUND_EVENT_DETAILS
40245baa3a62a97544669fba6d65a11c07f252e654ddSteve Block                ALOGD("Unhandled key event: No fallback key.");
4025da3d5a91b6b311ed77f2707d4456c1f18b84d73bJeff Brown#endif
402649ed71db425c5054e3ad9526496a7e116c89556bJeff Brown            }
40273915bb845b032dc184dba5e60970b803390ca3edJeff Brown        }
40283915bb845b032dc184dba5e60970b803390ca3edJeff Brown    }
4029fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    return false;
4030fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown}
40313915bb845b032dc184dba5e60970b803390ca3edJeff Brown
4032fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brownbool InputDispatcher::afterMotionEventLockedInterruptible(const sp<Connection>& connection,
4033fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        DispatchEntry* dispatchEntry, MotionEntry* motionEntry, bool handled) {
4034fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown    return false;
40353915bb845b032dc184dba5e60970b803390ca3edJeff Brown}
40363915bb845b032dc184dba5e60970b803390ca3edJeff Brown
4037b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brownvoid InputDispatcher::doPokeUserActivityLockedInterruptible(CommandEntry* commandEntry) {
4038b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    mLock.unlock();
4039b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
404001ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    mPolicy->pokeUserActivity(commandEntry->eventTime, commandEntry->userActivityEventType);
4041b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
4042b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    mLock.lock();
4043b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown}
4044b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
40453915bb845b032dc184dba5e60970b803390ca3edJeff Brownvoid InputDispatcher::initializeKeyEvent(KeyEvent* event, const KeyEntry* entry) {
40463915bb845b032dc184dba5e60970b803390ca3edJeff Brown    event->initialize(entry->deviceId, entry->source, entry->action, entry->flags,
40473915bb845b032dc184dba5e60970b803390ca3edJeff Brown            entry->keyCode, entry->scanCode, entry->metaState, entry->repeatCount,
40483915bb845b032dc184dba5e60970b803390ca3edJeff Brown            entry->downTime, entry->eventTime);
40493915bb845b032dc184dba5e60970b803390ca3edJeff Brown}
40503915bb845b032dc184dba5e60970b803390ca3edJeff Brown
4051519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brownvoid InputDispatcher::updateDispatchStatisticsLocked(nsecs_t currentTime, const EventEntry* entry,
4052519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown        int32_t injectionResult, nsecs_t timeSpentWaitingForApplication) {
4053519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown    // TODO Write some statistics about how long we spend waiting.
4054b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown}
4055b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
4056b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brownvoid InputDispatcher::dump(String8& dump) {
405789ef0720ee8e0ac6ae1758faa917e4d6c9606fb4Jeff Brown    AutoMutex _l(mLock);
405889ef0720ee8e0ac6ae1758faa917e4d6c9606fb4Jeff Brown
4059f2f487183052865d50c004a835360be1728b5a52Jeff Brown    dump.append("Input Dispatcher State:\n");
4060b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    dumpDispatchStateLocked(dump);
4061214eaf48878bba00cbd5831871bcbd82632b6e34Jeff Brown
4062214eaf48878bba00cbd5831871bcbd82632b6e34Jeff Brown    dump.append(INDENT "Configuration:\n");
4063214eaf48878bba00cbd5831871bcbd82632b6e34Jeff Brown    dump.appendFormat(INDENT2 "MaxEventsPerSecond: %d\n", mConfig.maxEventsPerSecond);
4064214eaf48878bba00cbd5831871bcbd82632b6e34Jeff Brown    dump.appendFormat(INDENT2 "KeyRepeatDelay: %0.1fms\n", mConfig.keyRepeatDelay * 0.000001f);
4065214eaf48878bba00cbd5831871bcbd82632b6e34Jeff Brown    dump.appendFormat(INDENT2 "KeyRepeatTimeout: %0.1fms\n", mConfig.keyRepeatTimeout * 0.000001f);
4066b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown}
4067b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
406889ef0720ee8e0ac6ae1758faa917e4d6c9606fb4Jeff Brownvoid InputDispatcher::monitor() {
406989ef0720ee8e0ac6ae1758faa917e4d6c9606fb4Jeff Brown    // Acquire and release the lock to ensure that the dispatcher has not deadlocked.
407089ef0720ee8e0ac6ae1758faa917e4d6c9606fb4Jeff Brown    mLock.lock();
407189ef0720ee8e0ac6ae1758faa917e4d6c9606fb4Jeff Brown    mLock.unlock();
407289ef0720ee8e0ac6ae1758faa917e4d6c9606fb4Jeff Brown}
407389ef0720ee8e0ac6ae1758faa917e4d6c9606fb4Jeff Brown
40749c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown
4075519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown// --- InputDispatcher::Queue ---
4076519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown
4077519e024d1e682ca458cc2dab743589a12992c0e1Jeff Browntemplate <typename T>
4078519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brownuint32_t InputDispatcher::Queue<T>::count() const {
4079519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown    uint32_t result = 0;
4080ac386073df2514b79a2ca169f4a89f129733002fJeff Brown    for (const T* entry = head; entry; entry = entry->next) {
4081519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown        result += 1;
4082519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown    }
4083519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown    return result;
4084519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown}
4085519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown
4086519e024d1e682ca458cc2dab743589a12992c0e1Jeff Brown
4087ac386073df2514b79a2ca169f4a89f129733002fJeff Brown// --- InputDispatcher::InjectionState ---
408846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
4089ac386073df2514b79a2ca169f4a89f129733002fJeff BrownInputDispatcher::InjectionState::InjectionState(int32_t injectorPid, int32_t injectorUid) :
4090ac386073df2514b79a2ca169f4a89f129733002fJeff Brown        refCount(1),
4091ac386073df2514b79a2ca169f4a89f129733002fJeff Brown        injectorPid(injectorPid), injectorUid(injectorUid),
4092ac386073df2514b79a2ca169f4a89f129733002fJeff Brown        injectionResult(INPUT_EVENT_INJECTION_PENDING), injectionIsAsync(false),
4093ac386073df2514b79a2ca169f4a89f129733002fJeff Brown        pendingForegroundDispatches(0) {
409446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
409546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
4096ac386073df2514b79a2ca169f4a89f129733002fJeff BrownInputDispatcher::InjectionState::~InjectionState() {
409701ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown}
409801ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown
4099ac386073df2514b79a2ca169f4a89f129733002fJeff Brownvoid InputDispatcher::InjectionState::release() {
4100ac386073df2514b79a2ca169f4a89f129733002fJeff Brown    refCount -= 1;
4101ac386073df2514b79a2ca169f4a89f129733002fJeff Brown    if (refCount == 0) {
4102ac386073df2514b79a2ca169f4a89f129733002fJeff Brown        delete this;
4103ac386073df2514b79a2ca169f4a89f129733002fJeff Brown    } else {
4104ac386073df2514b79a2ca169f4a89f129733002fJeff Brown        LOG_ASSERT(refCount > 0);
410501ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    }
41067fbdc84e87dd3a0e196b9803bb04495d11e9cb8aJeff Brown}
41077fbdc84e87dd3a0e196b9803bb04495d11e9cb8aJeff Brown
410846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
4109ac386073df2514b79a2ca169f4a89f129733002fJeff Brown// --- InputDispatcher::EventEntry ---
411046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
4111ac386073df2514b79a2ca169f4a89f129733002fJeff BrownInputDispatcher::EventEntry::EventEntry(int32_t type, nsecs_t eventTime, uint32_t policyFlags) :
4112ac386073df2514b79a2ca169f4a89f129733002fJeff Brown        refCount(1), type(type), eventTime(eventTime), policyFlags(policyFlags),
4113ac386073df2514b79a2ca169f4a89f129733002fJeff Brown        injectionState(NULL), dispatchInProgress(false) {
411446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
411546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
4116ac386073df2514b79a2ca169f4a89f129733002fJeff BrownInputDispatcher::EventEntry::~EventEntry() {
4117ac386073df2514b79a2ca169f4a89f129733002fJeff Brown    releaseInjectionState();
411846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
411946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
4120ac386073df2514b79a2ca169f4a89f129733002fJeff Brownvoid InputDispatcher::EventEntry::release() {
4121ac386073df2514b79a2ca169f4a89f129733002fJeff Brown    refCount -= 1;
4122ac386073df2514b79a2ca169f4a89f129733002fJeff Brown    if (refCount == 0) {
4123ac386073df2514b79a2ca169f4a89f129733002fJeff Brown        delete this;
412401ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    } else {
4125ac386073df2514b79a2ca169f4a89f129733002fJeff Brown        LOG_ASSERT(refCount > 0);
412601ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    }
412701ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown}
412801ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown
4129ac386073df2514b79a2ca169f4a89f129733002fJeff Brownvoid InputDispatcher::EventEntry::releaseInjectionState() {
4130ac386073df2514b79a2ca169f4a89f129733002fJeff Brown    if (injectionState) {
4131ac386073df2514b79a2ca169f4a89f129733002fJeff Brown        injectionState->release();
4132ac386073df2514b79a2ca169f4a89f129733002fJeff Brown        injectionState = NULL;
413346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
413446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
413546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
413646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
4137ac386073df2514b79a2ca169f4a89f129733002fJeff Brown// --- InputDispatcher::ConfigurationChangedEntry ---
413846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
4139ac386073df2514b79a2ca169f4a89f129733002fJeff BrownInputDispatcher::ConfigurationChangedEntry::ConfigurationChangedEntry(nsecs_t eventTime) :
4140ac386073df2514b79a2ca169f4a89f129733002fJeff Brown        EventEntry(TYPE_CONFIGURATION_CHANGED, eventTime, 0) {
414146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
414246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
4143ac386073df2514b79a2ca169f4a89f129733002fJeff BrownInputDispatcher::ConfigurationChangedEntry::~ConfigurationChangedEntry() {
4144a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown}
4145a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown
4146ac386073df2514b79a2ca169f4a89f129733002fJeff Brown
414765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown// --- InputDispatcher::DeviceResetEntry ---
414865fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
414965fd251c3913fc921468a3dad190810db19eb9dfJeff BrownInputDispatcher::DeviceResetEntry::DeviceResetEntry(nsecs_t eventTime, int32_t deviceId) :
415065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        EventEntry(TYPE_DEVICE_RESET, eventTime, 0),
415165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        deviceId(deviceId) {
415265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown}
415365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
415465fd251c3913fc921468a3dad190810db19eb9dfJeff BrownInputDispatcher::DeviceResetEntry::~DeviceResetEntry() {
415565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown}
415665fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
415765fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
4158ac386073df2514b79a2ca169f4a89f129733002fJeff Brown// --- InputDispatcher::KeyEntry ---
4159ac386073df2514b79a2ca169f4a89f129733002fJeff Brown
4160ac386073df2514b79a2ca169f4a89f129733002fJeff BrownInputDispatcher::KeyEntry::KeyEntry(nsecs_t eventTime,
4161ac386073df2514b79a2ca169f4a89f129733002fJeff Brown        int32_t deviceId, uint32_t source, uint32_t policyFlags, int32_t action,
4162ac386073df2514b79a2ca169f4a89f129733002fJeff Brown        int32_t flags, int32_t keyCode, int32_t scanCode, int32_t metaState,
4163ac386073df2514b79a2ca169f4a89f129733002fJeff Brown        int32_t repeatCount, nsecs_t downTime) :
4164ac386073df2514b79a2ca169f4a89f129733002fJeff Brown        EventEntry(TYPE_KEY, eventTime, policyFlags),
4165ac386073df2514b79a2ca169f4a89f129733002fJeff Brown        deviceId(deviceId), source(source), action(action), flags(flags),
4166ac386073df2514b79a2ca169f4a89f129733002fJeff Brown        keyCode(keyCode), scanCode(scanCode), metaState(metaState),
4167ac386073df2514b79a2ca169f4a89f129733002fJeff Brown        repeatCount(repeatCount), downTime(downTime),
4168905805ad7ce18a386076fff99264f821bbad9f83Jeff Brown        syntheticRepeat(false), interceptKeyResult(KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN),
4169905805ad7ce18a386076fff99264f821bbad9f83Jeff Brown        interceptKeyWakeupTime(0) {
417046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
417146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
4172ac386073df2514b79a2ca169f4a89f129733002fJeff BrownInputDispatcher::KeyEntry::~KeyEntry() {
41739c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown}
41749c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown
4175ac386073df2514b79a2ca169f4a89f129733002fJeff Brownvoid InputDispatcher::KeyEntry::recycle() {
4176ac386073df2514b79a2ca169f4a89f129733002fJeff Brown    releaseInjectionState();
417746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
4178ac386073df2514b79a2ca169f4a89f129733002fJeff Brown    dispatchInProgress = false;
4179ac386073df2514b79a2ca169f4a89f129733002fJeff Brown    syntheticRepeat = false;
4180ac386073df2514b79a2ca169f4a89f129733002fJeff Brown    interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
4181905805ad7ce18a386076fff99264f821bbad9f83Jeff Brown    interceptKeyWakeupTime = 0;
418246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
418346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
4184b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
4185ac386073df2514b79a2ca169f4a89f129733002fJeff Brown// --- InputDispatcher::MotionSample ---
4186ac386073df2514b79a2ca169f4a89f129733002fJeff Brown
4187ac386073df2514b79a2ca169f4a89f129733002fJeff BrownInputDispatcher::MotionSample::MotionSample(nsecs_t eventTime,
4188ac386073df2514b79a2ca169f4a89f129733002fJeff Brown        const PointerCoords* pointerCoords, uint32_t pointerCount) :
4189ac386073df2514b79a2ca169f4a89f129733002fJeff Brown        next(NULL), eventTime(eventTime), eventTimeBeforeCoalescing(eventTime) {
4190ac386073df2514b79a2ca169f4a89f129733002fJeff Brown    for (uint32_t i = 0; i < pointerCount; i++) {
4191ac386073df2514b79a2ca169f4a89f129733002fJeff Brown        this->pointerCoords[i].copyFrom(pointerCoords[i]);
4192ac386073df2514b79a2ca169f4a89f129733002fJeff Brown    }
4193b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown}
4194b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
4195b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
4196ae9fc03bdccda709101291bbcd3beaa5b6daebfcJeff Brown// --- InputDispatcher::MotionEntry ---
4197ae9fc03bdccda709101291bbcd3beaa5b6daebfcJeff Brown
4198ac386073df2514b79a2ca169f4a89f129733002fJeff BrownInputDispatcher::MotionEntry::MotionEntry(nsecs_t eventTime,
4199ac386073df2514b79a2ca169f4a89f129733002fJeff Brown        int32_t deviceId, uint32_t source, uint32_t policyFlags, int32_t action, int32_t flags,
4200ac386073df2514b79a2ca169f4a89f129733002fJeff Brown        int32_t metaState, int32_t buttonState,
4201ac386073df2514b79a2ca169f4a89f129733002fJeff Brown        int32_t edgeFlags, float xPrecision, float yPrecision,
4202ac386073df2514b79a2ca169f4a89f129733002fJeff Brown        nsecs_t downTime, uint32_t pointerCount,
4203ac386073df2514b79a2ca169f4a89f129733002fJeff Brown        const PointerProperties* pointerProperties, const PointerCoords* pointerCoords) :
4204ac386073df2514b79a2ca169f4a89f129733002fJeff Brown        EventEntry(TYPE_MOTION, eventTime, policyFlags),
4205ac386073df2514b79a2ca169f4a89f129733002fJeff Brown        deviceId(deviceId), source(source), action(action), flags(flags),
4206ac386073df2514b79a2ca169f4a89f129733002fJeff Brown        metaState(metaState), buttonState(buttonState), edgeFlags(edgeFlags),
4207ac386073df2514b79a2ca169f4a89f129733002fJeff Brown        xPrecision(xPrecision), yPrecision(yPrecision),
4208ac386073df2514b79a2ca169f4a89f129733002fJeff Brown        downTime(downTime), pointerCount(pointerCount),
4209ac386073df2514b79a2ca169f4a89f129733002fJeff Brown        firstSample(eventTime, pointerCoords, pointerCount),
4210ac386073df2514b79a2ca169f4a89f129733002fJeff Brown        lastSample(&firstSample) {
4211ac386073df2514b79a2ca169f4a89f129733002fJeff Brown    for (uint32_t i = 0; i < pointerCount; i++) {
4212ac386073df2514b79a2ca169f4a89f129733002fJeff Brown        this->pointerProperties[i].copyFrom(pointerProperties[i]);
4213ac386073df2514b79a2ca169f4a89f129733002fJeff Brown    }
4214ac386073df2514b79a2ca169f4a89f129733002fJeff Brown}
4215ac386073df2514b79a2ca169f4a89f129733002fJeff Brown
4216ac386073df2514b79a2ca169f4a89f129733002fJeff BrownInputDispatcher::MotionEntry::~MotionEntry() {
4217ac386073df2514b79a2ca169f4a89f129733002fJeff Brown    for (MotionSample* sample = firstSample.next; sample != NULL; ) {
4218ac386073df2514b79a2ca169f4a89f129733002fJeff Brown        MotionSample* next = sample->next;
4219ac386073df2514b79a2ca169f4a89f129733002fJeff Brown        delete sample;
4220ac386073df2514b79a2ca169f4a89f129733002fJeff Brown        sample = next;
4221ac386073df2514b79a2ca169f4a89f129733002fJeff Brown    }
4222ac386073df2514b79a2ca169f4a89f129733002fJeff Brown}
4223ac386073df2514b79a2ca169f4a89f129733002fJeff Brown
4224ae9fc03bdccda709101291bbcd3beaa5b6daebfcJeff Brownuint32_t InputDispatcher::MotionEntry::countSamples() const {
4225ae9fc03bdccda709101291bbcd3beaa5b6daebfcJeff Brown    uint32_t count = 1;
4226ae9fc03bdccda709101291bbcd3beaa5b6daebfcJeff Brown    for (MotionSample* sample = firstSample.next; sample != NULL; sample = sample->next) {
4227ae9fc03bdccda709101291bbcd3beaa5b6daebfcJeff Brown        count += 1;
4228ae9fc03bdccda709101291bbcd3beaa5b6daebfcJeff Brown    }
4229ae9fc03bdccda709101291bbcd3beaa5b6daebfcJeff Brown    return count;
4230ae9fc03bdccda709101291bbcd3beaa5b6daebfcJeff Brown}
4231ae9fc03bdccda709101291bbcd3beaa5b6daebfcJeff Brown
42324e91a180be46c0c7c3bf398d4df4cbe2404216b5Jeff Brownbool InputDispatcher::MotionEntry::canAppendSamples(int32_t action, uint32_t pointerCount,
4233fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        const PointerProperties* pointerProperties) const {
42344e91a180be46c0c7c3bf398d4df4cbe2404216b5Jeff Brown    if (this->action != action
42354e91a180be46c0c7c3bf398d4df4cbe2404216b5Jeff Brown            || this->pointerCount != pointerCount
42364e91a180be46c0c7c3bf398d4df4cbe2404216b5Jeff Brown            || this->isInjected()) {
42374e91a180be46c0c7c3bf398d4df4cbe2404216b5Jeff Brown        return false;
42384e91a180be46c0c7c3bf398d4df4cbe2404216b5Jeff Brown    }
42394e91a180be46c0c7c3bf398d4df4cbe2404216b5Jeff Brown    for (uint32_t i = 0; i < pointerCount; i++) {
4240fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        if (this->pointerProperties[i] != pointerProperties[i]) {
42414e91a180be46c0c7c3bf398d4df4cbe2404216b5Jeff Brown            return false;
42424e91a180be46c0c7c3bf398d4df4cbe2404216b5Jeff Brown        }
42434e91a180be46c0c7c3bf398d4df4cbe2404216b5Jeff Brown    }
42444e91a180be46c0c7c3bf398d4df4cbe2404216b5Jeff Brown    return true;
42454e91a180be46c0c7c3bf398d4df4cbe2404216b5Jeff Brown}
42464e91a180be46c0c7c3bf398d4df4cbe2404216b5Jeff Brown
4247ac386073df2514b79a2ca169f4a89f129733002fJeff Brownvoid InputDispatcher::MotionEntry::appendSample(
4248ac386073df2514b79a2ca169f4a89f129733002fJeff Brown        nsecs_t eventTime, const PointerCoords* pointerCoords) {
4249ac386073df2514b79a2ca169f4a89f129733002fJeff Brown    MotionSample* sample = new MotionSample(eventTime, pointerCoords, pointerCount);
4250ac386073df2514b79a2ca169f4a89f129733002fJeff Brown
4251ac386073df2514b79a2ca169f4a89f129733002fJeff Brown    lastSample->next = sample;
4252ac386073df2514b79a2ca169f4a89f129733002fJeff Brown    lastSample = sample;
4253ac386073df2514b79a2ca169f4a89f129733002fJeff Brown}
4254ac386073df2514b79a2ca169f4a89f129733002fJeff Brown
4255ac386073df2514b79a2ca169f4a89f129733002fJeff Brown
4256ac386073df2514b79a2ca169f4a89f129733002fJeff Brown// --- InputDispatcher::DispatchEntry ---
4257ac386073df2514b79a2ca169f4a89f129733002fJeff Brown
4258ac386073df2514b79a2ca169f4a89f129733002fJeff BrownInputDispatcher::DispatchEntry::DispatchEntry(EventEntry* eventEntry,
4259ac386073df2514b79a2ca169f4a89f129733002fJeff Brown        int32_t targetFlags, float xOffset, float yOffset, float scaleFactor) :
4260ac386073df2514b79a2ca169f4a89f129733002fJeff Brown        eventEntry(eventEntry), targetFlags(targetFlags),
4261ac386073df2514b79a2ca169f4a89f129733002fJeff Brown        xOffset(xOffset), yOffset(yOffset), scaleFactor(scaleFactor),
4262ac386073df2514b79a2ca169f4a89f129733002fJeff Brown        inProgress(false),
4263ac386073df2514b79a2ca169f4a89f129733002fJeff Brown        resolvedAction(0), resolvedFlags(0),
4264ac386073df2514b79a2ca169f4a89f129733002fJeff Brown        headMotionSample(NULL), tailMotionSample(NULL) {
4265ac386073df2514b79a2ca169f4a89f129733002fJeff Brown    eventEntry->refCount += 1;
4266ac386073df2514b79a2ca169f4a89f129733002fJeff Brown}
4267ac386073df2514b79a2ca169f4a89f129733002fJeff Brown
4268ac386073df2514b79a2ca169f4a89f129733002fJeff BrownInputDispatcher::DispatchEntry::~DispatchEntry() {
4269ac386073df2514b79a2ca169f4a89f129733002fJeff Brown    eventEntry->release();
4270ac386073df2514b79a2ca169f4a89f129733002fJeff Brown}
4271ac386073df2514b79a2ca169f4a89f129733002fJeff Brown
4272b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
4273b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown// --- InputDispatcher::InputState ---
4274b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
4275b699726018a0049665d8ad6b90dbc5af0e18f135Jeff BrownInputDispatcher::InputState::InputState() {
4276b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown}
4277b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
4278b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff BrownInputDispatcher::InputState::~InputState() {
4279b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown}
4280b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
4281b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brownbool InputDispatcher::InputState::isNeutral() const {
4282b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    return mKeyMementos.isEmpty() && mMotionMementos.isEmpty();
4283b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown}
4284b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
42858134681b25dfff814ffeaad8ff70e84316c1869fJeff Brownbool InputDispatcher::InputState::isHovering(int32_t deviceId, uint32_t source) const {
42868134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown    for (size_t i = 0; i < mMotionMementos.size(); i++) {
42878134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        const MotionMemento& memento = mMotionMementos.itemAt(i);
42888134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        if (memento.deviceId == deviceId
42898134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown                && memento.source == source
42908134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown                && memento.hovering) {
42918134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown            return true;
42928134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        }
4293b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    }
42948134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown    return false;
4295b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown}
4296b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
42978134681b25dfff814ffeaad8ff70e84316c1869fJeff Brownbool InputDispatcher::InputState::trackKey(const KeyEntry* entry,
42988134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        int32_t action, int32_t flags) {
42998134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown    switch (action) {
43008134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown    case AKEY_EVENT_ACTION_UP: {
43018134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        if (entry->flags & AKEY_EVENT_FLAG_FALLBACK) {
43028134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown            for (size_t i = 0; i < mFallbackKeys.size(); ) {
43038134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown                if (mFallbackKeys.valueAt(i) == entry->keyCode) {
43048134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown                    mFallbackKeys.removeItemsAt(i);
43058134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown                } else {
43068134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown                    i += 1;
43078134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown                }
4308da3d5a91b6b311ed77f2707d4456c1f18b84d73bJeff Brown            }
4309da3d5a91b6b311ed77f2707d4456c1f18b84d73bJeff Brown        }
43108134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        ssize_t index = findKeyMemento(entry);
43118134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        if (index >= 0) {
43128134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown            mKeyMementos.removeAt(index);
43138134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown            return true;
43148134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        }
431568b909d8acd92343fa0b1dff2f77fcd9d9991f9fJeff Brown        /* FIXME: We can't just drop the key up event because that prevents creating
431668b909d8acd92343fa0b1dff2f77fcd9d9991f9fJeff Brown         * popup windows that are automatically shown when a key is held and then
431768b909d8acd92343fa0b1dff2f77fcd9d9991f9fJeff Brown         * dismissed when the key is released.  The problem is that the popup will
431868b909d8acd92343fa0b1dff2f77fcd9d9991f9fJeff Brown         * not have received the original key down, so the key up will be considered
431968b909d8acd92343fa0b1dff2f77fcd9d9991f9fJeff Brown         * to be inconsistent with its observed state.  We could perhaps handle this
432068b909d8acd92343fa0b1dff2f77fcd9d9991f9fJeff Brown         * by synthesizing a key down but that will cause other problems.
432168b909d8acd92343fa0b1dff2f77fcd9d9991f9fJeff Brown         *
432268b909d8acd92343fa0b1dff2f77fcd9d9991f9fJeff Brown         * So for now, allow inconsistent key up events to be dispatched.
432368b909d8acd92343fa0b1dff2f77fcd9d9991f9fJeff Brown         *
43248134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown#if DEBUG_OUTBOUND_EVENT_DETAILS
43255baa3a62a97544669fba6d65a11c07f252e654ddSteve Block        ALOGD("Dropping inconsistent key up event: deviceId=%d, source=%08x, "
43268134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown                "keyCode=%d, scanCode=%d",
43278134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown                entry->deviceId, entry->source, entry->keyCode, entry->scanCode);
43288134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown#endif
43298134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        return false;
433068b909d8acd92343fa0b1dff2f77fcd9d9991f9fJeff Brown        */
433168b909d8acd92343fa0b1dff2f77fcd9d9991f9fJeff Brown        return true;
4332da3d5a91b6b311ed77f2707d4456c1f18b84d73bJeff Brown    }
4333da3d5a91b6b311ed77f2707d4456c1f18b84d73bJeff Brown
43348134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown    case AKEY_EVENT_ACTION_DOWN: {
43358134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        ssize_t index = findKeyMemento(entry);
43368134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        if (index >= 0) {
43378134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown            mKeyMementos.removeAt(index);
4338b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        }
43398134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        addKeyMemento(entry, flags);
43408134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        return true;
4341b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    }
4342b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
43438134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown    default:
43448134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        return true;
4345b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    }
4346b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown}
4347b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
43488134681b25dfff814ffeaad8ff70e84316c1869fJeff Brownbool InputDispatcher::InputState::trackMotion(const MotionEntry* entry,
43498134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        int32_t action, int32_t flags) {
4350a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown    int32_t actionMasked = action & AMOTION_EVENT_ACTION_MASK;
43518134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown    switch (actionMasked) {
43528134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown    case AMOTION_EVENT_ACTION_UP:
43538134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown    case AMOTION_EVENT_ACTION_CANCEL: {
43548134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        ssize_t index = findMotionMemento(entry, false /*hovering*/);
43558134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        if (index >= 0) {
43568134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown            mMotionMementos.removeAt(index);
43578134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown            return true;
43588134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        }
43598134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown#if DEBUG_OUTBOUND_EVENT_DETAILS
43605baa3a62a97544669fba6d65a11c07f252e654ddSteve Block        ALOGD("Dropping inconsistent motion up or cancel event: deviceId=%d, source=%08x, "
43618134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown                "actionMasked=%d",
43628134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown                entry->deviceId, entry->source, actionMasked);
43638134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown#endif
43648134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        return false;
43658134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown    }
4366b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
43678134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown    case AMOTION_EVENT_ACTION_DOWN: {
43688134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        ssize_t index = findMotionMemento(entry, false /*hovering*/);
43698134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        if (index >= 0) {
43708134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown            mMotionMementos.removeAt(index);
43718134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        }
43728134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        addMotionMemento(entry, flags, false /*hovering*/);
43738134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        return true;
43748134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown    }
4375b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
43768134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown    case AMOTION_EVENT_ACTION_POINTER_UP:
43778134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown    case AMOTION_EVENT_ACTION_POINTER_DOWN:
43788134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown    case AMOTION_EVENT_ACTION_MOVE: {
43798134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        ssize_t index = findMotionMemento(entry, false /*hovering*/);
43808134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        if (index >= 0) {
43818134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown            MotionMemento& memento = mMotionMementos.editItemAt(index);
43828134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown            memento.setPointers(entry);
43838134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown            return true;
43848134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        }
43852e45fb6f951d0e0c68d4211fe68108d2230814bcJeff Brown        if (actionMasked == AMOTION_EVENT_ACTION_MOVE
43862e45fb6f951d0e0c68d4211fe68108d2230814bcJeff Brown                && (entry->source & (AINPUT_SOURCE_CLASS_JOYSTICK
43872e45fb6f951d0e0c68d4211fe68108d2230814bcJeff Brown                        | AINPUT_SOURCE_CLASS_NAVIGATION))) {
43882e45fb6f951d0e0c68d4211fe68108d2230814bcJeff Brown            // Joysticks and trackballs can send MOVE events without corresponding DOWN or UP.
43892e45fb6f951d0e0c68d4211fe68108d2230814bcJeff Brown            return true;
43902e45fb6f951d0e0c68d4211fe68108d2230814bcJeff Brown        }
43918134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown#if DEBUG_OUTBOUND_EVENT_DETAILS
43925baa3a62a97544669fba6d65a11c07f252e654ddSteve Block        ALOGD("Dropping inconsistent motion pointer up/down or move event: "
43938134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown                "deviceId=%d, source=%08x, actionMasked=%d",
43948134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown                entry->deviceId, entry->source, actionMasked);
43958134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown#endif
43968134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        return false;
43978134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown    }
4398b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
43998134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown    case AMOTION_EVENT_ACTION_HOVER_EXIT: {
44008134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        ssize_t index = findMotionMemento(entry, true /*hovering*/);
44018134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        if (index >= 0) {
44028134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown            mMotionMementos.removeAt(index);
44038134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown            return true;
4404b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        }
44058134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown#if DEBUG_OUTBOUND_EVENT_DETAILS
44065baa3a62a97544669fba6d65a11c07f252e654ddSteve Block        ALOGD("Dropping inconsistent motion hover exit event: deviceId=%d, source=%08x",
44078134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown                entry->deviceId, entry->source);
44088134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown#endif
44098134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        return false;
4410b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    }
4411b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
4412a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown    case AMOTION_EVENT_ACTION_HOVER_ENTER:
44138134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown    case AMOTION_EVENT_ACTION_HOVER_MOVE: {
44148134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        ssize_t index = findMotionMemento(entry, true /*hovering*/);
44158134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        if (index >= 0) {
44168134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown            mMotionMementos.removeAt(index);
44178134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        }
44188134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        addMotionMemento(entry, flags, true /*hovering*/);
44198134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        return true;
44208134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown    }
44218134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown
44228134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown    default:
44238134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        return true;
44248134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown    }
44258134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown}
44268134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown
44278134681b25dfff814ffeaad8ff70e84316c1869fJeff Brownssize_t InputDispatcher::InputState::findKeyMemento(const KeyEntry* entry) const {
44288134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown    for (size_t i = 0; i < mKeyMementos.size(); i++) {
44298134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        const KeyMemento& memento = mKeyMementos.itemAt(i);
44308134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        if (memento.deviceId == entry->deviceId
44318134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown                && memento.source == entry->source
44328134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown                && memento.keyCode == entry->keyCode
44338134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown                && memento.scanCode == entry->scanCode) {
44348134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown            return i;
44358134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        }
4436b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    }
44378134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown    return -1;
44388134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown}
44398134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown
44408134681b25dfff814ffeaad8ff70e84316c1869fJeff Brownssize_t InputDispatcher::InputState::findMotionMemento(const MotionEntry* entry,
44418134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        bool hovering) const {
44428134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown    for (size_t i = 0; i < mMotionMementos.size(); i++) {
44438134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        const MotionMemento& memento = mMotionMementos.itemAt(i);
44448134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        if (memento.deviceId == entry->deviceId
44458134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown                && memento.source == entry->source
44468134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown                && memento.hovering == hovering) {
44478134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown            return i;
44488134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        }
44498134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown    }
44508134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown    return -1;
44518134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown}
44528134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown
44538134681b25dfff814ffeaad8ff70e84316c1869fJeff Brownvoid InputDispatcher::InputState::addKeyMemento(const KeyEntry* entry, int32_t flags) {
44548134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown    mKeyMementos.push();
44558134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown    KeyMemento& memento = mKeyMementos.editTop();
44568134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown    memento.deviceId = entry->deviceId;
44578134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown    memento.source = entry->source;
44588134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown    memento.keyCode = entry->keyCode;
44598134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown    memento.scanCode = entry->scanCode;
44608134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown    memento.flags = flags;
44618134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown    memento.downTime = entry->downTime;
44628134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown}
44638134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown
44648134681b25dfff814ffeaad8ff70e84316c1869fJeff Brownvoid InputDispatcher::InputState::addMotionMemento(const MotionEntry* entry,
44658134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown        int32_t flags, bool hovering) {
44668134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown    mMotionMementos.push();
44678134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown    MotionMemento& memento = mMotionMementos.editTop();
44688134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown    memento.deviceId = entry->deviceId;
44698134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown    memento.source = entry->source;
44708134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown    memento.flags = flags;
44718134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown    memento.xPrecision = entry->xPrecision;
44728134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown    memento.yPrecision = entry->yPrecision;
44738134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown    memento.downTime = entry->downTime;
44748134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown    memento.setPointers(entry);
44758134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown    memento.hovering = hovering;
4476b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown}
4477b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
4478b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brownvoid InputDispatcher::InputState::MotionMemento::setPointers(const MotionEntry* entry) {
4479b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    pointerCount = entry->pointerCount;
4480b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    for (uint32_t i = 0; i < entry->pointerCount; i++) {
4481fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown        pointerProperties[i].copyFrom(entry->pointerProperties[i]);
4482ace13b17866dc9136aeecf6dfaf7077f37434469Jeff Brown        pointerCoords[i].copyFrom(entry->lastSample->pointerCoords[i]);
4483b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    }
4484b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown}
4485b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
4486b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brownvoid InputDispatcher::InputState::synthesizeCancelationEvents(nsecs_t currentTime,
4487ac386073df2514b79a2ca169f4a89f129733002fJeff Brown        Vector<EventEntry*>& outEvents, const CancelationOptions& options) {
44888134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown    for (size_t i = 0; i < mKeyMementos.size(); i++) {
4489b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        const KeyMemento& memento = mKeyMementos.itemAt(i);
449049ed71db425c5054e3ad9526496a7e116c89556bJeff Brown        if (shouldCancelKey(memento, options)) {
4491ac386073df2514b79a2ca169f4a89f129733002fJeff Brown            outEvents.push(new KeyEntry(currentTime,
4492b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown                    memento.deviceId, memento.source, 0,
449349ed71db425c5054e3ad9526496a7e116c89556bJeff Brown                    AKEY_EVENT_ACTION_UP, memento.flags | AKEY_EVENT_FLAG_CANCELED,
4494b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown                    memento.keyCode, memento.scanCode, 0, 0, memento.downTime));
4495b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown        }
4496b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    }
4497b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
44988134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown    for (size_t i = 0; i < mMotionMementos.size(); i++) {
4499b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown        const MotionMemento& memento = mMotionMementos.itemAt(i);
450049ed71db425c5054e3ad9526496a7e116c89556bJeff Brown        if (shouldCancelMotion(memento, options)) {
4501ac386073df2514b79a2ca169f4a89f129733002fJeff Brown            outEvents.push(new MotionEntry(currentTime,
4502b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown                    memento.deviceId, memento.source, 0,
4503a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown                    memento.hovering
4504a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown                            ? AMOTION_EVENT_ACTION_HOVER_EXIT
4505a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown                            : AMOTION_EVENT_ACTION_CANCEL,
45068134681b25dfff814ffeaad8ff70e84316c1869fJeff Brown                    memento.flags, 0, 0, 0,
4507b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown                    memento.xPrecision, memento.yPrecision, memento.downTime,
4508fe9f8ab03a63b1037f07dd85799fbea80ec6adaaJeff Brown                    memento.pointerCount, memento.pointerProperties, memento.pointerCoords));
4509b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown        }
4510b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    }
4511b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown}
4512b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
4513b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brownvoid InputDispatcher::InputState::clear() {
4514b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    mKeyMementos.clear();
4515b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown    mMotionMementos.clear();
4516da3d5a91b6b311ed77f2707d4456c1f18b84d73bJeff Brown    mFallbackKeys.clear();
4517b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown}
4518b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown
45199c9f1a3ba1bc19754e4d38cb27a537d4dfedc0feJeff Brownvoid InputDispatcher::InputState::copyPointerStateTo(InputState& other) const {
45209c9f1a3ba1bc19754e4d38cb27a537d4dfedc0feJeff Brown    for (size_t i = 0; i < mMotionMementos.size(); i++) {
45219c9f1a3ba1bc19754e4d38cb27a537d4dfedc0feJeff Brown        const MotionMemento& memento = mMotionMementos.itemAt(i);
45229c9f1a3ba1bc19754e4d38cb27a537d4dfedc0feJeff Brown        if (memento.source & AINPUT_SOURCE_CLASS_POINTER) {
45239c9f1a3ba1bc19754e4d38cb27a537d4dfedc0feJeff Brown            for (size_t j = 0; j < other.mMotionMementos.size(); ) {
45249c9f1a3ba1bc19754e4d38cb27a537d4dfedc0feJeff Brown                const MotionMemento& otherMemento = other.mMotionMementos.itemAt(j);
45259c9f1a3ba1bc19754e4d38cb27a537d4dfedc0feJeff Brown                if (memento.deviceId == otherMemento.deviceId
45269c9f1a3ba1bc19754e4d38cb27a537d4dfedc0feJeff Brown                        && memento.source == otherMemento.source) {
45279c9f1a3ba1bc19754e4d38cb27a537d4dfedc0feJeff Brown                    other.mMotionMementos.removeAt(j);
45289c9f1a3ba1bc19754e4d38cb27a537d4dfedc0feJeff Brown                } else {
45299c9f1a3ba1bc19754e4d38cb27a537d4dfedc0feJeff Brown                    j += 1;
45309c9f1a3ba1bc19754e4d38cb27a537d4dfedc0feJeff Brown                }
45319c9f1a3ba1bc19754e4d38cb27a537d4dfedc0feJeff Brown            }
45329c9f1a3ba1bc19754e4d38cb27a537d4dfedc0feJeff Brown            other.mMotionMementos.push(memento);
45339c9f1a3ba1bc19754e4d38cb27a537d4dfedc0feJeff Brown        }
45349c9f1a3ba1bc19754e4d38cb27a537d4dfedc0feJeff Brown    }
45359c9f1a3ba1bc19754e4d38cb27a537d4dfedc0feJeff Brown}
45369c9f1a3ba1bc19754e4d38cb27a537d4dfedc0feJeff Brown
4537da3d5a91b6b311ed77f2707d4456c1f18b84d73bJeff Brownint32_t InputDispatcher::InputState::getFallbackKey(int32_t originalKeyCode) {
4538da3d5a91b6b311ed77f2707d4456c1f18b84d73bJeff Brown    ssize_t index = mFallbackKeys.indexOfKey(originalKeyCode);
4539da3d5a91b6b311ed77f2707d4456c1f18b84d73bJeff Brown    return index >= 0 ? mFallbackKeys.valueAt(index) : -1;
4540da3d5a91b6b311ed77f2707d4456c1f18b84d73bJeff Brown}
4541da3d5a91b6b311ed77f2707d4456c1f18b84d73bJeff Brown
4542da3d5a91b6b311ed77f2707d4456c1f18b84d73bJeff Brownvoid InputDispatcher::InputState::setFallbackKey(int32_t originalKeyCode,
4543da3d5a91b6b311ed77f2707d4456c1f18b84d73bJeff Brown        int32_t fallbackKeyCode) {
4544da3d5a91b6b311ed77f2707d4456c1f18b84d73bJeff Brown    ssize_t index = mFallbackKeys.indexOfKey(originalKeyCode);
4545da3d5a91b6b311ed77f2707d4456c1f18b84d73bJeff Brown    if (index >= 0) {
4546da3d5a91b6b311ed77f2707d4456c1f18b84d73bJeff Brown        mFallbackKeys.replaceValueAt(index, fallbackKeyCode);
4547da3d5a91b6b311ed77f2707d4456c1f18b84d73bJeff Brown    } else {
4548da3d5a91b6b311ed77f2707d4456c1f18b84d73bJeff Brown        mFallbackKeys.add(originalKeyCode, fallbackKeyCode);
4549da3d5a91b6b311ed77f2707d4456c1f18b84d73bJeff Brown    }
4550da3d5a91b6b311ed77f2707d4456c1f18b84d73bJeff Brown}
4551da3d5a91b6b311ed77f2707d4456c1f18b84d73bJeff Brown
4552da3d5a91b6b311ed77f2707d4456c1f18b84d73bJeff Brownvoid InputDispatcher::InputState::removeFallbackKey(int32_t originalKeyCode) {
4553da3d5a91b6b311ed77f2707d4456c1f18b84d73bJeff Brown    mFallbackKeys.removeItem(originalKeyCode);
4554da3d5a91b6b311ed77f2707d4456c1f18b84d73bJeff Brown}
4555da3d5a91b6b311ed77f2707d4456c1f18b84d73bJeff Brown
455649ed71db425c5054e3ad9526496a7e116c89556bJeff Brownbool InputDispatcher::InputState::shouldCancelKey(const KeyMemento& memento,
4557da3d5a91b6b311ed77f2707d4456c1f18b84d73bJeff Brown        const CancelationOptions& options) {
4558da3d5a91b6b311ed77f2707d4456c1f18b84d73bJeff Brown    if (options.keyCode != -1 && memento.keyCode != options.keyCode) {
4559da3d5a91b6b311ed77f2707d4456c1f18b84d73bJeff Brown        return false;
4560da3d5a91b6b311ed77f2707d4456c1f18b84d73bJeff Brown    }
4561da3d5a91b6b311ed77f2707d4456c1f18b84d73bJeff Brown
456265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    if (options.deviceId != -1 && memento.deviceId != options.deviceId) {
456365fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        return false;
456465fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    }
456565fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
4566da3d5a91b6b311ed77f2707d4456c1f18b84d73bJeff Brown    switch (options.mode) {
4567da3d5a91b6b311ed77f2707d4456c1f18b84d73bJeff Brown    case CancelationOptions::CANCEL_ALL_EVENTS:
4568da3d5a91b6b311ed77f2707d4456c1f18b84d73bJeff Brown    case CancelationOptions::CANCEL_NON_POINTER_EVENTS:
456949ed71db425c5054e3ad9526496a7e116c89556bJeff Brown        return true;
4570da3d5a91b6b311ed77f2707d4456c1f18b84d73bJeff Brown    case CancelationOptions::CANCEL_FALLBACK_EVENTS:
457149ed71db425c5054e3ad9526496a7e116c89556bJeff Brown        return memento.flags & AKEY_EVENT_FLAG_FALLBACK;
4572b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown    default:
457349ed71db425c5054e3ad9526496a7e116c89556bJeff Brown        return false;
457449ed71db425c5054e3ad9526496a7e116c89556bJeff Brown    }
457549ed71db425c5054e3ad9526496a7e116c89556bJeff Brown}
457649ed71db425c5054e3ad9526496a7e116c89556bJeff Brown
457749ed71db425c5054e3ad9526496a7e116c89556bJeff Brownbool InputDispatcher::InputState::shouldCancelMotion(const MotionMemento& memento,
4578da3d5a91b6b311ed77f2707d4456c1f18b84d73bJeff Brown        const CancelationOptions& options) {
457965fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    if (options.deviceId != -1 && memento.deviceId != options.deviceId) {
458065fd251c3913fc921468a3dad190810db19eb9dfJeff Brown        return false;
458165fd251c3913fc921468a3dad190810db19eb9dfJeff Brown    }
458265fd251c3913fc921468a3dad190810db19eb9dfJeff Brown
4583da3d5a91b6b311ed77f2707d4456c1f18b84d73bJeff Brown    switch (options.mode) {
4584da3d5a91b6b311ed77f2707d4456c1f18b84d73bJeff Brown    case CancelationOptions::CANCEL_ALL_EVENTS:
4585b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown        return true;
4586da3d5a91b6b311ed77f2707d4456c1f18b84d73bJeff Brown    case CancelationOptions::CANCEL_POINTER_EVENTS:
458749ed71db425c5054e3ad9526496a7e116c89556bJeff Brown        return memento.source & AINPUT_SOURCE_CLASS_POINTER;
4588da3d5a91b6b311ed77f2707d4456c1f18b84d73bJeff Brown    case CancelationOptions::CANCEL_NON_POINTER_EVENTS:
458949ed71db425c5054e3ad9526496a7e116c89556bJeff Brown        return !(memento.source & AINPUT_SOURCE_CLASS_POINTER);
459049ed71db425c5054e3ad9526496a7e116c89556bJeff Brown    default:
459149ed71db425c5054e3ad9526496a7e116c89556bJeff Brown        return false;
4592b699726018a0049665d8ad6b90dbc5af0e18f135Jeff Brown    }
4593b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown}
4594b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
4595b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
459646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown// --- InputDispatcher::Connection ---
459746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
4598928e054931d357326613c78e62f4d850b7c442ffJeff BrownInputDispatcher::Connection::Connection(const sp<InputChannel>& inputChannel,
4599cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown        const sp<InputWindowHandle>& inputWindowHandle, bool monitor) :
4600928e054931d357326613c78e62f4d850b7c442ffJeff Brown        status(STATUS_NORMAL), inputChannel(inputChannel), inputWindowHandle(inputWindowHandle),
4601cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown        monitor(monitor),
4602928e054931d357326613c78e62f4d850b7c442ffJeff Brown        inputPublisher(inputChannel),
4603da3d5a91b6b311ed77f2707d4456c1f18b84d73bJeff Brown        lastEventTime(LONG_LONG_MAX), lastDispatchTime(LONG_LONG_MAX) {
460446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
460546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
460646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff BrownInputDispatcher::Connection::~Connection() {
460746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
460846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
460946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownstatus_t InputDispatcher::Connection::initialize() {
461046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    return inputPublisher.initialize();
461146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
461246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
46139c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brownconst char* InputDispatcher::Connection::getStatusLabel() const {
46149c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown    switch (status) {
46159c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown    case STATUS_NORMAL:
46169c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown        return "NORMAL";
46179c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown
46189c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown    case STATUS_BROKEN:
46199c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown        return "BROKEN";
46209c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown
46219c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown    case STATUS_ZOMBIE:
46229c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown        return "ZOMBIE";
46239c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown
46249c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown    default:
46259c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown        return "UNKNOWN";
46269c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown    }
46279c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown}
46289c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown
462946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff BrownInputDispatcher::DispatchEntry* InputDispatcher::Connection::findQueuedDispatchEntryForEvent(
463046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        const EventEntry* eventEntry) const {
4631ac386073df2514b79a2ca169f4a89f129733002fJeff Brown    for (DispatchEntry* dispatchEntry = outboundQueue.tail; dispatchEntry;
4632ac386073df2514b79a2ca169f4a89f129733002fJeff Brown            dispatchEntry = dispatchEntry->prev) {
463346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        if (dispatchEntry->eventEntry == eventEntry) {
463446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            return dispatchEntry;
463546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        }
463646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    }
463746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    return NULL;
463846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
463946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
4640b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown
46419c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown// --- InputDispatcher::CommandEntry ---
46429c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown
4643ac386073df2514b79a2ca169f4a89f129733002fJeff BrownInputDispatcher::CommandEntry::CommandEntry(Command command) :
4644ac386073df2514b79a2ca169f4a89f129733002fJeff Brown    command(command), eventTime(0), keyEntry(NULL), userActivityEventType(0), handled(false) {
46459c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown}
46469c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown
46479c3cda04d969912bc46184f2b326d1db95e0aba5Jeff BrownInputDispatcher::CommandEntry::~CommandEntry() {
46489c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown}
46499c3cda04d969912bc46184f2b326d1db95e0aba5Jeff Brown
465046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
465101ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown// --- InputDispatcher::TouchState ---
465201ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown
465301ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff BrownInputDispatcher::TouchState::TouchState() :
465458a2da843f2f22f406df8df1f011738eb8b7fcb1Jeff Brown    down(false), split(false), deviceId(-1), source(0) {
465501ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown}
465601ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown
465701ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff BrownInputDispatcher::TouchState::~TouchState() {
465801ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown}
465901ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown
466001ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brownvoid InputDispatcher::TouchState::reset() {
466101ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    down = false;
466201ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    split = false;
466395712850665492af670824abdba77f0944d984d1Jeff Brown    deviceId = -1;
466458a2da843f2f22f406df8df1f011738eb8b7fcb1Jeff Brown    source = 0;
466501ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    windows.clear();
466601ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown}
466701ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown
466801ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brownvoid InputDispatcher::TouchState::copyFrom(const TouchState& other) {
466901ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    down = other.down;
467001ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    split = other.split;
467195712850665492af670824abdba77f0944d984d1Jeff Brown    deviceId = other.deviceId;
467258a2da843f2f22f406df8df1f011738eb8b7fcb1Jeff Brown    source = other.source;
46739302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown    windows = other.windows;
467401ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown}
467501ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown
46769302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brownvoid InputDispatcher::TouchState::addOrUpdateWindow(const sp<InputWindowHandle>& windowHandle,
467701ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown        int32_t targetFlags, BitSet32 pointerIds) {
467801ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    if (targetFlags & InputTarget::FLAG_SPLIT) {
467901ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown        split = true;
468001ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    }
468101ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown
468201ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    for (size_t i = 0; i < windows.size(); i++) {
468301ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown        TouchedWindow& touchedWindow = windows.editItemAt(i);
46849302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown        if (touchedWindow.windowHandle == windowHandle) {
468501ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown            touchedWindow.targetFlags |= targetFlags;
468698db5fabdad86dca379740d8050697950b9f026cJeff Brown            if (targetFlags & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT) {
468798db5fabdad86dca379740d8050697950b9f026cJeff Brown                touchedWindow.targetFlags &= ~InputTarget::FLAG_DISPATCH_AS_IS;
468898db5fabdad86dca379740d8050697950b9f026cJeff Brown            }
468901ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown            touchedWindow.pointerIds.value |= pointerIds.value;
469001ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown            return;
469101ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown        }
469201ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    }
469301ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown
469401ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    windows.push();
469501ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown
469601ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    TouchedWindow& touchedWindow = windows.editTop();
46979302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown    touchedWindow.windowHandle = windowHandle;
469801ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    touchedWindow.targetFlags = targetFlags;
469901ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    touchedWindow.pointerIds = pointerIds;
470001ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown}
470101ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown
4702a032cc008618b83ecbbede537517d1e7998e3264Jeff Brownvoid InputDispatcher::TouchState::filterNonAsIsTouchWindows() {
470301ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    for (size_t i = 0 ; i < windows.size(); ) {
4704a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown        TouchedWindow& window = windows.editItemAt(i);
470598db5fabdad86dca379740d8050697950b9f026cJeff Brown        if (window.targetFlags & (InputTarget::FLAG_DISPATCH_AS_IS
470698db5fabdad86dca379740d8050697950b9f026cJeff Brown                | InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER)) {
4707a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown            window.targetFlags &= ~InputTarget::FLAG_DISPATCH_MASK;
4708a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown            window.targetFlags |= InputTarget::FLAG_DISPATCH_AS_IS;
470901ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown            i += 1;
4710a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown        } else {
4711a032cc008618b83ecbbede537517d1e7998e3264Jeff Brown            windows.removeAt(i);
471201ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown        }
471301ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    }
471401ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown}
471501ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown
47169302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brownsp<InputWindowHandle> InputDispatcher::TouchState::getFirstForegroundWindowHandle() const {
471701ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    for (size_t i = 0; i < windows.size(); i++) {
471898db5fabdad86dca379740d8050697950b9f026cJeff Brown        const TouchedWindow& window = windows.itemAt(i);
471998db5fabdad86dca379740d8050697950b9f026cJeff Brown        if (window.targetFlags & InputTarget::FLAG_FOREGROUND) {
47209302c8796fc4dcda08d4bd1e11733848fd4fafafJeff Brown            return window.windowHandle;
472101ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown        }
472201ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    }
472301ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown    return NULL;
472401ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown}
472501ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown
472698db5fabdad86dca379740d8050697950b9f026cJeff Brownbool InputDispatcher::TouchState::isSlippery() const {
472798db5fabdad86dca379740d8050697950b9f026cJeff Brown    // Must have exactly one foreground window.
472898db5fabdad86dca379740d8050697950b9f026cJeff Brown    bool haveSlipperyForegroundWindow = false;
472998db5fabdad86dca379740d8050697950b9f026cJeff Brown    for (size_t i = 0; i < windows.size(); i++) {
473098db5fabdad86dca379740d8050697950b9f026cJeff Brown        const TouchedWindow& window = windows.itemAt(i);
473198db5fabdad86dca379740d8050697950b9f026cJeff Brown        if (window.targetFlags & InputTarget::FLAG_FOREGROUND) {
4732cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown            if (haveSlipperyForegroundWindow
4733cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown                    || !(window.windowHandle->getInfo()->layoutParamsFlags
4734cc4f7db698f88b633a286d8ab1105b28a474cd09Jeff Brown                            & InputWindowInfo::FLAG_SLIPPERY)) {
473598db5fabdad86dca379740d8050697950b9f026cJeff Brown                return false;
473698db5fabdad86dca379740d8050697950b9f026cJeff Brown            }
473798db5fabdad86dca379740d8050697950b9f026cJeff Brown            haveSlipperyForegroundWindow = true;
473898db5fabdad86dca379740d8050697950b9f026cJeff Brown        }
473998db5fabdad86dca379740d8050697950b9f026cJeff Brown    }
474098db5fabdad86dca379740d8050697950b9f026cJeff Brown    return haveSlipperyForegroundWindow;
474198db5fabdad86dca379740d8050697950b9f026cJeff Brown}
474298db5fabdad86dca379740d8050697950b9f026cJeff Brown
474301ce2e9eee41cc0c24b0d16465710a28ea337d5dJeff Brown
474446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown// --- InputDispatcherThread ---
474546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
474646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff BrownInputDispatcherThread::InputDispatcherThread(const sp<InputDispatcherInterface>& dispatcher) :
474746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        Thread(/*canCallJava*/ true), mDispatcher(dispatcher) {
474846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
474946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
475046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff BrownInputDispatcherThread::~InputDispatcherThread() {
475146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
475246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
475346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownbool InputDispatcherThread::threadLoop() {
475446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    mDispatcher->dispatchOnce();
475546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    return true;
475646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
475746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
475846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown} // namespace android
4759