Mir

Merge lp:~alan-griffiths/mir/fix-1483223 into lp:mir

Proposed by Alan Griffiths
Status: Work in progress
Proposed branch: lp:~alan-griffiths/mir/fix-1483223
Merge into: lp:mir
Prerequisite: lp:~alan-griffiths/mir/prerequsites-for-fixing-1483223
Diff against target: 5491 lines (+52/-5300)
14 files modified
3rd_party/android-input/android/CMakeLists.txt (+9/-31)
3rd_party/android-input/android/frameworks/base/services/input/InputApplication.cpp (+0/-42)
3rd_party/android-input/android/frameworks/base/services/input/InputDispatcher.cpp (+0/-4312)
3rd_party/android-input/android/frameworks/base/services/input/InputWindow.cpp (+0/-65)
3rd_party/android-input/android/frameworks/base/services/input/PointerController.cpp (+0/-276)
3rd_party/android-input/android/frameworks/native/libs/utils/Looper.cpp (+0/-561)
benchmarks/android-input/CMakeLists.txt (+0/-1)
src/client/CMakeLists.txt (+11/-2)
src/client/input/CMakeLists.txt (+0/-5)
src/client/symbols.map (+31/-1)
src/server/CMakeLists.txt (+0/-1)
src/utils/CMakeLists.txt (+1/-1)
tests/integration-tests/CMakeLists.txt (+0/-1)
tests/unit-tests/CMakeLists.txt (+0/-1)
To merge this branch: bzr merge lp:~alan-griffiths/mir/fix-1483223
Reviewer Review Type Date Requested Status
Daniel van Vugt Needs Information
PS Jenkins bot (community) continuous-integration Approve
Review via email: mp+267664@code.launchpad.net

Commit message

Put the former android-input-static library into mirclient (instead of linking it into both mirclient and mirserver).

Description of the change

Put the former android-input-static library into mirclient (instead of linking it into both mirclient and mirserver).

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
lp:~alan-griffiths/mir/fix-1483223 updated
2838. By Alan Griffiths

Remove parts of android input not used by libmirclient (or libmirserver)

2839. By Alan Griffiths

merge lp:mir

Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

I'm a little puzzled how things ever worked.

All the android-input stuff that remains here is (at least transitively) used in mirclient.

But that includes use of udev code that lives in mirplatform (until lp:~alan-griffiths/mir/prerequsites-for-fixing-1483223)

So how did clients ever link?

Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

OTOH this series does pull more stuff into libmirclient, so I've got something wrong in the above reasoning.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

Wow, 5k lines of diff by removing dead code!?

Revision history for this message
Daniel van Vugt (vanvugt) wrote :

The best news is input-reader-perf.bin is 10MB smaller.

And libmirserver is 6MB smaller, but libmircommon+libmirclient are now bigger to compensate. So the overall gain is almost negligible.

(1) Shouldn't MIR_CLIENT_DETAIL_9 become MIR_CLIENT_DETAIL_9.1 for new functions? Even as an internal ABI I feel we should probably manage it like the others.

(2) Doesn't putting the input code into libmircommon make more sense than libmirclient? I gather that would require moving some exception code mentioned in the bug. But it feels like we're using libmirclient as a helper library for libmirserver, which seems ugly. This isn't a new problem; libmirserver is already linking to libmirclient to support nesting (I assume), but I thought that was something we'd like to move away from eventually.

review: Needs Information

Unmerged revisions

2839. By Alan Griffiths

merge lp:mir

2838. By Alan Griffiths

Remove parts of android input not used by libmirclient (or libmirserver)

2837. By Alan Griffiths

merge lp:mir

2836. By Alan Griffiths

Move android-input-static to mirclient

2835. By Alan Griffiths

Revert libmirserver soname bump

2834. By Alan Griffiths

Fix thinko (we're still on 0.16)

2833. By Alan Griffiths

mirserver ABI break - bump the soname

2832. By Alan Griffiths

mirserver ABI break - bump the soname

2831. By Alan Griffiths

Fix symbol versioning in mircommon

2830. By Alan Griffiths

Move mir::udev to common

Preview Diff

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

Subscribers

People subscribed via source and target branches