xref: /aosp_15_r20/frameworks/native/services/inputflinger/dispatcher/InputDispatcher.cpp (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
1*38e8c45fSAndroid Build Coastguard Worker /*
2*38e8c45fSAndroid Build Coastguard Worker  * Copyright (C) 2010 The Android Open Source Project
3*38e8c45fSAndroid Build Coastguard Worker  *
4*38e8c45fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*38e8c45fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*38e8c45fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*38e8c45fSAndroid Build Coastguard Worker  *
8*38e8c45fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*38e8c45fSAndroid Build Coastguard Worker  *
10*38e8c45fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*38e8c45fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*38e8c45fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*38e8c45fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*38e8c45fSAndroid Build Coastguard Worker  * limitations under the License.
15*38e8c45fSAndroid Build Coastguard Worker  */
16*38e8c45fSAndroid Build Coastguard Worker 
17*38e8c45fSAndroid Build Coastguard Worker #define LOG_TAG "InputDispatcher"
18*38e8c45fSAndroid Build Coastguard Worker #define ATRACE_TAG ATRACE_TAG_INPUT
19*38e8c45fSAndroid Build Coastguard Worker 
20*38e8c45fSAndroid Build Coastguard Worker #define LOG_NDEBUG 1
21*38e8c45fSAndroid Build Coastguard Worker 
22*38e8c45fSAndroid Build Coastguard Worker #include <android-base/chrono_utils.h>
23*38e8c45fSAndroid Build Coastguard Worker #include <android-base/logging.h>
24*38e8c45fSAndroid Build Coastguard Worker #include <android-base/properties.h>
25*38e8c45fSAndroid Build Coastguard Worker #include <android-base/stringprintf.h>
26*38e8c45fSAndroid Build Coastguard Worker #include <android/os/IInputConstants.h>
27*38e8c45fSAndroid Build Coastguard Worker #include <binder/Binder.h>
28*38e8c45fSAndroid Build Coastguard Worker #include <com_android_input_flags.h>
29*38e8c45fSAndroid Build Coastguard Worker #include <ftl/enum.h>
30*38e8c45fSAndroid Build Coastguard Worker #include <log/log_event_list.h>
31*38e8c45fSAndroid Build Coastguard Worker #if defined(__ANDROID__)
32*38e8c45fSAndroid Build Coastguard Worker #include <gui/SurfaceComposerClient.h>
33*38e8c45fSAndroid Build Coastguard Worker #endif
34*38e8c45fSAndroid Build Coastguard Worker #include <input/InputDevice.h>
35*38e8c45fSAndroid Build Coastguard Worker #include <input/PrintTools.h>
36*38e8c45fSAndroid Build Coastguard Worker #include <input/TraceTools.h>
37*38e8c45fSAndroid Build Coastguard Worker #include <openssl/mem.h>
38*38e8c45fSAndroid Build Coastguard Worker #include <private/android_filesystem_config.h>
39*38e8c45fSAndroid Build Coastguard Worker #include <unistd.h>
40*38e8c45fSAndroid Build Coastguard Worker #include <utils/Trace.h>
41*38e8c45fSAndroid Build Coastguard Worker 
42*38e8c45fSAndroid Build Coastguard Worker #include <cerrno>
43*38e8c45fSAndroid Build Coastguard Worker #include <cinttypes>
44*38e8c45fSAndroid Build Coastguard Worker #include <climits>
45*38e8c45fSAndroid Build Coastguard Worker #include <cstddef>
46*38e8c45fSAndroid Build Coastguard Worker #include <ctime>
47*38e8c45fSAndroid Build Coastguard Worker #include <queue>
48*38e8c45fSAndroid Build Coastguard Worker #include <sstream>
49*38e8c45fSAndroid Build Coastguard Worker 
50*38e8c45fSAndroid Build Coastguard Worker #include "../InputDeviceMetricsSource.h"
51*38e8c45fSAndroid Build Coastguard Worker 
52*38e8c45fSAndroid Build Coastguard Worker #include "Connection.h"
53*38e8c45fSAndroid Build Coastguard Worker #include "DebugConfig.h"
54*38e8c45fSAndroid Build Coastguard Worker #include "InputDispatcher.h"
55*38e8c45fSAndroid Build Coastguard Worker #include "InputEventTimeline.h"
56*38e8c45fSAndroid Build Coastguard Worker #include "trace/InputTracer.h"
57*38e8c45fSAndroid Build Coastguard Worker #include "trace/InputTracingPerfettoBackend.h"
58*38e8c45fSAndroid Build Coastguard Worker #include "trace/ThreadedBackend.h"
59*38e8c45fSAndroid Build Coastguard Worker 
60*38e8c45fSAndroid Build Coastguard Worker #define INDENT "  "
61*38e8c45fSAndroid Build Coastguard Worker #define INDENT2 "    "
62*38e8c45fSAndroid Build Coastguard Worker #define INDENT3 "      "
63*38e8c45fSAndroid Build Coastguard Worker #define INDENT4 "        "
64*38e8c45fSAndroid Build Coastguard Worker 
65*38e8c45fSAndroid Build Coastguard Worker using namespace android::ftl::flag_operators;
66*38e8c45fSAndroid Build Coastguard Worker using android::base::Error;
67*38e8c45fSAndroid Build Coastguard Worker using android::base::HwTimeoutMultiplier;
68*38e8c45fSAndroid Build Coastguard Worker using android::base::Result;
69*38e8c45fSAndroid Build Coastguard Worker using android::base::StringPrintf;
70*38e8c45fSAndroid Build Coastguard Worker using android::gui::DisplayInfo;
71*38e8c45fSAndroid Build Coastguard Worker using android::gui::FocusRequest;
72*38e8c45fSAndroid Build Coastguard Worker using android::gui::TouchOcclusionMode;
73*38e8c45fSAndroid Build Coastguard Worker using android::gui::WindowInfo;
74*38e8c45fSAndroid Build Coastguard Worker using android::gui::WindowInfoHandle;
75*38e8c45fSAndroid Build Coastguard Worker using android::os::InputEventInjectionResult;
76*38e8c45fSAndroid Build Coastguard Worker using android::os::InputEventInjectionSync;
77*38e8c45fSAndroid Build Coastguard Worker namespace input_flags = com::android::input::flags;
78*38e8c45fSAndroid Build Coastguard Worker 
79*38e8c45fSAndroid Build Coastguard Worker namespace android::inputdispatcher {
80*38e8c45fSAndroid Build Coastguard Worker 
81*38e8c45fSAndroid Build Coastguard Worker namespace {
82*38e8c45fSAndroid Build Coastguard Worker 
83*38e8c45fSAndroid Build Coastguard Worker // Input tracing is only available on debuggable builds (userdebug and eng) when the feature
84*38e8c45fSAndroid Build Coastguard Worker // flag is enabled. When the flag is changed, tracing will only be available after reboot.
isInputTracingEnabled()85*38e8c45fSAndroid Build Coastguard Worker bool isInputTracingEnabled() {
86*38e8c45fSAndroid Build Coastguard Worker     static const std::string buildType = base::GetProperty("ro.build.type", "user");
87*38e8c45fSAndroid Build Coastguard Worker     static const bool isUserdebugOrEng = buildType == "userdebug" || buildType == "eng";
88*38e8c45fSAndroid Build Coastguard Worker     return input_flags::enable_input_event_tracing() && isUserdebugOrEng;
89*38e8c45fSAndroid Build Coastguard Worker }
90*38e8c45fSAndroid Build Coastguard Worker 
91*38e8c45fSAndroid Build Coastguard Worker // Create the input tracing backend that writes to perfetto from a single thread.
createInputTracingBackendIfEnabled()92*38e8c45fSAndroid Build Coastguard Worker std::unique_ptr<trace::InputTracingBackendInterface> createInputTracingBackendIfEnabled() {
93*38e8c45fSAndroid Build Coastguard Worker     if (!isInputTracingEnabled()) {
94*38e8c45fSAndroid Build Coastguard Worker         return nullptr;
95*38e8c45fSAndroid Build Coastguard Worker     }
96*38e8c45fSAndroid Build Coastguard Worker     return std::make_unique<trace::impl::ThreadedBackend<trace::impl::PerfettoBackend>>(
97*38e8c45fSAndroid Build Coastguard Worker             trace::impl::PerfettoBackend());
98*38e8c45fSAndroid Build Coastguard Worker }
99*38e8c45fSAndroid Build Coastguard Worker 
100*38e8c45fSAndroid Build Coastguard Worker template <class Entry>
ensureEventTraced(const Entry & entry)101*38e8c45fSAndroid Build Coastguard Worker void ensureEventTraced(const Entry& entry) {
102*38e8c45fSAndroid Build Coastguard Worker     if (!entry.traceTracker) {
103*38e8c45fSAndroid Build Coastguard Worker         LOG(FATAL) << "Expected event entry to be traced, but it wasn't: " << entry;
104*38e8c45fSAndroid Build Coastguard Worker     }
105*38e8c45fSAndroid Build Coastguard Worker }
106*38e8c45fSAndroid Build Coastguard Worker 
107*38e8c45fSAndroid Build Coastguard Worker // Helper to get a trace tracker from a traced key or motion entry.
getTraceTracker(const EventEntry & entry)108*38e8c45fSAndroid Build Coastguard Worker const std::unique_ptr<trace::EventTrackerInterface>& getTraceTracker(const EventEntry& entry) {
109*38e8c45fSAndroid Build Coastguard Worker     switch (entry.type) {
110*38e8c45fSAndroid Build Coastguard Worker         case EventEntry::Type::MOTION: {
111*38e8c45fSAndroid Build Coastguard Worker             const auto& motion = static_cast<const MotionEntry&>(entry);
112*38e8c45fSAndroid Build Coastguard Worker             ensureEventTraced(motion);
113*38e8c45fSAndroid Build Coastguard Worker             return motion.traceTracker;
114*38e8c45fSAndroid Build Coastguard Worker         }
115*38e8c45fSAndroid Build Coastguard Worker         case EventEntry::Type::KEY: {
116*38e8c45fSAndroid Build Coastguard Worker             const auto& key = static_cast<const KeyEntry&>(entry);
117*38e8c45fSAndroid Build Coastguard Worker             ensureEventTraced(key);
118*38e8c45fSAndroid Build Coastguard Worker             return key.traceTracker;
119*38e8c45fSAndroid Build Coastguard Worker         }
120*38e8c45fSAndroid Build Coastguard Worker         default: {
121*38e8c45fSAndroid Build Coastguard Worker             const static std::unique_ptr<trace::EventTrackerInterface> kNullTracker;
122*38e8c45fSAndroid Build Coastguard Worker             return kNullTracker;
123*38e8c45fSAndroid Build Coastguard Worker         }
124*38e8c45fSAndroid Build Coastguard Worker     }
125*38e8c45fSAndroid Build Coastguard Worker }
126*38e8c45fSAndroid Build Coastguard Worker 
127*38e8c45fSAndroid Build Coastguard Worker // Temporarily releases a held mutex for the lifetime of the instance.
128*38e8c45fSAndroid Build Coastguard Worker // Named to match std::scoped_lock
129*38e8c45fSAndroid Build Coastguard Worker class scoped_unlock {
130*38e8c45fSAndroid Build Coastguard Worker public:
scoped_unlock(std::mutex & mutex)131*38e8c45fSAndroid Build Coastguard Worker     explicit scoped_unlock(std::mutex& mutex) : mMutex(mutex) { mMutex.unlock(); }
~scoped_unlock()132*38e8c45fSAndroid Build Coastguard Worker     ~scoped_unlock() { mMutex.lock(); }
133*38e8c45fSAndroid Build Coastguard Worker 
134*38e8c45fSAndroid Build Coastguard Worker private:
135*38e8c45fSAndroid Build Coastguard Worker     std::mutex& mMutex;
136*38e8c45fSAndroid Build Coastguard Worker };
137*38e8c45fSAndroid Build Coastguard Worker 
138*38e8c45fSAndroid Build Coastguard Worker // Default input dispatching timeout if there is no focused application or paused window
139*38e8c45fSAndroid Build Coastguard Worker // from which to determine an appropriate dispatching timeout.
140*38e8c45fSAndroid Build Coastguard Worker const std::chrono::duration DEFAULT_INPUT_DISPATCHING_TIMEOUT = std::chrono::milliseconds(
141*38e8c45fSAndroid Build Coastguard Worker         android::os::IInputConstants::UNMULTIPLIED_DEFAULT_DISPATCHING_TIMEOUT_MILLIS *
142*38e8c45fSAndroid Build Coastguard Worker         HwTimeoutMultiplier());
143*38e8c45fSAndroid Build Coastguard Worker 
144*38e8c45fSAndroid Build Coastguard Worker // The default minimum time gap between two user activity poke events.
145*38e8c45fSAndroid Build Coastguard Worker const std::chrono::milliseconds DEFAULT_USER_ACTIVITY_POKE_INTERVAL = 100ms;
146*38e8c45fSAndroid Build Coastguard Worker 
147*38e8c45fSAndroid Build Coastguard Worker const std::chrono::duration STALE_EVENT_TIMEOUT = std::chrono::seconds(10) * HwTimeoutMultiplier();
148*38e8c45fSAndroid Build Coastguard Worker 
149*38e8c45fSAndroid Build Coastguard Worker // Log a warning when an event takes longer than this to process, even if an ANR does not occur.
150*38e8c45fSAndroid Build Coastguard Worker constexpr nsecs_t SLOW_EVENT_PROCESSING_WARNING_TIMEOUT = 2000 * 1000000LL; // 2sec
151*38e8c45fSAndroid Build Coastguard Worker 
152*38e8c45fSAndroid Build Coastguard Worker // Log a warning when an interception call takes longer than this to process.
153*38e8c45fSAndroid Build Coastguard Worker constexpr std::chrono::milliseconds SLOW_INTERCEPTION_THRESHOLD = 50ms;
154*38e8c45fSAndroid Build Coastguard Worker 
155*38e8c45fSAndroid Build Coastguard Worker // Number of recent events to keep for debugging purposes.
156*38e8c45fSAndroid Build Coastguard Worker constexpr size_t RECENT_QUEUE_MAX_SIZE = 10;
157*38e8c45fSAndroid Build Coastguard Worker 
158*38e8c45fSAndroid Build Coastguard Worker // Interval at which we should push the atom gathering input event latencies in
159*38e8c45fSAndroid Build Coastguard Worker // LatencyAggregatorWithHistograms
160*38e8c45fSAndroid Build Coastguard Worker constexpr nsecs_t LATENCY_STATISTICS_PUSH_INTERVAL = 6 * 3600 * 1000000000LL; // 6 hours
161*38e8c45fSAndroid Build Coastguard Worker 
162*38e8c45fSAndroid Build Coastguard Worker // Event log tags. See EventLogTags.logtags for reference.
163*38e8c45fSAndroid Build Coastguard Worker constexpr int LOGTAG_INPUT_INTERACTION = 62000;
164*38e8c45fSAndroid Build Coastguard Worker constexpr int LOGTAG_INPUT_FOCUS = 62001;
165*38e8c45fSAndroid Build Coastguard Worker constexpr int LOGTAG_INPUT_CANCEL = 62003;
166*38e8c45fSAndroid Build Coastguard Worker 
167*38e8c45fSAndroid Build Coastguard Worker const ui::Transform kIdentityTransform;
168*38e8c45fSAndroid Build Coastguard Worker 
now()169*38e8c45fSAndroid Build Coastguard Worker inline nsecs_t now() {
170*38e8c45fSAndroid Build Coastguard Worker     return systemTime(SYSTEM_TIME_MONOTONIC);
171*38e8c45fSAndroid Build Coastguard Worker }
172*38e8c45fSAndroid Build Coastguard Worker 
binderToString(const sp<IBinder> & binder)173*38e8c45fSAndroid Build Coastguard Worker inline const std::string binderToString(const sp<IBinder>& binder) {
174*38e8c45fSAndroid Build Coastguard Worker     if (binder == nullptr) {
175*38e8c45fSAndroid Build Coastguard Worker         return "<null>";
176*38e8c45fSAndroid Build Coastguard Worker     }
177*38e8c45fSAndroid Build Coastguard Worker     return StringPrintf("%p", binder.get());
178*38e8c45fSAndroid Build Coastguard Worker }
179*38e8c45fSAndroid Build Coastguard Worker 
uidString(const gui::Uid & uid)180*38e8c45fSAndroid Build Coastguard Worker static std::string uidString(const gui::Uid& uid) {
181*38e8c45fSAndroid Build Coastguard Worker     return uid.toString();
182*38e8c45fSAndroid Build Coastguard Worker }
183*38e8c45fSAndroid Build Coastguard Worker 
checkKeyAction(int32_t action)184*38e8c45fSAndroid Build Coastguard Worker Result<void> checkKeyAction(int32_t action) {
185*38e8c45fSAndroid Build Coastguard Worker     switch (action) {
186*38e8c45fSAndroid Build Coastguard Worker         case AKEY_EVENT_ACTION_DOWN:
187*38e8c45fSAndroid Build Coastguard Worker         case AKEY_EVENT_ACTION_UP:
188*38e8c45fSAndroid Build Coastguard Worker             return {};
189*38e8c45fSAndroid Build Coastguard Worker         default:
190*38e8c45fSAndroid Build Coastguard Worker             return Error() << "Key event has invalid action code " << action;
191*38e8c45fSAndroid Build Coastguard Worker     }
192*38e8c45fSAndroid Build Coastguard Worker }
193*38e8c45fSAndroid Build Coastguard Worker 
validateKeyEvent(int32_t action)194*38e8c45fSAndroid Build Coastguard Worker Result<void> validateKeyEvent(int32_t action) {
195*38e8c45fSAndroid Build Coastguard Worker     return checkKeyAction(action);
196*38e8c45fSAndroid Build Coastguard Worker }
197*38e8c45fSAndroid Build Coastguard Worker 
checkMotionAction(int32_t action,int32_t actionButton,int32_t pointerCount)198*38e8c45fSAndroid Build Coastguard Worker Result<void> checkMotionAction(int32_t action, int32_t actionButton, int32_t pointerCount) {
199*38e8c45fSAndroid Build Coastguard Worker     switch (MotionEvent::getActionMasked(action)) {
200*38e8c45fSAndroid Build Coastguard Worker         case AMOTION_EVENT_ACTION_DOWN:
201*38e8c45fSAndroid Build Coastguard Worker         case AMOTION_EVENT_ACTION_UP: {
202*38e8c45fSAndroid Build Coastguard Worker             if (pointerCount != 1) {
203*38e8c45fSAndroid Build Coastguard Worker                 return Error() << "invalid pointer count " << pointerCount;
204*38e8c45fSAndroid Build Coastguard Worker             }
205*38e8c45fSAndroid Build Coastguard Worker             return {};
206*38e8c45fSAndroid Build Coastguard Worker         }
207*38e8c45fSAndroid Build Coastguard Worker         case AMOTION_EVENT_ACTION_MOVE:
208*38e8c45fSAndroid Build Coastguard Worker         case AMOTION_EVENT_ACTION_HOVER_ENTER:
209*38e8c45fSAndroid Build Coastguard Worker         case AMOTION_EVENT_ACTION_HOVER_MOVE:
210*38e8c45fSAndroid Build Coastguard Worker         case AMOTION_EVENT_ACTION_HOVER_EXIT: {
211*38e8c45fSAndroid Build Coastguard Worker             if (pointerCount < 1) {
212*38e8c45fSAndroid Build Coastguard Worker                 return Error() << "invalid pointer count " << pointerCount;
213*38e8c45fSAndroid Build Coastguard Worker             }
214*38e8c45fSAndroid Build Coastguard Worker             return {};
215*38e8c45fSAndroid Build Coastguard Worker         }
216*38e8c45fSAndroid Build Coastguard Worker         case AMOTION_EVENT_ACTION_CANCEL:
217*38e8c45fSAndroid Build Coastguard Worker         case AMOTION_EVENT_ACTION_OUTSIDE:
218*38e8c45fSAndroid Build Coastguard Worker         case AMOTION_EVENT_ACTION_SCROLL:
219*38e8c45fSAndroid Build Coastguard Worker             return {};
220*38e8c45fSAndroid Build Coastguard Worker         case AMOTION_EVENT_ACTION_POINTER_DOWN:
221*38e8c45fSAndroid Build Coastguard Worker         case AMOTION_EVENT_ACTION_POINTER_UP: {
222*38e8c45fSAndroid Build Coastguard Worker             const int32_t index = MotionEvent::getActionIndex(action);
223*38e8c45fSAndroid Build Coastguard Worker             if (index < 0) {
224*38e8c45fSAndroid Build Coastguard Worker                 return Error() << "invalid index " << index << " for "
225*38e8c45fSAndroid Build Coastguard Worker                                << MotionEvent::actionToString(action);
226*38e8c45fSAndroid Build Coastguard Worker             }
227*38e8c45fSAndroid Build Coastguard Worker             if (index >= pointerCount) {
228*38e8c45fSAndroid Build Coastguard Worker                 return Error() << "invalid index " << index << " for pointerCount " << pointerCount;
229*38e8c45fSAndroid Build Coastguard Worker             }
230*38e8c45fSAndroid Build Coastguard Worker             if (pointerCount <= 1) {
231*38e8c45fSAndroid Build Coastguard Worker                 return Error() << "invalid pointer count " << pointerCount << " for "
232*38e8c45fSAndroid Build Coastguard Worker                                << MotionEvent::actionToString(action);
233*38e8c45fSAndroid Build Coastguard Worker             }
234*38e8c45fSAndroid Build Coastguard Worker             return {};
235*38e8c45fSAndroid Build Coastguard Worker         }
236*38e8c45fSAndroid Build Coastguard Worker         case AMOTION_EVENT_ACTION_BUTTON_PRESS:
237*38e8c45fSAndroid Build Coastguard Worker         case AMOTION_EVENT_ACTION_BUTTON_RELEASE: {
238*38e8c45fSAndroid Build Coastguard Worker             if (actionButton == 0) {
239*38e8c45fSAndroid Build Coastguard Worker                 return Error() << "action button should be nonzero for "
240*38e8c45fSAndroid Build Coastguard Worker                                << MotionEvent::actionToString(action);
241*38e8c45fSAndroid Build Coastguard Worker             }
242*38e8c45fSAndroid Build Coastguard Worker             return {};
243*38e8c45fSAndroid Build Coastguard Worker         }
244*38e8c45fSAndroid Build Coastguard Worker         default:
245*38e8c45fSAndroid Build Coastguard Worker             return Error() << "invalid action " << action;
246*38e8c45fSAndroid Build Coastguard Worker     }
247*38e8c45fSAndroid Build Coastguard Worker }
248*38e8c45fSAndroid Build Coastguard Worker 
millis(std::chrono::nanoseconds t)249*38e8c45fSAndroid Build Coastguard Worker int64_t millis(std::chrono::nanoseconds t) {
250*38e8c45fSAndroid Build Coastguard Worker     return std::chrono::duration_cast<std::chrono::milliseconds>(t).count();
251*38e8c45fSAndroid Build Coastguard Worker }
252*38e8c45fSAndroid Build Coastguard Worker 
validateMotionEvent(int32_t action,int32_t actionButton,size_t pointerCount,const PointerProperties * pointerProperties)253*38e8c45fSAndroid Build Coastguard Worker Result<void> validateMotionEvent(int32_t action, int32_t actionButton, size_t pointerCount,
254*38e8c45fSAndroid Build Coastguard Worker                                  const PointerProperties* pointerProperties) {
255*38e8c45fSAndroid Build Coastguard Worker     Result<void> actionCheck = checkMotionAction(action, actionButton, pointerCount);
256*38e8c45fSAndroid Build Coastguard Worker     if (!actionCheck.ok()) {
257*38e8c45fSAndroid Build Coastguard Worker         return actionCheck;
258*38e8c45fSAndroid Build Coastguard Worker     }
259*38e8c45fSAndroid Build Coastguard Worker     if (pointerCount < 1 || pointerCount > MAX_POINTERS) {
260*38e8c45fSAndroid Build Coastguard Worker         return Error() << "Motion event has invalid pointer count " << pointerCount
261*38e8c45fSAndroid Build Coastguard Worker                        << "; value must be between 1 and " << MAX_POINTERS << ".";
262*38e8c45fSAndroid Build Coastguard Worker     }
263*38e8c45fSAndroid Build Coastguard Worker     std::bitset<MAX_POINTER_ID + 1> pointerIdBits;
264*38e8c45fSAndroid Build Coastguard Worker     for (size_t i = 0; i < pointerCount; i++) {
265*38e8c45fSAndroid Build Coastguard Worker         int32_t id = pointerProperties[i].id;
266*38e8c45fSAndroid Build Coastguard Worker         if (id < 0 || id > MAX_POINTER_ID) {
267*38e8c45fSAndroid Build Coastguard Worker             return Error() << "Motion event has invalid pointer id " << id
268*38e8c45fSAndroid Build Coastguard Worker                            << "; value must be between 0 and " << MAX_POINTER_ID;
269*38e8c45fSAndroid Build Coastguard Worker         }
270*38e8c45fSAndroid Build Coastguard Worker         if (pointerIdBits.test(id)) {
271*38e8c45fSAndroid Build Coastguard Worker             return Error() << "Motion event has duplicate pointer id " << id;
272*38e8c45fSAndroid Build Coastguard Worker         }
273*38e8c45fSAndroid Build Coastguard Worker         pointerIdBits.set(id);
274*38e8c45fSAndroid Build Coastguard Worker     }
275*38e8c45fSAndroid Build Coastguard Worker     return {};
276*38e8c45fSAndroid Build Coastguard Worker }
277*38e8c45fSAndroid Build Coastguard Worker 
validateInputEvent(const InputEvent & event)278*38e8c45fSAndroid Build Coastguard Worker Result<void> validateInputEvent(const InputEvent& event) {
279*38e8c45fSAndroid Build Coastguard Worker     switch (event.getType()) {
280*38e8c45fSAndroid Build Coastguard Worker         case InputEventType::KEY: {
281*38e8c45fSAndroid Build Coastguard Worker             const KeyEvent& key = static_cast<const KeyEvent&>(event);
282*38e8c45fSAndroid Build Coastguard Worker             const int32_t action = key.getAction();
283*38e8c45fSAndroid Build Coastguard Worker             return validateKeyEvent(action);
284*38e8c45fSAndroid Build Coastguard Worker         }
285*38e8c45fSAndroid Build Coastguard Worker         case InputEventType::MOTION: {
286*38e8c45fSAndroid Build Coastguard Worker             const MotionEvent& motion = static_cast<const MotionEvent&>(event);
287*38e8c45fSAndroid Build Coastguard Worker             const int32_t action = motion.getAction();
288*38e8c45fSAndroid Build Coastguard Worker             const size_t pointerCount = motion.getPointerCount();
289*38e8c45fSAndroid Build Coastguard Worker             const PointerProperties* pointerProperties = motion.getPointerProperties();
290*38e8c45fSAndroid Build Coastguard Worker             const int32_t actionButton = motion.getActionButton();
291*38e8c45fSAndroid Build Coastguard Worker             return validateMotionEvent(action, actionButton, pointerCount, pointerProperties);
292*38e8c45fSAndroid Build Coastguard Worker         }
293*38e8c45fSAndroid Build Coastguard Worker         default: {
294*38e8c45fSAndroid Build Coastguard Worker             return {};
295*38e8c45fSAndroid Build Coastguard Worker         }
296*38e8c45fSAndroid Build Coastguard Worker     }
297*38e8c45fSAndroid Build Coastguard Worker }
298*38e8c45fSAndroid Build Coastguard Worker 
getPointerIds(const std::vector<PointerProperties> & pointers)299*38e8c45fSAndroid Build Coastguard Worker std::bitset<MAX_POINTER_ID + 1> getPointerIds(const std::vector<PointerProperties>& pointers) {
300*38e8c45fSAndroid Build Coastguard Worker     std::bitset<MAX_POINTER_ID + 1> pointerIds;
301*38e8c45fSAndroid Build Coastguard Worker     for (const PointerProperties& pointer : pointers) {
302*38e8c45fSAndroid Build Coastguard Worker         pointerIds.set(pointer.id);
303*38e8c45fSAndroid Build Coastguard Worker     }
304*38e8c45fSAndroid Build Coastguard Worker     return pointerIds;
305*38e8c45fSAndroid Build Coastguard Worker }
306*38e8c45fSAndroid Build Coastguard Worker 
dumpRegion(const Region & region)307*38e8c45fSAndroid Build Coastguard Worker std::string dumpRegion(const Region& region) {
308*38e8c45fSAndroid Build Coastguard Worker     if (region.isEmpty()) {
309*38e8c45fSAndroid Build Coastguard Worker         return "<empty>";
310*38e8c45fSAndroid Build Coastguard Worker     }
311*38e8c45fSAndroid Build Coastguard Worker 
312*38e8c45fSAndroid Build Coastguard Worker     std::string dump;
313*38e8c45fSAndroid Build Coastguard Worker     bool first = true;
314*38e8c45fSAndroid Build Coastguard Worker     Region::const_iterator cur = region.begin();
315*38e8c45fSAndroid Build Coastguard Worker     Region::const_iterator const tail = region.end();
316*38e8c45fSAndroid Build Coastguard Worker     while (cur != tail) {
317*38e8c45fSAndroid Build Coastguard Worker         if (first) {
318*38e8c45fSAndroid Build Coastguard Worker             first = false;
319*38e8c45fSAndroid Build Coastguard Worker         } else {
320*38e8c45fSAndroid Build Coastguard Worker             dump += "|";
321*38e8c45fSAndroid Build Coastguard Worker         }
322*38e8c45fSAndroid Build Coastguard Worker         dump += StringPrintf("[%d,%d][%d,%d]", cur->left, cur->top, cur->right, cur->bottom);
323*38e8c45fSAndroid Build Coastguard Worker         cur++;
324*38e8c45fSAndroid Build Coastguard Worker     }
325*38e8c45fSAndroid Build Coastguard Worker     return dump;
326*38e8c45fSAndroid Build Coastguard Worker }
327*38e8c45fSAndroid Build Coastguard Worker 
dumpQueue(const std::deque<std::unique_ptr<DispatchEntry>> & queue,nsecs_t currentTime)328*38e8c45fSAndroid Build Coastguard Worker std::string dumpQueue(const std::deque<std::unique_ptr<DispatchEntry>>& queue,
329*38e8c45fSAndroid Build Coastguard Worker                       nsecs_t currentTime) {
330*38e8c45fSAndroid Build Coastguard Worker     constexpr size_t maxEntries = 50; // max events to print
331*38e8c45fSAndroid Build Coastguard Worker     constexpr size_t skipBegin = maxEntries / 2;
332*38e8c45fSAndroid Build Coastguard Worker     const size_t skipEnd = queue.size() - maxEntries / 2;
333*38e8c45fSAndroid Build Coastguard Worker     // skip from maxEntries / 2 ... size() - maxEntries/2
334*38e8c45fSAndroid Build Coastguard Worker     // only print from 0 .. skipBegin and then from skipEnd .. size()
335*38e8c45fSAndroid Build Coastguard Worker 
336*38e8c45fSAndroid Build Coastguard Worker     std::string dump;
337*38e8c45fSAndroid Build Coastguard Worker     for (size_t i = 0; i < queue.size(); i++) {
338*38e8c45fSAndroid Build Coastguard Worker         const DispatchEntry& entry = *queue[i];
339*38e8c45fSAndroid Build Coastguard Worker         if (i >= skipBegin && i < skipEnd) {
340*38e8c45fSAndroid Build Coastguard Worker             dump += StringPrintf(INDENT4 "<skipped %zu entries>\n", skipEnd - skipBegin);
341*38e8c45fSAndroid Build Coastguard Worker             i = skipEnd - 1; // it will be incremented to "skipEnd" by 'continue'
342*38e8c45fSAndroid Build Coastguard Worker             continue;
343*38e8c45fSAndroid Build Coastguard Worker         }
344*38e8c45fSAndroid Build Coastguard Worker         dump.append(INDENT4);
345*38e8c45fSAndroid Build Coastguard Worker         dump += entry.eventEntry->getDescription();
346*38e8c45fSAndroid Build Coastguard Worker         dump += StringPrintf(", seq=%" PRIu32 ", targetFlags=%s, age=%" PRId64 "ms", entry.seq,
347*38e8c45fSAndroid Build Coastguard Worker                              entry.targetFlags.string().c_str(),
348*38e8c45fSAndroid Build Coastguard Worker                              ns2ms(currentTime - entry.eventEntry->eventTime));
349*38e8c45fSAndroid Build Coastguard Worker         if (entry.deliveryTime != 0) {
350*38e8c45fSAndroid Build Coastguard Worker             // This entry was delivered, so add information on how long we've been waiting
351*38e8c45fSAndroid Build Coastguard Worker             dump += StringPrintf(", wait=%" PRId64 "ms", ns2ms(currentTime - entry.deliveryTime));
352*38e8c45fSAndroid Build Coastguard Worker         }
353*38e8c45fSAndroid Build Coastguard Worker         dump.append("\n");
354*38e8c45fSAndroid Build Coastguard Worker     }
355*38e8c45fSAndroid Build Coastguard Worker     return dump;
356*38e8c45fSAndroid Build Coastguard Worker }
357*38e8c45fSAndroid Build Coastguard Worker 
358*38e8c45fSAndroid Build Coastguard Worker /**
359*38e8c45fSAndroid Build Coastguard Worker  * Find the entry in std::unordered_map by key, and return it.
360*38e8c45fSAndroid Build Coastguard Worker  * If the entry is not found, return a default constructed entry.
361*38e8c45fSAndroid Build Coastguard Worker  *
362*38e8c45fSAndroid Build Coastguard Worker  * Useful when the entries are vectors, since an empty vector will be returned
363*38e8c45fSAndroid Build Coastguard Worker  * if the entry is not found.
364*38e8c45fSAndroid Build Coastguard Worker  * Also useful when the entries are sp<>. If an entry is not found, nullptr is returned.
365*38e8c45fSAndroid Build Coastguard Worker  */
366*38e8c45fSAndroid Build Coastguard Worker template <typename K, typename V>
getValueByKey(const std::unordered_map<K,V> & map,K key)367*38e8c45fSAndroid Build Coastguard Worker V getValueByKey(const std::unordered_map<K, V>& map, K key) {
368*38e8c45fSAndroid Build Coastguard Worker     auto it = map.find(key);
369*38e8c45fSAndroid Build Coastguard Worker     return it != map.end() ? it->second : V{};
370*38e8c45fSAndroid Build Coastguard Worker }
371*38e8c45fSAndroid Build Coastguard Worker 
haveSameToken(const sp<WindowInfoHandle> & first,const sp<WindowInfoHandle> & second)372*38e8c45fSAndroid Build Coastguard Worker bool haveSameToken(const sp<WindowInfoHandle>& first, const sp<WindowInfoHandle>& second) {
373*38e8c45fSAndroid Build Coastguard Worker     if (first == second) {
374*38e8c45fSAndroid Build Coastguard Worker         return true;
375*38e8c45fSAndroid Build Coastguard Worker     }
376*38e8c45fSAndroid Build Coastguard Worker 
377*38e8c45fSAndroid Build Coastguard Worker     if (first == nullptr || second == nullptr) {
378*38e8c45fSAndroid Build Coastguard Worker         return false;
379*38e8c45fSAndroid Build Coastguard Worker     }
380*38e8c45fSAndroid Build Coastguard Worker 
381*38e8c45fSAndroid Build Coastguard Worker     return first->getToken() == second->getToken();
382*38e8c45fSAndroid Build Coastguard Worker }
383*38e8c45fSAndroid Build Coastguard Worker 
haveSameApplicationToken(const WindowInfo * first,const WindowInfo * second)384*38e8c45fSAndroid Build Coastguard Worker bool haveSameApplicationToken(const WindowInfo* first, const WindowInfo* second) {
385*38e8c45fSAndroid Build Coastguard Worker     if (first == nullptr || second == nullptr) {
386*38e8c45fSAndroid Build Coastguard Worker         return false;
387*38e8c45fSAndroid Build Coastguard Worker     }
388*38e8c45fSAndroid Build Coastguard Worker     return first->applicationInfo.token != nullptr &&
389*38e8c45fSAndroid Build Coastguard Worker             first->applicationInfo.token == second->applicationInfo.token;
390*38e8c45fSAndroid Build Coastguard Worker }
391*38e8c45fSAndroid Build Coastguard Worker 
392*38e8c45fSAndroid Build Coastguard Worker template <typename T>
firstMarkedBit(T set)393*38e8c45fSAndroid Build Coastguard Worker size_t firstMarkedBit(T set) {
394*38e8c45fSAndroid Build Coastguard Worker     // TODO: replace with std::countr_zero from <bit> when that's available
395*38e8c45fSAndroid Build Coastguard Worker     LOG_ALWAYS_FATAL_IF(set.none());
396*38e8c45fSAndroid Build Coastguard Worker     size_t i = 0;
397*38e8c45fSAndroid Build Coastguard Worker     while (!set.test(i)) {
398*38e8c45fSAndroid Build Coastguard Worker         i++;
399*38e8c45fSAndroid Build Coastguard Worker     }
400*38e8c45fSAndroid Build Coastguard Worker     return i;
401*38e8c45fSAndroid Build Coastguard Worker }
402*38e8c45fSAndroid Build Coastguard Worker 
createDispatchEntry(const IdGenerator & idGenerator,const InputTarget & inputTarget,std::shared_ptr<const EventEntry> eventEntry,ftl::Flags<InputTarget::Flags> inputTargetFlags,int64_t vsyncId,trace::InputTracerInterface * tracer)403*38e8c45fSAndroid Build Coastguard Worker std::unique_ptr<DispatchEntry> createDispatchEntry(const IdGenerator& idGenerator,
404*38e8c45fSAndroid Build Coastguard Worker                                                    const InputTarget& inputTarget,
405*38e8c45fSAndroid Build Coastguard Worker                                                    std::shared_ptr<const EventEntry> eventEntry,
406*38e8c45fSAndroid Build Coastguard Worker                                                    ftl::Flags<InputTarget::Flags> inputTargetFlags,
407*38e8c45fSAndroid Build Coastguard Worker                                                    int64_t vsyncId,
408*38e8c45fSAndroid Build Coastguard Worker                                                    trace::InputTracerInterface* tracer) {
409*38e8c45fSAndroid Build Coastguard Worker     const bool zeroCoords = inputTargetFlags.test(InputTarget::Flags::ZERO_COORDS);
410*38e8c45fSAndroid Build Coastguard Worker     const sp<WindowInfoHandle> win = inputTarget.windowHandle;
411*38e8c45fSAndroid Build Coastguard Worker     const std::optional<int32_t> windowId =
412*38e8c45fSAndroid Build Coastguard Worker             win ? std::make_optional(win->getInfo()->id) : std::nullopt;
413*38e8c45fSAndroid Build Coastguard Worker     // Assume the only targets that are not associated with a window are global monitors, and use
414*38e8c45fSAndroid Build Coastguard Worker     // the system UID for global monitors for tracing purposes.
415*38e8c45fSAndroid Build Coastguard Worker     const gui::Uid uid = win ? win->getInfo()->ownerUid : gui::Uid(AID_SYSTEM);
416*38e8c45fSAndroid Build Coastguard Worker 
417*38e8c45fSAndroid Build Coastguard Worker     if (inputTarget.useDefaultPointerTransform() && !zeroCoords) {
418*38e8c45fSAndroid Build Coastguard Worker         const ui::Transform& transform = inputTarget.getDefaultPointerTransform();
419*38e8c45fSAndroid Build Coastguard Worker         return std::make_unique<DispatchEntry>(eventEntry, inputTargetFlags, transform,
420*38e8c45fSAndroid Build Coastguard Worker                                                inputTarget.displayTransform,
421*38e8c45fSAndroid Build Coastguard Worker                                                inputTarget.globalScaleFactor, uid, vsyncId,
422*38e8c45fSAndroid Build Coastguard Worker                                                windowId);
423*38e8c45fSAndroid Build Coastguard Worker     }
424*38e8c45fSAndroid Build Coastguard Worker 
425*38e8c45fSAndroid Build Coastguard Worker     ALOG_ASSERT(eventEntry->type == EventEntry::Type::MOTION);
426*38e8c45fSAndroid Build Coastguard Worker     const MotionEntry& motionEntry = static_cast<const MotionEntry&>(*eventEntry);
427*38e8c45fSAndroid Build Coastguard Worker 
428*38e8c45fSAndroid Build Coastguard Worker     std::vector<PointerCoords> pointerCoords{motionEntry.getPointerCount()};
429*38e8c45fSAndroid Build Coastguard Worker 
430*38e8c45fSAndroid Build Coastguard Worker     const ui::Transform* transform = &kIdentityTransform;
431*38e8c45fSAndroid Build Coastguard Worker     const ui::Transform* displayTransform = &kIdentityTransform;
432*38e8c45fSAndroid Build Coastguard Worker     if (zeroCoords) {
433*38e8c45fSAndroid Build Coastguard Worker         std::for_each(pointerCoords.begin(), pointerCoords.end(), [](auto& pc) { pc.clear(); });
434*38e8c45fSAndroid Build Coastguard Worker     } else {
435*38e8c45fSAndroid Build Coastguard Worker         // Use the first pointer information to normalize all other pointers. This could be any
436*38e8c45fSAndroid Build Coastguard Worker         // pointer as long as all other pointers are normalized to the same value and the final
437*38e8c45fSAndroid Build Coastguard Worker         // DispatchEntry uses the transform for the normalized pointer.
438*38e8c45fSAndroid Build Coastguard Worker         transform =
439*38e8c45fSAndroid Build Coastguard Worker                 &inputTarget.getTransformForPointer(firstMarkedBit(inputTarget.getPointerIds()));
440*38e8c45fSAndroid Build Coastguard Worker         const ui::Transform inverseTransform = transform->inverse();
441*38e8c45fSAndroid Build Coastguard Worker         displayTransform = &inputTarget.displayTransform;
442*38e8c45fSAndroid Build Coastguard Worker 
443*38e8c45fSAndroid Build Coastguard Worker         // Iterate through all pointers in the event to normalize against the first.
444*38e8c45fSAndroid Build Coastguard Worker         for (size_t i = 0; i < motionEntry.getPointerCount(); i++) {
445*38e8c45fSAndroid Build Coastguard Worker             PointerCoords& newCoords = pointerCoords[i];
446*38e8c45fSAndroid Build Coastguard Worker             const auto pointerId = motionEntry.pointerProperties[i].id;
447*38e8c45fSAndroid Build Coastguard Worker             const ui::Transform& currTransform = inputTarget.getTransformForPointer(pointerId);
448*38e8c45fSAndroid Build Coastguard Worker 
449*38e8c45fSAndroid Build Coastguard Worker             newCoords.copyFrom(motionEntry.pointerCoords[i]);
450*38e8c45fSAndroid Build Coastguard Worker             // First, apply the current pointer's transform to update the coordinates into
451*38e8c45fSAndroid Build Coastguard Worker             // window space.
452*38e8c45fSAndroid Build Coastguard Worker             MotionEvent::calculateTransformedCoordsInPlace(newCoords, motionEntry.source,
453*38e8c45fSAndroid Build Coastguard Worker                                                            motionEntry.flags, currTransform);
454*38e8c45fSAndroid Build Coastguard Worker             // Next, apply the inverse transform of the normalized coordinates so the
455*38e8c45fSAndroid Build Coastguard Worker             // current coordinates are transformed into the normalized coordinate space.
456*38e8c45fSAndroid Build Coastguard Worker             MotionEvent::calculateTransformedCoordsInPlace(newCoords, motionEntry.source,
457*38e8c45fSAndroid Build Coastguard Worker                                                            motionEntry.flags, inverseTransform);
458*38e8c45fSAndroid Build Coastguard Worker         }
459*38e8c45fSAndroid Build Coastguard Worker     }
460*38e8c45fSAndroid Build Coastguard Worker 
461*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<MotionEntry> combinedMotionEntry =
462*38e8c45fSAndroid Build Coastguard Worker             std::make_unique<MotionEntry>(idGenerator.nextId(), motionEntry.injectionState,
463*38e8c45fSAndroid Build Coastguard Worker                                           motionEntry.eventTime, motionEntry.deviceId,
464*38e8c45fSAndroid Build Coastguard Worker                                           motionEntry.source, motionEntry.displayId,
465*38e8c45fSAndroid Build Coastguard Worker                                           motionEntry.policyFlags, motionEntry.action,
466*38e8c45fSAndroid Build Coastguard Worker                                           motionEntry.actionButton, motionEntry.flags,
467*38e8c45fSAndroid Build Coastguard Worker                                           motionEntry.metaState, motionEntry.buttonState,
468*38e8c45fSAndroid Build Coastguard Worker                                           motionEntry.classification, motionEntry.edgeFlags,
469*38e8c45fSAndroid Build Coastguard Worker                                           motionEntry.xPrecision, motionEntry.yPrecision,
470*38e8c45fSAndroid Build Coastguard Worker                                           motionEntry.xCursorPosition, motionEntry.yCursorPosition,
471*38e8c45fSAndroid Build Coastguard Worker                                           motionEntry.downTime, motionEntry.pointerProperties,
472*38e8c45fSAndroid Build Coastguard Worker                                           pointerCoords);
473*38e8c45fSAndroid Build Coastguard Worker     if (tracer) {
474*38e8c45fSAndroid Build Coastguard Worker         combinedMotionEntry->traceTracker =
475*38e8c45fSAndroid Build Coastguard Worker                 tracer->traceDerivedEvent(*combinedMotionEntry, *motionEntry.traceTracker);
476*38e8c45fSAndroid Build Coastguard Worker     }
477*38e8c45fSAndroid Build Coastguard Worker 
478*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<DispatchEntry> dispatchEntry =
479*38e8c45fSAndroid Build Coastguard Worker             std::make_unique<DispatchEntry>(std::move(combinedMotionEntry), inputTargetFlags,
480*38e8c45fSAndroid Build Coastguard Worker                                             *transform, *displayTransform,
481*38e8c45fSAndroid Build Coastguard Worker                                             inputTarget.globalScaleFactor, uid, vsyncId, windowId);
482*38e8c45fSAndroid Build Coastguard Worker     return dispatchEntry;
483*38e8c45fSAndroid Build Coastguard Worker }
484*38e8c45fSAndroid Build Coastguard Worker 
485*38e8c45fSAndroid Build Coastguard Worker template <typename T>
sharedPointersEqual(const std::shared_ptr<T> & lhs,const std::shared_ptr<T> & rhs)486*38e8c45fSAndroid Build Coastguard Worker bool sharedPointersEqual(const std::shared_ptr<T>& lhs, const std::shared_ptr<T>& rhs) {
487*38e8c45fSAndroid Build Coastguard Worker     if (lhs == nullptr && rhs == nullptr) {
488*38e8c45fSAndroid Build Coastguard Worker         return true;
489*38e8c45fSAndroid Build Coastguard Worker     }
490*38e8c45fSAndroid Build Coastguard Worker     if (lhs == nullptr || rhs == nullptr) {
491*38e8c45fSAndroid Build Coastguard Worker         return false;
492*38e8c45fSAndroid Build Coastguard Worker     }
493*38e8c45fSAndroid Build Coastguard Worker     return *lhs == *rhs;
494*38e8c45fSAndroid Build Coastguard Worker }
495*38e8c45fSAndroid Build Coastguard Worker 
createKeyEvent(const KeyEntry & entry)496*38e8c45fSAndroid Build Coastguard Worker KeyEvent createKeyEvent(const KeyEntry& entry) {
497*38e8c45fSAndroid Build Coastguard Worker     KeyEvent event;
498*38e8c45fSAndroid Build Coastguard Worker     event.initialize(entry.id, entry.deviceId, entry.source, entry.displayId, INVALID_HMAC,
499*38e8c45fSAndroid Build Coastguard Worker                      entry.action, entry.flags, entry.keyCode, entry.scanCode, entry.metaState,
500*38e8c45fSAndroid Build Coastguard Worker                      entry.repeatCount, entry.downTime, entry.eventTime);
501*38e8c45fSAndroid Build Coastguard Worker     return event;
502*38e8c45fSAndroid Build Coastguard Worker }
503*38e8c45fSAndroid Build Coastguard Worker 
shouldReportMetricsForConnection(const Connection & connection)504*38e8c45fSAndroid Build Coastguard Worker bool shouldReportMetricsForConnection(const Connection& connection) {
505*38e8c45fSAndroid Build Coastguard Worker     // Do not keep track of gesture monitors. They receive every event and would disproportionately
506*38e8c45fSAndroid Build Coastguard Worker     // affect the statistics.
507*38e8c45fSAndroid Build Coastguard Worker     if (connection.monitor) {
508*38e8c45fSAndroid Build Coastguard Worker         return false;
509*38e8c45fSAndroid Build Coastguard Worker     }
510*38e8c45fSAndroid Build Coastguard Worker     // If the connection is experiencing ANR, let's skip it. We have separate ANR metrics
511*38e8c45fSAndroid Build Coastguard Worker     if (!connection.responsive) {
512*38e8c45fSAndroid Build Coastguard Worker         return false;
513*38e8c45fSAndroid Build Coastguard Worker     }
514*38e8c45fSAndroid Build Coastguard Worker     return true;
515*38e8c45fSAndroid Build Coastguard Worker }
516*38e8c45fSAndroid Build Coastguard Worker 
shouldReportFinishedEvent(const DispatchEntry & dispatchEntry,const Connection & connection)517*38e8c45fSAndroid Build Coastguard Worker bool shouldReportFinishedEvent(const DispatchEntry& dispatchEntry, const Connection& connection) {
518*38e8c45fSAndroid Build Coastguard Worker     const EventEntry& eventEntry = *dispatchEntry.eventEntry;
519*38e8c45fSAndroid Build Coastguard Worker     const int32_t& inputEventId = eventEntry.id;
520*38e8c45fSAndroid Build Coastguard Worker     if (inputEventId == android::os::IInputConstants::INVALID_INPUT_EVENT_ID) {
521*38e8c45fSAndroid Build Coastguard Worker         return false;
522*38e8c45fSAndroid Build Coastguard Worker     }
523*38e8c45fSAndroid Build Coastguard Worker     // Only track latency for events that originated from hardware
524*38e8c45fSAndroid Build Coastguard Worker     if (eventEntry.isSynthesized()) {
525*38e8c45fSAndroid Build Coastguard Worker         return false;
526*38e8c45fSAndroid Build Coastguard Worker     }
527*38e8c45fSAndroid Build Coastguard Worker     const EventEntry::Type& inputEventEntryType = eventEntry.type;
528*38e8c45fSAndroid Build Coastguard Worker     if (inputEventEntryType == EventEntry::Type::KEY) {
529*38e8c45fSAndroid Build Coastguard Worker         const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
530*38e8c45fSAndroid Build Coastguard Worker         if (keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) {
531*38e8c45fSAndroid Build Coastguard Worker             return false;
532*38e8c45fSAndroid Build Coastguard Worker         }
533*38e8c45fSAndroid Build Coastguard Worker     } else if (inputEventEntryType == EventEntry::Type::MOTION) {
534*38e8c45fSAndroid Build Coastguard Worker         const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
535*38e8c45fSAndroid Build Coastguard Worker         if (motionEntry.action == AMOTION_EVENT_ACTION_CANCEL ||
536*38e8c45fSAndroid Build Coastguard Worker             motionEntry.action == AMOTION_EVENT_ACTION_HOVER_EXIT) {
537*38e8c45fSAndroid Build Coastguard Worker             return false;
538*38e8c45fSAndroid Build Coastguard Worker         }
539*38e8c45fSAndroid Build Coastguard Worker     } else {
540*38e8c45fSAndroid Build Coastguard Worker         // Not a key or a motion
541*38e8c45fSAndroid Build Coastguard Worker         return false;
542*38e8c45fSAndroid Build Coastguard Worker     }
543*38e8c45fSAndroid Build Coastguard Worker     if (!shouldReportMetricsForConnection(connection)) {
544*38e8c45fSAndroid Build Coastguard Worker         return false;
545*38e8c45fSAndroid Build Coastguard Worker     }
546*38e8c45fSAndroid Build Coastguard Worker     return true;
547*38e8c45fSAndroid Build Coastguard Worker }
548*38e8c45fSAndroid Build Coastguard Worker 
549*38e8c45fSAndroid Build Coastguard Worker /**
550*38e8c45fSAndroid Build Coastguard Worker  * Connection is responsive if it has no events in the waitQueue that are older than the
551*38e8c45fSAndroid Build Coastguard Worker  * current time.
552*38e8c45fSAndroid Build Coastguard Worker  */
isConnectionResponsive(const Connection & connection)553*38e8c45fSAndroid Build Coastguard Worker bool isConnectionResponsive(const Connection& connection) {
554*38e8c45fSAndroid Build Coastguard Worker     const nsecs_t currentTime = now();
555*38e8c45fSAndroid Build Coastguard Worker     for (const auto& dispatchEntry : connection.waitQueue) {
556*38e8c45fSAndroid Build Coastguard Worker         if (dispatchEntry->timeoutTime < currentTime) {
557*38e8c45fSAndroid Build Coastguard Worker             return false;
558*38e8c45fSAndroid Build Coastguard Worker         }
559*38e8c45fSAndroid Build Coastguard Worker     }
560*38e8c45fSAndroid Build Coastguard Worker     return true;
561*38e8c45fSAndroid Build Coastguard Worker }
562*38e8c45fSAndroid Build Coastguard Worker 
563*38e8c45fSAndroid Build Coastguard Worker // Returns true if the event type passed as argument represents a user activity.
isUserActivityEvent(const EventEntry & eventEntry)564*38e8c45fSAndroid Build Coastguard Worker bool isUserActivityEvent(const EventEntry& eventEntry) {
565*38e8c45fSAndroid Build Coastguard Worker     switch (eventEntry.type) {
566*38e8c45fSAndroid Build Coastguard Worker         case EventEntry::Type::DEVICE_RESET:
567*38e8c45fSAndroid Build Coastguard Worker         case EventEntry::Type::DRAG:
568*38e8c45fSAndroid Build Coastguard Worker         case EventEntry::Type::FOCUS:
569*38e8c45fSAndroid Build Coastguard Worker         case EventEntry::Type::POINTER_CAPTURE_CHANGED:
570*38e8c45fSAndroid Build Coastguard Worker         case EventEntry::Type::SENSOR:
571*38e8c45fSAndroid Build Coastguard Worker         case EventEntry::Type::TOUCH_MODE_CHANGED:
572*38e8c45fSAndroid Build Coastguard Worker             return false;
573*38e8c45fSAndroid Build Coastguard Worker         case EventEntry::Type::KEY:
574*38e8c45fSAndroid Build Coastguard Worker         case EventEntry::Type::MOTION:
575*38e8c45fSAndroid Build Coastguard Worker             return true;
576*38e8c45fSAndroid Build Coastguard Worker     }
577*38e8c45fSAndroid Build Coastguard Worker }
578*38e8c45fSAndroid Build Coastguard Worker 
579*38e8c45fSAndroid Build Coastguard Worker // Returns true if the given window can accept pointer events at the given display location.
windowAcceptsTouchAt(const WindowInfo & windowInfo,ui::LogicalDisplayId displayId,float x,float y,bool isStylus,const ui::Transform & displayTransform)580*38e8c45fSAndroid Build Coastguard Worker bool windowAcceptsTouchAt(const WindowInfo& windowInfo, ui::LogicalDisplayId displayId, float x,
581*38e8c45fSAndroid Build Coastguard Worker                           float y, bool isStylus, const ui::Transform& displayTransform) {
582*38e8c45fSAndroid Build Coastguard Worker     const auto inputConfig = windowInfo.inputConfig;
583*38e8c45fSAndroid Build Coastguard Worker     if (windowInfo.displayId != displayId ||
584*38e8c45fSAndroid Build Coastguard Worker         inputConfig.test(WindowInfo::InputConfig::NOT_VISIBLE)) {
585*38e8c45fSAndroid Build Coastguard Worker         return false;
586*38e8c45fSAndroid Build Coastguard Worker     }
587*38e8c45fSAndroid Build Coastguard Worker     const bool windowCanInterceptTouch = isStylus && windowInfo.interceptsStylus();
588*38e8c45fSAndroid Build Coastguard Worker     if (inputConfig.test(WindowInfo::InputConfig::NOT_TOUCHABLE) && !windowCanInterceptTouch) {
589*38e8c45fSAndroid Build Coastguard Worker         return false;
590*38e8c45fSAndroid Build Coastguard Worker     }
591*38e8c45fSAndroid Build Coastguard Worker 
592*38e8c45fSAndroid Build Coastguard Worker     // Window Manager works in the logical display coordinate space. When it specifies bounds for a
593*38e8c45fSAndroid Build Coastguard Worker     // window as (l, t, r, b), the range of x in [l, r) and y in [t, b) are considered to be inside
594*38e8c45fSAndroid Build Coastguard Worker     // the window. Points on the right and bottom edges should not be inside the window, so we need
595*38e8c45fSAndroid Build Coastguard Worker     // to be careful about performing a hit test when the display is rotated, since the "right" and
596*38e8c45fSAndroid Build Coastguard Worker     // "bottom" of the window will be different in the display (un-rotated) space compared to in the
597*38e8c45fSAndroid Build Coastguard Worker     // logical display in which WM determined the bounds. Perform the hit test in the logical
598*38e8c45fSAndroid Build Coastguard Worker     // display space to ensure these edges are considered correctly in all orientations.
599*38e8c45fSAndroid Build Coastguard Worker     const auto touchableRegion = displayTransform.transform(windowInfo.touchableRegion);
600*38e8c45fSAndroid Build Coastguard Worker     const auto p = displayTransform.transform(x, y);
601*38e8c45fSAndroid Build Coastguard Worker     if (!touchableRegion.contains(std::floor(p.x), std::floor(p.y))) {
602*38e8c45fSAndroid Build Coastguard Worker         return false;
603*38e8c45fSAndroid Build Coastguard Worker     }
604*38e8c45fSAndroid Build Coastguard Worker     return true;
605*38e8c45fSAndroid Build Coastguard Worker }
606*38e8c45fSAndroid Build Coastguard Worker 
607*38e8c45fSAndroid Build Coastguard Worker // Returns true if the given window's frame can occlude pointer events at the given display
608*38e8c45fSAndroid Build Coastguard Worker // location.
windowOccludesTouchAt(const WindowInfo & windowInfo,ui::LogicalDisplayId displayId,float x,float y,const ui::Transform & displayTransform)609*38e8c45fSAndroid Build Coastguard Worker bool windowOccludesTouchAt(const WindowInfo& windowInfo, ui::LogicalDisplayId displayId, float x,
610*38e8c45fSAndroid Build Coastguard Worker                            float y, const ui::Transform& displayTransform) {
611*38e8c45fSAndroid Build Coastguard Worker     if (windowInfo.displayId != displayId) {
612*38e8c45fSAndroid Build Coastguard Worker         return false;
613*38e8c45fSAndroid Build Coastguard Worker     }
614*38e8c45fSAndroid Build Coastguard Worker     const auto frame = displayTransform.transform(windowInfo.frame);
615*38e8c45fSAndroid Build Coastguard Worker     const auto p = floor(displayTransform.transform(x, y));
616*38e8c45fSAndroid Build Coastguard Worker     return p.x >= frame.left && p.x < frame.right && p.y >= frame.top && p.y < frame.bottom;
617*38e8c45fSAndroid Build Coastguard Worker }
618*38e8c45fSAndroid Build Coastguard Worker 
isPointerFromStylus(const MotionEntry & entry,int32_t pointerIndex)619*38e8c45fSAndroid Build Coastguard Worker bool isPointerFromStylus(const MotionEntry& entry, int32_t pointerIndex) {
620*38e8c45fSAndroid Build Coastguard Worker     return isFromSource(entry.source, AINPUT_SOURCE_STYLUS) &&
621*38e8c45fSAndroid Build Coastguard Worker             isStylusToolType(entry.pointerProperties[pointerIndex].toolType);
622*38e8c45fSAndroid Build Coastguard Worker }
623*38e8c45fSAndroid Build Coastguard Worker 
624*38e8c45fSAndroid Build Coastguard Worker // Determines if the given window can be targeted as InputTarget::Flags::FOREGROUND.
625*38e8c45fSAndroid Build Coastguard Worker // Foreground events are only sent to "foreground targetable" windows, but not all gestures sent to
626*38e8c45fSAndroid Build Coastguard Worker // such window are necessarily targeted with the flag. For example, an event with ACTION_OUTSIDE can
627*38e8c45fSAndroid Build Coastguard Worker // be sent to such a window, but it is not a foreground event and doesn't use
628*38e8c45fSAndroid Build Coastguard Worker // InputTarget::Flags::FOREGROUND.
canReceiveForegroundTouches(const WindowInfo & info)629*38e8c45fSAndroid Build Coastguard Worker bool canReceiveForegroundTouches(const WindowInfo& info) {
630*38e8c45fSAndroid Build Coastguard Worker     // A non-touchable window can still receive touch events (e.g. in the case of
631*38e8c45fSAndroid Build Coastguard Worker     // STYLUS_INTERCEPTOR), so prevent such windows from receiving foreground events for touches.
632*38e8c45fSAndroid Build Coastguard Worker     return !info.inputConfig.test(gui::WindowInfo::InputConfig::NOT_TOUCHABLE) && !info.isSpy();
633*38e8c45fSAndroid Build Coastguard Worker }
634*38e8c45fSAndroid Build Coastguard Worker 
isWindowOwnedBy(const sp<WindowInfoHandle> & windowHandle,gui::Pid pid,gui::Uid uid)635*38e8c45fSAndroid Build Coastguard Worker bool isWindowOwnedBy(const sp<WindowInfoHandle>& windowHandle, gui::Pid pid, gui::Uid uid) {
636*38e8c45fSAndroid Build Coastguard Worker     if (windowHandle == nullptr) {
637*38e8c45fSAndroid Build Coastguard Worker         return false;
638*38e8c45fSAndroid Build Coastguard Worker     }
639*38e8c45fSAndroid Build Coastguard Worker     const WindowInfo* windowInfo = windowHandle->getInfo();
640*38e8c45fSAndroid Build Coastguard Worker     if (pid == windowInfo->ownerPid && uid == windowInfo->ownerUid) {
641*38e8c45fSAndroid Build Coastguard Worker         return true;
642*38e8c45fSAndroid Build Coastguard Worker     }
643*38e8c45fSAndroid Build Coastguard Worker     return false;
644*38e8c45fSAndroid Build Coastguard Worker }
645*38e8c45fSAndroid Build Coastguard Worker 
646*38e8c45fSAndroid Build Coastguard Worker // Checks targeted injection using the window's owner's uid.
647*38e8c45fSAndroid Build Coastguard Worker // Returns an empty string if an entry can be sent to the given window, or an error message if the
648*38e8c45fSAndroid Build Coastguard Worker // entry is a targeted injection whose uid target doesn't match the window owner.
verifyTargetedInjection(const sp<WindowInfoHandle> & window,const EventEntry & entry)649*38e8c45fSAndroid Build Coastguard Worker std::optional<std::string> verifyTargetedInjection(const sp<WindowInfoHandle>& window,
650*38e8c45fSAndroid Build Coastguard Worker                                                    const EventEntry& entry) {
651*38e8c45fSAndroid Build Coastguard Worker     if (entry.injectionState == nullptr || !entry.injectionState->targetUid) {
652*38e8c45fSAndroid Build Coastguard Worker         // The event was not injected, or the injected event does not target a window.
653*38e8c45fSAndroid Build Coastguard Worker         return {};
654*38e8c45fSAndroid Build Coastguard Worker     }
655*38e8c45fSAndroid Build Coastguard Worker     const auto uid = *entry.injectionState->targetUid;
656*38e8c45fSAndroid Build Coastguard Worker     if (window == nullptr) {
657*38e8c45fSAndroid Build Coastguard Worker         return StringPrintf("No valid window target for injection into uid %s.",
658*38e8c45fSAndroid Build Coastguard Worker                             uid.toString().c_str());
659*38e8c45fSAndroid Build Coastguard Worker     }
660*38e8c45fSAndroid Build Coastguard Worker     if (entry.injectionState->targetUid != window->getInfo()->ownerUid) {
661*38e8c45fSAndroid Build Coastguard Worker         return StringPrintf("Injected event targeted at uid %s would be dispatched to window '%s' "
662*38e8c45fSAndroid Build Coastguard Worker                             "owned by uid %s.",
663*38e8c45fSAndroid Build Coastguard Worker                             uid.toString().c_str(), window->getName().c_str(),
664*38e8c45fSAndroid Build Coastguard Worker                             window->getInfo()->ownerUid.toString().c_str());
665*38e8c45fSAndroid Build Coastguard Worker     }
666*38e8c45fSAndroid Build Coastguard Worker     return {};
667*38e8c45fSAndroid Build Coastguard Worker }
668*38e8c45fSAndroid Build Coastguard Worker 
resolveTouchedPosition(const MotionEntry & entry)669*38e8c45fSAndroid Build Coastguard Worker std::pair<float, float> resolveTouchedPosition(const MotionEntry& entry) {
670*38e8c45fSAndroid Build Coastguard Worker     const bool isFromMouse = isFromSource(entry.source, AINPUT_SOURCE_MOUSE);
671*38e8c45fSAndroid Build Coastguard Worker     // Always dispatch mouse events to cursor position.
672*38e8c45fSAndroid Build Coastguard Worker     if (isFromMouse) {
673*38e8c45fSAndroid Build Coastguard Worker         return {entry.xCursorPosition, entry.yCursorPosition};
674*38e8c45fSAndroid Build Coastguard Worker     }
675*38e8c45fSAndroid Build Coastguard Worker 
676*38e8c45fSAndroid Build Coastguard Worker     const int32_t pointerIndex = MotionEvent::getActionIndex(entry.action);
677*38e8c45fSAndroid Build Coastguard Worker     return {entry.pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_X),
678*38e8c45fSAndroid Build Coastguard Worker             entry.pointerCoords[pointerIndex].getAxisValue(AMOTION_EVENT_AXIS_Y)};
679*38e8c45fSAndroid Build Coastguard Worker }
680*38e8c45fSAndroid Build Coastguard Worker 
getDownTime(const EventEntry & eventEntry)681*38e8c45fSAndroid Build Coastguard Worker std::optional<nsecs_t> getDownTime(const EventEntry& eventEntry) {
682*38e8c45fSAndroid Build Coastguard Worker     if (eventEntry.type == EventEntry::Type::KEY) {
683*38e8c45fSAndroid Build Coastguard Worker         const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
684*38e8c45fSAndroid Build Coastguard Worker         return keyEntry.downTime;
685*38e8c45fSAndroid Build Coastguard Worker     } else if (eventEntry.type == EventEntry::Type::MOTION) {
686*38e8c45fSAndroid Build Coastguard Worker         const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
687*38e8c45fSAndroid Build Coastguard Worker         return motionEntry.downTime;
688*38e8c45fSAndroid Build Coastguard Worker     }
689*38e8c45fSAndroid Build Coastguard Worker     return std::nullopt;
690*38e8c45fSAndroid Build Coastguard Worker }
691*38e8c45fSAndroid Build Coastguard Worker 
692*38e8c45fSAndroid Build Coastguard Worker /**
693*38e8c45fSAndroid Build Coastguard Worker  * Compare the old touch state to the new touch state, and generate the corresponding touched
694*38e8c45fSAndroid Build Coastguard Worker  * windows (== input targets).
695*38e8c45fSAndroid Build Coastguard Worker  * If a window had the hovering pointer, but now it doesn't, produce HOVER_EXIT for that window.
696*38e8c45fSAndroid Build Coastguard Worker  * If the pointer just entered the new window, produce HOVER_ENTER.
697*38e8c45fSAndroid Build Coastguard Worker  * For pointers remaining in the window, produce HOVER_MOVE.
698*38e8c45fSAndroid Build Coastguard Worker  */
getHoveringWindowsLocked(const TouchState * oldState,const TouchState & newTouchState,const MotionEntry & entry,std::function<void ()> dump)699*38e8c45fSAndroid Build Coastguard Worker std::vector<TouchedWindow> getHoveringWindowsLocked(const TouchState* oldState,
700*38e8c45fSAndroid Build Coastguard Worker                                                     const TouchState& newTouchState,
701*38e8c45fSAndroid Build Coastguard Worker                                                     const MotionEntry& entry,
702*38e8c45fSAndroid Build Coastguard Worker                                                     std::function<void()> dump) {
703*38e8c45fSAndroid Build Coastguard Worker     const int32_t maskedAction = MotionEvent::getActionMasked(entry.action);
704*38e8c45fSAndroid Build Coastguard Worker 
705*38e8c45fSAndroid Build Coastguard Worker     if (maskedAction == AMOTION_EVENT_ACTION_SCROLL) {
706*38e8c45fSAndroid Build Coastguard Worker         // ACTION_SCROLL events should not affect the hovering pointer dispatch
707*38e8c45fSAndroid Build Coastguard Worker         return {};
708*38e8c45fSAndroid Build Coastguard Worker     }
709*38e8c45fSAndroid Build Coastguard Worker     std::vector<TouchedWindow> out;
710*38e8c45fSAndroid Build Coastguard Worker 
711*38e8c45fSAndroid Build Coastguard Worker     // We should consider all hovering pointers here. But for now, just use the first one
712*38e8c45fSAndroid Build Coastguard Worker     const PointerProperties& pointer = entry.pointerProperties[0];
713*38e8c45fSAndroid Build Coastguard Worker 
714*38e8c45fSAndroid Build Coastguard Worker     std::set<sp<WindowInfoHandle>> oldWindows;
715*38e8c45fSAndroid Build Coastguard Worker     if (oldState != nullptr) {
716*38e8c45fSAndroid Build Coastguard Worker         oldWindows = oldState->getWindowsWithHoveringPointer(entry.deviceId, pointer.id);
717*38e8c45fSAndroid Build Coastguard Worker     }
718*38e8c45fSAndroid Build Coastguard Worker 
719*38e8c45fSAndroid Build Coastguard Worker     std::set<sp<WindowInfoHandle>> newWindows =
720*38e8c45fSAndroid Build Coastguard Worker             newTouchState.getWindowsWithHoveringPointer(entry.deviceId, pointer.id);
721*38e8c45fSAndroid Build Coastguard Worker 
722*38e8c45fSAndroid Build Coastguard Worker     // If the pointer is no longer in the new window set, send HOVER_EXIT.
723*38e8c45fSAndroid Build Coastguard Worker     for (const sp<WindowInfoHandle>& oldWindow : oldWindows) {
724*38e8c45fSAndroid Build Coastguard Worker         if (newWindows.find(oldWindow) == newWindows.end()) {
725*38e8c45fSAndroid Build Coastguard Worker             TouchedWindow touchedWindow;
726*38e8c45fSAndroid Build Coastguard Worker             touchedWindow.windowHandle = oldWindow;
727*38e8c45fSAndroid Build Coastguard Worker             touchedWindow.dispatchMode = InputTarget::DispatchMode::HOVER_EXIT;
728*38e8c45fSAndroid Build Coastguard Worker             out.push_back(touchedWindow);
729*38e8c45fSAndroid Build Coastguard Worker         }
730*38e8c45fSAndroid Build Coastguard Worker     }
731*38e8c45fSAndroid Build Coastguard Worker 
732*38e8c45fSAndroid Build Coastguard Worker     for (const sp<WindowInfoHandle>& newWindow : newWindows) {
733*38e8c45fSAndroid Build Coastguard Worker         TouchedWindow touchedWindow;
734*38e8c45fSAndroid Build Coastguard Worker         touchedWindow.windowHandle = newWindow;
735*38e8c45fSAndroid Build Coastguard Worker         if (oldWindows.find(newWindow) == oldWindows.end()) {
736*38e8c45fSAndroid Build Coastguard Worker             // Any windows that have this pointer now, and didn't have it before, should get
737*38e8c45fSAndroid Build Coastguard Worker             // HOVER_ENTER
738*38e8c45fSAndroid Build Coastguard Worker             touchedWindow.dispatchMode = InputTarget::DispatchMode::HOVER_ENTER;
739*38e8c45fSAndroid Build Coastguard Worker         } else {
740*38e8c45fSAndroid Build Coastguard Worker             // This pointer was already sent to the window. Use ACTION_HOVER_MOVE.
741*38e8c45fSAndroid Build Coastguard Worker             if (CC_UNLIKELY(maskedAction != AMOTION_EVENT_ACTION_HOVER_MOVE)) {
742*38e8c45fSAndroid Build Coastguard Worker                 android::base::LogSeverity severity = android::base::LogSeverity::FATAL;
743*38e8c45fSAndroid Build Coastguard Worker                 if (!input_flags::a11y_crash_on_inconsistent_event_stream() &&
744*38e8c45fSAndroid Build Coastguard Worker                     entry.flags & AMOTION_EVENT_FLAG_IS_ACCESSIBILITY_EVENT) {
745*38e8c45fSAndroid Build Coastguard Worker                     // The Accessibility injected touch exploration event stream
746*38e8c45fSAndroid Build Coastguard Worker                     // has known inconsistencies, so log ERROR instead of
747*38e8c45fSAndroid Build Coastguard Worker                     // crashing the device with FATAL.
748*38e8c45fSAndroid Build Coastguard Worker                     severity = android::base::LogSeverity::ERROR;
749*38e8c45fSAndroid Build Coastguard Worker                 }
750*38e8c45fSAndroid Build Coastguard Worker                 dump();
751*38e8c45fSAndroid Build Coastguard Worker                 LOG(severity) << "Expected ACTION_HOVER_MOVE instead of " << entry.getDescription();
752*38e8c45fSAndroid Build Coastguard Worker             }
753*38e8c45fSAndroid Build Coastguard Worker             touchedWindow.dispatchMode = InputTarget::DispatchMode::AS_IS;
754*38e8c45fSAndroid Build Coastguard Worker         }
755*38e8c45fSAndroid Build Coastguard Worker         const auto [x, y] = resolveTouchedPosition(entry);
756*38e8c45fSAndroid Build Coastguard Worker         touchedWindow.addHoveringPointer(entry.deviceId, pointer, x, y);
757*38e8c45fSAndroid Build Coastguard Worker         if (canReceiveForegroundTouches(*newWindow->getInfo())) {
758*38e8c45fSAndroid Build Coastguard Worker             touchedWindow.targetFlags |= InputTarget::Flags::FOREGROUND;
759*38e8c45fSAndroid Build Coastguard Worker         }
760*38e8c45fSAndroid Build Coastguard Worker         out.push_back(touchedWindow);
761*38e8c45fSAndroid Build Coastguard Worker     }
762*38e8c45fSAndroid Build Coastguard Worker     return out;
763*38e8c45fSAndroid Build Coastguard Worker }
764*38e8c45fSAndroid Build Coastguard Worker 
765*38e8c45fSAndroid Build Coastguard Worker template <typename T>
operator +=(std::vector<T> & left,const std::vector<T> & right)766*38e8c45fSAndroid Build Coastguard Worker std::vector<T>& operator+=(std::vector<T>& left, const std::vector<T>& right) {
767*38e8c45fSAndroid Build Coastguard Worker     left.insert(left.end(), right.begin(), right.end());
768*38e8c45fSAndroid Build Coastguard Worker     return left;
769*38e8c45fSAndroid Build Coastguard Worker }
770*38e8c45fSAndroid Build Coastguard Worker 
771*38e8c45fSAndroid Build Coastguard Worker // Filter windows in a TouchState and targets in a vector to remove untrusted windows/targets from
772*38e8c45fSAndroid Build Coastguard Worker // both.
filterUntrustedTargets(TouchState & touchState,std::vector<InputTarget> & targets)773*38e8c45fSAndroid Build Coastguard Worker void filterUntrustedTargets(TouchState& touchState, std::vector<InputTarget>& targets) {
774*38e8c45fSAndroid Build Coastguard Worker     std::erase_if(touchState.windows, [&](const TouchedWindow& window) {
775*38e8c45fSAndroid Build Coastguard Worker         if (!window.windowHandle->getInfo()->inputConfig.test(
776*38e8c45fSAndroid Build Coastguard Worker                     WindowInfo::InputConfig::TRUSTED_OVERLAY)) {
777*38e8c45fSAndroid Build Coastguard Worker             // In addition to TouchState, erase this window from the input targets! We don't have a
778*38e8c45fSAndroid Build Coastguard Worker             // good way to do this today except by adding a nested loop.
779*38e8c45fSAndroid Build Coastguard Worker             // TODO(b/282025641): simplify this code once InputTargets are being identified
780*38e8c45fSAndroid Build Coastguard Worker             // separately from TouchedWindows.
781*38e8c45fSAndroid Build Coastguard Worker             std::erase_if(targets, [&](const InputTarget& target) {
782*38e8c45fSAndroid Build Coastguard Worker                 return target.connection->getToken() == window.windowHandle->getToken();
783*38e8c45fSAndroid Build Coastguard Worker             });
784*38e8c45fSAndroid Build Coastguard Worker             return true;
785*38e8c45fSAndroid Build Coastguard Worker         }
786*38e8c45fSAndroid Build Coastguard Worker         return false;
787*38e8c45fSAndroid Build Coastguard Worker     });
788*38e8c45fSAndroid Build Coastguard Worker }
789*38e8c45fSAndroid Build Coastguard Worker 
790*38e8c45fSAndroid Build Coastguard Worker /**
791*38e8c45fSAndroid Build Coastguard Worker  * In general, touch should be always split between windows. Some exceptions:
792*38e8c45fSAndroid Build Coastguard Worker  * 1. Don't split touch if all of the below is true:
793*38e8c45fSAndroid Build Coastguard Worker  *     (a) we have an active pointer down *and*
794*38e8c45fSAndroid Build Coastguard Worker  *     (b) a new pointer is going down that's from the same device *and*
795*38e8c45fSAndroid Build Coastguard Worker  *     (c) the window that's receiving the current pointer does not support split touch.
796*38e8c45fSAndroid Build Coastguard Worker  * 2. Don't split mouse events
797*38e8c45fSAndroid Build Coastguard Worker  */
shouldSplitTouch(const TouchState & touchState,const MotionEntry & entry)798*38e8c45fSAndroid Build Coastguard Worker bool shouldSplitTouch(const TouchState& touchState, const MotionEntry& entry) {
799*38e8c45fSAndroid Build Coastguard Worker     if (isFromSource(entry.source, AINPUT_SOURCE_MOUSE)) {
800*38e8c45fSAndroid Build Coastguard Worker         // We should never split mouse events
801*38e8c45fSAndroid Build Coastguard Worker         return false;
802*38e8c45fSAndroid Build Coastguard Worker     }
803*38e8c45fSAndroid Build Coastguard Worker     for (const TouchedWindow& touchedWindow : touchState.windows) {
804*38e8c45fSAndroid Build Coastguard Worker         if (touchedWindow.windowHandle->getInfo()->isSpy()) {
805*38e8c45fSAndroid Build Coastguard Worker             // Spy windows should not affect whether or not touch is split.
806*38e8c45fSAndroid Build Coastguard Worker             continue;
807*38e8c45fSAndroid Build Coastguard Worker         }
808*38e8c45fSAndroid Build Coastguard Worker         if (touchedWindow.windowHandle->getInfo()->supportsSplitTouch()) {
809*38e8c45fSAndroid Build Coastguard Worker             continue;
810*38e8c45fSAndroid Build Coastguard Worker         }
811*38e8c45fSAndroid Build Coastguard Worker         if (touchedWindow.windowHandle->getInfo()->inputConfig.test(
812*38e8c45fSAndroid Build Coastguard Worker                     gui::WindowInfo::InputConfig::IS_WALLPAPER)) {
813*38e8c45fSAndroid Build Coastguard Worker             // Wallpaper window should not affect whether or not touch is split
814*38e8c45fSAndroid Build Coastguard Worker             continue;
815*38e8c45fSAndroid Build Coastguard Worker         }
816*38e8c45fSAndroid Build Coastguard Worker 
817*38e8c45fSAndroid Build Coastguard Worker         if (touchedWindow.hasTouchingPointers(entry.deviceId)) {
818*38e8c45fSAndroid Build Coastguard Worker             return false;
819*38e8c45fSAndroid Build Coastguard Worker         }
820*38e8c45fSAndroid Build Coastguard Worker     }
821*38e8c45fSAndroid Build Coastguard Worker     return true;
822*38e8c45fSAndroid Build Coastguard Worker }
823*38e8c45fSAndroid Build Coastguard Worker 
824*38e8c45fSAndroid Build Coastguard Worker /**
825*38e8c45fSAndroid Build Coastguard Worker  * Return true if stylus is currently down anywhere on the specified display, and false otherwise.
826*38e8c45fSAndroid Build Coastguard Worker  */
isStylusActiveInDisplay(ui::LogicalDisplayId displayId,const std::unordered_map<ui::LogicalDisplayId,TouchState> & touchStatesByDisplay)827*38e8c45fSAndroid Build Coastguard Worker bool isStylusActiveInDisplay(ui::LogicalDisplayId displayId,
828*38e8c45fSAndroid Build Coastguard Worker                              const std::unordered_map<ui::LogicalDisplayId /*displayId*/,
829*38e8c45fSAndroid Build Coastguard Worker                                                       TouchState>& touchStatesByDisplay) {
830*38e8c45fSAndroid Build Coastguard Worker     const auto it = touchStatesByDisplay.find(displayId);
831*38e8c45fSAndroid Build Coastguard Worker     if (it == touchStatesByDisplay.end()) {
832*38e8c45fSAndroid Build Coastguard Worker         return false;
833*38e8c45fSAndroid Build Coastguard Worker     }
834*38e8c45fSAndroid Build Coastguard Worker     const TouchState& state = it->second;
835*38e8c45fSAndroid Build Coastguard Worker     return state.hasActiveStylus();
836*38e8c45fSAndroid Build Coastguard Worker }
837*38e8c45fSAndroid Build Coastguard Worker 
validateWindowInfosUpdate(const gui::WindowInfosUpdate & update)838*38e8c45fSAndroid Build Coastguard Worker Result<void> validateWindowInfosUpdate(const gui::WindowInfosUpdate& update) {
839*38e8c45fSAndroid Build Coastguard Worker     std::unordered_set<int32_t> windowIds;
840*38e8c45fSAndroid Build Coastguard Worker     for (const WindowInfo& info : update.windowInfos) {
841*38e8c45fSAndroid Build Coastguard Worker         const auto [_, inserted] = windowIds.insert(info.id);
842*38e8c45fSAndroid Build Coastguard Worker         if (!inserted) {
843*38e8c45fSAndroid Build Coastguard Worker             return Error() << "Duplicate entry for " << info;
844*38e8c45fSAndroid Build Coastguard Worker         }
845*38e8c45fSAndroid Build Coastguard Worker     }
846*38e8c45fSAndroid Build Coastguard Worker     return {};
847*38e8c45fSAndroid Build Coastguard Worker }
848*38e8c45fSAndroid Build Coastguard Worker 
getUserActivityEventType(const EventEntry & eventEntry)849*38e8c45fSAndroid Build Coastguard Worker int32_t getUserActivityEventType(const EventEntry& eventEntry) {
850*38e8c45fSAndroid Build Coastguard Worker     switch (eventEntry.type) {
851*38e8c45fSAndroid Build Coastguard Worker         case EventEntry::Type::KEY: {
852*38e8c45fSAndroid Build Coastguard Worker             return USER_ACTIVITY_EVENT_BUTTON;
853*38e8c45fSAndroid Build Coastguard Worker         }
854*38e8c45fSAndroid Build Coastguard Worker         case EventEntry::Type::MOTION: {
855*38e8c45fSAndroid Build Coastguard Worker             const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
856*38e8c45fSAndroid Build Coastguard Worker             if (MotionEvent::isTouchEvent(motionEntry.source, motionEntry.action)) {
857*38e8c45fSAndroid Build Coastguard Worker                 return USER_ACTIVITY_EVENT_TOUCH;
858*38e8c45fSAndroid Build Coastguard Worker             }
859*38e8c45fSAndroid Build Coastguard Worker             return USER_ACTIVITY_EVENT_OTHER;
860*38e8c45fSAndroid Build Coastguard Worker         }
861*38e8c45fSAndroid Build Coastguard Worker         default: {
862*38e8c45fSAndroid Build Coastguard Worker             LOG_ALWAYS_FATAL("%s events are not user activity",
863*38e8c45fSAndroid Build Coastguard Worker                              ftl::enum_string(eventEntry.type).c_str());
864*38e8c45fSAndroid Build Coastguard Worker         }
865*38e8c45fSAndroid Build Coastguard Worker     }
866*38e8c45fSAndroid Build Coastguard Worker }
867*38e8c45fSAndroid Build Coastguard Worker 
expandCancellationMode(CancelationOptions::Mode mode)868*38e8c45fSAndroid Build Coastguard Worker std::pair<bool /*cancelPointers*/, bool /*cancelNonPointers*/> expandCancellationMode(
869*38e8c45fSAndroid Build Coastguard Worker         CancelationOptions::Mode mode) {
870*38e8c45fSAndroid Build Coastguard Worker     switch (mode) {
871*38e8c45fSAndroid Build Coastguard Worker         case CancelationOptions::Mode::CANCEL_ALL_EVENTS:
872*38e8c45fSAndroid Build Coastguard Worker             return {true, true};
873*38e8c45fSAndroid Build Coastguard Worker         case CancelationOptions::Mode::CANCEL_POINTER_EVENTS:
874*38e8c45fSAndroid Build Coastguard Worker             return {true, false};
875*38e8c45fSAndroid Build Coastguard Worker         case CancelationOptions::Mode::CANCEL_NON_POINTER_EVENTS:
876*38e8c45fSAndroid Build Coastguard Worker             return {false, true};
877*38e8c45fSAndroid Build Coastguard Worker         case CancelationOptions::Mode::CANCEL_FALLBACK_EVENTS:
878*38e8c45fSAndroid Build Coastguard Worker             return {false, true};
879*38e8c45fSAndroid Build Coastguard Worker         case CancelationOptions::Mode::CANCEL_HOVER_EVENTS:
880*38e8c45fSAndroid Build Coastguard Worker             return {true, false};
881*38e8c45fSAndroid Build Coastguard Worker     }
882*38e8c45fSAndroid Build Coastguard Worker }
883*38e8c45fSAndroid Build Coastguard Worker 
884*38e8c45fSAndroid Build Coastguard Worker class ScopedSyntheticEventTracer {
885*38e8c45fSAndroid Build Coastguard Worker public:
ScopedSyntheticEventTracer(std::unique_ptr<trace::InputTracerInterface> & tracer)886*38e8c45fSAndroid Build Coastguard Worker     ScopedSyntheticEventTracer(std::unique_ptr<trace::InputTracerInterface>& tracer)
887*38e8c45fSAndroid Build Coastguard Worker           : mTracer(tracer), mProcessingTimestamp(now()) {
888*38e8c45fSAndroid Build Coastguard Worker         if (mTracer) {
889*38e8c45fSAndroid Build Coastguard Worker             mEventTracker = mTracer->createTrackerForSyntheticEvent();
890*38e8c45fSAndroid Build Coastguard Worker         }
891*38e8c45fSAndroid Build Coastguard Worker     }
892*38e8c45fSAndroid Build Coastguard Worker 
~ScopedSyntheticEventTracer()893*38e8c45fSAndroid Build Coastguard Worker     ~ScopedSyntheticEventTracer() {
894*38e8c45fSAndroid Build Coastguard Worker         if (mTracer) {
895*38e8c45fSAndroid Build Coastguard Worker             mTracer->eventProcessingComplete(*mEventTracker, mProcessingTimestamp);
896*38e8c45fSAndroid Build Coastguard Worker         }
897*38e8c45fSAndroid Build Coastguard Worker     }
898*38e8c45fSAndroid Build Coastguard Worker 
getTracker() const899*38e8c45fSAndroid Build Coastguard Worker     const std::unique_ptr<trace::EventTrackerInterface>& getTracker() const {
900*38e8c45fSAndroid Build Coastguard Worker         return mEventTracker;
901*38e8c45fSAndroid Build Coastguard Worker     }
902*38e8c45fSAndroid Build Coastguard Worker 
903*38e8c45fSAndroid Build Coastguard Worker private:
904*38e8c45fSAndroid Build Coastguard Worker     const std::unique_ptr<trace::InputTracerInterface>& mTracer;
905*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<trace::EventTrackerInterface> mEventTracker;
906*38e8c45fSAndroid Build Coastguard Worker     const nsecs_t mProcessingTimestamp;
907*38e8c45fSAndroid Build Coastguard Worker };
908*38e8c45fSAndroid Build Coastguard Worker 
909*38e8c45fSAndroid Build Coastguard Worker /**
910*38e8c45fSAndroid Build Coastguard Worker  * This is needed to help use "InputEventInjectionResult" with base::Result.
911*38e8c45fSAndroid Build Coastguard Worker  */
912*38e8c45fSAndroid Build Coastguard Worker template <typename T>
913*38e8c45fSAndroid Build Coastguard Worker struct EnumErrorWrapper {
914*38e8c45fSAndroid Build Coastguard Worker     T mVal;
EnumErrorWrapperandroid::inputdispatcher::__anond529f6320111::EnumErrorWrapper915*38e8c45fSAndroid Build Coastguard Worker     EnumErrorWrapper(T&& e) : mVal(std::forward<T>(e)) {}
operator const T&android::inputdispatcher::__anond529f6320111::EnumErrorWrapper916*38e8c45fSAndroid Build Coastguard Worker     operator const T&() const { return mVal; }
valueandroid::inputdispatcher::__anond529f6320111::EnumErrorWrapper917*38e8c45fSAndroid Build Coastguard Worker     T value() const { return mVal; }
printandroid::inputdispatcher::__anond529f6320111::EnumErrorWrapper918*38e8c45fSAndroid Build Coastguard Worker     std::string print() const { return ftl::enum_string(mVal); }
919*38e8c45fSAndroid Build Coastguard Worker };
920*38e8c45fSAndroid Build Coastguard Worker 
injectionError(InputEventInjectionResult && e)921*38e8c45fSAndroid Build Coastguard Worker Error<EnumErrorWrapper<InputEventInjectionResult>> injectionError(InputEventInjectionResult&& e) {
922*38e8c45fSAndroid Build Coastguard Worker     LOG_ALWAYS_FATAL_IF(e == InputEventInjectionResult::SUCCEEDED);
923*38e8c45fSAndroid Build Coastguard Worker     return Error<EnumErrorWrapper<InputEventInjectionResult>>(
924*38e8c45fSAndroid Build Coastguard Worker             std::forward<InputEventInjectionResult>(e));
925*38e8c45fSAndroid Build Coastguard Worker }
926*38e8c45fSAndroid Build Coastguard Worker 
927*38e8c45fSAndroid Build Coastguard Worker } // namespace
928*38e8c45fSAndroid Build Coastguard Worker 
929*38e8c45fSAndroid Build Coastguard Worker // --- InputDispatcher ---
930*38e8c45fSAndroid Build Coastguard Worker 
InputDispatcher(InputDispatcherPolicyInterface & policy)931*38e8c45fSAndroid Build Coastguard Worker InputDispatcher::InputDispatcher(InputDispatcherPolicyInterface& policy)
932*38e8c45fSAndroid Build Coastguard Worker       : InputDispatcher(policy, createInputTracingBackendIfEnabled()) {}
933*38e8c45fSAndroid Build Coastguard Worker 
InputDispatcher(InputDispatcherPolicyInterface & policy,std::unique_ptr<trace::InputTracingBackendInterface> traceBackend)934*38e8c45fSAndroid Build Coastguard Worker InputDispatcher::InputDispatcher(InputDispatcherPolicyInterface& policy,
935*38e8c45fSAndroid Build Coastguard Worker                                  std::unique_ptr<trace::InputTracingBackendInterface> traceBackend)
936*38e8c45fSAndroid Build Coastguard Worker       : mPolicy(policy),
937*38e8c45fSAndroid Build Coastguard Worker         mPendingEvent(nullptr),
938*38e8c45fSAndroid Build Coastguard Worker         mLastDropReason(DropReason::NOT_DROPPED),
939*38e8c45fSAndroid Build Coastguard Worker         mIdGenerator(IdGenerator::Source::INPUT_DISPATCHER),
940*38e8c45fSAndroid Build Coastguard Worker         mMinTimeBetweenUserActivityPokes(DEFAULT_USER_ACTIVITY_POKE_INTERVAL),
941*38e8c45fSAndroid Build Coastguard Worker         mNextUnblockedEvent(nullptr),
942*38e8c45fSAndroid Build Coastguard Worker         mMonitorDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT),
943*38e8c45fSAndroid Build Coastguard Worker         mDispatchEnabled(false),
944*38e8c45fSAndroid Build Coastguard Worker         mDispatchFrozen(false),
945*38e8c45fSAndroid Build Coastguard Worker         mInputFilterEnabled(false),
946*38e8c45fSAndroid Build Coastguard Worker         mMaximumObscuringOpacityForTouch(1.0f),
947*38e8c45fSAndroid Build Coastguard Worker         mFocusedDisplayId(ui::LogicalDisplayId::DEFAULT),
948*38e8c45fSAndroid Build Coastguard Worker         mWindowTokenWithPointerCapture(nullptr),
949*38e8c45fSAndroid Build Coastguard Worker         mAwaitedApplicationDisplayId(ui::LogicalDisplayId::INVALID),
950*38e8c45fSAndroid Build Coastguard Worker         mInputEventTimelineProcessor(
951*38e8c45fSAndroid Build Coastguard Worker                 input_flags::enable_per_device_input_latency_metrics()
952*38e8c45fSAndroid Build Coastguard Worker                         ? std::move(std::unique_ptr<InputEventTimelineProcessor>(
953*38e8c45fSAndroid Build Coastguard Worker                                   new LatencyAggregatorWithHistograms()))
954*38e8c45fSAndroid Build Coastguard Worker                         : std::move(std::unique_ptr<InputEventTimelineProcessor>(
955*38e8c45fSAndroid Build Coastguard Worker                                   new LatencyAggregator()))),
956*38e8c45fSAndroid Build Coastguard Worker         mLatencyTracker(*mInputEventTimelineProcessor) {
957*38e8c45fSAndroid Build Coastguard Worker     mLooper = sp<Looper>::make(false);
958*38e8c45fSAndroid Build Coastguard Worker     mReporter = createInputReporter();
959*38e8c45fSAndroid Build Coastguard Worker 
960*38e8c45fSAndroid Build Coastguard Worker     mWindowInfoListener = sp<DispatcherWindowListener>::make(*this);
961*38e8c45fSAndroid Build Coastguard Worker #if defined(__ANDROID__)
962*38e8c45fSAndroid Build Coastguard Worker     SurfaceComposerClient::getDefault()->addWindowInfosListener(mWindowInfoListener);
963*38e8c45fSAndroid Build Coastguard Worker #endif
964*38e8c45fSAndroid Build Coastguard Worker     mKeyRepeatState.lastKeyEntry = nullptr;
965*38e8c45fSAndroid Build Coastguard Worker 
966*38e8c45fSAndroid Build Coastguard Worker     if (traceBackend) {
967*38e8c45fSAndroid Build Coastguard Worker         mTracer = std::make_unique<trace::impl::InputTracer>(std::move(traceBackend));
968*38e8c45fSAndroid Build Coastguard Worker     }
969*38e8c45fSAndroid Build Coastguard Worker 
970*38e8c45fSAndroid Build Coastguard Worker     mLastUserActivityTimes.fill(0);
971*38e8c45fSAndroid Build Coastguard Worker }
972*38e8c45fSAndroid Build Coastguard Worker 
~InputDispatcher()973*38e8c45fSAndroid Build Coastguard Worker InputDispatcher::~InputDispatcher() {
974*38e8c45fSAndroid Build Coastguard Worker     std::scoped_lock _l(mLock);
975*38e8c45fSAndroid Build Coastguard Worker 
976*38e8c45fSAndroid Build Coastguard Worker     resetKeyRepeatLocked();
977*38e8c45fSAndroid Build Coastguard Worker     releasePendingEventLocked();
978*38e8c45fSAndroid Build Coastguard Worker     drainInboundQueueLocked();
979*38e8c45fSAndroid Build Coastguard Worker     mCommandQueue.clear();
980*38e8c45fSAndroid Build Coastguard Worker 
981*38e8c45fSAndroid Build Coastguard Worker     while (!mConnectionsByToken.empty()) {
982*38e8c45fSAndroid Build Coastguard Worker         std::shared_ptr<Connection> connection = mConnectionsByToken.begin()->second;
983*38e8c45fSAndroid Build Coastguard Worker         removeInputChannelLocked(connection->getToken(), /*notify=*/false);
984*38e8c45fSAndroid Build Coastguard Worker     }
985*38e8c45fSAndroid Build Coastguard Worker }
986*38e8c45fSAndroid Build Coastguard Worker 
start()987*38e8c45fSAndroid Build Coastguard Worker status_t InputDispatcher::start() {
988*38e8c45fSAndroid Build Coastguard Worker     if (mThread) {
989*38e8c45fSAndroid Build Coastguard Worker         return ALREADY_EXISTS;
990*38e8c45fSAndroid Build Coastguard Worker     }
991*38e8c45fSAndroid Build Coastguard Worker     mThread = std::make_unique<InputThread>(
992*38e8c45fSAndroid Build Coastguard Worker             "InputDispatcher", [this]() { dispatchOnce(); }, [this]() { mLooper->wake(); },
993*38e8c45fSAndroid Build Coastguard Worker             /*isInCriticalPath=*/true);
994*38e8c45fSAndroid Build Coastguard Worker     return OK;
995*38e8c45fSAndroid Build Coastguard Worker }
996*38e8c45fSAndroid Build Coastguard Worker 
stop()997*38e8c45fSAndroid Build Coastguard Worker status_t InputDispatcher::stop() {
998*38e8c45fSAndroid Build Coastguard Worker     if (mThread && mThread->isCallingThread()) {
999*38e8c45fSAndroid Build Coastguard Worker         ALOGE("InputDispatcher cannot be stopped from its own thread!");
1000*38e8c45fSAndroid Build Coastguard Worker         return INVALID_OPERATION;
1001*38e8c45fSAndroid Build Coastguard Worker     }
1002*38e8c45fSAndroid Build Coastguard Worker     mThread.reset();
1003*38e8c45fSAndroid Build Coastguard Worker     return OK;
1004*38e8c45fSAndroid Build Coastguard Worker }
1005*38e8c45fSAndroid Build Coastguard Worker 
dispatchOnce()1006*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::dispatchOnce() {
1007*38e8c45fSAndroid Build Coastguard Worker     nsecs_t nextWakeupTime = LLONG_MAX;
1008*38e8c45fSAndroid Build Coastguard Worker     { // acquire lock
1009*38e8c45fSAndroid Build Coastguard Worker         std::scoped_lock _l(mLock);
1010*38e8c45fSAndroid Build Coastguard Worker         mDispatcherIsAlive.notify_all();
1011*38e8c45fSAndroid Build Coastguard Worker 
1012*38e8c45fSAndroid Build Coastguard Worker         // Run a dispatch loop if there are no pending commands.
1013*38e8c45fSAndroid Build Coastguard Worker         // The dispatch loop might enqueue commands to run afterwards.
1014*38e8c45fSAndroid Build Coastguard Worker         if (!haveCommandsLocked()) {
1015*38e8c45fSAndroid Build Coastguard Worker             dispatchOnceInnerLocked(/*byref*/ nextWakeupTime);
1016*38e8c45fSAndroid Build Coastguard Worker         }
1017*38e8c45fSAndroid Build Coastguard Worker 
1018*38e8c45fSAndroid Build Coastguard Worker         // Run all pending commands if there are any.
1019*38e8c45fSAndroid Build Coastguard Worker         // If any commands were run then force the next poll to wake up immediately.
1020*38e8c45fSAndroid Build Coastguard Worker         if (runCommandsLockedInterruptable()) {
1021*38e8c45fSAndroid Build Coastguard Worker             nextWakeupTime = LLONG_MIN;
1022*38e8c45fSAndroid Build Coastguard Worker         }
1023*38e8c45fSAndroid Build Coastguard Worker 
1024*38e8c45fSAndroid Build Coastguard Worker         // If we are still waiting for ack on some events,
1025*38e8c45fSAndroid Build Coastguard Worker         // we might have to wake up earlier to check if an app is anr'ing.
1026*38e8c45fSAndroid Build Coastguard Worker         const nsecs_t nextAnrCheck = processAnrsLocked();
1027*38e8c45fSAndroid Build Coastguard Worker         nextWakeupTime = std::min(nextWakeupTime, nextAnrCheck);
1028*38e8c45fSAndroid Build Coastguard Worker 
1029*38e8c45fSAndroid Build Coastguard Worker         if (mPerDeviceInputLatencyMetricsFlag) {
1030*38e8c45fSAndroid Build Coastguard Worker             processLatencyStatisticsLocked();
1031*38e8c45fSAndroid Build Coastguard Worker         }
1032*38e8c45fSAndroid Build Coastguard Worker 
1033*38e8c45fSAndroid Build Coastguard Worker         // We are about to enter an infinitely long sleep, because we have no commands or
1034*38e8c45fSAndroid Build Coastguard Worker         // pending or queued events
1035*38e8c45fSAndroid Build Coastguard Worker         if (nextWakeupTime == LLONG_MAX) {
1036*38e8c45fSAndroid Build Coastguard Worker             mDispatcherEnteredIdle.notify_all();
1037*38e8c45fSAndroid Build Coastguard Worker         }
1038*38e8c45fSAndroid Build Coastguard Worker     } // release lock
1039*38e8c45fSAndroid Build Coastguard Worker 
1040*38e8c45fSAndroid Build Coastguard Worker     // Wait for callback or timeout or wake.  (make sure we round up, not down)
1041*38e8c45fSAndroid Build Coastguard Worker     nsecs_t currentTime = now();
1042*38e8c45fSAndroid Build Coastguard Worker     int timeoutMillis = toMillisecondTimeoutDelay(currentTime, nextWakeupTime);
1043*38e8c45fSAndroid Build Coastguard Worker     mLooper->pollOnce(timeoutMillis);
1044*38e8c45fSAndroid Build Coastguard Worker }
1045*38e8c45fSAndroid Build Coastguard Worker 
1046*38e8c45fSAndroid Build Coastguard Worker /**
1047*38e8c45fSAndroid Build Coastguard Worker  * Raise ANR if there is no focused window.
1048*38e8c45fSAndroid Build Coastguard Worker  * Before the ANR is raised, do a final state check:
1049*38e8c45fSAndroid Build Coastguard Worker  * 1. The currently focused application must be the same one we are waiting for.
1050*38e8c45fSAndroid Build Coastguard Worker  * 2. Ensure we still don't have a focused window.
1051*38e8c45fSAndroid Build Coastguard Worker  */
processNoFocusedWindowAnrLocked()1052*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::processNoFocusedWindowAnrLocked() {
1053*38e8c45fSAndroid Build Coastguard Worker     // Check if the application that we are waiting for is still focused.
1054*38e8c45fSAndroid Build Coastguard Worker     std::shared_ptr<InputApplicationHandle> focusedApplication =
1055*38e8c45fSAndroid Build Coastguard Worker             getValueByKey(mFocusedApplicationHandlesByDisplay, mAwaitedApplicationDisplayId);
1056*38e8c45fSAndroid Build Coastguard Worker     if (focusedApplication == nullptr ||
1057*38e8c45fSAndroid Build Coastguard Worker         focusedApplication->getApplicationToken() !=
1058*38e8c45fSAndroid Build Coastguard Worker                 mAwaitedFocusedApplication->getApplicationToken()) {
1059*38e8c45fSAndroid Build Coastguard Worker         // Unexpected because we should have reset the ANR timer when focused application changed
1060*38e8c45fSAndroid Build Coastguard Worker         ALOGE("Waited for a focused window, but focused application has already changed to %s",
1061*38e8c45fSAndroid Build Coastguard Worker               focusedApplication->getName().c_str());
1062*38e8c45fSAndroid Build Coastguard Worker         return; // The focused application has changed.
1063*38e8c45fSAndroid Build Coastguard Worker     }
1064*38e8c45fSAndroid Build Coastguard Worker 
1065*38e8c45fSAndroid Build Coastguard Worker     const sp<WindowInfoHandle>& focusedWindowHandle =
1066*38e8c45fSAndroid Build Coastguard Worker             getFocusedWindowHandleLocked(mAwaitedApplicationDisplayId);
1067*38e8c45fSAndroid Build Coastguard Worker     if (focusedWindowHandle != nullptr) {
1068*38e8c45fSAndroid Build Coastguard Worker         return; // We now have a focused window. No need for ANR.
1069*38e8c45fSAndroid Build Coastguard Worker     }
1070*38e8c45fSAndroid Build Coastguard Worker     onAnrLocked(mAwaitedFocusedApplication);
1071*38e8c45fSAndroid Build Coastguard Worker }
1072*38e8c45fSAndroid Build Coastguard Worker 
1073*38e8c45fSAndroid Build Coastguard Worker /**
1074*38e8c45fSAndroid Build Coastguard Worker  * Check if any of the connections' wait queues have events that are too old.
1075*38e8c45fSAndroid Build Coastguard Worker  * If we waited for events to be ack'ed for more than the window timeout, raise an ANR.
1076*38e8c45fSAndroid Build Coastguard Worker  * Return the time at which we should wake up next.
1077*38e8c45fSAndroid Build Coastguard Worker  */
processAnrsLocked()1078*38e8c45fSAndroid Build Coastguard Worker nsecs_t InputDispatcher::processAnrsLocked() {
1079*38e8c45fSAndroid Build Coastguard Worker     const nsecs_t currentTime = now();
1080*38e8c45fSAndroid Build Coastguard Worker     nsecs_t nextAnrCheck = LLONG_MAX;
1081*38e8c45fSAndroid Build Coastguard Worker     // Check if we are waiting for a focused window to appear. Raise ANR if waited too long
1082*38e8c45fSAndroid Build Coastguard Worker     if (mNoFocusedWindowTimeoutTime.has_value() && mAwaitedFocusedApplication != nullptr) {
1083*38e8c45fSAndroid Build Coastguard Worker         if (currentTime >= *mNoFocusedWindowTimeoutTime) {
1084*38e8c45fSAndroid Build Coastguard Worker             processNoFocusedWindowAnrLocked();
1085*38e8c45fSAndroid Build Coastguard Worker             mAwaitedFocusedApplication.reset();
1086*38e8c45fSAndroid Build Coastguard Worker             mNoFocusedWindowTimeoutTime = std::nullopt;
1087*38e8c45fSAndroid Build Coastguard Worker             return LLONG_MIN;
1088*38e8c45fSAndroid Build Coastguard Worker         } else {
1089*38e8c45fSAndroid Build Coastguard Worker             // Keep waiting. We will drop the event when mNoFocusedWindowTimeoutTime comes.
1090*38e8c45fSAndroid Build Coastguard Worker             nextAnrCheck = *mNoFocusedWindowTimeoutTime;
1091*38e8c45fSAndroid Build Coastguard Worker         }
1092*38e8c45fSAndroid Build Coastguard Worker     }
1093*38e8c45fSAndroid Build Coastguard Worker 
1094*38e8c45fSAndroid Build Coastguard Worker     // Check if any connection ANRs are due
1095*38e8c45fSAndroid Build Coastguard Worker     nextAnrCheck = std::min(nextAnrCheck, mAnrTracker.firstTimeout());
1096*38e8c45fSAndroid Build Coastguard Worker     if (currentTime < nextAnrCheck) { // most likely scenario
1097*38e8c45fSAndroid Build Coastguard Worker         return nextAnrCheck;          // everything is normal. Let's check again at nextAnrCheck
1098*38e8c45fSAndroid Build Coastguard Worker     }
1099*38e8c45fSAndroid Build Coastguard Worker 
1100*38e8c45fSAndroid Build Coastguard Worker     // If we reached here, we have an unresponsive connection.
1101*38e8c45fSAndroid Build Coastguard Worker     std::shared_ptr<Connection> connection = getConnectionLocked(mAnrTracker.firstToken());
1102*38e8c45fSAndroid Build Coastguard Worker     if (connection == nullptr) {
1103*38e8c45fSAndroid Build Coastguard Worker         ALOGE("Could not find connection for entry %" PRId64, mAnrTracker.firstTimeout());
1104*38e8c45fSAndroid Build Coastguard Worker         return nextAnrCheck;
1105*38e8c45fSAndroid Build Coastguard Worker     }
1106*38e8c45fSAndroid Build Coastguard Worker     connection->responsive = false;
1107*38e8c45fSAndroid Build Coastguard Worker     // Stop waking up for this unresponsive connection
1108*38e8c45fSAndroid Build Coastguard Worker     mAnrTracker.eraseToken(connection->getToken());
1109*38e8c45fSAndroid Build Coastguard Worker     onAnrLocked(connection);
1110*38e8c45fSAndroid Build Coastguard Worker     return LLONG_MIN;
1111*38e8c45fSAndroid Build Coastguard Worker }
1112*38e8c45fSAndroid Build Coastguard Worker 
1113*38e8c45fSAndroid Build Coastguard Worker /**
1114*38e8c45fSAndroid Build Coastguard Worker  * Check if enough time has passed since the last latency statistics push.
1115*38e8c45fSAndroid Build Coastguard Worker  */
processLatencyStatisticsLocked()1116*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::processLatencyStatisticsLocked() {
1117*38e8c45fSAndroid Build Coastguard Worker     const nsecs_t currentTime = now();
1118*38e8c45fSAndroid Build Coastguard Worker     // Log the atom recording latency statistics if more than 6 hours passed from the last
1119*38e8c45fSAndroid Build Coastguard Worker     // push
1120*38e8c45fSAndroid Build Coastguard Worker     if (currentTime - mLastStatisticPushTime >= LATENCY_STATISTICS_PUSH_INTERVAL) {
1121*38e8c45fSAndroid Build Coastguard Worker         mInputEventTimelineProcessor->pushLatencyStatistics();
1122*38e8c45fSAndroid Build Coastguard Worker         mLastStatisticPushTime = currentTime;
1123*38e8c45fSAndroid Build Coastguard Worker     }
1124*38e8c45fSAndroid Build Coastguard Worker }
1125*38e8c45fSAndroid Build Coastguard Worker 
getDispatchingTimeoutLocked(const std::shared_ptr<Connection> & connection)1126*38e8c45fSAndroid Build Coastguard Worker std::chrono::nanoseconds InputDispatcher::getDispatchingTimeoutLocked(
1127*38e8c45fSAndroid Build Coastguard Worker         const std::shared_ptr<Connection>& connection) {
1128*38e8c45fSAndroid Build Coastguard Worker     if (connection->monitor) {
1129*38e8c45fSAndroid Build Coastguard Worker         return mMonitorDispatchingTimeout;
1130*38e8c45fSAndroid Build Coastguard Worker     }
1131*38e8c45fSAndroid Build Coastguard Worker     const sp<WindowInfoHandle> window = getWindowHandleLocked(connection->getToken());
1132*38e8c45fSAndroid Build Coastguard Worker     if (window != nullptr) {
1133*38e8c45fSAndroid Build Coastguard Worker         return window->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
1134*38e8c45fSAndroid Build Coastguard Worker     }
1135*38e8c45fSAndroid Build Coastguard Worker     return DEFAULT_INPUT_DISPATCHING_TIMEOUT;
1136*38e8c45fSAndroid Build Coastguard Worker }
1137*38e8c45fSAndroid Build Coastguard Worker 
dispatchOnceInnerLocked(nsecs_t & nextWakeupTime)1138*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::dispatchOnceInnerLocked(nsecs_t& nextWakeupTime) {
1139*38e8c45fSAndroid Build Coastguard Worker     nsecs_t currentTime = now();
1140*38e8c45fSAndroid Build Coastguard Worker 
1141*38e8c45fSAndroid Build Coastguard Worker     // Reset the key repeat timer whenever normal dispatch is suspended while the
1142*38e8c45fSAndroid Build Coastguard Worker     // device is in a non-interactive state.  This is to ensure that we abort a key
1143*38e8c45fSAndroid Build Coastguard Worker     // repeat if the device is just coming out of sleep.
1144*38e8c45fSAndroid Build Coastguard Worker     if (!mDispatchEnabled) {
1145*38e8c45fSAndroid Build Coastguard Worker         resetKeyRepeatLocked();
1146*38e8c45fSAndroid Build Coastguard Worker     }
1147*38e8c45fSAndroid Build Coastguard Worker 
1148*38e8c45fSAndroid Build Coastguard Worker     // If dispatching is frozen, do not process timeouts or try to deliver any new events.
1149*38e8c45fSAndroid Build Coastguard Worker     if (mDispatchFrozen) {
1150*38e8c45fSAndroid Build Coastguard Worker         if (DEBUG_FOCUS) {
1151*38e8c45fSAndroid Build Coastguard Worker             ALOGD("Dispatch frozen.  Waiting some more.");
1152*38e8c45fSAndroid Build Coastguard Worker         }
1153*38e8c45fSAndroid Build Coastguard Worker         return;
1154*38e8c45fSAndroid Build Coastguard Worker     }
1155*38e8c45fSAndroid Build Coastguard Worker 
1156*38e8c45fSAndroid Build Coastguard Worker     // Ready to start a new event.
1157*38e8c45fSAndroid Build Coastguard Worker     // If we don't already have a pending event, go grab one.
1158*38e8c45fSAndroid Build Coastguard Worker     if (!mPendingEvent) {
1159*38e8c45fSAndroid Build Coastguard Worker         if (mInboundQueue.empty()) {
1160*38e8c45fSAndroid Build Coastguard Worker             // Synthesize a key repeat if appropriate.
1161*38e8c45fSAndroid Build Coastguard Worker             if (mKeyRepeatState.lastKeyEntry) {
1162*38e8c45fSAndroid Build Coastguard Worker                 if (currentTime >= mKeyRepeatState.nextRepeatTime) {
1163*38e8c45fSAndroid Build Coastguard Worker                     mPendingEvent = synthesizeKeyRepeatLocked(currentTime);
1164*38e8c45fSAndroid Build Coastguard Worker                 } else {
1165*38e8c45fSAndroid Build Coastguard Worker                     nextWakeupTime = std::min(nextWakeupTime, mKeyRepeatState.nextRepeatTime);
1166*38e8c45fSAndroid Build Coastguard Worker                 }
1167*38e8c45fSAndroid Build Coastguard Worker             }
1168*38e8c45fSAndroid Build Coastguard Worker 
1169*38e8c45fSAndroid Build Coastguard Worker             // Nothing to do if there is no pending event.
1170*38e8c45fSAndroid Build Coastguard Worker             if (!mPendingEvent) {
1171*38e8c45fSAndroid Build Coastguard Worker                 return;
1172*38e8c45fSAndroid Build Coastguard Worker             }
1173*38e8c45fSAndroid Build Coastguard Worker         } else {
1174*38e8c45fSAndroid Build Coastguard Worker             // Inbound queue has at least one entry.
1175*38e8c45fSAndroid Build Coastguard Worker             mPendingEvent = mInboundQueue.front();
1176*38e8c45fSAndroid Build Coastguard Worker             mInboundQueue.pop_front();
1177*38e8c45fSAndroid Build Coastguard Worker             traceInboundQueueLengthLocked();
1178*38e8c45fSAndroid Build Coastguard Worker         }
1179*38e8c45fSAndroid Build Coastguard Worker 
1180*38e8c45fSAndroid Build Coastguard Worker         // Poke user activity for this event.
1181*38e8c45fSAndroid Build Coastguard Worker         if (mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER) {
1182*38e8c45fSAndroid Build Coastguard Worker             pokeUserActivityLocked(*mPendingEvent);
1183*38e8c45fSAndroid Build Coastguard Worker         }
1184*38e8c45fSAndroid Build Coastguard Worker     }
1185*38e8c45fSAndroid Build Coastguard Worker 
1186*38e8c45fSAndroid Build Coastguard Worker     // Now we have an event to dispatch.
1187*38e8c45fSAndroid Build Coastguard Worker     // All events are eventually dequeued and processed this way, even if we intend to drop them.
1188*38e8c45fSAndroid Build Coastguard Worker     ALOG_ASSERT(mPendingEvent != nullptr);
1189*38e8c45fSAndroid Build Coastguard Worker     bool done = false;
1190*38e8c45fSAndroid Build Coastguard Worker     DropReason dropReason = DropReason::NOT_DROPPED;
1191*38e8c45fSAndroid Build Coastguard Worker     if (!(mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER)) {
1192*38e8c45fSAndroid Build Coastguard Worker         dropReason = DropReason::POLICY;
1193*38e8c45fSAndroid Build Coastguard Worker     } else if (!mDispatchEnabled) {
1194*38e8c45fSAndroid Build Coastguard Worker         dropReason = DropReason::DISABLED;
1195*38e8c45fSAndroid Build Coastguard Worker     }
1196*38e8c45fSAndroid Build Coastguard Worker 
1197*38e8c45fSAndroid Build Coastguard Worker     if (mNextUnblockedEvent == mPendingEvent) {
1198*38e8c45fSAndroid Build Coastguard Worker         mNextUnblockedEvent = nullptr;
1199*38e8c45fSAndroid Build Coastguard Worker     }
1200*38e8c45fSAndroid Build Coastguard Worker 
1201*38e8c45fSAndroid Build Coastguard Worker     switch (mPendingEvent->type) {
1202*38e8c45fSAndroid Build Coastguard Worker         case EventEntry::Type::DEVICE_RESET: {
1203*38e8c45fSAndroid Build Coastguard Worker             const DeviceResetEntry& typedEntry =
1204*38e8c45fSAndroid Build Coastguard Worker                     static_cast<const DeviceResetEntry&>(*mPendingEvent);
1205*38e8c45fSAndroid Build Coastguard Worker             done = dispatchDeviceResetLocked(currentTime, typedEntry);
1206*38e8c45fSAndroid Build Coastguard Worker             dropReason = DropReason::NOT_DROPPED; // device resets are never dropped
1207*38e8c45fSAndroid Build Coastguard Worker             break;
1208*38e8c45fSAndroid Build Coastguard Worker         }
1209*38e8c45fSAndroid Build Coastguard Worker 
1210*38e8c45fSAndroid Build Coastguard Worker         case EventEntry::Type::FOCUS: {
1211*38e8c45fSAndroid Build Coastguard Worker             std::shared_ptr<const FocusEntry> typedEntry =
1212*38e8c45fSAndroid Build Coastguard Worker                     std::static_pointer_cast<const FocusEntry>(mPendingEvent);
1213*38e8c45fSAndroid Build Coastguard Worker             dispatchFocusLocked(currentTime, typedEntry);
1214*38e8c45fSAndroid Build Coastguard Worker             done = true;
1215*38e8c45fSAndroid Build Coastguard Worker             dropReason = DropReason::NOT_DROPPED; // focus events are never dropped
1216*38e8c45fSAndroid Build Coastguard Worker             break;
1217*38e8c45fSAndroid Build Coastguard Worker         }
1218*38e8c45fSAndroid Build Coastguard Worker 
1219*38e8c45fSAndroid Build Coastguard Worker         case EventEntry::Type::TOUCH_MODE_CHANGED: {
1220*38e8c45fSAndroid Build Coastguard Worker             const auto typedEntry = std::static_pointer_cast<const TouchModeEntry>(mPendingEvent);
1221*38e8c45fSAndroid Build Coastguard Worker             dispatchTouchModeChangeLocked(currentTime, typedEntry);
1222*38e8c45fSAndroid Build Coastguard Worker             done = true;
1223*38e8c45fSAndroid Build Coastguard Worker             dropReason = DropReason::NOT_DROPPED; // touch mode events are never dropped
1224*38e8c45fSAndroid Build Coastguard Worker             break;
1225*38e8c45fSAndroid Build Coastguard Worker         }
1226*38e8c45fSAndroid Build Coastguard Worker 
1227*38e8c45fSAndroid Build Coastguard Worker         case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
1228*38e8c45fSAndroid Build Coastguard Worker             const auto typedEntry =
1229*38e8c45fSAndroid Build Coastguard Worker                     std::static_pointer_cast<const PointerCaptureChangedEntry>(mPendingEvent);
1230*38e8c45fSAndroid Build Coastguard Worker             dispatchPointerCaptureChangedLocked(currentTime, typedEntry, dropReason);
1231*38e8c45fSAndroid Build Coastguard Worker             done = true;
1232*38e8c45fSAndroid Build Coastguard Worker             break;
1233*38e8c45fSAndroid Build Coastguard Worker         }
1234*38e8c45fSAndroid Build Coastguard Worker 
1235*38e8c45fSAndroid Build Coastguard Worker         case EventEntry::Type::DRAG: {
1236*38e8c45fSAndroid Build Coastguard Worker             std::shared_ptr<const DragEntry> typedEntry =
1237*38e8c45fSAndroid Build Coastguard Worker                     std::static_pointer_cast<const DragEntry>(mPendingEvent);
1238*38e8c45fSAndroid Build Coastguard Worker             dispatchDragLocked(currentTime, typedEntry);
1239*38e8c45fSAndroid Build Coastguard Worker             done = true;
1240*38e8c45fSAndroid Build Coastguard Worker             break;
1241*38e8c45fSAndroid Build Coastguard Worker         }
1242*38e8c45fSAndroid Build Coastguard Worker 
1243*38e8c45fSAndroid Build Coastguard Worker         case EventEntry::Type::KEY: {
1244*38e8c45fSAndroid Build Coastguard Worker             std::shared_ptr<const KeyEntry> keyEntry =
1245*38e8c45fSAndroid Build Coastguard Worker                     std::static_pointer_cast<const KeyEntry>(mPendingEvent);
1246*38e8c45fSAndroid Build Coastguard Worker             if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(currentTime, *keyEntry)) {
1247*38e8c45fSAndroid Build Coastguard Worker                 dropReason = DropReason::STALE;
1248*38e8c45fSAndroid Build Coastguard Worker             }
1249*38e8c45fSAndroid Build Coastguard Worker             if (dropReason == DropReason::NOT_DROPPED && mNextUnblockedEvent) {
1250*38e8c45fSAndroid Build Coastguard Worker                 dropReason = DropReason::BLOCKED;
1251*38e8c45fSAndroid Build Coastguard Worker             }
1252*38e8c45fSAndroid Build Coastguard Worker             done = dispatchKeyLocked(currentTime, keyEntry, &dropReason, nextWakeupTime);
1253*38e8c45fSAndroid Build Coastguard Worker             break;
1254*38e8c45fSAndroid Build Coastguard Worker         }
1255*38e8c45fSAndroid Build Coastguard Worker 
1256*38e8c45fSAndroid Build Coastguard Worker         case EventEntry::Type::MOTION: {
1257*38e8c45fSAndroid Build Coastguard Worker             std::shared_ptr<const MotionEntry> motionEntry =
1258*38e8c45fSAndroid Build Coastguard Worker                     std::static_pointer_cast<const MotionEntry>(mPendingEvent);
1259*38e8c45fSAndroid Build Coastguard Worker             if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(currentTime, *motionEntry)) {
1260*38e8c45fSAndroid Build Coastguard Worker                 // The event is stale. However, only drop stale events if there isn't an ongoing
1261*38e8c45fSAndroid Build Coastguard Worker                 // gesture. That would allow us to complete the processing of the current stroke.
1262*38e8c45fSAndroid Build Coastguard Worker                 const auto touchStateIt = mTouchStatesByDisplay.find(motionEntry->displayId);
1263*38e8c45fSAndroid Build Coastguard Worker                 if (touchStateIt != mTouchStatesByDisplay.end()) {
1264*38e8c45fSAndroid Build Coastguard Worker                     const TouchState& touchState = touchStateIt->second;
1265*38e8c45fSAndroid Build Coastguard Worker                     if (!touchState.hasTouchingPointers(motionEntry->deviceId) &&
1266*38e8c45fSAndroid Build Coastguard Worker                         !touchState.hasHoveringPointers(motionEntry->deviceId)) {
1267*38e8c45fSAndroid Build Coastguard Worker                         dropReason = DropReason::STALE;
1268*38e8c45fSAndroid Build Coastguard Worker                     }
1269*38e8c45fSAndroid Build Coastguard Worker                 }
1270*38e8c45fSAndroid Build Coastguard Worker             }
1271*38e8c45fSAndroid Build Coastguard Worker             if (dropReason == DropReason::NOT_DROPPED && mNextUnblockedEvent) {
1272*38e8c45fSAndroid Build Coastguard Worker                 if (!isFromSource(motionEntry->source, AINPUT_SOURCE_CLASS_POINTER)) {
1273*38e8c45fSAndroid Build Coastguard Worker                     // Only drop events that are focus-dispatched.
1274*38e8c45fSAndroid Build Coastguard Worker                     dropReason = DropReason::BLOCKED;
1275*38e8c45fSAndroid Build Coastguard Worker                 }
1276*38e8c45fSAndroid Build Coastguard Worker             }
1277*38e8c45fSAndroid Build Coastguard Worker             done = dispatchMotionLocked(currentTime, motionEntry, &dropReason, nextWakeupTime);
1278*38e8c45fSAndroid Build Coastguard Worker             break;
1279*38e8c45fSAndroid Build Coastguard Worker         }
1280*38e8c45fSAndroid Build Coastguard Worker 
1281*38e8c45fSAndroid Build Coastguard Worker         case EventEntry::Type::SENSOR: {
1282*38e8c45fSAndroid Build Coastguard Worker             std::shared_ptr<const SensorEntry> sensorEntry =
1283*38e8c45fSAndroid Build Coastguard Worker                     std::static_pointer_cast<const SensorEntry>(mPendingEvent);
1284*38e8c45fSAndroid Build Coastguard Worker 
1285*38e8c45fSAndroid Build Coastguard Worker             //  Sensor timestamps use SYSTEM_TIME_BOOTTIME time base, so we can't use
1286*38e8c45fSAndroid Build Coastguard Worker             // 'currentTime' here, get SYSTEM_TIME_BOOTTIME instead.
1287*38e8c45fSAndroid Build Coastguard Worker             nsecs_t bootTime = systemTime(SYSTEM_TIME_BOOTTIME);
1288*38e8c45fSAndroid Build Coastguard Worker             if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(bootTime, *sensorEntry)) {
1289*38e8c45fSAndroid Build Coastguard Worker                 dropReason = DropReason::STALE;
1290*38e8c45fSAndroid Build Coastguard Worker             }
1291*38e8c45fSAndroid Build Coastguard Worker             dispatchSensorLocked(currentTime, sensorEntry, &dropReason, nextWakeupTime);
1292*38e8c45fSAndroid Build Coastguard Worker             done = true;
1293*38e8c45fSAndroid Build Coastguard Worker             break;
1294*38e8c45fSAndroid Build Coastguard Worker         }
1295*38e8c45fSAndroid Build Coastguard Worker     }
1296*38e8c45fSAndroid Build Coastguard Worker 
1297*38e8c45fSAndroid Build Coastguard Worker     if (done) {
1298*38e8c45fSAndroid Build Coastguard Worker         if (dropReason != DropReason::NOT_DROPPED) {
1299*38e8c45fSAndroid Build Coastguard Worker             dropInboundEventLocked(*mPendingEvent, dropReason);
1300*38e8c45fSAndroid Build Coastguard Worker         }
1301*38e8c45fSAndroid Build Coastguard Worker         mLastDropReason = dropReason;
1302*38e8c45fSAndroid Build Coastguard Worker 
1303*38e8c45fSAndroid Build Coastguard Worker         if (mTracer) {
1304*38e8c45fSAndroid Build Coastguard Worker             if (auto& traceTracker = getTraceTracker(*mPendingEvent); traceTracker != nullptr) {
1305*38e8c45fSAndroid Build Coastguard Worker                 mTracer->eventProcessingComplete(*traceTracker, currentTime);
1306*38e8c45fSAndroid Build Coastguard Worker             }
1307*38e8c45fSAndroid Build Coastguard Worker         }
1308*38e8c45fSAndroid Build Coastguard Worker 
1309*38e8c45fSAndroid Build Coastguard Worker         releasePendingEventLocked();
1310*38e8c45fSAndroid Build Coastguard Worker         nextWakeupTime = LLONG_MIN; // force next poll to wake up immediately
1311*38e8c45fSAndroid Build Coastguard Worker     }
1312*38e8c45fSAndroid Build Coastguard Worker }
1313*38e8c45fSAndroid Build Coastguard Worker 
isStaleEvent(nsecs_t currentTime,const EventEntry & entry)1314*38e8c45fSAndroid Build Coastguard Worker bool InputDispatcher::isStaleEvent(nsecs_t currentTime, const EventEntry& entry) {
1315*38e8c45fSAndroid Build Coastguard Worker     return mPolicy.isStaleEvent(currentTime, entry.eventTime);
1316*38e8c45fSAndroid Build Coastguard Worker }
1317*38e8c45fSAndroid Build Coastguard Worker 
1318*38e8c45fSAndroid Build Coastguard Worker /**
1319*38e8c45fSAndroid Build Coastguard Worker  * Return true if the events preceding this incoming motion event should be dropped
1320*38e8c45fSAndroid Build Coastguard Worker  * Return false otherwise (the default behaviour)
1321*38e8c45fSAndroid Build Coastguard Worker  */
shouldPruneInboundQueueLocked(const MotionEntry & motionEntry) const1322*38e8c45fSAndroid Build Coastguard Worker bool InputDispatcher::shouldPruneInboundQueueLocked(const MotionEntry& motionEntry) const {
1323*38e8c45fSAndroid Build Coastguard Worker     const bool isPointerDownEvent = motionEntry.action == AMOTION_EVENT_ACTION_DOWN &&
1324*38e8c45fSAndroid Build Coastguard Worker             isFromSource(motionEntry.source, AINPUT_SOURCE_CLASS_POINTER);
1325*38e8c45fSAndroid Build Coastguard Worker 
1326*38e8c45fSAndroid Build Coastguard Worker     // Optimize case where the current application is unresponsive and the user
1327*38e8c45fSAndroid Build Coastguard Worker     // decides to touch a window in a different application.
1328*38e8c45fSAndroid Build Coastguard Worker     // If the application takes too long to catch up then we drop all events preceding
1329*38e8c45fSAndroid Build Coastguard Worker     // the touch into the other window.
1330*38e8c45fSAndroid Build Coastguard Worker     if (isPointerDownEvent && mAwaitedFocusedApplication != nullptr) {
1331*38e8c45fSAndroid Build Coastguard Worker         const ui::LogicalDisplayId displayId = motionEntry.displayId;
1332*38e8c45fSAndroid Build Coastguard Worker         const auto [x, y] = resolveTouchedPosition(motionEntry);
1333*38e8c45fSAndroid Build Coastguard Worker         const bool isStylus = isPointerFromStylus(motionEntry, /*pointerIndex=*/0);
1334*38e8c45fSAndroid Build Coastguard Worker 
1335*38e8c45fSAndroid Build Coastguard Worker         sp<WindowInfoHandle> touchedWindowHandle =
1336*38e8c45fSAndroid Build Coastguard Worker                 findTouchedWindowAtLocked(displayId, x, y, isStylus);
1337*38e8c45fSAndroid Build Coastguard Worker         if (touchedWindowHandle != nullptr &&
1338*38e8c45fSAndroid Build Coastguard Worker             touchedWindowHandle->getApplicationToken() !=
1339*38e8c45fSAndroid Build Coastguard Worker                     mAwaitedFocusedApplication->getApplicationToken()) {
1340*38e8c45fSAndroid Build Coastguard Worker             // User touched a different application than the one we are waiting on.
1341*38e8c45fSAndroid Build Coastguard Worker             ALOGI("Pruning input queue because user touched a different application while waiting "
1342*38e8c45fSAndroid Build Coastguard Worker                   "for %s",
1343*38e8c45fSAndroid Build Coastguard Worker                   mAwaitedFocusedApplication->getName().c_str());
1344*38e8c45fSAndroid Build Coastguard Worker             return true;
1345*38e8c45fSAndroid Build Coastguard Worker         }
1346*38e8c45fSAndroid Build Coastguard Worker 
1347*38e8c45fSAndroid Build Coastguard Worker         // Alternatively, maybe there's a spy window that could handle this event.
1348*38e8c45fSAndroid Build Coastguard Worker         const std::vector<sp<WindowInfoHandle>> touchedSpies =
1349*38e8c45fSAndroid Build Coastguard Worker                 findTouchedSpyWindowsAtLocked(displayId, x, y, isStylus, motionEntry.deviceId);
1350*38e8c45fSAndroid Build Coastguard Worker         for (const auto& windowHandle : touchedSpies) {
1351*38e8c45fSAndroid Build Coastguard Worker             const std::shared_ptr<Connection> connection =
1352*38e8c45fSAndroid Build Coastguard Worker                     getConnectionLocked(windowHandle->getToken());
1353*38e8c45fSAndroid Build Coastguard Worker             if (connection != nullptr && connection->responsive) {
1354*38e8c45fSAndroid Build Coastguard Worker                 // This spy window could take more input. Drop all events preceding this
1355*38e8c45fSAndroid Build Coastguard Worker                 // event, so that the spy window can get a chance to receive the stream.
1356*38e8c45fSAndroid Build Coastguard Worker                 ALOGW("Pruning the input queue because %s is unresponsive, but we have a "
1357*38e8c45fSAndroid Build Coastguard Worker                       "responsive spy window that may handle the event.",
1358*38e8c45fSAndroid Build Coastguard Worker                       mAwaitedFocusedApplication->getName().c_str());
1359*38e8c45fSAndroid Build Coastguard Worker                 return true;
1360*38e8c45fSAndroid Build Coastguard Worker             }
1361*38e8c45fSAndroid Build Coastguard Worker         }
1362*38e8c45fSAndroid Build Coastguard Worker     }
1363*38e8c45fSAndroid Build Coastguard Worker 
1364*38e8c45fSAndroid Build Coastguard Worker     return false;
1365*38e8c45fSAndroid Build Coastguard Worker }
1366*38e8c45fSAndroid Build Coastguard Worker 
enqueueInboundEventLocked(std::unique_ptr<EventEntry> newEntry)1367*38e8c45fSAndroid Build Coastguard Worker bool InputDispatcher::enqueueInboundEventLocked(std::unique_ptr<EventEntry> newEntry) {
1368*38e8c45fSAndroid Build Coastguard Worker     bool needWake = mInboundQueue.empty();
1369*38e8c45fSAndroid Build Coastguard Worker     mInboundQueue.push_back(std::move(newEntry));
1370*38e8c45fSAndroid Build Coastguard Worker     const EventEntry& entry = *(mInboundQueue.back());
1371*38e8c45fSAndroid Build Coastguard Worker     traceInboundQueueLengthLocked();
1372*38e8c45fSAndroid Build Coastguard Worker 
1373*38e8c45fSAndroid Build Coastguard Worker     switch (entry.type) {
1374*38e8c45fSAndroid Build Coastguard Worker         case EventEntry::Type::KEY: {
1375*38e8c45fSAndroid Build Coastguard Worker             LOG_ALWAYS_FATAL_IF((entry.policyFlags & POLICY_FLAG_TRUSTED) == 0,
1376*38e8c45fSAndroid Build Coastguard Worker                                 "Unexpected untrusted event.");
1377*38e8c45fSAndroid Build Coastguard Worker 
1378*38e8c45fSAndroid Build Coastguard Worker             const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
1379*38e8c45fSAndroid Build Coastguard Worker             if (mTracer) {
1380*38e8c45fSAndroid Build Coastguard Worker                 ensureEventTraced(keyEntry);
1381*38e8c45fSAndroid Build Coastguard Worker             }
1382*38e8c45fSAndroid Build Coastguard Worker 
1383*38e8c45fSAndroid Build Coastguard Worker             // If a new up event comes in, and the pending event with same key code has been asked
1384*38e8c45fSAndroid Build Coastguard Worker             // to try again later because of the policy. We have to reset the intercept key wake up
1385*38e8c45fSAndroid Build Coastguard Worker             // time for it may have been handled in the policy and could be dropped.
1386*38e8c45fSAndroid Build Coastguard Worker             if (keyEntry.action == AKEY_EVENT_ACTION_UP && mPendingEvent &&
1387*38e8c45fSAndroid Build Coastguard Worker                 mPendingEvent->type == EventEntry::Type::KEY) {
1388*38e8c45fSAndroid Build Coastguard Worker                 const KeyEntry& pendingKey = static_cast<const KeyEntry&>(*mPendingEvent);
1389*38e8c45fSAndroid Build Coastguard Worker                 if (pendingKey.keyCode == keyEntry.keyCode &&
1390*38e8c45fSAndroid Build Coastguard Worker                     pendingKey.interceptKeyResult ==
1391*38e8c45fSAndroid Build Coastguard Worker                             KeyEntry::InterceptKeyResult::TRY_AGAIN_LATER) {
1392*38e8c45fSAndroid Build Coastguard Worker                     pendingKey.interceptKeyResult = KeyEntry::InterceptKeyResult::UNKNOWN;
1393*38e8c45fSAndroid Build Coastguard Worker                     pendingKey.interceptKeyWakeupTime = 0;
1394*38e8c45fSAndroid Build Coastguard Worker                     needWake = true;
1395*38e8c45fSAndroid Build Coastguard Worker                 }
1396*38e8c45fSAndroid Build Coastguard Worker             }
1397*38e8c45fSAndroid Build Coastguard Worker             break;
1398*38e8c45fSAndroid Build Coastguard Worker         }
1399*38e8c45fSAndroid Build Coastguard Worker 
1400*38e8c45fSAndroid Build Coastguard Worker         case EventEntry::Type::MOTION: {
1401*38e8c45fSAndroid Build Coastguard Worker             LOG_ALWAYS_FATAL_IF((entry.policyFlags & POLICY_FLAG_TRUSTED) == 0,
1402*38e8c45fSAndroid Build Coastguard Worker                                 "Unexpected untrusted event.");
1403*38e8c45fSAndroid Build Coastguard Worker             const auto& motionEntry = static_cast<const MotionEntry&>(entry);
1404*38e8c45fSAndroid Build Coastguard Worker             if (mTracer) {
1405*38e8c45fSAndroid Build Coastguard Worker                 ensureEventTraced(motionEntry);
1406*38e8c45fSAndroid Build Coastguard Worker             }
1407*38e8c45fSAndroid Build Coastguard Worker             if (shouldPruneInboundQueueLocked(motionEntry)) {
1408*38e8c45fSAndroid Build Coastguard Worker                 mNextUnblockedEvent = mInboundQueue.back();
1409*38e8c45fSAndroid Build Coastguard Worker                 needWake = true;
1410*38e8c45fSAndroid Build Coastguard Worker             }
1411*38e8c45fSAndroid Build Coastguard Worker 
1412*38e8c45fSAndroid Build Coastguard Worker             const bool isPointerDownEvent = motionEntry.action == AMOTION_EVENT_ACTION_DOWN &&
1413*38e8c45fSAndroid Build Coastguard Worker                     isFromSource(motionEntry.source, AINPUT_SOURCE_CLASS_POINTER);
1414*38e8c45fSAndroid Build Coastguard Worker             if (isPointerDownEvent && mKeyIsWaitingForEventsTimeout) {
1415*38e8c45fSAndroid Build Coastguard Worker                 // Prevent waiting too long for unprocessed events: if we have a pending key event,
1416*38e8c45fSAndroid Build Coastguard Worker                 // and some other events have not yet been processed, the dispatcher will wait for
1417*38e8c45fSAndroid Build Coastguard Worker                 // these events to be processed before dispatching the key event. This is because
1418*38e8c45fSAndroid Build Coastguard Worker                 // the unprocessed events may cause the focus to change (for example, by launching a
1419*38e8c45fSAndroid Build Coastguard Worker                 // new window or tapping a different window). To prevent waiting too long, we force
1420*38e8c45fSAndroid Build Coastguard Worker                 // the key to be sent to the currently focused window when a new tap comes in.
1421*38e8c45fSAndroid Build Coastguard Worker                 ALOGD("Received a new pointer down event, stop waiting for events to process and "
1422*38e8c45fSAndroid Build Coastguard Worker                       "just send the pending key event to the currently focused window.");
1423*38e8c45fSAndroid Build Coastguard Worker                 mKeyIsWaitingForEventsTimeout = now();
1424*38e8c45fSAndroid Build Coastguard Worker                 needWake = true;
1425*38e8c45fSAndroid Build Coastguard Worker             }
1426*38e8c45fSAndroid Build Coastguard Worker             break;
1427*38e8c45fSAndroid Build Coastguard Worker         }
1428*38e8c45fSAndroid Build Coastguard Worker         case EventEntry::Type::FOCUS: {
1429*38e8c45fSAndroid Build Coastguard Worker             LOG_ALWAYS_FATAL("Focus events should be inserted using enqueueFocusEventLocked");
1430*38e8c45fSAndroid Build Coastguard Worker             break;
1431*38e8c45fSAndroid Build Coastguard Worker         }
1432*38e8c45fSAndroid Build Coastguard Worker         case EventEntry::Type::TOUCH_MODE_CHANGED:
1433*38e8c45fSAndroid Build Coastguard Worker         case EventEntry::Type::DEVICE_RESET:
1434*38e8c45fSAndroid Build Coastguard Worker         case EventEntry::Type::SENSOR:
1435*38e8c45fSAndroid Build Coastguard Worker         case EventEntry::Type::POINTER_CAPTURE_CHANGED:
1436*38e8c45fSAndroid Build Coastguard Worker         case EventEntry::Type::DRAG: {
1437*38e8c45fSAndroid Build Coastguard Worker             // nothing to do
1438*38e8c45fSAndroid Build Coastguard Worker             break;
1439*38e8c45fSAndroid Build Coastguard Worker         }
1440*38e8c45fSAndroid Build Coastguard Worker     }
1441*38e8c45fSAndroid Build Coastguard Worker 
1442*38e8c45fSAndroid Build Coastguard Worker     return needWake;
1443*38e8c45fSAndroid Build Coastguard Worker }
1444*38e8c45fSAndroid Build Coastguard Worker 
addRecentEventLocked(std::shared_ptr<const EventEntry> entry)1445*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::addRecentEventLocked(std::shared_ptr<const EventEntry> entry) {
1446*38e8c45fSAndroid Build Coastguard Worker     // Do not store sensor event in recent queue to avoid flooding the queue.
1447*38e8c45fSAndroid Build Coastguard Worker     if (entry->type != EventEntry::Type::SENSOR) {
1448*38e8c45fSAndroid Build Coastguard Worker         mRecentQueue.push_back(entry);
1449*38e8c45fSAndroid Build Coastguard Worker     }
1450*38e8c45fSAndroid Build Coastguard Worker     if (mRecentQueue.size() > RECENT_QUEUE_MAX_SIZE) {
1451*38e8c45fSAndroid Build Coastguard Worker         mRecentQueue.pop_front();
1452*38e8c45fSAndroid Build Coastguard Worker     }
1453*38e8c45fSAndroid Build Coastguard Worker }
1454*38e8c45fSAndroid Build Coastguard Worker 
findTouchedWindowAtLocked(ui::LogicalDisplayId displayId,float x,float y,bool isStylus,bool ignoreDragWindow) const1455*38e8c45fSAndroid Build Coastguard Worker sp<WindowInfoHandle> InputDispatcher::findTouchedWindowAtLocked(ui::LogicalDisplayId displayId,
1456*38e8c45fSAndroid Build Coastguard Worker                                                                 float x, float y, bool isStylus,
1457*38e8c45fSAndroid Build Coastguard Worker                                                                 bool ignoreDragWindow) const {
1458*38e8c45fSAndroid Build Coastguard Worker     // Traverse windows from front to back to find touched window.
1459*38e8c45fSAndroid Build Coastguard Worker     const auto& windowHandles = getWindowHandlesLocked(displayId);
1460*38e8c45fSAndroid Build Coastguard Worker     for (const sp<WindowInfoHandle>& windowHandle : windowHandles) {
1461*38e8c45fSAndroid Build Coastguard Worker         if (ignoreDragWindow && haveSameToken(windowHandle, mDragState->dragWindow)) {
1462*38e8c45fSAndroid Build Coastguard Worker             continue;
1463*38e8c45fSAndroid Build Coastguard Worker         }
1464*38e8c45fSAndroid Build Coastguard Worker 
1465*38e8c45fSAndroid Build Coastguard Worker         const WindowInfo& info = *windowHandle->getInfo();
1466*38e8c45fSAndroid Build Coastguard Worker         if (!info.isSpy() &&
1467*38e8c45fSAndroid Build Coastguard Worker             windowAcceptsTouchAt(info, displayId, x, y, isStylus, getTransformLocked(displayId))) {
1468*38e8c45fSAndroid Build Coastguard Worker             return windowHandle;
1469*38e8c45fSAndroid Build Coastguard Worker         }
1470*38e8c45fSAndroid Build Coastguard Worker     }
1471*38e8c45fSAndroid Build Coastguard Worker     return nullptr;
1472*38e8c45fSAndroid Build Coastguard Worker }
1473*38e8c45fSAndroid Build Coastguard Worker 
findOutsideTargetsLocked(ui::LogicalDisplayId displayId,const sp<WindowInfoHandle> & touchedWindow,int32_t pointerId) const1474*38e8c45fSAndroid Build Coastguard Worker std::vector<InputTarget> InputDispatcher::findOutsideTargetsLocked(
1475*38e8c45fSAndroid Build Coastguard Worker         ui::LogicalDisplayId displayId, const sp<WindowInfoHandle>& touchedWindow,
1476*38e8c45fSAndroid Build Coastguard Worker         int32_t pointerId) const {
1477*38e8c45fSAndroid Build Coastguard Worker     if (touchedWindow == nullptr) {
1478*38e8c45fSAndroid Build Coastguard Worker         return {};
1479*38e8c45fSAndroid Build Coastguard Worker     }
1480*38e8c45fSAndroid Build Coastguard Worker     // Traverse windows from front to back until we encounter the touched window.
1481*38e8c45fSAndroid Build Coastguard Worker     std::vector<InputTarget> outsideTargets;
1482*38e8c45fSAndroid Build Coastguard Worker     const auto& windowHandles = getWindowHandlesLocked(displayId);
1483*38e8c45fSAndroid Build Coastguard Worker     for (const sp<WindowInfoHandle>& windowHandle : windowHandles) {
1484*38e8c45fSAndroid Build Coastguard Worker         if (windowHandle == touchedWindow) {
1485*38e8c45fSAndroid Build Coastguard Worker             // Stop iterating once we found a touched window. Any WATCH_OUTSIDE_TOUCH window
1486*38e8c45fSAndroid Build Coastguard Worker             // below the touched window will not get ACTION_OUTSIDE event.
1487*38e8c45fSAndroid Build Coastguard Worker             return outsideTargets;
1488*38e8c45fSAndroid Build Coastguard Worker         }
1489*38e8c45fSAndroid Build Coastguard Worker 
1490*38e8c45fSAndroid Build Coastguard Worker         const WindowInfo& info = *windowHandle->getInfo();
1491*38e8c45fSAndroid Build Coastguard Worker         if (info.inputConfig.test(WindowInfo::InputConfig::WATCH_OUTSIDE_TOUCH)) {
1492*38e8c45fSAndroid Build Coastguard Worker             std::bitset<MAX_POINTER_ID + 1> pointerIds;
1493*38e8c45fSAndroid Build Coastguard Worker             pointerIds.set(pointerId);
1494*38e8c45fSAndroid Build Coastguard Worker             addPointerWindowTargetLocked(windowHandle, InputTarget::DispatchMode::OUTSIDE,
1495*38e8c45fSAndroid Build Coastguard Worker                                          ftl::Flags<InputTarget::Flags>(), pointerIds,
1496*38e8c45fSAndroid Build Coastguard Worker                                          /*firstDownTimeInTarget=*/std::nullopt, outsideTargets);
1497*38e8c45fSAndroid Build Coastguard Worker         }
1498*38e8c45fSAndroid Build Coastguard Worker     }
1499*38e8c45fSAndroid Build Coastguard Worker     return outsideTargets;
1500*38e8c45fSAndroid Build Coastguard Worker }
1501*38e8c45fSAndroid Build Coastguard Worker 
findTouchedSpyWindowsAtLocked(ui::LogicalDisplayId displayId,float x,float y,bool isStylus,DeviceId deviceId) const1502*38e8c45fSAndroid Build Coastguard Worker std::vector<sp<WindowInfoHandle>> InputDispatcher::findTouchedSpyWindowsAtLocked(
1503*38e8c45fSAndroid Build Coastguard Worker         ui::LogicalDisplayId displayId, float x, float y, bool isStylus, DeviceId deviceId) const {
1504*38e8c45fSAndroid Build Coastguard Worker     // Traverse windows from front to back and gather the touched spy windows.
1505*38e8c45fSAndroid Build Coastguard Worker     std::vector<sp<WindowInfoHandle>> spyWindows;
1506*38e8c45fSAndroid Build Coastguard Worker     const auto& windowHandles = getWindowHandlesLocked(displayId);
1507*38e8c45fSAndroid Build Coastguard Worker     for (const sp<WindowInfoHandle>& windowHandle : windowHandles) {
1508*38e8c45fSAndroid Build Coastguard Worker         const WindowInfo& info = *windowHandle->getInfo();
1509*38e8c45fSAndroid Build Coastguard Worker         if (!windowAcceptsTouchAt(info, displayId, x, y, isStylus, getTransformLocked(displayId))) {
1510*38e8c45fSAndroid Build Coastguard Worker             // Generally, we would skip any pointer that's outside of the window. However, if the
1511*38e8c45fSAndroid Build Coastguard Worker             // spy prevents splitting, and already has some of the pointers from this device, then
1512*38e8c45fSAndroid Build Coastguard Worker             // it should get more pointers from the same device, even if they are outside of that
1513*38e8c45fSAndroid Build Coastguard Worker             // window
1514*38e8c45fSAndroid Build Coastguard Worker             if (info.supportsSplitTouch()) {
1515*38e8c45fSAndroid Build Coastguard Worker                 continue;
1516*38e8c45fSAndroid Build Coastguard Worker             }
1517*38e8c45fSAndroid Build Coastguard Worker 
1518*38e8c45fSAndroid Build Coastguard Worker             // We know that split touch is not supported. Skip this window only if it doesn't have
1519*38e8c45fSAndroid Build Coastguard Worker             // any touching pointers for this device already.
1520*38e8c45fSAndroid Build Coastguard Worker             if (!windowHasTouchingPointersLocked(windowHandle, deviceId)) {
1521*38e8c45fSAndroid Build Coastguard Worker                 continue;
1522*38e8c45fSAndroid Build Coastguard Worker             }
1523*38e8c45fSAndroid Build Coastguard Worker             // If it already has pointers down for this device, then give it this pointer, too.
1524*38e8c45fSAndroid Build Coastguard Worker         }
1525*38e8c45fSAndroid Build Coastguard Worker         if (!info.isSpy()) {
1526*38e8c45fSAndroid Build Coastguard Worker             // The first touched non-spy window was found, so return the spy windows touched so far.
1527*38e8c45fSAndroid Build Coastguard Worker             return spyWindows;
1528*38e8c45fSAndroid Build Coastguard Worker         }
1529*38e8c45fSAndroid Build Coastguard Worker         spyWindows.push_back(windowHandle);
1530*38e8c45fSAndroid Build Coastguard Worker     }
1531*38e8c45fSAndroid Build Coastguard Worker     return spyWindows;
1532*38e8c45fSAndroid Build Coastguard Worker }
1533*38e8c45fSAndroid Build Coastguard Worker 
dropInboundEventLocked(const EventEntry & entry,DropReason dropReason)1534*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::dropInboundEventLocked(const EventEntry& entry, DropReason dropReason) {
1535*38e8c45fSAndroid Build Coastguard Worker     const char* reason;
1536*38e8c45fSAndroid Build Coastguard Worker     switch (dropReason) {
1537*38e8c45fSAndroid Build Coastguard Worker         case DropReason::POLICY:
1538*38e8c45fSAndroid Build Coastguard Worker             if (debugInboundEventDetails()) {
1539*38e8c45fSAndroid Build Coastguard Worker                 ALOGD("Dropped event because policy consumed it.");
1540*38e8c45fSAndroid Build Coastguard Worker             }
1541*38e8c45fSAndroid Build Coastguard Worker             reason = "inbound event was dropped because the policy consumed it";
1542*38e8c45fSAndroid Build Coastguard Worker             break;
1543*38e8c45fSAndroid Build Coastguard Worker         case DropReason::DISABLED:
1544*38e8c45fSAndroid Build Coastguard Worker             if (mLastDropReason != DropReason::DISABLED) {
1545*38e8c45fSAndroid Build Coastguard Worker                 ALOGI("Dropped event because input dispatch is disabled.");
1546*38e8c45fSAndroid Build Coastguard Worker             }
1547*38e8c45fSAndroid Build Coastguard Worker             reason = "inbound event was dropped because input dispatch is disabled";
1548*38e8c45fSAndroid Build Coastguard Worker             break;
1549*38e8c45fSAndroid Build Coastguard Worker         case DropReason::BLOCKED:
1550*38e8c45fSAndroid Build Coastguard Worker             LOG(INFO) << "Dropping because the current application is not responding and the user "
1551*38e8c45fSAndroid Build Coastguard Worker                          "has started interacting with a different application: "
1552*38e8c45fSAndroid Build Coastguard Worker                       << entry.getDescription();
1553*38e8c45fSAndroid Build Coastguard Worker             reason = "inbound event was dropped because the current application is not responding "
1554*38e8c45fSAndroid Build Coastguard Worker                      "and the user has started interacting with a different application";
1555*38e8c45fSAndroid Build Coastguard Worker             break;
1556*38e8c45fSAndroid Build Coastguard Worker         case DropReason::STALE:
1557*38e8c45fSAndroid Build Coastguard Worker             ALOGI("Dropped event because it is stale.");
1558*38e8c45fSAndroid Build Coastguard Worker             reason = "inbound event was dropped because it is stale";
1559*38e8c45fSAndroid Build Coastguard Worker             break;
1560*38e8c45fSAndroid Build Coastguard Worker         case DropReason::NO_POINTER_CAPTURE:
1561*38e8c45fSAndroid Build Coastguard Worker             ALOGI("Dropped event because there is no window with Pointer Capture.");
1562*38e8c45fSAndroid Build Coastguard Worker             reason = "inbound event was dropped because there is no window with Pointer Capture";
1563*38e8c45fSAndroid Build Coastguard Worker             break;
1564*38e8c45fSAndroid Build Coastguard Worker         case DropReason::NOT_DROPPED: {
1565*38e8c45fSAndroid Build Coastguard Worker             LOG_ALWAYS_FATAL("Should not be dropping a NOT_DROPPED event");
1566*38e8c45fSAndroid Build Coastguard Worker             return;
1567*38e8c45fSAndroid Build Coastguard Worker         }
1568*38e8c45fSAndroid Build Coastguard Worker     }
1569*38e8c45fSAndroid Build Coastguard Worker 
1570*38e8c45fSAndroid Build Coastguard Worker     switch (entry.type) {
1571*38e8c45fSAndroid Build Coastguard Worker         case EventEntry::Type::KEY: {
1572*38e8c45fSAndroid Build Coastguard Worker             const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
1573*38e8c45fSAndroid Build Coastguard Worker             CancelationOptions options(CancelationOptions::Mode::CANCEL_NON_POINTER_EVENTS, reason,
1574*38e8c45fSAndroid Build Coastguard Worker                                        keyEntry.traceTracker);
1575*38e8c45fSAndroid Build Coastguard Worker             options.displayId = keyEntry.displayId;
1576*38e8c45fSAndroid Build Coastguard Worker             options.deviceId = keyEntry.deviceId;
1577*38e8c45fSAndroid Build Coastguard Worker             synthesizeCancelationEventsForAllConnectionsLocked(options);
1578*38e8c45fSAndroid Build Coastguard Worker             break;
1579*38e8c45fSAndroid Build Coastguard Worker         }
1580*38e8c45fSAndroid Build Coastguard Worker         case EventEntry::Type::MOTION: {
1581*38e8c45fSAndroid Build Coastguard Worker             const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
1582*38e8c45fSAndroid Build Coastguard Worker             if (motionEntry.source & AINPUT_SOURCE_CLASS_POINTER) {
1583*38e8c45fSAndroid Build Coastguard Worker                 CancelationOptions options(CancelationOptions::Mode::CANCEL_POINTER_EVENTS, reason,
1584*38e8c45fSAndroid Build Coastguard Worker                                            motionEntry.traceTracker);
1585*38e8c45fSAndroid Build Coastguard Worker                 options.displayId = motionEntry.displayId;
1586*38e8c45fSAndroid Build Coastguard Worker                 options.deviceId = motionEntry.deviceId;
1587*38e8c45fSAndroid Build Coastguard Worker                 synthesizeCancelationEventsForAllConnectionsLocked(options);
1588*38e8c45fSAndroid Build Coastguard Worker             } else {
1589*38e8c45fSAndroid Build Coastguard Worker                 CancelationOptions options(CancelationOptions::Mode::CANCEL_NON_POINTER_EVENTS,
1590*38e8c45fSAndroid Build Coastguard Worker                                            reason, motionEntry.traceTracker);
1591*38e8c45fSAndroid Build Coastguard Worker                 options.displayId = motionEntry.displayId;
1592*38e8c45fSAndroid Build Coastguard Worker                 options.deviceId = motionEntry.deviceId;
1593*38e8c45fSAndroid Build Coastguard Worker                 synthesizeCancelationEventsForAllConnectionsLocked(options);
1594*38e8c45fSAndroid Build Coastguard Worker             }
1595*38e8c45fSAndroid Build Coastguard Worker             break;
1596*38e8c45fSAndroid Build Coastguard Worker         }
1597*38e8c45fSAndroid Build Coastguard Worker         case EventEntry::Type::SENSOR: {
1598*38e8c45fSAndroid Build Coastguard Worker             break;
1599*38e8c45fSAndroid Build Coastguard Worker         }
1600*38e8c45fSAndroid Build Coastguard Worker         case EventEntry::Type::POINTER_CAPTURE_CHANGED:
1601*38e8c45fSAndroid Build Coastguard Worker         case EventEntry::Type::DRAG: {
1602*38e8c45fSAndroid Build Coastguard Worker             break;
1603*38e8c45fSAndroid Build Coastguard Worker         }
1604*38e8c45fSAndroid Build Coastguard Worker         case EventEntry::Type::FOCUS:
1605*38e8c45fSAndroid Build Coastguard Worker         case EventEntry::Type::TOUCH_MODE_CHANGED:
1606*38e8c45fSAndroid Build Coastguard Worker         case EventEntry::Type::DEVICE_RESET: {
1607*38e8c45fSAndroid Build Coastguard Worker             LOG_ALWAYS_FATAL("Should not drop %s events", ftl::enum_string(entry.type).c_str());
1608*38e8c45fSAndroid Build Coastguard Worker             break;
1609*38e8c45fSAndroid Build Coastguard Worker         }
1610*38e8c45fSAndroid Build Coastguard Worker     }
1611*38e8c45fSAndroid Build Coastguard Worker }
1612*38e8c45fSAndroid Build Coastguard Worker 
haveCommandsLocked() const1613*38e8c45fSAndroid Build Coastguard Worker bool InputDispatcher::haveCommandsLocked() const {
1614*38e8c45fSAndroid Build Coastguard Worker     return !mCommandQueue.empty();
1615*38e8c45fSAndroid Build Coastguard Worker }
1616*38e8c45fSAndroid Build Coastguard Worker 
runCommandsLockedInterruptable()1617*38e8c45fSAndroid Build Coastguard Worker bool InputDispatcher::runCommandsLockedInterruptable() {
1618*38e8c45fSAndroid Build Coastguard Worker     if (mCommandQueue.empty()) {
1619*38e8c45fSAndroid Build Coastguard Worker         return false;
1620*38e8c45fSAndroid Build Coastguard Worker     }
1621*38e8c45fSAndroid Build Coastguard Worker 
1622*38e8c45fSAndroid Build Coastguard Worker     do {
1623*38e8c45fSAndroid Build Coastguard Worker         auto command = std::move(mCommandQueue.front());
1624*38e8c45fSAndroid Build Coastguard Worker         mCommandQueue.pop_front();
1625*38e8c45fSAndroid Build Coastguard Worker         // Commands are run with the lock held, but may release and re-acquire the lock from within.
1626*38e8c45fSAndroid Build Coastguard Worker         command();
1627*38e8c45fSAndroid Build Coastguard Worker     } while (!mCommandQueue.empty());
1628*38e8c45fSAndroid Build Coastguard Worker     return true;
1629*38e8c45fSAndroid Build Coastguard Worker }
1630*38e8c45fSAndroid Build Coastguard Worker 
postCommandLocked(Command && command)1631*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::postCommandLocked(Command&& command) {
1632*38e8c45fSAndroid Build Coastguard Worker     mCommandQueue.push_back(command);
1633*38e8c45fSAndroid Build Coastguard Worker }
1634*38e8c45fSAndroid Build Coastguard Worker 
drainInboundQueueLocked()1635*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::drainInboundQueueLocked() {
1636*38e8c45fSAndroid Build Coastguard Worker     while (!mInboundQueue.empty()) {
1637*38e8c45fSAndroid Build Coastguard Worker         std::shared_ptr<const EventEntry> entry = mInboundQueue.front();
1638*38e8c45fSAndroid Build Coastguard Worker         mInboundQueue.pop_front();
1639*38e8c45fSAndroid Build Coastguard Worker         releaseInboundEventLocked(entry);
1640*38e8c45fSAndroid Build Coastguard Worker     }
1641*38e8c45fSAndroid Build Coastguard Worker     traceInboundQueueLengthLocked();
1642*38e8c45fSAndroid Build Coastguard Worker }
1643*38e8c45fSAndroid Build Coastguard Worker 
releasePendingEventLocked()1644*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::releasePendingEventLocked() {
1645*38e8c45fSAndroid Build Coastguard Worker     if (mPendingEvent) {
1646*38e8c45fSAndroid Build Coastguard Worker         releaseInboundEventLocked(mPendingEvent);
1647*38e8c45fSAndroid Build Coastguard Worker         mPendingEvent = nullptr;
1648*38e8c45fSAndroid Build Coastguard Worker     }
1649*38e8c45fSAndroid Build Coastguard Worker }
1650*38e8c45fSAndroid Build Coastguard Worker 
releaseInboundEventLocked(std::shared_ptr<const EventEntry> entry)1651*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::releaseInboundEventLocked(std::shared_ptr<const EventEntry> entry) {
1652*38e8c45fSAndroid Build Coastguard Worker     const std::shared_ptr<InjectionState>& injectionState = entry->injectionState;
1653*38e8c45fSAndroid Build Coastguard Worker     if (injectionState && injectionState->injectionResult == InputEventInjectionResult::PENDING) {
1654*38e8c45fSAndroid Build Coastguard Worker         if (DEBUG_DISPATCH_CYCLE) {
1655*38e8c45fSAndroid Build Coastguard Worker             ALOGD("Injected inbound event was dropped.");
1656*38e8c45fSAndroid Build Coastguard Worker         }
1657*38e8c45fSAndroid Build Coastguard Worker         setInjectionResult(*entry, InputEventInjectionResult::FAILED);
1658*38e8c45fSAndroid Build Coastguard Worker     }
1659*38e8c45fSAndroid Build Coastguard Worker     if (entry == mNextUnblockedEvent) {
1660*38e8c45fSAndroid Build Coastguard Worker         mNextUnblockedEvent = nullptr;
1661*38e8c45fSAndroid Build Coastguard Worker     }
1662*38e8c45fSAndroid Build Coastguard Worker     addRecentEventLocked(entry);
1663*38e8c45fSAndroid Build Coastguard Worker }
1664*38e8c45fSAndroid Build Coastguard Worker 
resetKeyRepeatLocked()1665*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::resetKeyRepeatLocked() {
1666*38e8c45fSAndroid Build Coastguard Worker     if (mKeyRepeatState.lastKeyEntry) {
1667*38e8c45fSAndroid Build Coastguard Worker         mKeyRepeatState.lastKeyEntry = nullptr;
1668*38e8c45fSAndroid Build Coastguard Worker     }
1669*38e8c45fSAndroid Build Coastguard Worker }
1670*38e8c45fSAndroid Build Coastguard Worker 
synthesizeKeyRepeatLocked(nsecs_t currentTime)1671*38e8c45fSAndroid Build Coastguard Worker std::shared_ptr<KeyEntry> InputDispatcher::synthesizeKeyRepeatLocked(nsecs_t currentTime) {
1672*38e8c45fSAndroid Build Coastguard Worker     std::shared_ptr<const KeyEntry> entry = mKeyRepeatState.lastKeyEntry;
1673*38e8c45fSAndroid Build Coastguard Worker 
1674*38e8c45fSAndroid Build Coastguard Worker     uint32_t policyFlags = entry->policyFlags &
1675*38e8c45fSAndroid Build Coastguard Worker             (POLICY_FLAG_RAW_MASK | POLICY_FLAG_PASS_TO_USER | POLICY_FLAG_TRUSTED);
1676*38e8c45fSAndroid Build Coastguard Worker 
1677*38e8c45fSAndroid Build Coastguard Worker     std::shared_ptr<KeyEntry> newEntry =
1678*38e8c45fSAndroid Build Coastguard Worker             std::make_unique<KeyEntry>(mIdGenerator.nextId(), /*injectionState=*/nullptr,
1679*38e8c45fSAndroid Build Coastguard Worker                                        currentTime, entry->deviceId, entry->source,
1680*38e8c45fSAndroid Build Coastguard Worker                                        entry->displayId, policyFlags, entry->action, entry->flags,
1681*38e8c45fSAndroid Build Coastguard Worker                                        entry->keyCode, entry->scanCode, entry->metaState,
1682*38e8c45fSAndroid Build Coastguard Worker                                        entry->repeatCount + 1, entry->downTime);
1683*38e8c45fSAndroid Build Coastguard Worker 
1684*38e8c45fSAndroid Build Coastguard Worker     newEntry->syntheticRepeat = true;
1685*38e8c45fSAndroid Build Coastguard Worker     if (mTracer) {
1686*38e8c45fSAndroid Build Coastguard Worker         newEntry->traceTracker = mTracer->traceInboundEvent(*newEntry);
1687*38e8c45fSAndroid Build Coastguard Worker     }
1688*38e8c45fSAndroid Build Coastguard Worker 
1689*38e8c45fSAndroid Build Coastguard Worker     mKeyRepeatState.lastKeyEntry = newEntry;
1690*38e8c45fSAndroid Build Coastguard Worker     mKeyRepeatState.nextRepeatTime = currentTime + mConfig.keyRepeatDelay;
1691*38e8c45fSAndroid Build Coastguard Worker     return newEntry;
1692*38e8c45fSAndroid Build Coastguard Worker }
1693*38e8c45fSAndroid Build Coastguard Worker 
dispatchDeviceResetLocked(nsecs_t currentTime,const DeviceResetEntry & entry)1694*38e8c45fSAndroid Build Coastguard Worker bool InputDispatcher::dispatchDeviceResetLocked(nsecs_t currentTime,
1695*38e8c45fSAndroid Build Coastguard Worker                                                 const DeviceResetEntry& entry) {
1696*38e8c45fSAndroid Build Coastguard Worker     if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1697*38e8c45fSAndroid Build Coastguard Worker         ALOGD("dispatchDeviceReset - eventTime=%" PRId64 ", deviceId=%d", entry.eventTime,
1698*38e8c45fSAndroid Build Coastguard Worker               entry.deviceId);
1699*38e8c45fSAndroid Build Coastguard Worker     }
1700*38e8c45fSAndroid Build Coastguard Worker 
1701*38e8c45fSAndroid Build Coastguard Worker     // Reset key repeating in case a keyboard device was disabled or enabled.
1702*38e8c45fSAndroid Build Coastguard Worker     if (mKeyRepeatState.lastKeyEntry && mKeyRepeatState.lastKeyEntry->deviceId == entry.deviceId) {
1703*38e8c45fSAndroid Build Coastguard Worker         resetKeyRepeatLocked();
1704*38e8c45fSAndroid Build Coastguard Worker     }
1705*38e8c45fSAndroid Build Coastguard Worker 
1706*38e8c45fSAndroid Build Coastguard Worker     ScopedSyntheticEventTracer traceContext(mTracer);
1707*38e8c45fSAndroid Build Coastguard Worker     CancelationOptions options(CancelationOptions::Mode::CANCEL_ALL_EVENTS, "device was reset",
1708*38e8c45fSAndroid Build Coastguard Worker                                traceContext.getTracker());
1709*38e8c45fSAndroid Build Coastguard Worker     options.deviceId = entry.deviceId;
1710*38e8c45fSAndroid Build Coastguard Worker     synthesizeCancelationEventsForAllConnectionsLocked(options);
1711*38e8c45fSAndroid Build Coastguard Worker 
1712*38e8c45fSAndroid Build Coastguard Worker     // Remove all active pointers from this device
1713*38e8c45fSAndroid Build Coastguard Worker     for (auto& [_, touchState] : mTouchStatesByDisplay) {
1714*38e8c45fSAndroid Build Coastguard Worker         touchState.removeAllPointersForDevice(entry.deviceId);
1715*38e8c45fSAndroid Build Coastguard Worker     }
1716*38e8c45fSAndroid Build Coastguard Worker     return true;
1717*38e8c45fSAndroid Build Coastguard Worker }
1718*38e8c45fSAndroid Build Coastguard Worker 
enqueueFocusEventLocked(const sp<IBinder> & windowToken,bool hasFocus,const std::string & reason)1719*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::enqueueFocusEventLocked(const sp<IBinder>& windowToken, bool hasFocus,
1720*38e8c45fSAndroid Build Coastguard Worker                                               const std::string& reason) {
1721*38e8c45fSAndroid Build Coastguard Worker     if (mPendingEvent != nullptr) {
1722*38e8c45fSAndroid Build Coastguard Worker         // Move the pending event to the front of the queue. This will give the chance
1723*38e8c45fSAndroid Build Coastguard Worker         // for the pending event to get dispatched to the newly focused window
1724*38e8c45fSAndroid Build Coastguard Worker         mInboundQueue.push_front(mPendingEvent);
1725*38e8c45fSAndroid Build Coastguard Worker         mPendingEvent = nullptr;
1726*38e8c45fSAndroid Build Coastguard Worker     }
1727*38e8c45fSAndroid Build Coastguard Worker 
1728*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<FocusEntry> focusEntry =
1729*38e8c45fSAndroid Build Coastguard Worker             std::make_unique<FocusEntry>(mIdGenerator.nextId(), now(), windowToken, hasFocus,
1730*38e8c45fSAndroid Build Coastguard Worker                                          reason);
1731*38e8c45fSAndroid Build Coastguard Worker 
1732*38e8c45fSAndroid Build Coastguard Worker     // This event should go to the front of the queue, but behind all other focus events
1733*38e8c45fSAndroid Build Coastguard Worker     // Find the last focus event, and insert right after it
1734*38e8c45fSAndroid Build Coastguard Worker     auto it = std::find_if(mInboundQueue.rbegin(), mInboundQueue.rend(),
1735*38e8c45fSAndroid Build Coastguard Worker                            [](const std::shared_ptr<const EventEntry>& event) {
1736*38e8c45fSAndroid Build Coastguard Worker                                return event->type == EventEntry::Type::FOCUS;
1737*38e8c45fSAndroid Build Coastguard Worker                            });
1738*38e8c45fSAndroid Build Coastguard Worker 
1739*38e8c45fSAndroid Build Coastguard Worker     // Maintain the order of focus events. Insert the entry after all other focus events.
1740*38e8c45fSAndroid Build Coastguard Worker     mInboundQueue.insert(it.base(), std::move(focusEntry));
1741*38e8c45fSAndroid Build Coastguard Worker }
1742*38e8c45fSAndroid Build Coastguard Worker 
dispatchFocusLocked(nsecs_t currentTime,std::shared_ptr<const FocusEntry> entry)1743*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::dispatchFocusLocked(nsecs_t currentTime,
1744*38e8c45fSAndroid Build Coastguard Worker                                           std::shared_ptr<const FocusEntry> entry) {
1745*38e8c45fSAndroid Build Coastguard Worker     std::shared_ptr<Connection> connection = getConnectionLocked(entry->connectionToken);
1746*38e8c45fSAndroid Build Coastguard Worker     if (connection == nullptr) {
1747*38e8c45fSAndroid Build Coastguard Worker         return; // Connection has gone away
1748*38e8c45fSAndroid Build Coastguard Worker     }
1749*38e8c45fSAndroid Build Coastguard Worker     entry->dispatchInProgress = true;
1750*38e8c45fSAndroid Build Coastguard Worker     std::string message = std::string("Focus ") + (entry->hasFocus ? "entering " : "leaving ") +
1751*38e8c45fSAndroid Build Coastguard Worker             connection->getInputChannelName();
1752*38e8c45fSAndroid Build Coastguard Worker     std::string reason = std::string("reason=").append(entry->reason);
1753*38e8c45fSAndroid Build Coastguard Worker     android_log_event_list(LOGTAG_INPUT_FOCUS) << message << reason << LOG_ID_EVENTS;
1754*38e8c45fSAndroid Build Coastguard Worker     dispatchEventLocked(currentTime, entry, {{connection}});
1755*38e8c45fSAndroid Build Coastguard Worker }
1756*38e8c45fSAndroid Build Coastguard Worker 
dispatchPointerCaptureChangedLocked(nsecs_t currentTime,const std::shared_ptr<const PointerCaptureChangedEntry> & entry,DropReason & dropReason)1757*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::dispatchPointerCaptureChangedLocked(
1758*38e8c45fSAndroid Build Coastguard Worker         nsecs_t currentTime, const std::shared_ptr<const PointerCaptureChangedEntry>& entry,
1759*38e8c45fSAndroid Build Coastguard Worker         DropReason& dropReason) {
1760*38e8c45fSAndroid Build Coastguard Worker     dropReason = DropReason::NOT_DROPPED;
1761*38e8c45fSAndroid Build Coastguard Worker 
1762*38e8c45fSAndroid Build Coastguard Worker     const bool haveWindowWithPointerCapture = mWindowTokenWithPointerCapture != nullptr;
1763*38e8c45fSAndroid Build Coastguard Worker     sp<IBinder> token;
1764*38e8c45fSAndroid Build Coastguard Worker 
1765*38e8c45fSAndroid Build Coastguard Worker     if (entry->pointerCaptureRequest.isEnable()) {
1766*38e8c45fSAndroid Build Coastguard Worker         // Enable Pointer Capture.
1767*38e8c45fSAndroid Build Coastguard Worker         if (haveWindowWithPointerCapture &&
1768*38e8c45fSAndroid Build Coastguard Worker             (entry->pointerCaptureRequest == mCurrentPointerCaptureRequest)) {
1769*38e8c45fSAndroid Build Coastguard Worker             // This can happen if pointer capture is disabled and re-enabled before we notify the
1770*38e8c45fSAndroid Build Coastguard Worker             // app of the state change, so there is no need to notify the app.
1771*38e8c45fSAndroid Build Coastguard Worker             ALOGI("Skipping dispatch of Pointer Capture being enabled: no state change.");
1772*38e8c45fSAndroid Build Coastguard Worker             return;
1773*38e8c45fSAndroid Build Coastguard Worker         }
1774*38e8c45fSAndroid Build Coastguard Worker         if (!mCurrentPointerCaptureRequest.isEnable()) {
1775*38e8c45fSAndroid Build Coastguard Worker             // This can happen if a window requests capture and immediately releases capture.
1776*38e8c45fSAndroid Build Coastguard Worker             ALOGW("No window requested Pointer Capture.");
1777*38e8c45fSAndroid Build Coastguard Worker             dropReason = DropReason::NO_POINTER_CAPTURE;
1778*38e8c45fSAndroid Build Coastguard Worker             return;
1779*38e8c45fSAndroid Build Coastguard Worker         }
1780*38e8c45fSAndroid Build Coastguard Worker         if (entry->pointerCaptureRequest.seq != mCurrentPointerCaptureRequest.seq) {
1781*38e8c45fSAndroid Build Coastguard Worker             ALOGI("Skipping dispatch of Pointer Capture being enabled: sequence number mismatch.");
1782*38e8c45fSAndroid Build Coastguard Worker             return;
1783*38e8c45fSAndroid Build Coastguard Worker         }
1784*38e8c45fSAndroid Build Coastguard Worker 
1785*38e8c45fSAndroid Build Coastguard Worker         token = mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
1786*38e8c45fSAndroid Build Coastguard Worker         LOG_ALWAYS_FATAL_IF(!token, "Cannot find focused window for Pointer Capture.");
1787*38e8c45fSAndroid Build Coastguard Worker         LOG_ALWAYS_FATAL_IF(token != entry->pointerCaptureRequest.window,
1788*38e8c45fSAndroid Build Coastguard Worker                             "Unexpected requested window for Pointer Capture.");
1789*38e8c45fSAndroid Build Coastguard Worker         mWindowTokenWithPointerCapture = token;
1790*38e8c45fSAndroid Build Coastguard Worker     } else {
1791*38e8c45fSAndroid Build Coastguard Worker         // Disable Pointer Capture.
1792*38e8c45fSAndroid Build Coastguard Worker         // We do not check if the sequence number matches for requests to disable Pointer Capture
1793*38e8c45fSAndroid Build Coastguard Worker         // for two reasons:
1794*38e8c45fSAndroid Build Coastguard Worker         //  1. Pointer Capture can be disabled by a focus change, which means we can get two entries
1795*38e8c45fSAndroid Build Coastguard Worker         //     to disable capture with the same sequence number: one generated by
1796*38e8c45fSAndroid Build Coastguard Worker         //     disablePointerCaptureForcedLocked() and another as an acknowledgement of Pointer
1797*38e8c45fSAndroid Build Coastguard Worker         //     Capture being disabled in InputReader.
1798*38e8c45fSAndroid Build Coastguard Worker         //  2. We respect any request to disable Pointer Capture generated by InputReader, since the
1799*38e8c45fSAndroid Build Coastguard Worker         //     actual Pointer Capture state that affects events being generated by input devices is
1800*38e8c45fSAndroid Build Coastguard Worker         //     in InputReader.
1801*38e8c45fSAndroid Build Coastguard Worker         if (!haveWindowWithPointerCapture) {
1802*38e8c45fSAndroid Build Coastguard Worker             // Pointer capture was already forcefully disabled because of focus change.
1803*38e8c45fSAndroid Build Coastguard Worker             dropReason = DropReason::NOT_DROPPED;
1804*38e8c45fSAndroid Build Coastguard Worker             return;
1805*38e8c45fSAndroid Build Coastguard Worker         }
1806*38e8c45fSAndroid Build Coastguard Worker         token = mWindowTokenWithPointerCapture;
1807*38e8c45fSAndroid Build Coastguard Worker         mWindowTokenWithPointerCapture = nullptr;
1808*38e8c45fSAndroid Build Coastguard Worker         if (mCurrentPointerCaptureRequest.isEnable()) {
1809*38e8c45fSAndroid Build Coastguard Worker             setPointerCaptureLocked(nullptr);
1810*38e8c45fSAndroid Build Coastguard Worker         }
1811*38e8c45fSAndroid Build Coastguard Worker     }
1812*38e8c45fSAndroid Build Coastguard Worker 
1813*38e8c45fSAndroid Build Coastguard Worker     auto connection = getConnectionLocked(token);
1814*38e8c45fSAndroid Build Coastguard Worker     if (connection == nullptr) {
1815*38e8c45fSAndroid Build Coastguard Worker         // Window has gone away, clean up Pointer Capture state.
1816*38e8c45fSAndroid Build Coastguard Worker         mWindowTokenWithPointerCapture = nullptr;
1817*38e8c45fSAndroid Build Coastguard Worker         if (mCurrentPointerCaptureRequest.isEnable()) {
1818*38e8c45fSAndroid Build Coastguard Worker             setPointerCaptureLocked(nullptr);
1819*38e8c45fSAndroid Build Coastguard Worker         }
1820*38e8c45fSAndroid Build Coastguard Worker         return;
1821*38e8c45fSAndroid Build Coastguard Worker     }
1822*38e8c45fSAndroid Build Coastguard Worker     entry->dispatchInProgress = true;
1823*38e8c45fSAndroid Build Coastguard Worker     dispatchEventLocked(currentTime, entry, {{connection}});
1824*38e8c45fSAndroid Build Coastguard Worker 
1825*38e8c45fSAndroid Build Coastguard Worker     dropReason = DropReason::NOT_DROPPED;
1826*38e8c45fSAndroid Build Coastguard Worker }
1827*38e8c45fSAndroid Build Coastguard Worker 
dispatchTouchModeChangeLocked(nsecs_t currentTime,const std::shared_ptr<const TouchModeEntry> & entry)1828*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::dispatchTouchModeChangeLocked(
1829*38e8c45fSAndroid Build Coastguard Worker         nsecs_t currentTime, const std::shared_ptr<const TouchModeEntry>& entry) {
1830*38e8c45fSAndroid Build Coastguard Worker     const std::vector<sp<WindowInfoHandle>>& windowHandles =
1831*38e8c45fSAndroid Build Coastguard Worker             getWindowHandlesLocked(entry->displayId);
1832*38e8c45fSAndroid Build Coastguard Worker     if (windowHandles.empty()) {
1833*38e8c45fSAndroid Build Coastguard Worker         return;
1834*38e8c45fSAndroid Build Coastguard Worker     }
1835*38e8c45fSAndroid Build Coastguard Worker     const std::vector<InputTarget> inputTargets =
1836*38e8c45fSAndroid Build Coastguard Worker             getInputTargetsFromWindowHandlesLocked(windowHandles);
1837*38e8c45fSAndroid Build Coastguard Worker     if (inputTargets.empty()) {
1838*38e8c45fSAndroid Build Coastguard Worker         return;
1839*38e8c45fSAndroid Build Coastguard Worker     }
1840*38e8c45fSAndroid Build Coastguard Worker     entry->dispatchInProgress = true;
1841*38e8c45fSAndroid Build Coastguard Worker     dispatchEventLocked(currentTime, entry, inputTargets);
1842*38e8c45fSAndroid Build Coastguard Worker }
1843*38e8c45fSAndroid Build Coastguard Worker 
getInputTargetsFromWindowHandlesLocked(const std::vector<sp<WindowInfoHandle>> & windowHandles) const1844*38e8c45fSAndroid Build Coastguard Worker std::vector<InputTarget> InputDispatcher::getInputTargetsFromWindowHandlesLocked(
1845*38e8c45fSAndroid Build Coastguard Worker         const std::vector<sp<WindowInfoHandle>>& windowHandles) const {
1846*38e8c45fSAndroid Build Coastguard Worker     std::vector<InputTarget> inputTargets;
1847*38e8c45fSAndroid Build Coastguard Worker     for (const sp<WindowInfoHandle>& handle : windowHandles) {
1848*38e8c45fSAndroid Build Coastguard Worker         const sp<IBinder>& token = handle->getToken();
1849*38e8c45fSAndroid Build Coastguard Worker         if (token == nullptr) {
1850*38e8c45fSAndroid Build Coastguard Worker             continue;
1851*38e8c45fSAndroid Build Coastguard Worker         }
1852*38e8c45fSAndroid Build Coastguard Worker         std::shared_ptr<Connection> connection = getConnectionLocked(token);
1853*38e8c45fSAndroid Build Coastguard Worker         if (connection == nullptr) {
1854*38e8c45fSAndroid Build Coastguard Worker             continue; // Connection has gone away
1855*38e8c45fSAndroid Build Coastguard Worker         }
1856*38e8c45fSAndroid Build Coastguard Worker         inputTargets.emplace_back(connection);
1857*38e8c45fSAndroid Build Coastguard Worker     }
1858*38e8c45fSAndroid Build Coastguard Worker     return inputTargets;
1859*38e8c45fSAndroid Build Coastguard Worker }
1860*38e8c45fSAndroid Build Coastguard Worker 
dispatchKeyLocked(nsecs_t currentTime,std::shared_ptr<const KeyEntry> entry,DropReason * dropReason,nsecs_t & nextWakeupTime)1861*38e8c45fSAndroid Build Coastguard Worker bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, std::shared_ptr<const KeyEntry> entry,
1862*38e8c45fSAndroid Build Coastguard Worker                                         DropReason* dropReason, nsecs_t& nextWakeupTime) {
1863*38e8c45fSAndroid Build Coastguard Worker     // Preprocessing.
1864*38e8c45fSAndroid Build Coastguard Worker     if (!entry->dispatchInProgress) {
1865*38e8c45fSAndroid Build Coastguard Worker         if (!entry->syntheticRepeat && entry->action == AKEY_EVENT_ACTION_DOWN &&
1866*38e8c45fSAndroid Build Coastguard Worker             (entry->policyFlags & POLICY_FLAG_TRUSTED) &&
1867*38e8c45fSAndroid Build Coastguard Worker             (!(entry->policyFlags & POLICY_FLAG_DISABLE_KEY_REPEAT))) {
1868*38e8c45fSAndroid Build Coastguard Worker             if (mKeyRepeatState.lastKeyEntry &&
1869*38e8c45fSAndroid Build Coastguard Worker                 mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode &&
1870*38e8c45fSAndroid Build Coastguard Worker                 // We have seen two identical key downs in a row which indicates that the device
1871*38e8c45fSAndroid Build Coastguard Worker                 // driver is automatically generating key repeats itself.  We take note of the
1872*38e8c45fSAndroid Build Coastguard Worker                 // repeat here, but we disable our own next key repeat timer since it is clear that
1873*38e8c45fSAndroid Build Coastguard Worker                 // we will not need to synthesize key repeats ourselves.
1874*38e8c45fSAndroid Build Coastguard Worker                 mKeyRepeatState.lastKeyEntry->deviceId == entry->deviceId) {
1875*38e8c45fSAndroid Build Coastguard Worker                 // Make sure we don't get key down from a different device. If a different
1876*38e8c45fSAndroid Build Coastguard Worker                 // device Id has same key pressed down, the new device Id will replace the
1877*38e8c45fSAndroid Build Coastguard Worker                 // current one to hold the key repeat with repeat count reset.
1878*38e8c45fSAndroid Build Coastguard Worker                 // In the future when got a KEY_UP on the device id, drop it and do not
1879*38e8c45fSAndroid Build Coastguard Worker                 // stop the key repeat on current device.
1880*38e8c45fSAndroid Build Coastguard Worker                 entry->repeatCount = mKeyRepeatState.lastKeyEntry->repeatCount + 1;
1881*38e8c45fSAndroid Build Coastguard Worker                 resetKeyRepeatLocked();
1882*38e8c45fSAndroid Build Coastguard Worker                 mKeyRepeatState.nextRepeatTime = LLONG_MAX; // don't generate repeats ourselves
1883*38e8c45fSAndroid Build Coastguard Worker             } else {
1884*38e8c45fSAndroid Build Coastguard Worker                 // Not a repeat.  Save key down state in case we do see a repeat later.
1885*38e8c45fSAndroid Build Coastguard Worker                 resetKeyRepeatLocked();
1886*38e8c45fSAndroid Build Coastguard Worker                 mKeyRepeatState.nextRepeatTime = entry->eventTime + mConfig.keyRepeatTimeout;
1887*38e8c45fSAndroid Build Coastguard Worker             }
1888*38e8c45fSAndroid Build Coastguard Worker             mKeyRepeatState.lastKeyEntry = entry;
1889*38e8c45fSAndroid Build Coastguard Worker         } else if (entry->action == AKEY_EVENT_ACTION_UP && mKeyRepeatState.lastKeyEntry &&
1890*38e8c45fSAndroid Build Coastguard Worker                    mKeyRepeatState.lastKeyEntry->deviceId != entry->deviceId) {
1891*38e8c45fSAndroid Build Coastguard Worker             // The key on device 'deviceId' is still down, do not stop key repeat
1892*38e8c45fSAndroid Build Coastguard Worker             if (debugInboundEventDetails()) {
1893*38e8c45fSAndroid Build Coastguard Worker                 ALOGD("deviceId=%d got KEY_UP as stale", entry->deviceId);
1894*38e8c45fSAndroid Build Coastguard Worker             }
1895*38e8c45fSAndroid Build Coastguard Worker         } else if (!entry->syntheticRepeat) {
1896*38e8c45fSAndroid Build Coastguard Worker             resetKeyRepeatLocked();
1897*38e8c45fSAndroid Build Coastguard Worker         }
1898*38e8c45fSAndroid Build Coastguard Worker 
1899*38e8c45fSAndroid Build Coastguard Worker         if (entry->repeatCount == 1) {
1900*38e8c45fSAndroid Build Coastguard Worker             entry->flags |= AKEY_EVENT_FLAG_LONG_PRESS;
1901*38e8c45fSAndroid Build Coastguard Worker         } else {
1902*38e8c45fSAndroid Build Coastguard Worker             entry->flags &= ~AKEY_EVENT_FLAG_LONG_PRESS;
1903*38e8c45fSAndroid Build Coastguard Worker         }
1904*38e8c45fSAndroid Build Coastguard Worker 
1905*38e8c45fSAndroid Build Coastguard Worker         entry->dispatchInProgress = true;
1906*38e8c45fSAndroid Build Coastguard Worker 
1907*38e8c45fSAndroid Build Coastguard Worker         logOutboundKeyDetails("dispatchKey - ", *entry);
1908*38e8c45fSAndroid Build Coastguard Worker     }
1909*38e8c45fSAndroid Build Coastguard Worker 
1910*38e8c45fSAndroid Build Coastguard Worker     // Handle case where the policy asked us to try again later last time.
1911*38e8c45fSAndroid Build Coastguard Worker     if (entry->interceptKeyResult == KeyEntry::InterceptKeyResult::TRY_AGAIN_LATER) {
1912*38e8c45fSAndroid Build Coastguard Worker         if (currentTime < entry->interceptKeyWakeupTime) {
1913*38e8c45fSAndroid Build Coastguard Worker             nextWakeupTime = std::min(nextWakeupTime, entry->interceptKeyWakeupTime);
1914*38e8c45fSAndroid Build Coastguard Worker             return false; // wait until next wakeup
1915*38e8c45fSAndroid Build Coastguard Worker         }
1916*38e8c45fSAndroid Build Coastguard Worker         entry->interceptKeyResult = KeyEntry::InterceptKeyResult::UNKNOWN;
1917*38e8c45fSAndroid Build Coastguard Worker         entry->interceptKeyWakeupTime = 0;
1918*38e8c45fSAndroid Build Coastguard Worker     }
1919*38e8c45fSAndroid Build Coastguard Worker 
1920*38e8c45fSAndroid Build Coastguard Worker     // Give the policy a chance to intercept the key.
1921*38e8c45fSAndroid Build Coastguard Worker     if (entry->interceptKeyResult == KeyEntry::InterceptKeyResult::UNKNOWN) {
1922*38e8c45fSAndroid Build Coastguard Worker         if (entry->policyFlags & POLICY_FLAG_PASS_TO_USER) {
1923*38e8c45fSAndroid Build Coastguard Worker             sp<IBinder> focusedWindowToken =
1924*38e8c45fSAndroid Build Coastguard Worker                     mFocusResolver.getFocusedWindowToken(getTargetDisplayId(*entry));
1925*38e8c45fSAndroid Build Coastguard Worker 
1926*38e8c45fSAndroid Build Coastguard Worker             auto command = [this, focusedWindowToken, entry]() REQUIRES(mLock) {
1927*38e8c45fSAndroid Build Coastguard Worker                 doInterceptKeyBeforeDispatchingCommand(focusedWindowToken, *entry);
1928*38e8c45fSAndroid Build Coastguard Worker             };
1929*38e8c45fSAndroid Build Coastguard Worker             postCommandLocked(std::move(command));
1930*38e8c45fSAndroid Build Coastguard Worker             return false; // wait for the command to run
1931*38e8c45fSAndroid Build Coastguard Worker         } else {
1932*38e8c45fSAndroid Build Coastguard Worker             entry->interceptKeyResult = KeyEntry::InterceptKeyResult::CONTINUE;
1933*38e8c45fSAndroid Build Coastguard Worker         }
1934*38e8c45fSAndroid Build Coastguard Worker     } else if (entry->interceptKeyResult == KeyEntry::InterceptKeyResult::SKIP) {
1935*38e8c45fSAndroid Build Coastguard Worker         if (*dropReason == DropReason::NOT_DROPPED) {
1936*38e8c45fSAndroid Build Coastguard Worker             *dropReason = DropReason::POLICY;
1937*38e8c45fSAndroid Build Coastguard Worker         }
1938*38e8c45fSAndroid Build Coastguard Worker     }
1939*38e8c45fSAndroid Build Coastguard Worker 
1940*38e8c45fSAndroid Build Coastguard Worker     // Clean up if dropping the event.
1941*38e8c45fSAndroid Build Coastguard Worker     if (*dropReason != DropReason::NOT_DROPPED) {
1942*38e8c45fSAndroid Build Coastguard Worker         setInjectionResult(*entry,
1943*38e8c45fSAndroid Build Coastguard Worker                            *dropReason == DropReason::POLICY ? InputEventInjectionResult::SUCCEEDED
1944*38e8c45fSAndroid Build Coastguard Worker                                                              : InputEventInjectionResult::FAILED);
1945*38e8c45fSAndroid Build Coastguard Worker         mReporter->reportDroppedKey(entry->id);
1946*38e8c45fSAndroid Build Coastguard Worker         // Poke user activity for consumed keys, as it may have not been reported due to
1947*38e8c45fSAndroid Build Coastguard Worker         // the focused window requesting user activity to be disabled
1948*38e8c45fSAndroid Build Coastguard Worker         if (*dropReason == DropReason::POLICY &&
1949*38e8c45fSAndroid Build Coastguard Worker             mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER) {
1950*38e8c45fSAndroid Build Coastguard Worker             pokeUserActivityLocked(*entry);
1951*38e8c45fSAndroid Build Coastguard Worker         }
1952*38e8c45fSAndroid Build Coastguard Worker         return true;
1953*38e8c45fSAndroid Build Coastguard Worker     }
1954*38e8c45fSAndroid Build Coastguard Worker 
1955*38e8c45fSAndroid Build Coastguard Worker     // Identify targets.
1956*38e8c45fSAndroid Build Coastguard Worker     Result<sp<WindowInfoHandle>, InputEventInjectionResult> result =
1957*38e8c45fSAndroid Build Coastguard Worker             findFocusedWindowTargetLocked(currentTime, *entry, nextWakeupTime);
1958*38e8c45fSAndroid Build Coastguard Worker 
1959*38e8c45fSAndroid Build Coastguard Worker     if (!result.ok()) {
1960*38e8c45fSAndroid Build Coastguard Worker         if (result.error().code() == InputEventInjectionResult::PENDING) {
1961*38e8c45fSAndroid Build Coastguard Worker             return false;
1962*38e8c45fSAndroid Build Coastguard Worker         }
1963*38e8c45fSAndroid Build Coastguard Worker         setInjectionResult(*entry, result.error().code());
1964*38e8c45fSAndroid Build Coastguard Worker         return true;
1965*38e8c45fSAndroid Build Coastguard Worker     }
1966*38e8c45fSAndroid Build Coastguard Worker     sp<WindowInfoHandle>& focusedWindow = *result;
1967*38e8c45fSAndroid Build Coastguard Worker     LOG_ALWAYS_FATAL_IF(focusedWindow == nullptr);
1968*38e8c45fSAndroid Build Coastguard Worker 
1969*38e8c45fSAndroid Build Coastguard Worker     setInjectionResult(*entry, InputEventInjectionResult::SUCCEEDED);
1970*38e8c45fSAndroid Build Coastguard Worker 
1971*38e8c45fSAndroid Build Coastguard Worker     std::vector<InputTarget> inputTargets;
1972*38e8c45fSAndroid Build Coastguard Worker     addWindowTargetLocked(focusedWindow, InputTarget::DispatchMode::AS_IS,
1973*38e8c45fSAndroid Build Coastguard Worker                           InputTarget::Flags::FOREGROUND, getDownTime(*entry), inputTargets);
1974*38e8c45fSAndroid Build Coastguard Worker 
1975*38e8c45fSAndroid Build Coastguard Worker     // Add monitor channels from event's or focused display.
1976*38e8c45fSAndroid Build Coastguard Worker     addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
1977*38e8c45fSAndroid Build Coastguard Worker 
1978*38e8c45fSAndroid Build Coastguard Worker     if (mTracer) {
1979*38e8c45fSAndroid Build Coastguard Worker         ensureEventTraced(*entry);
1980*38e8c45fSAndroid Build Coastguard Worker         for (const auto& target : inputTargets) {
1981*38e8c45fSAndroid Build Coastguard Worker             mTracer->dispatchToTargetHint(*entry->traceTracker, target);
1982*38e8c45fSAndroid Build Coastguard Worker         }
1983*38e8c45fSAndroid Build Coastguard Worker     }
1984*38e8c45fSAndroid Build Coastguard Worker 
1985*38e8c45fSAndroid Build Coastguard Worker     // Dispatch the key.
1986*38e8c45fSAndroid Build Coastguard Worker     dispatchEventLocked(currentTime, entry, inputTargets);
1987*38e8c45fSAndroid Build Coastguard Worker     return true;
1988*38e8c45fSAndroid Build Coastguard Worker }
1989*38e8c45fSAndroid Build Coastguard Worker 
logOutboundKeyDetails(const char * prefix,const KeyEntry & entry)1990*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::logOutboundKeyDetails(const char* prefix, const KeyEntry& entry) {
1991*38e8c45fSAndroid Build Coastguard Worker     if (DEBUG_OUTBOUND_EVENT_DETAILS) {
1992*38e8c45fSAndroid Build Coastguard Worker         ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%s, "
1993*38e8c45fSAndroid Build Coastguard Worker               "policyFlags=0x%x, action=0x%x, flags=0x%x, keyCode=0x%x, scanCode=0x%x, "
1994*38e8c45fSAndroid Build Coastguard Worker               "metaState=0x%x, repeatCount=%d, downTime=%" PRId64,
1995*38e8c45fSAndroid Build Coastguard Worker               prefix, entry.eventTime, entry.deviceId, entry.source,
1996*38e8c45fSAndroid Build Coastguard Worker               entry.displayId.toString().c_str(), entry.policyFlags, entry.action, entry.flags,
1997*38e8c45fSAndroid Build Coastguard Worker               entry.keyCode, entry.scanCode, entry.metaState, entry.repeatCount, entry.downTime);
1998*38e8c45fSAndroid Build Coastguard Worker     }
1999*38e8c45fSAndroid Build Coastguard Worker }
2000*38e8c45fSAndroid Build Coastguard Worker 
dispatchSensorLocked(nsecs_t currentTime,const std::shared_ptr<const SensorEntry> & entry,DropReason * dropReason,nsecs_t & nextWakeupTime)2001*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::dispatchSensorLocked(nsecs_t currentTime,
2002*38e8c45fSAndroid Build Coastguard Worker                                            const std::shared_ptr<const SensorEntry>& entry,
2003*38e8c45fSAndroid Build Coastguard Worker                                            DropReason* dropReason, nsecs_t& nextWakeupTime) {
2004*38e8c45fSAndroid Build Coastguard Worker     if (DEBUG_OUTBOUND_EVENT_DETAILS) {
2005*38e8c45fSAndroid Build Coastguard Worker         ALOGD("notifySensorEvent eventTime=%" PRId64 ", hwTimestamp=%" PRId64 ", deviceId=%d, "
2006*38e8c45fSAndroid Build Coastguard Worker               "source=0x%x, sensorType=%s",
2007*38e8c45fSAndroid Build Coastguard Worker               entry->eventTime, entry->hwTimestamp, entry->deviceId, entry->source,
2008*38e8c45fSAndroid Build Coastguard Worker               ftl::enum_string(entry->sensorType).c_str());
2009*38e8c45fSAndroid Build Coastguard Worker     }
2010*38e8c45fSAndroid Build Coastguard Worker     auto command = [this, entry]() REQUIRES(mLock) {
2011*38e8c45fSAndroid Build Coastguard Worker         scoped_unlock unlock(mLock);
2012*38e8c45fSAndroid Build Coastguard Worker 
2013*38e8c45fSAndroid Build Coastguard Worker         if (entry->accuracyChanged) {
2014*38e8c45fSAndroid Build Coastguard Worker             mPolicy.notifySensorAccuracy(entry->deviceId, entry->sensorType, entry->accuracy);
2015*38e8c45fSAndroid Build Coastguard Worker         }
2016*38e8c45fSAndroid Build Coastguard Worker         mPolicy.notifySensorEvent(entry->deviceId, entry->sensorType, entry->accuracy,
2017*38e8c45fSAndroid Build Coastguard Worker                                   entry->hwTimestamp, entry->values);
2018*38e8c45fSAndroid Build Coastguard Worker     };
2019*38e8c45fSAndroid Build Coastguard Worker     postCommandLocked(std::move(command));
2020*38e8c45fSAndroid Build Coastguard Worker }
2021*38e8c45fSAndroid Build Coastguard Worker 
flushSensor(int deviceId,InputDeviceSensorType sensorType)2022*38e8c45fSAndroid Build Coastguard Worker bool InputDispatcher::flushSensor(int deviceId, InputDeviceSensorType sensorType) {
2023*38e8c45fSAndroid Build Coastguard Worker     if (DEBUG_OUTBOUND_EVENT_DETAILS) {
2024*38e8c45fSAndroid Build Coastguard Worker         ALOGD("flushSensor deviceId=%d, sensorType=%s", deviceId,
2025*38e8c45fSAndroid Build Coastguard Worker               ftl::enum_string(sensorType).c_str());
2026*38e8c45fSAndroid Build Coastguard Worker     }
2027*38e8c45fSAndroid Build Coastguard Worker     { // acquire lock
2028*38e8c45fSAndroid Build Coastguard Worker         std::scoped_lock _l(mLock);
2029*38e8c45fSAndroid Build Coastguard Worker 
2030*38e8c45fSAndroid Build Coastguard Worker         for (auto it = mInboundQueue.begin(); it != mInboundQueue.end(); it++) {
2031*38e8c45fSAndroid Build Coastguard Worker             std::shared_ptr<const EventEntry> entry = *it;
2032*38e8c45fSAndroid Build Coastguard Worker             if (entry->type == EventEntry::Type::SENSOR) {
2033*38e8c45fSAndroid Build Coastguard Worker                 it = mInboundQueue.erase(it);
2034*38e8c45fSAndroid Build Coastguard Worker                 releaseInboundEventLocked(entry);
2035*38e8c45fSAndroid Build Coastguard Worker             }
2036*38e8c45fSAndroid Build Coastguard Worker         }
2037*38e8c45fSAndroid Build Coastguard Worker     }
2038*38e8c45fSAndroid Build Coastguard Worker     return true;
2039*38e8c45fSAndroid Build Coastguard Worker }
2040*38e8c45fSAndroid Build Coastguard Worker 
dispatchMotionLocked(nsecs_t currentTime,std::shared_ptr<const MotionEntry> entry,DropReason * dropReason,nsecs_t & nextWakeupTime)2041*38e8c45fSAndroid Build Coastguard Worker bool InputDispatcher::dispatchMotionLocked(nsecs_t currentTime,
2042*38e8c45fSAndroid Build Coastguard Worker                                            std::shared_ptr<const MotionEntry> entry,
2043*38e8c45fSAndroid Build Coastguard Worker                                            DropReason* dropReason, nsecs_t& nextWakeupTime) {
2044*38e8c45fSAndroid Build Coastguard Worker     ATRACE_CALL();
2045*38e8c45fSAndroid Build Coastguard Worker     // Preprocessing.
2046*38e8c45fSAndroid Build Coastguard Worker     if (!entry->dispatchInProgress) {
2047*38e8c45fSAndroid Build Coastguard Worker         entry->dispatchInProgress = true;
2048*38e8c45fSAndroid Build Coastguard Worker 
2049*38e8c45fSAndroid Build Coastguard Worker         logOutboundMotionDetails("dispatchMotion - ", *entry);
2050*38e8c45fSAndroid Build Coastguard Worker     }
2051*38e8c45fSAndroid Build Coastguard Worker 
2052*38e8c45fSAndroid Build Coastguard Worker     // Clean up if dropping the event.
2053*38e8c45fSAndroid Build Coastguard Worker     if (*dropReason != DropReason::NOT_DROPPED) {
2054*38e8c45fSAndroid Build Coastguard Worker         setInjectionResult(*entry,
2055*38e8c45fSAndroid Build Coastguard Worker                            *dropReason == DropReason::POLICY ? InputEventInjectionResult::SUCCEEDED
2056*38e8c45fSAndroid Build Coastguard Worker                                                              : InputEventInjectionResult::FAILED);
2057*38e8c45fSAndroid Build Coastguard Worker         return true;
2058*38e8c45fSAndroid Build Coastguard Worker     }
2059*38e8c45fSAndroid Build Coastguard Worker 
2060*38e8c45fSAndroid Build Coastguard Worker     const bool isPointerEvent = isFromSource(entry->source, AINPUT_SOURCE_CLASS_POINTER);
2061*38e8c45fSAndroid Build Coastguard Worker 
2062*38e8c45fSAndroid Build Coastguard Worker     // Identify targets.
2063*38e8c45fSAndroid Build Coastguard Worker     std::vector<InputTarget> inputTargets;
2064*38e8c45fSAndroid Build Coastguard Worker 
2065*38e8c45fSAndroid Build Coastguard Worker     InputEventInjectionResult injectionResult;
2066*38e8c45fSAndroid Build Coastguard Worker     if (isPointerEvent) {
2067*38e8c45fSAndroid Build Coastguard Worker         // Pointer event.  (eg. touchscreen)
2068*38e8c45fSAndroid Build Coastguard Worker 
2069*38e8c45fSAndroid Build Coastguard Worker         if (mDragState &&
2070*38e8c45fSAndroid Build Coastguard Worker             (entry->action & AMOTION_EVENT_ACTION_MASK) == AMOTION_EVENT_ACTION_POINTER_DOWN) {
2071*38e8c45fSAndroid Build Coastguard Worker             // If drag and drop ongoing and pointer down occur: pilfer drag window pointers
2072*38e8c45fSAndroid Build Coastguard Worker             pilferPointersLocked(mDragState->dragWindow->getToken());
2073*38e8c45fSAndroid Build Coastguard Worker         }
2074*38e8c45fSAndroid Build Coastguard Worker 
2075*38e8c45fSAndroid Build Coastguard Worker         Result<std::vector<InputTarget>, InputEventInjectionResult> result =
2076*38e8c45fSAndroid Build Coastguard Worker                 findTouchedWindowTargetsLocked(currentTime, *entry);
2077*38e8c45fSAndroid Build Coastguard Worker 
2078*38e8c45fSAndroid Build Coastguard Worker         if (result.ok()) {
2079*38e8c45fSAndroid Build Coastguard Worker             inputTargets = std::move(*result);
2080*38e8c45fSAndroid Build Coastguard Worker             injectionResult = InputEventInjectionResult::SUCCEEDED;
2081*38e8c45fSAndroid Build Coastguard Worker         } else {
2082*38e8c45fSAndroid Build Coastguard Worker             injectionResult = result.error().code();
2083*38e8c45fSAndroid Build Coastguard Worker         }
2084*38e8c45fSAndroid Build Coastguard Worker     } else {
2085*38e8c45fSAndroid Build Coastguard Worker         // Non touch event.  (eg. trackball)
2086*38e8c45fSAndroid Build Coastguard Worker         Result<sp<WindowInfoHandle>, InputEventInjectionResult> result =
2087*38e8c45fSAndroid Build Coastguard Worker                 findFocusedWindowTargetLocked(currentTime, *entry, nextWakeupTime);
2088*38e8c45fSAndroid Build Coastguard Worker         if (result.ok()) {
2089*38e8c45fSAndroid Build Coastguard Worker             sp<WindowInfoHandle>& focusedWindow = *result;
2090*38e8c45fSAndroid Build Coastguard Worker             LOG_ALWAYS_FATAL_IF(focusedWindow == nullptr);
2091*38e8c45fSAndroid Build Coastguard Worker             addWindowTargetLocked(focusedWindow, InputTarget::DispatchMode::AS_IS,
2092*38e8c45fSAndroid Build Coastguard Worker                                   InputTarget::Flags::FOREGROUND, getDownTime(*entry),
2093*38e8c45fSAndroid Build Coastguard Worker                                   inputTargets);
2094*38e8c45fSAndroid Build Coastguard Worker             injectionResult = InputEventInjectionResult::SUCCEEDED;
2095*38e8c45fSAndroid Build Coastguard Worker         } else {
2096*38e8c45fSAndroid Build Coastguard Worker             injectionResult = result.error().code();
2097*38e8c45fSAndroid Build Coastguard Worker         }
2098*38e8c45fSAndroid Build Coastguard Worker     }
2099*38e8c45fSAndroid Build Coastguard Worker     if (injectionResult == InputEventInjectionResult::PENDING) {
2100*38e8c45fSAndroid Build Coastguard Worker         return false;
2101*38e8c45fSAndroid Build Coastguard Worker     }
2102*38e8c45fSAndroid Build Coastguard Worker 
2103*38e8c45fSAndroid Build Coastguard Worker     setInjectionResult(*entry, injectionResult);
2104*38e8c45fSAndroid Build Coastguard Worker     if (injectionResult == InputEventInjectionResult::TARGET_MISMATCH) {
2105*38e8c45fSAndroid Build Coastguard Worker         return true;
2106*38e8c45fSAndroid Build Coastguard Worker     }
2107*38e8c45fSAndroid Build Coastguard Worker     if (injectionResult != InputEventInjectionResult::SUCCEEDED) {
2108*38e8c45fSAndroid Build Coastguard Worker         CancelationOptions::Mode mode(
2109*38e8c45fSAndroid Build Coastguard Worker                 isPointerEvent ? CancelationOptions::Mode::CANCEL_POINTER_EVENTS
2110*38e8c45fSAndroid Build Coastguard Worker                                : CancelationOptions::Mode::CANCEL_NON_POINTER_EVENTS);
2111*38e8c45fSAndroid Build Coastguard Worker         CancelationOptions options(mode, "input event injection failed", entry->traceTracker);
2112*38e8c45fSAndroid Build Coastguard Worker         options.displayId = entry->displayId;
2113*38e8c45fSAndroid Build Coastguard Worker         synthesizeCancelationEventsForMonitorsLocked(options);
2114*38e8c45fSAndroid Build Coastguard Worker         return true;
2115*38e8c45fSAndroid Build Coastguard Worker     }
2116*38e8c45fSAndroid Build Coastguard Worker 
2117*38e8c45fSAndroid Build Coastguard Worker     // Add monitor channels from event's or focused display.
2118*38e8c45fSAndroid Build Coastguard Worker     addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
2119*38e8c45fSAndroid Build Coastguard Worker 
2120*38e8c45fSAndroid Build Coastguard Worker     if (mTracer) {
2121*38e8c45fSAndroid Build Coastguard Worker         ensureEventTraced(*entry);
2122*38e8c45fSAndroid Build Coastguard Worker         for (const auto& target : inputTargets) {
2123*38e8c45fSAndroid Build Coastguard Worker             mTracer->dispatchToTargetHint(*entry->traceTracker, target);
2124*38e8c45fSAndroid Build Coastguard Worker         }
2125*38e8c45fSAndroid Build Coastguard Worker     }
2126*38e8c45fSAndroid Build Coastguard Worker 
2127*38e8c45fSAndroid Build Coastguard Worker     // Dispatch the motion.
2128*38e8c45fSAndroid Build Coastguard Worker     dispatchEventLocked(currentTime, entry, inputTargets);
2129*38e8c45fSAndroid Build Coastguard Worker     return true;
2130*38e8c45fSAndroid Build Coastguard Worker }
2131*38e8c45fSAndroid Build Coastguard Worker 
enqueueDragEventLocked(const sp<WindowInfoHandle> & windowHandle,bool isExiting,const int32_t rawX,const int32_t rawY)2132*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::enqueueDragEventLocked(const sp<WindowInfoHandle>& windowHandle,
2133*38e8c45fSAndroid Build Coastguard Worker                                              bool isExiting, const int32_t rawX,
2134*38e8c45fSAndroid Build Coastguard Worker                                              const int32_t rawY) {
2135*38e8c45fSAndroid Build Coastguard Worker     const vec2 xy = windowHandle->getInfo()->transform.transform(vec2(rawX, rawY));
2136*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<DragEntry> dragEntry =
2137*38e8c45fSAndroid Build Coastguard Worker             std::make_unique<DragEntry>(mIdGenerator.nextId(), now(), windowHandle->getToken(),
2138*38e8c45fSAndroid Build Coastguard Worker                                         isExiting, xy.x, xy.y);
2139*38e8c45fSAndroid Build Coastguard Worker 
2140*38e8c45fSAndroid Build Coastguard Worker     enqueueInboundEventLocked(std::move(dragEntry));
2141*38e8c45fSAndroid Build Coastguard Worker }
2142*38e8c45fSAndroid Build Coastguard Worker 
dispatchDragLocked(nsecs_t currentTime,std::shared_ptr<const DragEntry> entry)2143*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::dispatchDragLocked(nsecs_t currentTime,
2144*38e8c45fSAndroid Build Coastguard Worker                                          std::shared_ptr<const DragEntry> entry) {
2145*38e8c45fSAndroid Build Coastguard Worker     std::shared_ptr<Connection> connection = getConnectionLocked(entry->connectionToken);
2146*38e8c45fSAndroid Build Coastguard Worker     if (connection == nullptr) {
2147*38e8c45fSAndroid Build Coastguard Worker         return; // Connection has gone away
2148*38e8c45fSAndroid Build Coastguard Worker     }
2149*38e8c45fSAndroid Build Coastguard Worker     entry->dispatchInProgress = true;
2150*38e8c45fSAndroid Build Coastguard Worker     dispatchEventLocked(currentTime, entry, {{connection}});
2151*38e8c45fSAndroid Build Coastguard Worker }
2152*38e8c45fSAndroid Build Coastguard Worker 
logOutboundMotionDetails(const char * prefix,const MotionEntry & entry)2153*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::logOutboundMotionDetails(const char* prefix, const MotionEntry& entry) {
2154*38e8c45fSAndroid Build Coastguard Worker     if (DEBUG_OUTBOUND_EVENT_DETAILS) {
2155*38e8c45fSAndroid Build Coastguard Worker         ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=%s, displayId=%s, policyFlags=0x%x, "
2156*38e8c45fSAndroid Build Coastguard Worker               "action=%s, actionButton=0x%x, flags=0x%x, "
2157*38e8c45fSAndroid Build Coastguard Worker               "metaState=0x%x, buttonState=0x%x, downTime=%" PRId64,
2158*38e8c45fSAndroid Build Coastguard Worker               prefix, entry.eventTime, entry.deviceId,
2159*38e8c45fSAndroid Build Coastguard Worker               inputEventSourceToString(entry.source).c_str(), entry.displayId.toString().c_str(),
2160*38e8c45fSAndroid Build Coastguard Worker               entry.policyFlags, MotionEvent::actionToString(entry.action).c_str(),
2161*38e8c45fSAndroid Build Coastguard Worker               entry.actionButton, entry.flags, entry.metaState, entry.buttonState, entry.downTime);
2162*38e8c45fSAndroid Build Coastguard Worker 
2163*38e8c45fSAndroid Build Coastguard Worker         for (uint32_t i = 0; i < entry.getPointerCount(); i++) {
2164*38e8c45fSAndroid Build Coastguard Worker             ALOGD("  Pointer %d: id=%d, toolType=%s, "
2165*38e8c45fSAndroid Build Coastguard Worker                   "x=%f, y=%f, pressure=%f, size=%f, "
2166*38e8c45fSAndroid Build Coastguard Worker                   "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, orientation=%f",
2167*38e8c45fSAndroid Build Coastguard Worker                   i, entry.pointerProperties[i].id,
2168*38e8c45fSAndroid Build Coastguard Worker                   ftl::enum_string(entry.pointerProperties[i].toolType).c_str(),
2169*38e8c45fSAndroid Build Coastguard Worker                   entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
2170*38e8c45fSAndroid Build Coastguard Worker                   entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
2171*38e8c45fSAndroid Build Coastguard Worker                   entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
2172*38e8c45fSAndroid Build Coastguard Worker                   entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
2173*38e8c45fSAndroid Build Coastguard Worker                   entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
2174*38e8c45fSAndroid Build Coastguard Worker                   entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
2175*38e8c45fSAndroid Build Coastguard Worker                   entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
2176*38e8c45fSAndroid Build Coastguard Worker                   entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
2177*38e8c45fSAndroid Build Coastguard Worker                   entry.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
2178*38e8c45fSAndroid Build Coastguard Worker         }
2179*38e8c45fSAndroid Build Coastguard Worker     }
2180*38e8c45fSAndroid Build Coastguard Worker }
2181*38e8c45fSAndroid Build Coastguard Worker 
dispatchEventLocked(nsecs_t currentTime,std::shared_ptr<const EventEntry> eventEntry,const std::vector<InputTarget> & inputTargets)2182*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::dispatchEventLocked(nsecs_t currentTime,
2183*38e8c45fSAndroid Build Coastguard Worker                                           std::shared_ptr<const EventEntry> eventEntry,
2184*38e8c45fSAndroid Build Coastguard Worker                                           const std::vector<InputTarget>& inputTargets) {
2185*38e8c45fSAndroid Build Coastguard Worker     ATRACE_CALL();
2186*38e8c45fSAndroid Build Coastguard Worker     if (DEBUG_DISPATCH_CYCLE) {
2187*38e8c45fSAndroid Build Coastguard Worker         ALOGD("dispatchEventToCurrentInputTargets");
2188*38e8c45fSAndroid Build Coastguard Worker     }
2189*38e8c45fSAndroid Build Coastguard Worker 
2190*38e8c45fSAndroid Build Coastguard Worker     processInteractionsLocked(*eventEntry, inputTargets);
2191*38e8c45fSAndroid Build Coastguard Worker 
2192*38e8c45fSAndroid Build Coastguard Worker     ALOG_ASSERT(eventEntry->dispatchInProgress); // should already have been set to true
2193*38e8c45fSAndroid Build Coastguard Worker 
2194*38e8c45fSAndroid Build Coastguard Worker     pokeUserActivityLocked(*eventEntry);
2195*38e8c45fSAndroid Build Coastguard Worker 
2196*38e8c45fSAndroid Build Coastguard Worker     for (const InputTarget& inputTarget : inputTargets) {
2197*38e8c45fSAndroid Build Coastguard Worker         std::shared_ptr<Connection> connection = inputTarget.connection;
2198*38e8c45fSAndroid Build Coastguard Worker         prepareDispatchCycleLocked(currentTime, connection, eventEntry, inputTarget);
2199*38e8c45fSAndroid Build Coastguard Worker     }
2200*38e8c45fSAndroid Build Coastguard Worker }
2201*38e8c45fSAndroid Build Coastguard Worker 
cancelEventsForAnrLocked(const std::shared_ptr<Connection> & connection)2202*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::cancelEventsForAnrLocked(const std::shared_ptr<Connection>& connection) {
2203*38e8c45fSAndroid Build Coastguard Worker     // We will not be breaking any connections here, even if the policy wants us to abort dispatch.
2204*38e8c45fSAndroid Build Coastguard Worker     // If the policy decides to close the app, we will get a channel removal event via
2205*38e8c45fSAndroid Build Coastguard Worker     // unregisterInputChannel, and will clean up the connection that way. We are already not
2206*38e8c45fSAndroid Build Coastguard Worker     // sending new pointers to the connection when it blocked, but focused events will continue to
2207*38e8c45fSAndroid Build Coastguard Worker     // pile up.
2208*38e8c45fSAndroid Build Coastguard Worker     ALOGW("Canceling events for %s because it is unresponsive",
2209*38e8c45fSAndroid Build Coastguard Worker           connection->getInputChannelName().c_str());
2210*38e8c45fSAndroid Build Coastguard Worker     if (connection->status != Connection::Status::NORMAL) {
2211*38e8c45fSAndroid Build Coastguard Worker         return;
2212*38e8c45fSAndroid Build Coastguard Worker     }
2213*38e8c45fSAndroid Build Coastguard Worker     ScopedSyntheticEventTracer traceContext(mTracer);
2214*38e8c45fSAndroid Build Coastguard Worker     CancelationOptions options(CancelationOptions::Mode::CANCEL_ALL_EVENTS,
2215*38e8c45fSAndroid Build Coastguard Worker                                "application not responding", traceContext.getTracker());
2216*38e8c45fSAndroid Build Coastguard Worker 
2217*38e8c45fSAndroid Build Coastguard Worker     sp<WindowInfoHandle> windowHandle;
2218*38e8c45fSAndroid Build Coastguard Worker     if (!connection->monitor) {
2219*38e8c45fSAndroid Build Coastguard Worker         windowHandle = getWindowHandleLocked(connection->getToken());
2220*38e8c45fSAndroid Build Coastguard Worker         if (windowHandle == nullptr) {
2221*38e8c45fSAndroid Build Coastguard Worker             // The window that is receiving this ANR was removed, so there is no need to generate
2222*38e8c45fSAndroid Build Coastguard Worker             // cancellations, because the cancellations would have already been generated when
2223*38e8c45fSAndroid Build Coastguard Worker             // the window was removed.
2224*38e8c45fSAndroid Build Coastguard Worker             return;
2225*38e8c45fSAndroid Build Coastguard Worker         }
2226*38e8c45fSAndroid Build Coastguard Worker     }
2227*38e8c45fSAndroid Build Coastguard Worker     synthesizeCancelationEventsForConnectionLocked(connection, options, windowHandle);
2228*38e8c45fSAndroid Build Coastguard Worker }
2229*38e8c45fSAndroid Build Coastguard Worker 
resetNoFocusedWindowTimeoutLocked()2230*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::resetNoFocusedWindowTimeoutLocked() {
2231*38e8c45fSAndroid Build Coastguard Worker     if (DEBUG_FOCUS) {
2232*38e8c45fSAndroid Build Coastguard Worker         ALOGD("Resetting ANR timeouts.");
2233*38e8c45fSAndroid Build Coastguard Worker     }
2234*38e8c45fSAndroid Build Coastguard Worker 
2235*38e8c45fSAndroid Build Coastguard Worker     // Reset input target wait timeout.
2236*38e8c45fSAndroid Build Coastguard Worker     mNoFocusedWindowTimeoutTime = std::nullopt;
2237*38e8c45fSAndroid Build Coastguard Worker     mAwaitedFocusedApplication.reset();
2238*38e8c45fSAndroid Build Coastguard Worker }
2239*38e8c45fSAndroid Build Coastguard Worker 
2240*38e8c45fSAndroid Build Coastguard Worker /**
2241*38e8c45fSAndroid Build Coastguard Worker  * Get the display id that the given event should go to. If this event specifies a valid display id,
2242*38e8c45fSAndroid Build Coastguard Worker  * then it should be dispatched to that display. Otherwise, the event goes to the focused display.
2243*38e8c45fSAndroid Build Coastguard Worker  * Focused display is the display that the user most recently interacted with.
2244*38e8c45fSAndroid Build Coastguard Worker  */
getTargetDisplayId(const EventEntry & entry)2245*38e8c45fSAndroid Build Coastguard Worker ui::LogicalDisplayId InputDispatcher::getTargetDisplayId(const EventEntry& entry) {
2246*38e8c45fSAndroid Build Coastguard Worker     ui::LogicalDisplayId displayId{ui::LogicalDisplayId::INVALID};
2247*38e8c45fSAndroid Build Coastguard Worker     switch (entry.type) {
2248*38e8c45fSAndroid Build Coastguard Worker         case EventEntry::Type::KEY: {
2249*38e8c45fSAndroid Build Coastguard Worker             const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
2250*38e8c45fSAndroid Build Coastguard Worker             displayId = keyEntry.displayId;
2251*38e8c45fSAndroid Build Coastguard Worker             break;
2252*38e8c45fSAndroid Build Coastguard Worker         }
2253*38e8c45fSAndroid Build Coastguard Worker         case EventEntry::Type::MOTION: {
2254*38e8c45fSAndroid Build Coastguard Worker             const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
2255*38e8c45fSAndroid Build Coastguard Worker             displayId = motionEntry.displayId;
2256*38e8c45fSAndroid Build Coastguard Worker             break;
2257*38e8c45fSAndroid Build Coastguard Worker         }
2258*38e8c45fSAndroid Build Coastguard Worker         case EventEntry::Type::TOUCH_MODE_CHANGED:
2259*38e8c45fSAndroid Build Coastguard Worker         case EventEntry::Type::POINTER_CAPTURE_CHANGED:
2260*38e8c45fSAndroid Build Coastguard Worker         case EventEntry::Type::FOCUS:
2261*38e8c45fSAndroid Build Coastguard Worker         case EventEntry::Type::DEVICE_RESET:
2262*38e8c45fSAndroid Build Coastguard Worker         case EventEntry::Type::SENSOR:
2263*38e8c45fSAndroid Build Coastguard Worker         case EventEntry::Type::DRAG: {
2264*38e8c45fSAndroid Build Coastguard Worker             ALOGE("%s events do not have a target display", ftl::enum_string(entry.type).c_str());
2265*38e8c45fSAndroid Build Coastguard Worker             return ui::LogicalDisplayId::INVALID;
2266*38e8c45fSAndroid Build Coastguard Worker         }
2267*38e8c45fSAndroid Build Coastguard Worker     }
2268*38e8c45fSAndroid Build Coastguard Worker     return displayId == ui::LogicalDisplayId::INVALID ? mFocusedDisplayId : displayId;
2269*38e8c45fSAndroid Build Coastguard Worker }
2270*38e8c45fSAndroid Build Coastguard Worker 
shouldWaitToSendKeyLocked(nsecs_t currentTime,const char * focusedWindowName)2271*38e8c45fSAndroid Build Coastguard Worker bool InputDispatcher::shouldWaitToSendKeyLocked(nsecs_t currentTime,
2272*38e8c45fSAndroid Build Coastguard Worker                                                 const char* focusedWindowName) {
2273*38e8c45fSAndroid Build Coastguard Worker     if (mAnrTracker.empty()) {
2274*38e8c45fSAndroid Build Coastguard Worker         // already processed all events that we waited for
2275*38e8c45fSAndroid Build Coastguard Worker         mKeyIsWaitingForEventsTimeout = std::nullopt;
2276*38e8c45fSAndroid Build Coastguard Worker         return false;
2277*38e8c45fSAndroid Build Coastguard Worker     }
2278*38e8c45fSAndroid Build Coastguard Worker 
2279*38e8c45fSAndroid Build Coastguard Worker     if (!mKeyIsWaitingForEventsTimeout.has_value()) {
2280*38e8c45fSAndroid Build Coastguard Worker         // Start the timer
2281*38e8c45fSAndroid Build Coastguard Worker         // Wait to send key because there are unprocessed events that may cause focus to change
2282*38e8c45fSAndroid Build Coastguard Worker         mKeyIsWaitingForEventsTimeout = currentTime +
2283*38e8c45fSAndroid Build Coastguard Worker                 std::chrono::duration_cast<std::chrono::nanoseconds>(
2284*38e8c45fSAndroid Build Coastguard Worker                         mPolicy.getKeyWaitingForEventsTimeout())
2285*38e8c45fSAndroid Build Coastguard Worker                         .count();
2286*38e8c45fSAndroid Build Coastguard Worker         return true;
2287*38e8c45fSAndroid Build Coastguard Worker     }
2288*38e8c45fSAndroid Build Coastguard Worker 
2289*38e8c45fSAndroid Build Coastguard Worker     // We still have pending events, and already started the timer
2290*38e8c45fSAndroid Build Coastguard Worker     if (currentTime < *mKeyIsWaitingForEventsTimeout) {
2291*38e8c45fSAndroid Build Coastguard Worker         return true; // Still waiting
2292*38e8c45fSAndroid Build Coastguard Worker     }
2293*38e8c45fSAndroid Build Coastguard Worker 
2294*38e8c45fSAndroid Build Coastguard Worker     // Waited too long, and some connection still hasn't processed all motions
2295*38e8c45fSAndroid Build Coastguard Worker     // Just send the key to the focused window
2296*38e8c45fSAndroid Build Coastguard Worker     ALOGW("Dispatching key to %s even though there are other unprocessed events",
2297*38e8c45fSAndroid Build Coastguard Worker           focusedWindowName);
2298*38e8c45fSAndroid Build Coastguard Worker     mKeyIsWaitingForEventsTimeout = std::nullopt;
2299*38e8c45fSAndroid Build Coastguard Worker     return false;
2300*38e8c45fSAndroid Build Coastguard Worker }
2301*38e8c45fSAndroid Build Coastguard Worker 
2302*38e8c45fSAndroid Build Coastguard Worker Result<sp<WindowInfoHandle>, InputEventInjectionResult>
findFocusedWindowTargetLocked(nsecs_t currentTime,const EventEntry & entry,nsecs_t & nextWakeupTime)2303*38e8c45fSAndroid Build Coastguard Worker InputDispatcher::findFocusedWindowTargetLocked(nsecs_t currentTime, const EventEntry& entry,
2304*38e8c45fSAndroid Build Coastguard Worker                                                nsecs_t& nextWakeupTime) {
2305*38e8c45fSAndroid Build Coastguard Worker     ui::LogicalDisplayId displayId = getTargetDisplayId(entry);
2306*38e8c45fSAndroid Build Coastguard Worker     sp<WindowInfoHandle> focusedWindowHandle = getFocusedWindowHandleLocked(displayId);
2307*38e8c45fSAndroid Build Coastguard Worker     std::shared_ptr<InputApplicationHandle> focusedApplicationHandle =
2308*38e8c45fSAndroid Build Coastguard Worker             getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
2309*38e8c45fSAndroid Build Coastguard Worker 
2310*38e8c45fSAndroid Build Coastguard Worker     // If there is no currently focused window and no focused application
2311*38e8c45fSAndroid Build Coastguard Worker     // then drop the event.
2312*38e8c45fSAndroid Build Coastguard Worker     if (focusedWindowHandle == nullptr && focusedApplicationHandle == nullptr) {
2313*38e8c45fSAndroid Build Coastguard Worker         ALOGI("Dropping %s event because there is no focused window or focused application in "
2314*38e8c45fSAndroid Build Coastguard Worker               "display %s.",
2315*38e8c45fSAndroid Build Coastguard Worker               ftl::enum_string(entry.type).c_str(), displayId.toString().c_str());
2316*38e8c45fSAndroid Build Coastguard Worker         return injectionError(InputEventInjectionResult::FAILED);
2317*38e8c45fSAndroid Build Coastguard Worker     }
2318*38e8c45fSAndroid Build Coastguard Worker 
2319*38e8c45fSAndroid Build Coastguard Worker     // Drop key events if requested by input feature
2320*38e8c45fSAndroid Build Coastguard Worker     if (focusedWindowHandle != nullptr && shouldDropInput(entry, focusedWindowHandle)) {
2321*38e8c45fSAndroid Build Coastguard Worker         return injectionError(InputEventInjectionResult::FAILED);
2322*38e8c45fSAndroid Build Coastguard Worker     }
2323*38e8c45fSAndroid Build Coastguard Worker 
2324*38e8c45fSAndroid Build Coastguard Worker     // Compatibility behavior: raise ANR if there is a focused application, but no focused window.
2325*38e8c45fSAndroid Build Coastguard Worker     // Only start counting when we have a focused event to dispatch. The ANR is canceled if we
2326*38e8c45fSAndroid Build Coastguard Worker     // start interacting with another application via touch (app switch). This code can be removed
2327*38e8c45fSAndroid Build Coastguard Worker     // if the "no focused window ANR" is moved to the policy. Input doesn't know whether
2328*38e8c45fSAndroid Build Coastguard Worker     // an app is expected to have a focused window.
2329*38e8c45fSAndroid Build Coastguard Worker     if (focusedWindowHandle == nullptr && focusedApplicationHandle != nullptr) {
2330*38e8c45fSAndroid Build Coastguard Worker         if (!mNoFocusedWindowTimeoutTime.has_value()) {
2331*38e8c45fSAndroid Build Coastguard Worker             // We just discovered that there's no focused window. Start the ANR timer
2332*38e8c45fSAndroid Build Coastguard Worker             std::chrono::nanoseconds timeout = focusedApplicationHandle->getDispatchingTimeout(
2333*38e8c45fSAndroid Build Coastguard Worker                     DEFAULT_INPUT_DISPATCHING_TIMEOUT);
2334*38e8c45fSAndroid Build Coastguard Worker             mNoFocusedWindowTimeoutTime = currentTime + timeout.count();
2335*38e8c45fSAndroid Build Coastguard Worker             mAwaitedFocusedApplication = focusedApplicationHandle;
2336*38e8c45fSAndroid Build Coastguard Worker             mAwaitedApplicationDisplayId = displayId;
2337*38e8c45fSAndroid Build Coastguard Worker             ALOGW("Waiting because no window has focus but %s may eventually add a "
2338*38e8c45fSAndroid Build Coastguard Worker                   "window when it finishes starting up. Will wait for %" PRId64 "ms",
2339*38e8c45fSAndroid Build Coastguard Worker                   mAwaitedFocusedApplication->getName().c_str(), millis(timeout));
2340*38e8c45fSAndroid Build Coastguard Worker             nextWakeupTime = std::min(nextWakeupTime, *mNoFocusedWindowTimeoutTime);
2341*38e8c45fSAndroid Build Coastguard Worker             return injectionError(InputEventInjectionResult::PENDING);
2342*38e8c45fSAndroid Build Coastguard Worker         } else if (currentTime > *mNoFocusedWindowTimeoutTime) {
2343*38e8c45fSAndroid Build Coastguard Worker             // Already raised ANR. Drop the event
2344*38e8c45fSAndroid Build Coastguard Worker             ALOGE("Dropping %s event because there is no focused window",
2345*38e8c45fSAndroid Build Coastguard Worker                   ftl::enum_string(entry.type).c_str());
2346*38e8c45fSAndroid Build Coastguard Worker             return injectionError(InputEventInjectionResult::FAILED);
2347*38e8c45fSAndroid Build Coastguard Worker         } else {
2348*38e8c45fSAndroid Build Coastguard Worker             // Still waiting for the focused window
2349*38e8c45fSAndroid Build Coastguard Worker             return injectionError(InputEventInjectionResult::PENDING);
2350*38e8c45fSAndroid Build Coastguard Worker         }
2351*38e8c45fSAndroid Build Coastguard Worker     }
2352*38e8c45fSAndroid Build Coastguard Worker 
2353*38e8c45fSAndroid Build Coastguard Worker     // we have a valid, non-null focused window
2354*38e8c45fSAndroid Build Coastguard Worker     resetNoFocusedWindowTimeoutLocked();
2355*38e8c45fSAndroid Build Coastguard Worker 
2356*38e8c45fSAndroid Build Coastguard Worker     // Verify targeted injection.
2357*38e8c45fSAndroid Build Coastguard Worker     if (const auto err = verifyTargetedInjection(focusedWindowHandle, entry); err) {
2358*38e8c45fSAndroid Build Coastguard Worker         ALOGW("Dropping injected event: %s", (*err).c_str());
2359*38e8c45fSAndroid Build Coastguard Worker         return injectionError(InputEventInjectionResult::TARGET_MISMATCH);
2360*38e8c45fSAndroid Build Coastguard Worker     }
2361*38e8c45fSAndroid Build Coastguard Worker 
2362*38e8c45fSAndroid Build Coastguard Worker     if (focusedWindowHandle->getInfo()->inputConfig.test(
2363*38e8c45fSAndroid Build Coastguard Worker                 WindowInfo::InputConfig::PAUSE_DISPATCHING)) {
2364*38e8c45fSAndroid Build Coastguard Worker         ALOGI("Waiting because %s is paused", focusedWindowHandle->getName().c_str());
2365*38e8c45fSAndroid Build Coastguard Worker         return injectionError(InputEventInjectionResult::PENDING);
2366*38e8c45fSAndroid Build Coastguard Worker     }
2367*38e8c45fSAndroid Build Coastguard Worker 
2368*38e8c45fSAndroid Build Coastguard Worker     // If the event is a key event, then we must wait for all previous events to
2369*38e8c45fSAndroid Build Coastguard Worker     // complete before delivering it because previous events may have the
2370*38e8c45fSAndroid Build Coastguard Worker     // side-effect of transferring focus to a different window and we want to
2371*38e8c45fSAndroid Build Coastguard Worker     // ensure that the following keys are sent to the new window.
2372*38e8c45fSAndroid Build Coastguard Worker     //
2373*38e8c45fSAndroid Build Coastguard Worker     // Suppose the user touches a button in a window then immediately presses "A".
2374*38e8c45fSAndroid Build Coastguard Worker     // If the button causes a pop-up window to appear then we want to ensure that
2375*38e8c45fSAndroid Build Coastguard Worker     // the "A" key is delivered to the new pop-up window.  This is because users
2376*38e8c45fSAndroid Build Coastguard Worker     // often anticipate pending UI changes when typing on a keyboard.
2377*38e8c45fSAndroid Build Coastguard Worker     // To obtain this behavior, we must serialize key events with respect to all
2378*38e8c45fSAndroid Build Coastguard Worker     // prior input events.
2379*38e8c45fSAndroid Build Coastguard Worker     if (entry.type == EventEntry::Type::KEY) {
2380*38e8c45fSAndroid Build Coastguard Worker         if (shouldWaitToSendKeyLocked(currentTime, focusedWindowHandle->getName().c_str())) {
2381*38e8c45fSAndroid Build Coastguard Worker             nextWakeupTime = std::min(nextWakeupTime, *mKeyIsWaitingForEventsTimeout);
2382*38e8c45fSAndroid Build Coastguard Worker             return injectionError(InputEventInjectionResult::PENDING);
2383*38e8c45fSAndroid Build Coastguard Worker         }
2384*38e8c45fSAndroid Build Coastguard Worker     }
2385*38e8c45fSAndroid Build Coastguard Worker     // Success!
2386*38e8c45fSAndroid Build Coastguard Worker     return focusedWindowHandle;
2387*38e8c45fSAndroid Build Coastguard Worker }
2388*38e8c45fSAndroid Build Coastguard Worker 
2389*38e8c45fSAndroid Build Coastguard Worker /**
2390*38e8c45fSAndroid Build Coastguard Worker  * Given a list of monitors, remove the ones we cannot find a connection for, and the ones
2391*38e8c45fSAndroid Build Coastguard Worker  * that are currently unresponsive.
2392*38e8c45fSAndroid Build Coastguard Worker  */
selectResponsiveMonitorsLocked(const std::vector<Monitor> & monitors) const2393*38e8c45fSAndroid Build Coastguard Worker std::vector<Monitor> InputDispatcher::selectResponsiveMonitorsLocked(
2394*38e8c45fSAndroid Build Coastguard Worker         const std::vector<Monitor>& monitors) const {
2395*38e8c45fSAndroid Build Coastguard Worker     std::vector<Monitor> responsiveMonitors;
2396*38e8c45fSAndroid Build Coastguard Worker     std::copy_if(monitors.begin(), monitors.end(), std::back_inserter(responsiveMonitors),
2397*38e8c45fSAndroid Build Coastguard Worker                  [](const Monitor& monitor) REQUIRES(mLock) {
2398*38e8c45fSAndroid Build Coastguard Worker                      std::shared_ptr<Connection> connection = monitor.connection;
2399*38e8c45fSAndroid Build Coastguard Worker                      if (!connection->responsive) {
2400*38e8c45fSAndroid Build Coastguard Worker                          ALOGW("Unresponsive monitor %s will not get the new gesture",
2401*38e8c45fSAndroid Build Coastguard Worker                                connection->getInputChannelName().c_str());
2402*38e8c45fSAndroid Build Coastguard Worker                          return false;
2403*38e8c45fSAndroid Build Coastguard Worker                      }
2404*38e8c45fSAndroid Build Coastguard Worker                      return true;
2405*38e8c45fSAndroid Build Coastguard Worker                  });
2406*38e8c45fSAndroid Build Coastguard Worker     return responsiveMonitors;
2407*38e8c45fSAndroid Build Coastguard Worker }
2408*38e8c45fSAndroid Build Coastguard Worker 
2409*38e8c45fSAndroid Build Coastguard Worker base::Result<std::vector<InputTarget>, android::os::InputEventInjectionResult>
findTouchedWindowTargetsLocked(nsecs_t currentTime,const MotionEntry & entry)2410*38e8c45fSAndroid Build Coastguard Worker InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime, const MotionEntry& entry) {
2411*38e8c45fSAndroid Build Coastguard Worker     ATRACE_CALL();
2412*38e8c45fSAndroid Build Coastguard Worker 
2413*38e8c45fSAndroid Build Coastguard Worker     std::vector<InputTarget> targets;
2414*38e8c45fSAndroid Build Coastguard Worker     // For security reasons, we defer updating the touch state until we are sure that
2415*38e8c45fSAndroid Build Coastguard Worker     // event injection will be allowed.
2416*38e8c45fSAndroid Build Coastguard Worker     const ui::LogicalDisplayId displayId = entry.displayId;
2417*38e8c45fSAndroid Build Coastguard Worker     const int32_t action = entry.action;
2418*38e8c45fSAndroid Build Coastguard Worker     const int32_t maskedAction = MotionEvent::getActionMasked(action);
2419*38e8c45fSAndroid Build Coastguard Worker 
2420*38e8c45fSAndroid Build Coastguard Worker     // Copy current touch state into tempTouchState.
2421*38e8c45fSAndroid Build Coastguard Worker     // This state will be used to update mTouchStatesByDisplay at the end of this function.
2422*38e8c45fSAndroid Build Coastguard Worker     // If no state for the specified display exists, then our initial state will be empty.
2423*38e8c45fSAndroid Build Coastguard Worker     const TouchState* oldState = nullptr;
2424*38e8c45fSAndroid Build Coastguard Worker     TouchState tempTouchState;
2425*38e8c45fSAndroid Build Coastguard Worker     if (const auto it = mTouchStatesByDisplay.find(displayId); it != mTouchStatesByDisplay.end()) {
2426*38e8c45fSAndroid Build Coastguard Worker         oldState = &(it->second);
2427*38e8c45fSAndroid Build Coastguard Worker         tempTouchState = *oldState;
2428*38e8c45fSAndroid Build Coastguard Worker     }
2429*38e8c45fSAndroid Build Coastguard Worker 
2430*38e8c45fSAndroid Build Coastguard Worker     bool isSplit = shouldSplitTouch(tempTouchState, entry);
2431*38e8c45fSAndroid Build Coastguard Worker 
2432*38e8c45fSAndroid Build Coastguard Worker     const bool isHoverAction = (maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE ||
2433*38e8c45fSAndroid Build Coastguard Worker                                 maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER ||
2434*38e8c45fSAndroid Build Coastguard Worker                                 maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT);
2435*38e8c45fSAndroid Build Coastguard Worker     // A DOWN could be generated from POINTER_DOWN if the initial pointers did not land into any
2436*38e8c45fSAndroid Build Coastguard Worker     // touchable windows.
2437*38e8c45fSAndroid Build Coastguard Worker     const bool wasDown = oldState != nullptr && oldState->isDown(entry.deviceId);
2438*38e8c45fSAndroid Build Coastguard Worker     const bool isDown = (maskedAction == AMOTION_EVENT_ACTION_DOWN) ||
2439*38e8c45fSAndroid Build Coastguard Worker             (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN && !wasDown);
2440*38e8c45fSAndroid Build Coastguard Worker     const bool newGesture = isDown || maskedAction == AMOTION_EVENT_ACTION_SCROLL ||
2441*38e8c45fSAndroid Build Coastguard Worker             maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER ||
2442*38e8c45fSAndroid Build Coastguard Worker             maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE;
2443*38e8c45fSAndroid Build Coastguard Worker     const bool isFromMouse = isFromSource(entry.source, AINPUT_SOURCE_MOUSE);
2444*38e8c45fSAndroid Build Coastguard Worker 
2445*38e8c45fSAndroid Build Coastguard Worker     if (newGesture) {
2446*38e8c45fSAndroid Build Coastguard Worker         isSplit = false;
2447*38e8c45fSAndroid Build Coastguard Worker     }
2448*38e8c45fSAndroid Build Coastguard Worker 
2449*38e8c45fSAndroid Build Coastguard Worker     if (isDown && tempTouchState.hasHoveringPointers(entry.deviceId)) {
2450*38e8c45fSAndroid Build Coastguard Worker         // Compatibility behaviour: ACTION_DOWN causes HOVER_EXIT to get generated.
2451*38e8c45fSAndroid Build Coastguard Worker         tempTouchState.clearHoveringPointers(entry.deviceId);
2452*38e8c45fSAndroid Build Coastguard Worker     }
2453*38e8c45fSAndroid Build Coastguard Worker 
2454*38e8c45fSAndroid Build Coastguard Worker     if (isHoverAction) {
2455*38e8c45fSAndroid Build Coastguard Worker         if (wasDown) {
2456*38e8c45fSAndroid Build Coastguard Worker             // Started hovering, but the device is already down: reject the hover event
2457*38e8c45fSAndroid Build Coastguard Worker             LOG(ERROR) << "Got hover event " << entry.getDescription()
2458*38e8c45fSAndroid Build Coastguard Worker                        << " but the device is already down " << oldState->dump();
2459*38e8c45fSAndroid Build Coastguard Worker             return injectionError(InputEventInjectionResult::FAILED);
2460*38e8c45fSAndroid Build Coastguard Worker         }
2461*38e8c45fSAndroid Build Coastguard Worker         // For hover actions, we will treat 'tempTouchState' as a new state, so let's erase
2462*38e8c45fSAndroid Build Coastguard Worker         // all of the existing hovering pointers and recompute.
2463*38e8c45fSAndroid Build Coastguard Worker         tempTouchState.clearHoveringPointers(entry.deviceId);
2464*38e8c45fSAndroid Build Coastguard Worker     }
2465*38e8c45fSAndroid Build Coastguard Worker 
2466*38e8c45fSAndroid Build Coastguard Worker     if (newGesture || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)) {
2467*38e8c45fSAndroid Build Coastguard Worker         /* Case 1: New splittable pointer going down, or need target for hover or scroll. */
2468*38e8c45fSAndroid Build Coastguard Worker         const auto [x, y] = resolveTouchedPosition(entry);
2469*38e8c45fSAndroid Build Coastguard Worker         const int32_t pointerIndex = MotionEvent::getActionIndex(action);
2470*38e8c45fSAndroid Build Coastguard Worker         const PointerProperties& pointer = entry.pointerProperties[pointerIndex];
2471*38e8c45fSAndroid Build Coastguard Worker         // Outside targets should be added upon first dispatched DOWN event. That means, this should
2472*38e8c45fSAndroid Build Coastguard Worker         // be a pointer that would generate ACTION_DOWN, *and* touch should not already be down.
2473*38e8c45fSAndroid Build Coastguard Worker         const bool isStylus = isPointerFromStylus(entry, pointerIndex);
2474*38e8c45fSAndroid Build Coastguard Worker         sp<WindowInfoHandle> newTouchedWindowHandle =
2475*38e8c45fSAndroid Build Coastguard Worker                 findTouchedWindowAtLocked(displayId, x, y, isStylus);
2476*38e8c45fSAndroid Build Coastguard Worker 
2477*38e8c45fSAndroid Build Coastguard Worker         if (isDown) {
2478*38e8c45fSAndroid Build Coastguard Worker             targets += findOutsideTargetsLocked(displayId, newTouchedWindowHandle, pointer.id);
2479*38e8c45fSAndroid Build Coastguard Worker         }
2480*38e8c45fSAndroid Build Coastguard Worker         LOG_IF(INFO, newTouchedWindowHandle == nullptr)
2481*38e8c45fSAndroid Build Coastguard Worker                 << "No new touched window at (" << std::format("{:.1f}, {:.1f}", x, y)
2482*38e8c45fSAndroid Build Coastguard Worker                 << ") in display " << displayId;
2483*38e8c45fSAndroid Build Coastguard Worker         // Handle the case where we did not find a window.
2484*38e8c45fSAndroid Build Coastguard Worker         if (!input_flags::split_all_touches()) {
2485*38e8c45fSAndroid Build Coastguard Worker             // If we are force splitting all touches, then touches outside of the window should
2486*38e8c45fSAndroid Build Coastguard Worker             // be dropped, even if this device already has pointers down in another window.
2487*38e8c45fSAndroid Build Coastguard Worker             if (newTouchedWindowHandle == nullptr) {
2488*38e8c45fSAndroid Build Coastguard Worker                 // Try to assign the pointer to the first foreground window we find, if there is
2489*38e8c45fSAndroid Build Coastguard Worker                 // one.
2490*38e8c45fSAndroid Build Coastguard Worker                 newTouchedWindowHandle =
2491*38e8c45fSAndroid Build Coastguard Worker                         tempTouchState.getFirstForegroundWindowHandle(entry.deviceId);
2492*38e8c45fSAndroid Build Coastguard Worker             }
2493*38e8c45fSAndroid Build Coastguard Worker         }
2494*38e8c45fSAndroid Build Coastguard Worker 
2495*38e8c45fSAndroid Build Coastguard Worker         // Verify targeted injection.
2496*38e8c45fSAndroid Build Coastguard Worker         if (const auto err = verifyTargetedInjection(newTouchedWindowHandle, entry); err) {
2497*38e8c45fSAndroid Build Coastguard Worker             ALOGW("Dropping injected touch event: %s", (*err).c_str());
2498*38e8c45fSAndroid Build Coastguard Worker             return injectionError(InputEventInjectionResult::TARGET_MISMATCH);
2499*38e8c45fSAndroid Build Coastguard Worker         }
2500*38e8c45fSAndroid Build Coastguard Worker 
2501*38e8c45fSAndroid Build Coastguard Worker         // Figure out whether splitting will be allowed for this window.
2502*38e8c45fSAndroid Build Coastguard Worker         if (newTouchedWindowHandle != nullptr) {
2503*38e8c45fSAndroid Build Coastguard Worker             if (newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
2504*38e8c45fSAndroid Build Coastguard Worker                 // New window supports splitting, but we should never split mouse events.
2505*38e8c45fSAndroid Build Coastguard Worker                 isSplit = !isFromMouse;
2506*38e8c45fSAndroid Build Coastguard Worker             } else if (isSplit) {
2507*38e8c45fSAndroid Build Coastguard Worker                 // New window does not support splitting but we have already split events.
2508*38e8c45fSAndroid Build Coastguard Worker                 // Ignore the new window.
2509*38e8c45fSAndroid Build Coastguard Worker                 LOG(INFO) << "Skipping " << newTouchedWindowHandle->getName()
2510*38e8c45fSAndroid Build Coastguard Worker                           << " because it doesn't support split touch";
2511*38e8c45fSAndroid Build Coastguard Worker                 newTouchedWindowHandle = nullptr;
2512*38e8c45fSAndroid Build Coastguard Worker             }
2513*38e8c45fSAndroid Build Coastguard Worker         } else {
2514*38e8c45fSAndroid Build Coastguard Worker             // No window is touched, so set split to true. This will allow the next pointer down to
2515*38e8c45fSAndroid Build Coastguard Worker             // be delivered to a new window which supports split touch. Pointers from a mouse device
2516*38e8c45fSAndroid Build Coastguard Worker             // should never be split.
2517*38e8c45fSAndroid Build Coastguard Worker             isSplit = !isFromMouse;
2518*38e8c45fSAndroid Build Coastguard Worker         }
2519*38e8c45fSAndroid Build Coastguard Worker 
2520*38e8c45fSAndroid Build Coastguard Worker         std::vector<sp<WindowInfoHandle>> newTouchedWindows =
2521*38e8c45fSAndroid Build Coastguard Worker                 findTouchedSpyWindowsAtLocked(displayId, x, y, isStylus, entry.deviceId);
2522*38e8c45fSAndroid Build Coastguard Worker         if (newTouchedWindowHandle != nullptr) {
2523*38e8c45fSAndroid Build Coastguard Worker             // Process the foreground window first so that it is the first to receive the event.
2524*38e8c45fSAndroid Build Coastguard Worker             newTouchedWindows.insert(newTouchedWindows.begin(), newTouchedWindowHandle);
2525*38e8c45fSAndroid Build Coastguard Worker         }
2526*38e8c45fSAndroid Build Coastguard Worker 
2527*38e8c45fSAndroid Build Coastguard Worker         if (newTouchedWindows.empty()) {
2528*38e8c45fSAndroid Build Coastguard Worker             LOG(INFO) << "Dropping event because there is no touchable window at (" << x << ", "
2529*38e8c45fSAndroid Build Coastguard Worker                       << y << ") on display " << displayId << ": " << entry;
2530*38e8c45fSAndroid Build Coastguard Worker             return injectionError(InputEventInjectionResult::FAILED);
2531*38e8c45fSAndroid Build Coastguard Worker         }
2532*38e8c45fSAndroid Build Coastguard Worker 
2533*38e8c45fSAndroid Build Coastguard Worker         for (const sp<WindowInfoHandle>& windowHandle : newTouchedWindows) {
2534*38e8c45fSAndroid Build Coastguard Worker             if (!canWindowReceiveMotionLocked(windowHandle, entry)) {
2535*38e8c45fSAndroid Build Coastguard Worker                 continue;
2536*38e8c45fSAndroid Build Coastguard Worker             }
2537*38e8c45fSAndroid Build Coastguard Worker 
2538*38e8c45fSAndroid Build Coastguard Worker             if (isHoverAction) {
2539*38e8c45fSAndroid Build Coastguard Worker                 // The "windowHandle" is the target of this hovering pointer.
2540*38e8c45fSAndroid Build Coastguard Worker                 tempTouchState.addHoveringPointerToWindow(windowHandle, entry.deviceId, pointer, x,
2541*38e8c45fSAndroid Build Coastguard Worker                                                           y);
2542*38e8c45fSAndroid Build Coastguard Worker             }
2543*38e8c45fSAndroid Build Coastguard Worker 
2544*38e8c45fSAndroid Build Coastguard Worker             // Set target flags.
2545*38e8c45fSAndroid Build Coastguard Worker             ftl::Flags<InputTarget::Flags> targetFlags;
2546*38e8c45fSAndroid Build Coastguard Worker 
2547*38e8c45fSAndroid Build Coastguard Worker             if (canReceiveForegroundTouches(*windowHandle->getInfo())) {
2548*38e8c45fSAndroid Build Coastguard Worker                 // There should only be one touched window that can be "foreground" for the pointer.
2549*38e8c45fSAndroid Build Coastguard Worker                 targetFlags |= InputTarget::Flags::FOREGROUND;
2550*38e8c45fSAndroid Build Coastguard Worker             }
2551*38e8c45fSAndroid Build Coastguard Worker 
2552*38e8c45fSAndroid Build Coastguard Worker             if (isSplit) {
2553*38e8c45fSAndroid Build Coastguard Worker                 targetFlags |= InputTarget::Flags::SPLIT;
2554*38e8c45fSAndroid Build Coastguard Worker             }
2555*38e8c45fSAndroid Build Coastguard Worker             if (isWindowObscuredAtPointLocked(windowHandle, x, y)) {
2556*38e8c45fSAndroid Build Coastguard Worker                 targetFlags |= InputTarget::Flags::WINDOW_IS_OBSCURED;
2557*38e8c45fSAndroid Build Coastguard Worker             } else if (isWindowObscuredLocked(windowHandle)) {
2558*38e8c45fSAndroid Build Coastguard Worker                 targetFlags |= InputTarget::Flags::WINDOW_IS_PARTIALLY_OBSCURED;
2559*38e8c45fSAndroid Build Coastguard Worker             }
2560*38e8c45fSAndroid Build Coastguard Worker 
2561*38e8c45fSAndroid Build Coastguard Worker             // Update the temporary touch state.
2562*38e8c45fSAndroid Build Coastguard Worker 
2563*38e8c45fSAndroid Build Coastguard Worker             if (!isHoverAction) {
2564*38e8c45fSAndroid Build Coastguard Worker                 const bool isDownOrPointerDown = maskedAction == AMOTION_EVENT_ACTION_DOWN ||
2565*38e8c45fSAndroid Build Coastguard Worker                         maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN;
2566*38e8c45fSAndroid Build Coastguard Worker                 Result<void> addResult =
2567*38e8c45fSAndroid Build Coastguard Worker                         tempTouchState.addOrUpdateWindow(windowHandle,
2568*38e8c45fSAndroid Build Coastguard Worker                                                          InputTarget::DispatchMode::AS_IS,
2569*38e8c45fSAndroid Build Coastguard Worker                                                          targetFlags, entry.deviceId, {pointer},
2570*38e8c45fSAndroid Build Coastguard Worker                                                          isDownOrPointerDown
2571*38e8c45fSAndroid Build Coastguard Worker                                                                  ? std::make_optional(
2572*38e8c45fSAndroid Build Coastguard Worker                                                                            entry.eventTime)
2573*38e8c45fSAndroid Build Coastguard Worker                                                                  : std::nullopt);
2574*38e8c45fSAndroid Build Coastguard Worker                 if (!addResult.ok()) {
2575*38e8c45fSAndroid Build Coastguard Worker                     LOG(ERROR) << "Error while processing " << entry << " for "
2576*38e8c45fSAndroid Build Coastguard Worker                                << windowHandle->getName();
2577*38e8c45fSAndroid Build Coastguard Worker                     logDispatchStateLocked();
2578*38e8c45fSAndroid Build Coastguard Worker                 }
2579*38e8c45fSAndroid Build Coastguard Worker                 // If this is the pointer going down and the touched window has a wallpaper
2580*38e8c45fSAndroid Build Coastguard Worker                 // then also add the touched wallpaper windows so they are locked in for the
2581*38e8c45fSAndroid Build Coastguard Worker                 // duration of the touch gesture. We do not collect wallpapers during HOVER_MOVE or
2582*38e8c45fSAndroid Build Coastguard Worker                 // SCROLL because the wallpaper engine only supports touch events.  We would need to
2583*38e8c45fSAndroid Build Coastguard Worker                 // add a mechanism similar to View.onGenericMotionEvent to enable wallpapers to
2584*38e8c45fSAndroid Build Coastguard Worker                 // handle these events.
2585*38e8c45fSAndroid Build Coastguard Worker                 if (isDownOrPointerDown && targetFlags.test(InputTarget::Flags::FOREGROUND) &&
2586*38e8c45fSAndroid Build Coastguard Worker                     windowHandle->getInfo()->inputConfig.test(
2587*38e8c45fSAndroid Build Coastguard Worker                             gui::WindowInfo::InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER)) {
2588*38e8c45fSAndroid Build Coastguard Worker                     sp<WindowInfoHandle> wallpaper = findWallpaperWindowBelow(windowHandle);
2589*38e8c45fSAndroid Build Coastguard Worker                     if (wallpaper != nullptr) {
2590*38e8c45fSAndroid Build Coastguard Worker                         ftl::Flags<InputTarget::Flags> wallpaperFlags =
2591*38e8c45fSAndroid Build Coastguard Worker                                 InputTarget::Flags::WINDOW_IS_OBSCURED |
2592*38e8c45fSAndroid Build Coastguard Worker                                 InputTarget::Flags::WINDOW_IS_PARTIALLY_OBSCURED;
2593*38e8c45fSAndroid Build Coastguard Worker                         if (isSplit) {
2594*38e8c45fSAndroid Build Coastguard Worker                             wallpaperFlags |= InputTarget::Flags::SPLIT;
2595*38e8c45fSAndroid Build Coastguard Worker                         }
2596*38e8c45fSAndroid Build Coastguard Worker                         tempTouchState.addOrUpdateWindow(wallpaper,
2597*38e8c45fSAndroid Build Coastguard Worker                                                          InputTarget::DispatchMode::AS_IS,
2598*38e8c45fSAndroid Build Coastguard Worker                                                          wallpaperFlags, entry.deviceId, {pointer},
2599*38e8c45fSAndroid Build Coastguard Worker                                                          entry.eventTime);
2600*38e8c45fSAndroid Build Coastguard Worker                     }
2601*38e8c45fSAndroid Build Coastguard Worker                 }
2602*38e8c45fSAndroid Build Coastguard Worker             }
2603*38e8c45fSAndroid Build Coastguard Worker         }
2604*38e8c45fSAndroid Build Coastguard Worker 
2605*38e8c45fSAndroid Build Coastguard Worker         // If a window is already pilfering some pointers, give it this new pointer as well and
2606*38e8c45fSAndroid Build Coastguard Worker         // make it pilfering. This will prevent other non-spy windows from getting this pointer,
2607*38e8c45fSAndroid Build Coastguard Worker         // which is a specific behaviour that we want.
2608*38e8c45fSAndroid Build Coastguard Worker         for (TouchedWindow& touchedWindow : tempTouchState.windows) {
2609*38e8c45fSAndroid Build Coastguard Worker             if (touchedWindow.hasTouchingPointer(entry.deviceId, pointer.id) &&
2610*38e8c45fSAndroid Build Coastguard Worker                 touchedWindow.hasPilferingPointers(entry.deviceId)) {
2611*38e8c45fSAndroid Build Coastguard Worker                 // This window is already pilfering some pointers, and this new pointer is also
2612*38e8c45fSAndroid Build Coastguard Worker                 // going to it. Therefore, take over this pointer and don't give it to anyone
2613*38e8c45fSAndroid Build Coastguard Worker                 // else.
2614*38e8c45fSAndroid Build Coastguard Worker                 touchedWindow.addPilferingPointer(entry.deviceId, pointer.id);
2615*38e8c45fSAndroid Build Coastguard Worker             }
2616*38e8c45fSAndroid Build Coastguard Worker         }
2617*38e8c45fSAndroid Build Coastguard Worker 
2618*38e8c45fSAndroid Build Coastguard Worker         // Restrict all pilfered pointers to the pilfering windows.
2619*38e8c45fSAndroid Build Coastguard Worker         tempTouchState.cancelPointersForNonPilferingWindows();
2620*38e8c45fSAndroid Build Coastguard Worker     } else {
2621*38e8c45fSAndroid Build Coastguard Worker         /* Case 2: Pointer move, up, cancel or non-splittable pointer down. */
2622*38e8c45fSAndroid Build Coastguard Worker 
2623*38e8c45fSAndroid Build Coastguard Worker         // If the pointer is not currently down, then ignore the event.
2624*38e8c45fSAndroid Build Coastguard Worker         if (!tempTouchState.isDown(entry.deviceId) &&
2625*38e8c45fSAndroid Build Coastguard Worker             maskedAction != AMOTION_EVENT_ACTION_HOVER_EXIT) {
2626*38e8c45fSAndroid Build Coastguard Worker             if (DEBUG_DROPPED_EVENTS_VERBOSE) {
2627*38e8c45fSAndroid Build Coastguard Worker                 LOG(INFO) << "Dropping event because the pointer for device " << entry.deviceId
2628*38e8c45fSAndroid Build Coastguard Worker                           << " is not down or we previously dropped the pointer down event in "
2629*38e8c45fSAndroid Build Coastguard Worker                           << "display " << displayId << ": " << entry.getDescription();
2630*38e8c45fSAndroid Build Coastguard Worker             }
2631*38e8c45fSAndroid Build Coastguard Worker             return injectionError(InputEventInjectionResult::FAILED);
2632*38e8c45fSAndroid Build Coastguard Worker         }
2633*38e8c45fSAndroid Build Coastguard Worker 
2634*38e8c45fSAndroid Build Coastguard Worker         // If the pointer is not currently hovering, then ignore the event.
2635*38e8c45fSAndroid Build Coastguard Worker         if (maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT) {
2636*38e8c45fSAndroid Build Coastguard Worker             const int32_t pointerId = entry.pointerProperties[0].id;
2637*38e8c45fSAndroid Build Coastguard Worker             if (oldState == nullptr ||
2638*38e8c45fSAndroid Build Coastguard Worker                 oldState->getWindowsWithHoveringPointer(entry.deviceId, pointerId).empty()) {
2639*38e8c45fSAndroid Build Coastguard Worker                 LOG(INFO) << "Dropping event because the hovering pointer is not in any windows in "
2640*38e8c45fSAndroid Build Coastguard Worker                              "display "
2641*38e8c45fSAndroid Build Coastguard Worker                           << displayId << ": " << entry.getDescription();
2642*38e8c45fSAndroid Build Coastguard Worker                 return injectionError(InputEventInjectionResult::FAILED);
2643*38e8c45fSAndroid Build Coastguard Worker             }
2644*38e8c45fSAndroid Build Coastguard Worker             tempTouchState.removeHoveringPointer(entry.deviceId, pointerId);
2645*38e8c45fSAndroid Build Coastguard Worker         }
2646*38e8c45fSAndroid Build Coastguard Worker 
2647*38e8c45fSAndroid Build Coastguard Worker         addDragEventLocked(entry);
2648*38e8c45fSAndroid Build Coastguard Worker 
2649*38e8c45fSAndroid Build Coastguard Worker         // Check whether touches should slip outside of the current foreground window.
2650*38e8c45fSAndroid Build Coastguard Worker         if (maskedAction == AMOTION_EVENT_ACTION_MOVE && entry.getPointerCount() == 1 &&
2651*38e8c45fSAndroid Build Coastguard Worker             tempTouchState.isSlippery(entry.deviceId)) {
2652*38e8c45fSAndroid Build Coastguard Worker             const auto [x, y] = resolveTouchedPosition(entry);
2653*38e8c45fSAndroid Build Coastguard Worker             const bool isStylus = isPointerFromStylus(entry, /*pointerIndex=*/0);
2654*38e8c45fSAndroid Build Coastguard Worker             sp<WindowInfoHandle> oldTouchedWindowHandle =
2655*38e8c45fSAndroid Build Coastguard Worker                     tempTouchState.getFirstForegroundWindowHandle(entry.deviceId);
2656*38e8c45fSAndroid Build Coastguard Worker             LOG_ALWAYS_FATAL_IF(oldTouchedWindowHandle == nullptr);
2657*38e8c45fSAndroid Build Coastguard Worker             sp<WindowInfoHandle> newTouchedWindowHandle =
2658*38e8c45fSAndroid Build Coastguard Worker                     findTouchedWindowAtLocked(displayId, x, y, isStylus);
2659*38e8c45fSAndroid Build Coastguard Worker 
2660*38e8c45fSAndroid Build Coastguard Worker             // Verify targeted injection.
2661*38e8c45fSAndroid Build Coastguard Worker             if (const auto err = verifyTargetedInjection(newTouchedWindowHandle, entry); err) {
2662*38e8c45fSAndroid Build Coastguard Worker                 ALOGW("Dropping injected event: %s", (*err).c_str());
2663*38e8c45fSAndroid Build Coastguard Worker                 return injectionError(InputEventInjectionResult::TARGET_MISMATCH);
2664*38e8c45fSAndroid Build Coastguard Worker             }
2665*38e8c45fSAndroid Build Coastguard Worker 
2666*38e8c45fSAndroid Build Coastguard Worker             // Do not slide events to the window which can not receive motion event
2667*38e8c45fSAndroid Build Coastguard Worker             if (newTouchedWindowHandle != nullptr &&
2668*38e8c45fSAndroid Build Coastguard Worker                 !canWindowReceiveMotionLocked(newTouchedWindowHandle, entry)) {
2669*38e8c45fSAndroid Build Coastguard Worker                 newTouchedWindowHandle = nullptr;
2670*38e8c45fSAndroid Build Coastguard Worker             }
2671*38e8c45fSAndroid Build Coastguard Worker 
2672*38e8c45fSAndroid Build Coastguard Worker             if (newTouchedWindowHandle != nullptr &&
2673*38e8c45fSAndroid Build Coastguard Worker                 !haveSameToken(oldTouchedWindowHandle, newTouchedWindowHandle)) {
2674*38e8c45fSAndroid Build Coastguard Worker                 ALOGI("Touch is slipping out of window %s into window %s in display %s",
2675*38e8c45fSAndroid Build Coastguard Worker                       oldTouchedWindowHandle->getName().c_str(),
2676*38e8c45fSAndroid Build Coastguard Worker                       newTouchedWindowHandle->getName().c_str(), displayId.toString().c_str());
2677*38e8c45fSAndroid Build Coastguard Worker 
2678*38e8c45fSAndroid Build Coastguard Worker                 // Make a slippery exit from the old window.
2679*38e8c45fSAndroid Build Coastguard Worker                 std::bitset<MAX_POINTER_ID + 1> pointerIds;
2680*38e8c45fSAndroid Build Coastguard Worker                 const PointerProperties& pointer = entry.pointerProperties[0];
2681*38e8c45fSAndroid Build Coastguard Worker                 pointerIds.set(pointer.id);
2682*38e8c45fSAndroid Build Coastguard Worker 
2683*38e8c45fSAndroid Build Coastguard Worker                 const TouchedWindow& touchedWindow =
2684*38e8c45fSAndroid Build Coastguard Worker                         tempTouchState.getTouchedWindow(oldTouchedWindowHandle);
2685*38e8c45fSAndroid Build Coastguard Worker                 addPointerWindowTargetLocked(oldTouchedWindowHandle,
2686*38e8c45fSAndroid Build Coastguard Worker                                              InputTarget::DispatchMode::SLIPPERY_EXIT,
2687*38e8c45fSAndroid Build Coastguard Worker                                              ftl::Flags<InputTarget::Flags>(), pointerIds,
2688*38e8c45fSAndroid Build Coastguard Worker                                              touchedWindow.getDownTimeInTarget(entry.deviceId),
2689*38e8c45fSAndroid Build Coastguard Worker                                              targets);
2690*38e8c45fSAndroid Build Coastguard Worker 
2691*38e8c45fSAndroid Build Coastguard Worker                 // Make a slippery entrance into the new window.
2692*38e8c45fSAndroid Build Coastguard Worker                 if (newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
2693*38e8c45fSAndroid Build Coastguard Worker                     isSplit = !isFromMouse;
2694*38e8c45fSAndroid Build Coastguard Worker                 }
2695*38e8c45fSAndroid Build Coastguard Worker 
2696*38e8c45fSAndroid Build Coastguard Worker                 ftl::Flags<InputTarget::Flags> targetFlags;
2697*38e8c45fSAndroid Build Coastguard Worker                 if (canReceiveForegroundTouches(*newTouchedWindowHandle->getInfo())) {
2698*38e8c45fSAndroid Build Coastguard Worker                     targetFlags |= InputTarget::Flags::FOREGROUND;
2699*38e8c45fSAndroid Build Coastguard Worker                 }
2700*38e8c45fSAndroid Build Coastguard Worker                 if (isSplit) {
2701*38e8c45fSAndroid Build Coastguard Worker                     targetFlags |= InputTarget::Flags::SPLIT;
2702*38e8c45fSAndroid Build Coastguard Worker                 }
2703*38e8c45fSAndroid Build Coastguard Worker                 if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
2704*38e8c45fSAndroid Build Coastguard Worker                     targetFlags |= InputTarget::Flags::WINDOW_IS_OBSCURED;
2705*38e8c45fSAndroid Build Coastguard Worker                 } else if (isWindowObscuredLocked(newTouchedWindowHandle)) {
2706*38e8c45fSAndroid Build Coastguard Worker                     targetFlags |= InputTarget::Flags::WINDOW_IS_PARTIALLY_OBSCURED;
2707*38e8c45fSAndroid Build Coastguard Worker                 }
2708*38e8c45fSAndroid Build Coastguard Worker 
2709*38e8c45fSAndroid Build Coastguard Worker                 tempTouchState.addOrUpdateWindow(newTouchedWindowHandle,
2710*38e8c45fSAndroid Build Coastguard Worker                                                  InputTarget::DispatchMode::SLIPPERY_ENTER,
2711*38e8c45fSAndroid Build Coastguard Worker                                                  targetFlags, entry.deviceId, {pointer},
2712*38e8c45fSAndroid Build Coastguard Worker                                                  entry.eventTime);
2713*38e8c45fSAndroid Build Coastguard Worker 
2714*38e8c45fSAndroid Build Coastguard Worker                 // Check if the wallpaper window should deliver the corresponding event.
2715*38e8c45fSAndroid Build Coastguard Worker                 slipWallpaperTouch(targetFlags, oldTouchedWindowHandle, newTouchedWindowHandle,
2716*38e8c45fSAndroid Build Coastguard Worker                                    tempTouchState, entry, targets);
2717*38e8c45fSAndroid Build Coastguard Worker                 tempTouchState.removeTouchingPointerFromWindow(entry.deviceId, pointer.id,
2718*38e8c45fSAndroid Build Coastguard Worker                                                                oldTouchedWindowHandle);
2719*38e8c45fSAndroid Build Coastguard Worker             }
2720*38e8c45fSAndroid Build Coastguard Worker         }
2721*38e8c45fSAndroid Build Coastguard Worker 
2722*38e8c45fSAndroid Build Coastguard Worker         // Update the pointerIds for non-splittable when it received pointer down.
2723*38e8c45fSAndroid Build Coastguard Worker         if (!isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN) {
2724*38e8c45fSAndroid Build Coastguard Worker             // If no split, we suppose all touched windows should receive pointer down.
2725*38e8c45fSAndroid Build Coastguard Worker             const int32_t pointerIndex = MotionEvent::getActionIndex(action);
2726*38e8c45fSAndroid Build Coastguard Worker             std::vector<PointerProperties> touchingPointers{entry.pointerProperties[pointerIndex]};
2727*38e8c45fSAndroid Build Coastguard Worker             for (TouchedWindow& touchedWindow : tempTouchState.windows) {
2728*38e8c45fSAndroid Build Coastguard Worker                 // Ignore drag window for it should just track one pointer.
2729*38e8c45fSAndroid Build Coastguard Worker                 if (mDragState && mDragState->dragWindow == touchedWindow.windowHandle) {
2730*38e8c45fSAndroid Build Coastguard Worker                     continue;
2731*38e8c45fSAndroid Build Coastguard Worker                 }
2732*38e8c45fSAndroid Build Coastguard Worker                 if (!touchedWindow.hasTouchingPointers(entry.deviceId)) {
2733*38e8c45fSAndroid Build Coastguard Worker                     continue;
2734*38e8c45fSAndroid Build Coastguard Worker                 }
2735*38e8c45fSAndroid Build Coastguard Worker                 touchedWindow.addTouchingPointers(entry.deviceId, touchingPointers);
2736*38e8c45fSAndroid Build Coastguard Worker             }
2737*38e8c45fSAndroid Build Coastguard Worker         }
2738*38e8c45fSAndroid Build Coastguard Worker     }
2739*38e8c45fSAndroid Build Coastguard Worker 
2740*38e8c45fSAndroid Build Coastguard Worker     // Update dispatching for hover enter and exit.
2741*38e8c45fSAndroid Build Coastguard Worker     {
2742*38e8c45fSAndroid Build Coastguard Worker         std::vector<TouchedWindow> hoveringWindows =
2743*38e8c45fSAndroid Build Coastguard Worker                 getHoveringWindowsLocked(oldState, tempTouchState, entry,
2744*38e8c45fSAndroid Build Coastguard Worker                                          std::bind_front(&InputDispatcher::logDispatchStateLocked,
2745*38e8c45fSAndroid Build Coastguard Worker                                                          this));
2746*38e8c45fSAndroid Build Coastguard Worker         // Hardcode to single hovering pointer for now.
2747*38e8c45fSAndroid Build Coastguard Worker         std::bitset<MAX_POINTER_ID + 1> pointerIds;
2748*38e8c45fSAndroid Build Coastguard Worker         pointerIds.set(entry.pointerProperties[0].id);
2749*38e8c45fSAndroid Build Coastguard Worker         for (const TouchedWindow& touchedWindow : hoveringWindows) {
2750*38e8c45fSAndroid Build Coastguard Worker             addPointerWindowTargetLocked(touchedWindow.windowHandle, touchedWindow.dispatchMode,
2751*38e8c45fSAndroid Build Coastguard Worker                                          touchedWindow.targetFlags, pointerIds,
2752*38e8c45fSAndroid Build Coastguard Worker                                          touchedWindow.getDownTimeInTarget(entry.deviceId),
2753*38e8c45fSAndroid Build Coastguard Worker                                          targets);
2754*38e8c45fSAndroid Build Coastguard Worker         }
2755*38e8c45fSAndroid Build Coastguard Worker     }
2756*38e8c45fSAndroid Build Coastguard Worker 
2757*38e8c45fSAndroid Build Coastguard Worker     // Ensure that all touched windows are valid for injection.
2758*38e8c45fSAndroid Build Coastguard Worker     if (entry.injectionState != nullptr) {
2759*38e8c45fSAndroid Build Coastguard Worker         std::string errs;
2760*38e8c45fSAndroid Build Coastguard Worker         for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
2761*38e8c45fSAndroid Build Coastguard Worker             const auto err = verifyTargetedInjection(touchedWindow.windowHandle, entry);
2762*38e8c45fSAndroid Build Coastguard Worker             if (err) errs += "\n  - " + *err;
2763*38e8c45fSAndroid Build Coastguard Worker         }
2764*38e8c45fSAndroid Build Coastguard Worker         if (!errs.empty()) {
2765*38e8c45fSAndroid Build Coastguard Worker             ALOGW("Dropping targeted injection: At least one touched window is not owned by uid "
2766*38e8c45fSAndroid Build Coastguard Worker                   "%s:%s",
2767*38e8c45fSAndroid Build Coastguard Worker                   entry.injectionState->targetUid->toString().c_str(), errs.c_str());
2768*38e8c45fSAndroid Build Coastguard Worker             return injectionError(InputEventInjectionResult::TARGET_MISMATCH);
2769*38e8c45fSAndroid Build Coastguard Worker         }
2770*38e8c45fSAndroid Build Coastguard Worker     }
2771*38e8c45fSAndroid Build Coastguard Worker 
2772*38e8c45fSAndroid Build Coastguard Worker     // Check whether windows listening for outside touches are owned by the same UID. If the owner
2773*38e8c45fSAndroid Build Coastguard Worker     // has a different UID, then we will not reveal coordinate information to this window.
2774*38e8c45fSAndroid Build Coastguard Worker     if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
2775*38e8c45fSAndroid Build Coastguard Worker         sp<WindowInfoHandle> foregroundWindowHandle =
2776*38e8c45fSAndroid Build Coastguard Worker                 tempTouchState.getFirstForegroundWindowHandle(entry.deviceId);
2777*38e8c45fSAndroid Build Coastguard Worker         if (foregroundWindowHandle) {
2778*38e8c45fSAndroid Build Coastguard Worker             const auto foregroundWindowUid = foregroundWindowHandle->getInfo()->ownerUid;
2779*38e8c45fSAndroid Build Coastguard Worker             for (InputTarget& target : targets) {
2780*38e8c45fSAndroid Build Coastguard Worker                 if (target.dispatchMode == InputTarget::DispatchMode::OUTSIDE) {
2781*38e8c45fSAndroid Build Coastguard Worker                     sp<WindowInfoHandle> targetWindow =
2782*38e8c45fSAndroid Build Coastguard Worker                             getWindowHandleLocked(target.connection->getToken());
2783*38e8c45fSAndroid Build Coastguard Worker                     if (targetWindow->getInfo()->ownerUid != foregroundWindowUid) {
2784*38e8c45fSAndroid Build Coastguard Worker                         target.flags |= InputTarget::Flags::ZERO_COORDS;
2785*38e8c45fSAndroid Build Coastguard Worker                     }
2786*38e8c45fSAndroid Build Coastguard Worker                 }
2787*38e8c45fSAndroid Build Coastguard Worker             }
2788*38e8c45fSAndroid Build Coastguard Worker         }
2789*38e8c45fSAndroid Build Coastguard Worker     }
2790*38e8c45fSAndroid Build Coastguard Worker 
2791*38e8c45fSAndroid Build Coastguard Worker     // If this is a touchpad navigation gesture, it needs to only be sent to trusted targets, as we
2792*38e8c45fSAndroid Build Coastguard Worker     // only want the system UI to handle these gestures.
2793*38e8c45fSAndroid Build Coastguard Worker     const bool isTouchpadNavGesture = isFromSource(entry.source, AINPUT_SOURCE_MOUSE) &&
2794*38e8c45fSAndroid Build Coastguard Worker             entry.classification == MotionClassification::MULTI_FINGER_SWIPE;
2795*38e8c45fSAndroid Build Coastguard Worker     if (isTouchpadNavGesture) {
2796*38e8c45fSAndroid Build Coastguard Worker         filterUntrustedTargets(/* byref */ tempTouchState, /* byref */ targets);
2797*38e8c45fSAndroid Build Coastguard Worker     }
2798*38e8c45fSAndroid Build Coastguard Worker 
2799*38e8c45fSAndroid Build Coastguard Worker     // Output targets from the touch state.
2800*38e8c45fSAndroid Build Coastguard Worker     for (const TouchedWindow& touchedWindow : tempTouchState.windows) {
2801*38e8c45fSAndroid Build Coastguard Worker         std::vector<PointerProperties> touchingPointers =
2802*38e8c45fSAndroid Build Coastguard Worker                 touchedWindow.getTouchingPointers(entry.deviceId);
2803*38e8c45fSAndroid Build Coastguard Worker         if (touchingPointers.empty()) {
2804*38e8c45fSAndroid Build Coastguard Worker             continue;
2805*38e8c45fSAndroid Build Coastguard Worker         }
2806*38e8c45fSAndroid Build Coastguard Worker         addPointerWindowTargetLocked(touchedWindow.windowHandle, touchedWindow.dispatchMode,
2807*38e8c45fSAndroid Build Coastguard Worker                                      touchedWindow.targetFlags, getPointerIds(touchingPointers),
2808*38e8c45fSAndroid Build Coastguard Worker                                      touchedWindow.getDownTimeInTarget(entry.deviceId), targets);
2809*38e8c45fSAndroid Build Coastguard Worker     }
2810*38e8c45fSAndroid Build Coastguard Worker 
2811*38e8c45fSAndroid Build Coastguard Worker     // During targeted injection, only allow owned targets to receive events
2812*38e8c45fSAndroid Build Coastguard Worker     std::erase_if(targets, [&](const InputTarget& target) {
2813*38e8c45fSAndroid Build Coastguard Worker         LOG_ALWAYS_FATAL_IF(target.windowHandle == nullptr);
2814*38e8c45fSAndroid Build Coastguard Worker         const auto err = verifyTargetedInjection(target.windowHandle, entry);
2815*38e8c45fSAndroid Build Coastguard Worker         if (err) {
2816*38e8c45fSAndroid Build Coastguard Worker             LOG(WARNING) << "Dropping injected event from " << target.windowHandle->getName()
2817*38e8c45fSAndroid Build Coastguard Worker                          << ": " << (*err);
2818*38e8c45fSAndroid Build Coastguard Worker             return true;
2819*38e8c45fSAndroid Build Coastguard Worker         }
2820*38e8c45fSAndroid Build Coastguard Worker         return false;
2821*38e8c45fSAndroid Build Coastguard Worker     });
2822*38e8c45fSAndroid Build Coastguard Worker 
2823*38e8c45fSAndroid Build Coastguard Worker     if (targets.empty()) {
2824*38e8c45fSAndroid Build Coastguard Worker         LOG(INFO) << "Dropping event because no targets were found: " << entry.getDescription();
2825*38e8c45fSAndroid Build Coastguard Worker         return injectionError(InputEventInjectionResult::FAILED);
2826*38e8c45fSAndroid Build Coastguard Worker     }
2827*38e8c45fSAndroid Build Coastguard Worker 
2828*38e8c45fSAndroid Build Coastguard Worker     // If we only have windows getting ACTION_OUTSIDE, then drop the event, because there is no
2829*38e8c45fSAndroid Build Coastguard Worker     // window that is actually receiving the entire gesture.
2830*38e8c45fSAndroid Build Coastguard Worker     if (std::all_of(targets.begin(), targets.end(), [](const InputTarget& target) {
2831*38e8c45fSAndroid Build Coastguard Worker             return target.dispatchMode == InputTarget::DispatchMode::OUTSIDE;
2832*38e8c45fSAndroid Build Coastguard Worker         })) {
2833*38e8c45fSAndroid Build Coastguard Worker         LOG(INFO) << "Dropping event because all windows would just receive ACTION_OUTSIDE: "
2834*38e8c45fSAndroid Build Coastguard Worker                   << entry.getDescription();
2835*38e8c45fSAndroid Build Coastguard Worker         return injectionError(InputEventInjectionResult::FAILED);
2836*38e8c45fSAndroid Build Coastguard Worker     }
2837*38e8c45fSAndroid Build Coastguard Worker 
2838*38e8c45fSAndroid Build Coastguard Worker     // Now that we have generated all of the input targets for this event, reset the dispatch
2839*38e8c45fSAndroid Build Coastguard Worker     // mode for all touched window to AS_IS.
2840*38e8c45fSAndroid Build Coastguard Worker     for (TouchedWindow& touchedWindow : tempTouchState.windows) {
2841*38e8c45fSAndroid Build Coastguard Worker         touchedWindow.dispatchMode = InputTarget::DispatchMode::AS_IS;
2842*38e8c45fSAndroid Build Coastguard Worker     }
2843*38e8c45fSAndroid Build Coastguard Worker 
2844*38e8c45fSAndroid Build Coastguard Worker     // Update final pieces of touch state if the injector had permission.
2845*38e8c45fSAndroid Build Coastguard Worker     if (maskedAction == AMOTION_EVENT_ACTION_UP) {
2846*38e8c45fSAndroid Build Coastguard Worker         // Pointer went up.
2847*38e8c45fSAndroid Build Coastguard Worker         tempTouchState.removeTouchingPointer(entry.deviceId, entry.pointerProperties[0].id);
2848*38e8c45fSAndroid Build Coastguard Worker     } else if (maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
2849*38e8c45fSAndroid Build Coastguard Worker         // All pointers up or canceled.
2850*38e8c45fSAndroid Build Coastguard Worker         tempTouchState.removeAllPointersForDevice(entry.deviceId);
2851*38e8c45fSAndroid Build Coastguard Worker     } else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
2852*38e8c45fSAndroid Build Coastguard Worker         // One pointer went up.
2853*38e8c45fSAndroid Build Coastguard Worker         const int32_t pointerIndex = MotionEvent::getActionIndex(action);
2854*38e8c45fSAndroid Build Coastguard Worker         const uint32_t pointerId = entry.pointerProperties[pointerIndex].id;
2855*38e8c45fSAndroid Build Coastguard Worker         tempTouchState.removeTouchingPointer(entry.deviceId, pointerId);
2856*38e8c45fSAndroid Build Coastguard Worker     }
2857*38e8c45fSAndroid Build Coastguard Worker 
2858*38e8c45fSAndroid Build Coastguard Worker     // Save changes unless the action was scroll in which case the temporary touch
2859*38e8c45fSAndroid Build Coastguard Worker     // state was only valid for this one action.
2860*38e8c45fSAndroid Build Coastguard Worker     if (maskedAction != AMOTION_EVENT_ACTION_SCROLL) {
2861*38e8c45fSAndroid Build Coastguard Worker         if (displayId >= ui::LogicalDisplayId::DEFAULT) {
2862*38e8c45fSAndroid Build Coastguard Worker             tempTouchState.clearWindowsWithoutPointers();
2863*38e8c45fSAndroid Build Coastguard Worker             mTouchStatesByDisplay[displayId] = tempTouchState;
2864*38e8c45fSAndroid Build Coastguard Worker         } else {
2865*38e8c45fSAndroid Build Coastguard Worker             mTouchStatesByDisplay.erase(displayId);
2866*38e8c45fSAndroid Build Coastguard Worker         }
2867*38e8c45fSAndroid Build Coastguard Worker     }
2868*38e8c45fSAndroid Build Coastguard Worker 
2869*38e8c45fSAndroid Build Coastguard Worker     if (tempTouchState.windows.empty()) {
2870*38e8c45fSAndroid Build Coastguard Worker         mTouchStatesByDisplay.erase(displayId);
2871*38e8c45fSAndroid Build Coastguard Worker     }
2872*38e8c45fSAndroid Build Coastguard Worker 
2873*38e8c45fSAndroid Build Coastguard Worker     return targets;
2874*38e8c45fSAndroid Build Coastguard Worker }
2875*38e8c45fSAndroid Build Coastguard Worker 
finishDragAndDrop(ui::LogicalDisplayId displayId,float x,float y)2876*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::finishDragAndDrop(ui::LogicalDisplayId displayId, float x, float y) {
2877*38e8c45fSAndroid Build Coastguard Worker     // Prevent stylus interceptor windows from affecting drag and drop behavior for now, until we
2878*38e8c45fSAndroid Build Coastguard Worker     // have an explicit reason to support it.
2879*38e8c45fSAndroid Build Coastguard Worker     constexpr bool isStylus = false;
2880*38e8c45fSAndroid Build Coastguard Worker 
2881*38e8c45fSAndroid Build Coastguard Worker     sp<WindowInfoHandle> dropWindow =
2882*38e8c45fSAndroid Build Coastguard Worker             findTouchedWindowAtLocked(displayId, x, y, isStylus, /*ignoreDragWindow=*/true);
2883*38e8c45fSAndroid Build Coastguard Worker     if (dropWindow) {
2884*38e8c45fSAndroid Build Coastguard Worker         vec2 local = dropWindow->getInfo()->transform.transform(x, y);
2885*38e8c45fSAndroid Build Coastguard Worker         sendDropWindowCommandLocked(dropWindow->getToken(), local.x, local.y);
2886*38e8c45fSAndroid Build Coastguard Worker     } else {
2887*38e8c45fSAndroid Build Coastguard Worker         ALOGW("No window found when drop.");
2888*38e8c45fSAndroid Build Coastguard Worker         sendDropWindowCommandLocked(nullptr, 0, 0);
2889*38e8c45fSAndroid Build Coastguard Worker     }
2890*38e8c45fSAndroid Build Coastguard Worker     mDragState.reset();
2891*38e8c45fSAndroid Build Coastguard Worker }
2892*38e8c45fSAndroid Build Coastguard Worker 
addDragEventLocked(const MotionEntry & entry)2893*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::addDragEventLocked(const MotionEntry& entry) {
2894*38e8c45fSAndroid Build Coastguard Worker     if (!mDragState || mDragState->dragWindow->getInfo()->displayId != entry.displayId ||
2895*38e8c45fSAndroid Build Coastguard Worker         mDragState->deviceId != entry.deviceId) {
2896*38e8c45fSAndroid Build Coastguard Worker         return;
2897*38e8c45fSAndroid Build Coastguard Worker     }
2898*38e8c45fSAndroid Build Coastguard Worker 
2899*38e8c45fSAndroid Build Coastguard Worker     if (!mDragState->isStartDrag) {
2900*38e8c45fSAndroid Build Coastguard Worker         mDragState->isStartDrag = true;
2901*38e8c45fSAndroid Build Coastguard Worker         mDragState->isStylusButtonDownAtStart =
2902*38e8c45fSAndroid Build Coastguard Worker                 (entry.buttonState & AMOTION_EVENT_BUTTON_STYLUS_PRIMARY) != 0;
2903*38e8c45fSAndroid Build Coastguard Worker     }
2904*38e8c45fSAndroid Build Coastguard Worker 
2905*38e8c45fSAndroid Build Coastguard Worker     // Find the pointer index by id.
2906*38e8c45fSAndroid Build Coastguard Worker     int32_t pointerIndex = 0;
2907*38e8c45fSAndroid Build Coastguard Worker     for (; static_cast<uint32_t>(pointerIndex) < entry.getPointerCount(); pointerIndex++) {
2908*38e8c45fSAndroid Build Coastguard Worker         const PointerProperties& pointerProperties = entry.pointerProperties[pointerIndex];
2909*38e8c45fSAndroid Build Coastguard Worker         if (pointerProperties.id == mDragState->pointerId) {
2910*38e8c45fSAndroid Build Coastguard Worker             break;
2911*38e8c45fSAndroid Build Coastguard Worker         }
2912*38e8c45fSAndroid Build Coastguard Worker     }
2913*38e8c45fSAndroid Build Coastguard Worker 
2914*38e8c45fSAndroid Build Coastguard Worker     if (uint32_t(pointerIndex) == entry.getPointerCount()) {
2915*38e8c45fSAndroid Build Coastguard Worker         LOG_ALWAYS_FATAL("Should find a valid pointer index by id %d", mDragState->pointerId);
2916*38e8c45fSAndroid Build Coastguard Worker     }
2917*38e8c45fSAndroid Build Coastguard Worker 
2918*38e8c45fSAndroid Build Coastguard Worker     const int32_t maskedAction = entry.action & AMOTION_EVENT_ACTION_MASK;
2919*38e8c45fSAndroid Build Coastguard Worker     const int32_t x = entry.pointerCoords[pointerIndex].getX();
2920*38e8c45fSAndroid Build Coastguard Worker     const int32_t y = entry.pointerCoords[pointerIndex].getY();
2921*38e8c45fSAndroid Build Coastguard Worker 
2922*38e8c45fSAndroid Build Coastguard Worker     switch (maskedAction) {
2923*38e8c45fSAndroid Build Coastguard Worker         case AMOTION_EVENT_ACTION_MOVE: {
2924*38e8c45fSAndroid Build Coastguard Worker             // Handle the special case : stylus button no longer pressed.
2925*38e8c45fSAndroid Build Coastguard Worker             bool isStylusButtonDown =
2926*38e8c45fSAndroid Build Coastguard Worker                     (entry.buttonState & AMOTION_EVENT_BUTTON_STYLUS_PRIMARY) != 0;
2927*38e8c45fSAndroid Build Coastguard Worker             if (mDragState->isStylusButtonDownAtStart && !isStylusButtonDown) {
2928*38e8c45fSAndroid Build Coastguard Worker                 finishDragAndDrop(entry.displayId, x, y);
2929*38e8c45fSAndroid Build Coastguard Worker                 return;
2930*38e8c45fSAndroid Build Coastguard Worker             }
2931*38e8c45fSAndroid Build Coastguard Worker 
2932*38e8c45fSAndroid Build Coastguard Worker             // Prevent stylus interceptor windows from affecting drag and drop behavior for now,
2933*38e8c45fSAndroid Build Coastguard Worker             // until we have an explicit reason to support it.
2934*38e8c45fSAndroid Build Coastguard Worker             constexpr bool isStylus = false;
2935*38e8c45fSAndroid Build Coastguard Worker 
2936*38e8c45fSAndroid Build Coastguard Worker             sp<WindowInfoHandle> hoverWindowHandle =
2937*38e8c45fSAndroid Build Coastguard Worker                     findTouchedWindowAtLocked(entry.displayId, x, y, isStylus,
2938*38e8c45fSAndroid Build Coastguard Worker                                               /*ignoreDragWindow=*/true);
2939*38e8c45fSAndroid Build Coastguard Worker             // enqueue drag exit if needed.
2940*38e8c45fSAndroid Build Coastguard Worker             if (hoverWindowHandle != mDragState->dragHoverWindowHandle &&
2941*38e8c45fSAndroid Build Coastguard Worker                 !haveSameToken(hoverWindowHandle, mDragState->dragHoverWindowHandle)) {
2942*38e8c45fSAndroid Build Coastguard Worker                 if (mDragState->dragHoverWindowHandle != nullptr) {
2943*38e8c45fSAndroid Build Coastguard Worker                     enqueueDragEventLocked(mDragState->dragHoverWindowHandle, /*isExiting=*/true, x,
2944*38e8c45fSAndroid Build Coastguard Worker                                            y);
2945*38e8c45fSAndroid Build Coastguard Worker                 }
2946*38e8c45fSAndroid Build Coastguard Worker                 mDragState->dragHoverWindowHandle = hoverWindowHandle;
2947*38e8c45fSAndroid Build Coastguard Worker             }
2948*38e8c45fSAndroid Build Coastguard Worker             // enqueue drag location if needed.
2949*38e8c45fSAndroid Build Coastguard Worker             if (hoverWindowHandle != nullptr) {
2950*38e8c45fSAndroid Build Coastguard Worker                 enqueueDragEventLocked(hoverWindowHandle, /*isExiting=*/false, x, y);
2951*38e8c45fSAndroid Build Coastguard Worker             }
2952*38e8c45fSAndroid Build Coastguard Worker             break;
2953*38e8c45fSAndroid Build Coastguard Worker         }
2954*38e8c45fSAndroid Build Coastguard Worker 
2955*38e8c45fSAndroid Build Coastguard Worker         case AMOTION_EVENT_ACTION_POINTER_UP:
2956*38e8c45fSAndroid Build Coastguard Worker             if (MotionEvent::getActionIndex(entry.action) != pointerIndex) {
2957*38e8c45fSAndroid Build Coastguard Worker                 break;
2958*38e8c45fSAndroid Build Coastguard Worker             }
2959*38e8c45fSAndroid Build Coastguard Worker             // The drag pointer is up.
2960*38e8c45fSAndroid Build Coastguard Worker             [[fallthrough]];
2961*38e8c45fSAndroid Build Coastguard Worker         case AMOTION_EVENT_ACTION_UP:
2962*38e8c45fSAndroid Build Coastguard Worker             finishDragAndDrop(entry.displayId, x, y);
2963*38e8c45fSAndroid Build Coastguard Worker             break;
2964*38e8c45fSAndroid Build Coastguard Worker         case AMOTION_EVENT_ACTION_CANCEL: {
2965*38e8c45fSAndroid Build Coastguard Worker             ALOGD("Receiving cancel when drag and drop.");
2966*38e8c45fSAndroid Build Coastguard Worker             sendDropWindowCommandLocked(nullptr, 0, 0);
2967*38e8c45fSAndroid Build Coastguard Worker             mDragState.reset();
2968*38e8c45fSAndroid Build Coastguard Worker             break;
2969*38e8c45fSAndroid Build Coastguard Worker         }
2970*38e8c45fSAndroid Build Coastguard Worker     }
2971*38e8c45fSAndroid Build Coastguard Worker }
2972*38e8c45fSAndroid Build Coastguard Worker 
createInputTargetLocked(const sp<android::gui::WindowInfoHandle> & windowHandle,InputTarget::DispatchMode dispatchMode,ftl::Flags<InputTarget::Flags> targetFlags,std::optional<nsecs_t> firstDownTimeInTarget) const2973*38e8c45fSAndroid Build Coastguard Worker std::optional<InputTarget> InputDispatcher::createInputTargetLocked(
2974*38e8c45fSAndroid Build Coastguard Worker         const sp<android::gui::WindowInfoHandle>& windowHandle,
2975*38e8c45fSAndroid Build Coastguard Worker         InputTarget::DispatchMode dispatchMode, ftl::Flags<InputTarget::Flags> targetFlags,
2976*38e8c45fSAndroid Build Coastguard Worker         std::optional<nsecs_t> firstDownTimeInTarget) const {
2977*38e8c45fSAndroid Build Coastguard Worker     std::shared_ptr<Connection> connection = getConnectionLocked(windowHandle->getToken());
2978*38e8c45fSAndroid Build Coastguard Worker     if (connection == nullptr) {
2979*38e8c45fSAndroid Build Coastguard Worker         ALOGW("Not creating InputTarget for %s, no input channel", windowHandle->getName().c_str());
2980*38e8c45fSAndroid Build Coastguard Worker         return {};
2981*38e8c45fSAndroid Build Coastguard Worker     }
2982*38e8c45fSAndroid Build Coastguard Worker     InputTarget inputTarget{connection};
2983*38e8c45fSAndroid Build Coastguard Worker     inputTarget.windowHandle = windowHandle;
2984*38e8c45fSAndroid Build Coastguard Worker     inputTarget.dispatchMode = dispatchMode;
2985*38e8c45fSAndroid Build Coastguard Worker     inputTarget.flags = targetFlags;
2986*38e8c45fSAndroid Build Coastguard Worker     inputTarget.globalScaleFactor = windowHandle->getInfo()->globalScaleFactor;
2987*38e8c45fSAndroid Build Coastguard Worker     inputTarget.firstDownTimeInTarget = firstDownTimeInTarget;
2988*38e8c45fSAndroid Build Coastguard Worker     const auto& displayInfoIt = mDisplayInfos.find(windowHandle->getInfo()->displayId);
2989*38e8c45fSAndroid Build Coastguard Worker     if (displayInfoIt != mDisplayInfos.end()) {
2990*38e8c45fSAndroid Build Coastguard Worker         inputTarget.displayTransform = displayInfoIt->second.transform;
2991*38e8c45fSAndroid Build Coastguard Worker     } else {
2992*38e8c45fSAndroid Build Coastguard Worker         // DisplayInfo not found for this window on display windowHandle->getInfo()->displayId.
2993*38e8c45fSAndroid Build Coastguard Worker         // TODO(b/198444055): Make this an error message after 'setInputWindows' API is removed.
2994*38e8c45fSAndroid Build Coastguard Worker     }
2995*38e8c45fSAndroid Build Coastguard Worker     return inputTarget;
2996*38e8c45fSAndroid Build Coastguard Worker }
2997*38e8c45fSAndroid Build Coastguard Worker 
addWindowTargetLocked(const sp<WindowInfoHandle> & windowHandle,InputTarget::DispatchMode dispatchMode,ftl::Flags<InputTarget::Flags> targetFlags,std::optional<nsecs_t> firstDownTimeInTarget,std::vector<InputTarget> & inputTargets) const2998*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::addWindowTargetLocked(const sp<WindowInfoHandle>& windowHandle,
2999*38e8c45fSAndroid Build Coastguard Worker                                             InputTarget::DispatchMode dispatchMode,
3000*38e8c45fSAndroid Build Coastguard Worker                                             ftl::Flags<InputTarget::Flags> targetFlags,
3001*38e8c45fSAndroid Build Coastguard Worker                                             std::optional<nsecs_t> firstDownTimeInTarget,
3002*38e8c45fSAndroid Build Coastguard Worker                                             std::vector<InputTarget>& inputTargets) const {
3003*38e8c45fSAndroid Build Coastguard Worker     std::vector<InputTarget>::iterator it =
3004*38e8c45fSAndroid Build Coastguard Worker             std::find_if(inputTargets.begin(), inputTargets.end(),
3005*38e8c45fSAndroid Build Coastguard Worker                          [&windowHandle](const InputTarget& inputTarget) {
3006*38e8c45fSAndroid Build Coastguard Worker                              return inputTarget.connection->getToken() == windowHandle->getToken();
3007*38e8c45fSAndroid Build Coastguard Worker                          });
3008*38e8c45fSAndroid Build Coastguard Worker 
3009*38e8c45fSAndroid Build Coastguard Worker     const WindowInfo* windowInfo = windowHandle->getInfo();
3010*38e8c45fSAndroid Build Coastguard Worker 
3011*38e8c45fSAndroid Build Coastguard Worker     if (it == inputTargets.end()) {
3012*38e8c45fSAndroid Build Coastguard Worker         std::optional<InputTarget> target =
3013*38e8c45fSAndroid Build Coastguard Worker                 createInputTargetLocked(windowHandle, dispatchMode, targetFlags,
3014*38e8c45fSAndroid Build Coastguard Worker                                         firstDownTimeInTarget);
3015*38e8c45fSAndroid Build Coastguard Worker         if (!target) {
3016*38e8c45fSAndroid Build Coastguard Worker             return;
3017*38e8c45fSAndroid Build Coastguard Worker         }
3018*38e8c45fSAndroid Build Coastguard Worker         inputTargets.push_back(*target);
3019*38e8c45fSAndroid Build Coastguard Worker         it = inputTargets.end() - 1;
3020*38e8c45fSAndroid Build Coastguard Worker     }
3021*38e8c45fSAndroid Build Coastguard Worker 
3022*38e8c45fSAndroid Build Coastguard Worker     if (it->flags != targetFlags) {
3023*38e8c45fSAndroid Build Coastguard Worker         LOG(ERROR) << "Flags don't match! targetFlags=" << targetFlags.string() << ", it=" << *it;
3024*38e8c45fSAndroid Build Coastguard Worker     }
3025*38e8c45fSAndroid Build Coastguard Worker     if (it->globalScaleFactor != windowInfo->globalScaleFactor) {
3026*38e8c45fSAndroid Build Coastguard Worker         LOG(ERROR) << "Mismatch! it->globalScaleFactor=" << it->globalScaleFactor
3027*38e8c45fSAndroid Build Coastguard Worker                    << ", windowInfo->globalScaleFactor=" << windowInfo->globalScaleFactor;
3028*38e8c45fSAndroid Build Coastguard Worker     }
3029*38e8c45fSAndroid Build Coastguard Worker }
3030*38e8c45fSAndroid Build Coastguard Worker 
addPointerWindowTargetLocked(const sp<android::gui::WindowInfoHandle> & windowHandle,InputTarget::DispatchMode dispatchMode,ftl::Flags<InputTarget::Flags> targetFlags,std::bitset<MAX_POINTER_ID+1> pointerIds,std::optional<nsecs_t> firstDownTimeInTarget,std::vector<InputTarget> & inputTargets) const3031*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::addPointerWindowTargetLocked(
3032*38e8c45fSAndroid Build Coastguard Worker         const sp<android::gui::WindowInfoHandle>& windowHandle,
3033*38e8c45fSAndroid Build Coastguard Worker         InputTarget::DispatchMode dispatchMode, ftl::Flags<InputTarget::Flags> targetFlags,
3034*38e8c45fSAndroid Build Coastguard Worker         std::bitset<MAX_POINTER_ID + 1> pointerIds, std::optional<nsecs_t> firstDownTimeInTarget,
3035*38e8c45fSAndroid Build Coastguard Worker         std::vector<InputTarget>& inputTargets) const REQUIRES(mLock) {
3036*38e8c45fSAndroid Build Coastguard Worker     if (pointerIds.none()) {
3037*38e8c45fSAndroid Build Coastguard Worker         for (const auto& target : inputTargets) {
3038*38e8c45fSAndroid Build Coastguard Worker             LOG(INFO) << "Target: " << target;
3039*38e8c45fSAndroid Build Coastguard Worker         }
3040*38e8c45fSAndroid Build Coastguard Worker         LOG(FATAL) << "No pointers specified for " << windowHandle->getName();
3041*38e8c45fSAndroid Build Coastguard Worker         return;
3042*38e8c45fSAndroid Build Coastguard Worker     }
3043*38e8c45fSAndroid Build Coastguard Worker     std::vector<InputTarget>::iterator it =
3044*38e8c45fSAndroid Build Coastguard Worker             std::find_if(inputTargets.begin(), inputTargets.end(),
3045*38e8c45fSAndroid Build Coastguard Worker                          [&windowHandle](const InputTarget& inputTarget) {
3046*38e8c45fSAndroid Build Coastguard Worker                              return inputTarget.connection->getToken() == windowHandle->getToken();
3047*38e8c45fSAndroid Build Coastguard Worker                          });
3048*38e8c45fSAndroid Build Coastguard Worker 
3049*38e8c45fSAndroid Build Coastguard Worker     // This is a hack, because the actual entry could potentially be an ACTION_DOWN event that
3050*38e8c45fSAndroid Build Coastguard Worker     // causes a HOVER_EXIT to be generated. That means that the same entry of ACTION_DOWN would
3051*38e8c45fSAndroid Build Coastguard Worker     // have DISPATCH_AS_HOVER_EXIT and DISPATCH_AS_IS. And therefore, we have to create separate
3052*38e8c45fSAndroid Build Coastguard Worker     // input targets for hovering pointers and for touching pointers.
3053*38e8c45fSAndroid Build Coastguard Worker     // If we picked an existing input target above, but it's for HOVER_EXIT - let's use a new
3054*38e8c45fSAndroid Build Coastguard Worker     // target instead.
3055*38e8c45fSAndroid Build Coastguard Worker     if (it != inputTargets.end() && it->dispatchMode == InputTarget::DispatchMode::HOVER_EXIT) {
3056*38e8c45fSAndroid Build Coastguard Worker         // Force the code below to create a new input target
3057*38e8c45fSAndroid Build Coastguard Worker         it = inputTargets.end();
3058*38e8c45fSAndroid Build Coastguard Worker     }
3059*38e8c45fSAndroid Build Coastguard Worker 
3060*38e8c45fSAndroid Build Coastguard Worker     const WindowInfo* windowInfo = windowHandle->getInfo();
3061*38e8c45fSAndroid Build Coastguard Worker 
3062*38e8c45fSAndroid Build Coastguard Worker     if (it == inputTargets.end()) {
3063*38e8c45fSAndroid Build Coastguard Worker         std::optional<InputTarget> target =
3064*38e8c45fSAndroid Build Coastguard Worker                 createInputTargetLocked(windowHandle, dispatchMode, targetFlags,
3065*38e8c45fSAndroid Build Coastguard Worker                                         firstDownTimeInTarget);
3066*38e8c45fSAndroid Build Coastguard Worker         if (!target) {
3067*38e8c45fSAndroid Build Coastguard Worker             return;
3068*38e8c45fSAndroid Build Coastguard Worker         }
3069*38e8c45fSAndroid Build Coastguard Worker         inputTargets.push_back(*target);
3070*38e8c45fSAndroid Build Coastguard Worker         it = inputTargets.end() - 1;
3071*38e8c45fSAndroid Build Coastguard Worker     }
3072*38e8c45fSAndroid Build Coastguard Worker 
3073*38e8c45fSAndroid Build Coastguard Worker     if (it->dispatchMode != dispatchMode) {
3074*38e8c45fSAndroid Build Coastguard Worker         LOG(ERROR) << __func__ << ": DispatchMode doesn't match! ignoring new mode="
3075*38e8c45fSAndroid Build Coastguard Worker                    << ftl::enum_string(dispatchMode) << ", it=" << *it;
3076*38e8c45fSAndroid Build Coastguard Worker     }
3077*38e8c45fSAndroid Build Coastguard Worker     if (it->flags != targetFlags) {
3078*38e8c45fSAndroid Build Coastguard Worker         LOG(ERROR) << __func__ << ": Flags don't match! new targetFlags=" << targetFlags.string()
3079*38e8c45fSAndroid Build Coastguard Worker                    << ", it=" << *it;
3080*38e8c45fSAndroid Build Coastguard Worker     }
3081*38e8c45fSAndroid Build Coastguard Worker     if (it->globalScaleFactor != windowInfo->globalScaleFactor) {
3082*38e8c45fSAndroid Build Coastguard Worker         LOG(ERROR) << __func__ << ": Mismatch! it->globalScaleFactor=" << it->globalScaleFactor
3083*38e8c45fSAndroid Build Coastguard Worker                    << ", windowInfo->globalScaleFactor=" << windowInfo->globalScaleFactor;
3084*38e8c45fSAndroid Build Coastguard Worker     }
3085*38e8c45fSAndroid Build Coastguard Worker 
3086*38e8c45fSAndroid Build Coastguard Worker     Result<void> result = it->addPointers(pointerIds, windowInfo->transform);
3087*38e8c45fSAndroid Build Coastguard Worker     if (!result.ok()) {
3088*38e8c45fSAndroid Build Coastguard Worker         logDispatchStateLocked();
3089*38e8c45fSAndroid Build Coastguard Worker         LOG(FATAL) << result.error().message();
3090*38e8c45fSAndroid Build Coastguard Worker     }
3091*38e8c45fSAndroid Build Coastguard Worker }
3092*38e8c45fSAndroid Build Coastguard Worker 
addGlobalMonitoringTargetsLocked(std::vector<InputTarget> & inputTargets,ui::LogicalDisplayId displayId)3093*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::addGlobalMonitoringTargetsLocked(std::vector<InputTarget>& inputTargets,
3094*38e8c45fSAndroid Build Coastguard Worker                                                        ui::LogicalDisplayId displayId) {
3095*38e8c45fSAndroid Build Coastguard Worker     auto monitorsIt = mGlobalMonitorsByDisplay.find(displayId);
3096*38e8c45fSAndroid Build Coastguard Worker     if (monitorsIt == mGlobalMonitorsByDisplay.end()) return;
3097*38e8c45fSAndroid Build Coastguard Worker 
3098*38e8c45fSAndroid Build Coastguard Worker     for (const Monitor& monitor : selectResponsiveMonitorsLocked(monitorsIt->second)) {
3099*38e8c45fSAndroid Build Coastguard Worker         InputTarget target{monitor.connection};
3100*38e8c45fSAndroid Build Coastguard Worker         // target.firstDownTimeInTarget is not set for global monitors. It is only required in split
3101*38e8c45fSAndroid Build Coastguard Worker         // touch and global monitoring works as intended even without setting firstDownTimeInTarget
3102*38e8c45fSAndroid Build Coastguard Worker         if (const auto& it = mDisplayInfos.find(displayId); it != mDisplayInfos.end()) {
3103*38e8c45fSAndroid Build Coastguard Worker             target.displayTransform = it->second.transform;
3104*38e8c45fSAndroid Build Coastguard Worker         }
3105*38e8c45fSAndroid Build Coastguard Worker         target.setDefaultPointerTransform(target.displayTransform);
3106*38e8c45fSAndroid Build Coastguard Worker         inputTargets.push_back(target);
3107*38e8c45fSAndroid Build Coastguard Worker     }
3108*38e8c45fSAndroid Build Coastguard Worker }
3109*38e8c45fSAndroid Build Coastguard Worker 
3110*38e8c45fSAndroid Build Coastguard Worker /**
3111*38e8c45fSAndroid Build Coastguard Worker  * Indicate whether one window handle should be considered as obscuring
3112*38e8c45fSAndroid Build Coastguard Worker  * another window handle. We only check a few preconditions. Actually
3113*38e8c45fSAndroid Build Coastguard Worker  * checking the bounds is left to the caller.
3114*38e8c45fSAndroid Build Coastguard Worker  */
canBeObscuredBy(const sp<WindowInfoHandle> & windowHandle,const sp<WindowInfoHandle> & otherHandle)3115*38e8c45fSAndroid Build Coastguard Worker static bool canBeObscuredBy(const sp<WindowInfoHandle>& windowHandle,
3116*38e8c45fSAndroid Build Coastguard Worker                             const sp<WindowInfoHandle>& otherHandle) {
3117*38e8c45fSAndroid Build Coastguard Worker     // Compare by token so cloned layers aren't counted
3118*38e8c45fSAndroid Build Coastguard Worker     if (haveSameToken(windowHandle, otherHandle)) {
3119*38e8c45fSAndroid Build Coastguard Worker         return false;
3120*38e8c45fSAndroid Build Coastguard Worker     }
3121*38e8c45fSAndroid Build Coastguard Worker     auto info = windowHandle->getInfo();
3122*38e8c45fSAndroid Build Coastguard Worker     auto otherInfo = otherHandle->getInfo();
3123*38e8c45fSAndroid Build Coastguard Worker     if (otherInfo->inputConfig.test(WindowInfo::InputConfig::NOT_VISIBLE)) {
3124*38e8c45fSAndroid Build Coastguard Worker         return false;
3125*38e8c45fSAndroid Build Coastguard Worker     } else if (otherInfo->alpha == 0 &&
3126*38e8c45fSAndroid Build Coastguard Worker                otherInfo->inputConfig.test(WindowInfo::InputConfig::NOT_TOUCHABLE)) {
3127*38e8c45fSAndroid Build Coastguard Worker         // Those act as if they were invisible, so we don't need to flag them.
3128*38e8c45fSAndroid Build Coastguard Worker         // We do want to potentially flag touchable windows even if they have 0
3129*38e8c45fSAndroid Build Coastguard Worker         // opacity, since they can consume touches and alter the effects of the
3130*38e8c45fSAndroid Build Coastguard Worker         // user interaction (eg. apps that rely on
3131*38e8c45fSAndroid Build Coastguard Worker         // Flags::WINDOW_IS_PARTIALLY_OBSCURED should still be told about those
3132*38e8c45fSAndroid Build Coastguard Worker         // windows), hence we also check for FLAG_NOT_TOUCHABLE.
3133*38e8c45fSAndroid Build Coastguard Worker         return false;
3134*38e8c45fSAndroid Build Coastguard Worker     } else if (info->ownerUid == otherInfo->ownerUid) {
3135*38e8c45fSAndroid Build Coastguard Worker         // If ownerUid is the same we don't generate occlusion events as there
3136*38e8c45fSAndroid Build Coastguard Worker         // is no security boundary within an uid.
3137*38e8c45fSAndroid Build Coastguard Worker         return false;
3138*38e8c45fSAndroid Build Coastguard Worker     } else if (otherInfo->inputConfig.test(gui::WindowInfo::InputConfig::TRUSTED_OVERLAY)) {
3139*38e8c45fSAndroid Build Coastguard Worker         return false;
3140*38e8c45fSAndroid Build Coastguard Worker     } else if (otherInfo->displayId != info->displayId) {
3141*38e8c45fSAndroid Build Coastguard Worker         return false;
3142*38e8c45fSAndroid Build Coastguard Worker     }
3143*38e8c45fSAndroid Build Coastguard Worker     return true;
3144*38e8c45fSAndroid Build Coastguard Worker }
3145*38e8c45fSAndroid Build Coastguard Worker 
3146*38e8c45fSAndroid Build Coastguard Worker /**
3147*38e8c45fSAndroid Build Coastguard Worker  * Returns touch occlusion information in the form of TouchOcclusionInfo. To check if the touch is
3148*38e8c45fSAndroid Build Coastguard Worker  * untrusted, one should check:
3149*38e8c45fSAndroid Build Coastguard Worker  *
3150*38e8c45fSAndroid Build Coastguard Worker  * 1. If result.hasBlockingOcclusion is true.
3151*38e8c45fSAndroid Build Coastguard Worker  *    If it's, it means the touch should be blocked due to a window with occlusion mode of
3152*38e8c45fSAndroid Build Coastguard Worker  *    BLOCK_UNTRUSTED.
3153*38e8c45fSAndroid Build Coastguard Worker  *
3154*38e8c45fSAndroid Build Coastguard Worker  * 2. If result.obscuringOpacity > mMaximumObscuringOpacityForTouch.
3155*38e8c45fSAndroid Build Coastguard Worker  *    If it is (and 1 is false), then the touch should be blocked because a stack of windows
3156*38e8c45fSAndroid Build Coastguard Worker  *    (possibly only one) with occlusion mode of USE_OPACITY from one UID resulted in a composed
3157*38e8c45fSAndroid Build Coastguard Worker  *    obscuring opacity above the threshold. Note that if there was no window of occlusion mode
3158*38e8c45fSAndroid Build Coastguard Worker  *    USE_OPACITY, result.obscuringOpacity would've been 0 and since
3159*38e8c45fSAndroid Build Coastguard Worker  *    mMaximumObscuringOpacityForTouch >= 0, the condition above would never be true.
3160*38e8c45fSAndroid Build Coastguard Worker  *
3161*38e8c45fSAndroid Build Coastguard Worker  * If neither of those is true, then it means the touch can be allowed.
3162*38e8c45fSAndroid Build Coastguard Worker  */
computeTouchOcclusionInfoLocked(const sp<WindowInfoHandle> & windowHandle,float x,float y) const3163*38e8c45fSAndroid Build Coastguard Worker InputDispatcher::TouchOcclusionInfo InputDispatcher::computeTouchOcclusionInfoLocked(
3164*38e8c45fSAndroid Build Coastguard Worker         const sp<WindowInfoHandle>& windowHandle, float x, float y) const {
3165*38e8c45fSAndroid Build Coastguard Worker     const WindowInfo* windowInfo = windowHandle->getInfo();
3166*38e8c45fSAndroid Build Coastguard Worker     ui::LogicalDisplayId displayId = windowInfo->displayId;
3167*38e8c45fSAndroid Build Coastguard Worker     const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
3168*38e8c45fSAndroid Build Coastguard Worker     TouchOcclusionInfo info;
3169*38e8c45fSAndroid Build Coastguard Worker     info.hasBlockingOcclusion = false;
3170*38e8c45fSAndroid Build Coastguard Worker     info.obscuringOpacity = 0;
3171*38e8c45fSAndroid Build Coastguard Worker     info.obscuringUid = gui::Uid::INVALID;
3172*38e8c45fSAndroid Build Coastguard Worker     std::map<gui::Uid, float> opacityByUid;
3173*38e8c45fSAndroid Build Coastguard Worker     for (const sp<WindowInfoHandle>& otherHandle : windowHandles) {
3174*38e8c45fSAndroid Build Coastguard Worker         if (windowHandle == otherHandle) {
3175*38e8c45fSAndroid Build Coastguard Worker             break; // All future windows are below us. Exit early.
3176*38e8c45fSAndroid Build Coastguard Worker         }
3177*38e8c45fSAndroid Build Coastguard Worker         const WindowInfo* otherInfo = otherHandle->getInfo();
3178*38e8c45fSAndroid Build Coastguard Worker         if (canBeObscuredBy(windowHandle, otherHandle) &&
3179*38e8c45fSAndroid Build Coastguard Worker             windowOccludesTouchAt(*otherInfo, displayId, x, y, getTransformLocked(displayId)) &&
3180*38e8c45fSAndroid Build Coastguard Worker             !haveSameApplicationToken(windowInfo, otherInfo)) {
3181*38e8c45fSAndroid Build Coastguard Worker             if (DEBUG_TOUCH_OCCLUSION) {
3182*38e8c45fSAndroid Build Coastguard Worker                 info.debugInfo.push_back(
3183*38e8c45fSAndroid Build Coastguard Worker                         dumpWindowForTouchOcclusion(otherInfo, /*isTouchedWindow=*/false));
3184*38e8c45fSAndroid Build Coastguard Worker             }
3185*38e8c45fSAndroid Build Coastguard Worker             // canBeObscuredBy() has returned true above, which means this window is untrusted, so
3186*38e8c45fSAndroid Build Coastguard Worker             // we perform the checks below to see if the touch can be propagated or not based on the
3187*38e8c45fSAndroid Build Coastguard Worker             // window's touch occlusion mode
3188*38e8c45fSAndroid Build Coastguard Worker             if (otherInfo->touchOcclusionMode == TouchOcclusionMode::BLOCK_UNTRUSTED) {
3189*38e8c45fSAndroid Build Coastguard Worker                 info.hasBlockingOcclusion = true;
3190*38e8c45fSAndroid Build Coastguard Worker                 info.obscuringUid = otherInfo->ownerUid;
3191*38e8c45fSAndroid Build Coastguard Worker                 info.obscuringPackage = otherInfo->packageName;
3192*38e8c45fSAndroid Build Coastguard Worker                 break;
3193*38e8c45fSAndroid Build Coastguard Worker             }
3194*38e8c45fSAndroid Build Coastguard Worker             if (otherInfo->touchOcclusionMode == TouchOcclusionMode::USE_OPACITY) {
3195*38e8c45fSAndroid Build Coastguard Worker                 const auto uid = otherInfo->ownerUid;
3196*38e8c45fSAndroid Build Coastguard Worker                 float opacity =
3197*38e8c45fSAndroid Build Coastguard Worker                         (opacityByUid.find(uid) == opacityByUid.end()) ? 0 : opacityByUid[uid];
3198*38e8c45fSAndroid Build Coastguard Worker                 // Given windows A and B:
3199*38e8c45fSAndroid Build Coastguard Worker                 // opacity(A, B) = 1 - [1 - opacity(A)] * [1 - opacity(B)]
3200*38e8c45fSAndroid Build Coastguard Worker                 opacity = 1 - (1 - opacity) * (1 - otherInfo->alpha);
3201*38e8c45fSAndroid Build Coastguard Worker                 opacityByUid[uid] = opacity;
3202*38e8c45fSAndroid Build Coastguard Worker                 if (opacity > info.obscuringOpacity) {
3203*38e8c45fSAndroid Build Coastguard Worker                     info.obscuringOpacity = opacity;
3204*38e8c45fSAndroid Build Coastguard Worker                     info.obscuringUid = uid;
3205*38e8c45fSAndroid Build Coastguard Worker                     info.obscuringPackage = otherInfo->packageName;
3206*38e8c45fSAndroid Build Coastguard Worker                 }
3207*38e8c45fSAndroid Build Coastguard Worker             }
3208*38e8c45fSAndroid Build Coastguard Worker         }
3209*38e8c45fSAndroid Build Coastguard Worker     }
3210*38e8c45fSAndroid Build Coastguard Worker     if (DEBUG_TOUCH_OCCLUSION) {
3211*38e8c45fSAndroid Build Coastguard Worker         info.debugInfo.push_back(dumpWindowForTouchOcclusion(windowInfo, /*isTouchedWindow=*/true));
3212*38e8c45fSAndroid Build Coastguard Worker     }
3213*38e8c45fSAndroid Build Coastguard Worker     return info;
3214*38e8c45fSAndroid Build Coastguard Worker }
3215*38e8c45fSAndroid Build Coastguard Worker 
dumpWindowForTouchOcclusion(const WindowInfo * info,bool isTouchedWindow) const3216*38e8c45fSAndroid Build Coastguard Worker std::string InputDispatcher::dumpWindowForTouchOcclusion(const WindowInfo* info,
3217*38e8c45fSAndroid Build Coastguard Worker                                                          bool isTouchedWindow) const {
3218*38e8c45fSAndroid Build Coastguard Worker     return StringPrintf(INDENT2 "* %spackage=%s/%s, id=%" PRId32 ", mode=%s, alpha=%.2f, "
3219*38e8c45fSAndroid Build Coastguard Worker                                 "frame=[%" PRId32 ",%" PRId32 "][%" PRId32 ",%" PRId32
3220*38e8c45fSAndroid Build Coastguard Worker                                 "], touchableRegion=%s, window={%s}, inputConfig={%s}, "
3221*38e8c45fSAndroid Build Coastguard Worker                                 "hasToken=%s, applicationInfo.name=%s, applicationInfo.token=%s\n",
3222*38e8c45fSAndroid Build Coastguard Worker                         isTouchedWindow ? "[TOUCHED] " : "", info->packageName.c_str(),
3223*38e8c45fSAndroid Build Coastguard Worker                         info->ownerUid.toString().c_str(), info->id,
3224*38e8c45fSAndroid Build Coastguard Worker                         toString(info->touchOcclusionMode).c_str(), info->alpha, info->frame.left,
3225*38e8c45fSAndroid Build Coastguard Worker                         info->frame.top, info->frame.right, info->frame.bottom,
3226*38e8c45fSAndroid Build Coastguard Worker                         dumpRegion(info->touchableRegion).c_str(), info->name.c_str(),
3227*38e8c45fSAndroid Build Coastguard Worker                         info->inputConfig.string().c_str(), toString(info->token != nullptr),
3228*38e8c45fSAndroid Build Coastguard Worker                         info->applicationInfo.name.c_str(),
3229*38e8c45fSAndroid Build Coastguard Worker                         binderToString(info->applicationInfo.token).c_str());
3230*38e8c45fSAndroid Build Coastguard Worker }
3231*38e8c45fSAndroid Build Coastguard Worker 
isTouchTrustedLocked(const TouchOcclusionInfo & occlusionInfo) const3232*38e8c45fSAndroid Build Coastguard Worker bool InputDispatcher::isTouchTrustedLocked(const TouchOcclusionInfo& occlusionInfo) const {
3233*38e8c45fSAndroid Build Coastguard Worker     if (occlusionInfo.hasBlockingOcclusion) {
3234*38e8c45fSAndroid Build Coastguard Worker         ALOGW("Untrusted touch due to occlusion by %s/%s", occlusionInfo.obscuringPackage.c_str(),
3235*38e8c45fSAndroid Build Coastguard Worker               occlusionInfo.obscuringUid.toString().c_str());
3236*38e8c45fSAndroid Build Coastguard Worker         return false;
3237*38e8c45fSAndroid Build Coastguard Worker     }
3238*38e8c45fSAndroid Build Coastguard Worker     if (occlusionInfo.obscuringOpacity > mMaximumObscuringOpacityForTouch) {
3239*38e8c45fSAndroid Build Coastguard Worker         ALOGW("Untrusted touch due to occlusion by %s/%s (obscuring opacity = "
3240*38e8c45fSAndroid Build Coastguard Worker               "%.2f, maximum allowed = %.2f)",
3241*38e8c45fSAndroid Build Coastguard Worker               occlusionInfo.obscuringPackage.c_str(), occlusionInfo.obscuringUid.toString().c_str(),
3242*38e8c45fSAndroid Build Coastguard Worker               occlusionInfo.obscuringOpacity, mMaximumObscuringOpacityForTouch);
3243*38e8c45fSAndroid Build Coastguard Worker         return false;
3244*38e8c45fSAndroid Build Coastguard Worker     }
3245*38e8c45fSAndroid Build Coastguard Worker     return true;
3246*38e8c45fSAndroid Build Coastguard Worker }
3247*38e8c45fSAndroid Build Coastguard Worker 
isWindowObscuredAtPointLocked(const sp<WindowInfoHandle> & windowHandle,float x,float y) const3248*38e8c45fSAndroid Build Coastguard Worker bool InputDispatcher::isWindowObscuredAtPointLocked(const sp<WindowInfoHandle>& windowHandle,
3249*38e8c45fSAndroid Build Coastguard Worker                                                     float x, float y) const {
3250*38e8c45fSAndroid Build Coastguard Worker     ui::LogicalDisplayId displayId = windowHandle->getInfo()->displayId;
3251*38e8c45fSAndroid Build Coastguard Worker     const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
3252*38e8c45fSAndroid Build Coastguard Worker     for (const sp<WindowInfoHandle>& otherHandle : windowHandles) {
3253*38e8c45fSAndroid Build Coastguard Worker         if (windowHandle == otherHandle) {
3254*38e8c45fSAndroid Build Coastguard Worker             break; // All future windows are below us. Exit early.
3255*38e8c45fSAndroid Build Coastguard Worker         }
3256*38e8c45fSAndroid Build Coastguard Worker         const WindowInfo* otherInfo = otherHandle->getInfo();
3257*38e8c45fSAndroid Build Coastguard Worker         if (canBeObscuredBy(windowHandle, otherHandle) &&
3258*38e8c45fSAndroid Build Coastguard Worker             windowOccludesTouchAt(*otherInfo, displayId, x, y, getTransformLocked(displayId))) {
3259*38e8c45fSAndroid Build Coastguard Worker             return true;
3260*38e8c45fSAndroid Build Coastguard Worker         }
3261*38e8c45fSAndroid Build Coastguard Worker     }
3262*38e8c45fSAndroid Build Coastguard Worker     return false;
3263*38e8c45fSAndroid Build Coastguard Worker }
3264*38e8c45fSAndroid Build Coastguard Worker 
isWindowObscuredLocked(const sp<WindowInfoHandle> & windowHandle) const3265*38e8c45fSAndroid Build Coastguard Worker bool InputDispatcher::isWindowObscuredLocked(const sp<WindowInfoHandle>& windowHandle) const {
3266*38e8c45fSAndroid Build Coastguard Worker     ui::LogicalDisplayId displayId = windowHandle->getInfo()->displayId;
3267*38e8c45fSAndroid Build Coastguard Worker     const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
3268*38e8c45fSAndroid Build Coastguard Worker     const WindowInfo* windowInfo = windowHandle->getInfo();
3269*38e8c45fSAndroid Build Coastguard Worker     for (const sp<WindowInfoHandle>& otherHandle : windowHandles) {
3270*38e8c45fSAndroid Build Coastguard Worker         if (windowHandle == otherHandle) {
3271*38e8c45fSAndroid Build Coastguard Worker             break; // All future windows are below us. Exit early.
3272*38e8c45fSAndroid Build Coastguard Worker         }
3273*38e8c45fSAndroid Build Coastguard Worker         const WindowInfo* otherInfo = otherHandle->getInfo();
3274*38e8c45fSAndroid Build Coastguard Worker         if (canBeObscuredBy(windowHandle, otherHandle) && otherInfo->overlaps(windowInfo)) {
3275*38e8c45fSAndroid Build Coastguard Worker             return true;
3276*38e8c45fSAndroid Build Coastguard Worker         }
3277*38e8c45fSAndroid Build Coastguard Worker     }
3278*38e8c45fSAndroid Build Coastguard Worker     return false;
3279*38e8c45fSAndroid Build Coastguard Worker }
3280*38e8c45fSAndroid Build Coastguard Worker 
getApplicationWindowLabel(const InputApplicationHandle * applicationHandle,const sp<WindowInfoHandle> & windowHandle)3281*38e8c45fSAndroid Build Coastguard Worker std::string InputDispatcher::getApplicationWindowLabel(
3282*38e8c45fSAndroid Build Coastguard Worker         const InputApplicationHandle* applicationHandle, const sp<WindowInfoHandle>& windowHandle) {
3283*38e8c45fSAndroid Build Coastguard Worker     if (applicationHandle != nullptr) {
3284*38e8c45fSAndroid Build Coastguard Worker         if (windowHandle != nullptr) {
3285*38e8c45fSAndroid Build Coastguard Worker             return applicationHandle->getName() + " - " + windowHandle->getName();
3286*38e8c45fSAndroid Build Coastguard Worker         } else {
3287*38e8c45fSAndroid Build Coastguard Worker             return applicationHandle->getName();
3288*38e8c45fSAndroid Build Coastguard Worker         }
3289*38e8c45fSAndroid Build Coastguard Worker     } else if (windowHandle != nullptr) {
3290*38e8c45fSAndroid Build Coastguard Worker         return windowHandle->getInfo()->applicationInfo.name + " - " + windowHandle->getName();
3291*38e8c45fSAndroid Build Coastguard Worker     } else {
3292*38e8c45fSAndroid Build Coastguard Worker         return "<unknown application or window>";
3293*38e8c45fSAndroid Build Coastguard Worker     }
3294*38e8c45fSAndroid Build Coastguard Worker }
3295*38e8c45fSAndroid Build Coastguard Worker 
pokeUserActivityLocked(const EventEntry & eventEntry)3296*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::pokeUserActivityLocked(const EventEntry& eventEntry) {
3297*38e8c45fSAndroid Build Coastguard Worker     if (!isUserActivityEvent(eventEntry)) {
3298*38e8c45fSAndroid Build Coastguard Worker         // Not poking user activity if the event type does not represent a user activity
3299*38e8c45fSAndroid Build Coastguard Worker         return;
3300*38e8c45fSAndroid Build Coastguard Worker     }
3301*38e8c45fSAndroid Build Coastguard Worker 
3302*38e8c45fSAndroid Build Coastguard Worker     const int32_t eventType = getUserActivityEventType(eventEntry);
3303*38e8c45fSAndroid Build Coastguard Worker     if (input_flags::rate_limit_user_activity_poke_in_dispatcher()) {
3304*38e8c45fSAndroid Build Coastguard Worker         // Note that we're directly getting the time diff between the current event and the previous
3305*38e8c45fSAndroid Build Coastguard Worker         // event. This is assuming that the first user event always happens at a timestamp that is
3306*38e8c45fSAndroid Build Coastguard Worker         // greater than `mMinTimeBetweenUserActivityPokes` (otherwise, the first user event will
3307*38e8c45fSAndroid Build Coastguard Worker         // wrongly be dropped). In real life, `mMinTimeBetweenUserActivityPokes` is a much smaller
3308*38e8c45fSAndroid Build Coastguard Worker         // value than the potential first user activity event time, so this is ok.
3309*38e8c45fSAndroid Build Coastguard Worker         std::chrono::nanoseconds timeSinceLastEvent =
3310*38e8c45fSAndroid Build Coastguard Worker                 std::chrono::nanoseconds(eventEntry.eventTime - mLastUserActivityTimes[eventType]);
3311*38e8c45fSAndroid Build Coastguard Worker         if (timeSinceLastEvent < mMinTimeBetweenUserActivityPokes) {
3312*38e8c45fSAndroid Build Coastguard Worker             return;
3313*38e8c45fSAndroid Build Coastguard Worker         }
3314*38e8c45fSAndroid Build Coastguard Worker     }
3315*38e8c45fSAndroid Build Coastguard Worker 
3316*38e8c45fSAndroid Build Coastguard Worker     ui::LogicalDisplayId displayId = getTargetDisplayId(eventEntry);
3317*38e8c45fSAndroid Build Coastguard Worker     sp<WindowInfoHandle> focusedWindowHandle = getFocusedWindowHandleLocked(displayId);
3318*38e8c45fSAndroid Build Coastguard Worker     const WindowInfo* windowDisablingUserActivityInfo = nullptr;
3319*38e8c45fSAndroid Build Coastguard Worker     if (focusedWindowHandle != nullptr) {
3320*38e8c45fSAndroid Build Coastguard Worker         const WindowInfo* info = focusedWindowHandle->getInfo();
3321*38e8c45fSAndroid Build Coastguard Worker         if (info->inputConfig.test(WindowInfo::InputConfig::DISABLE_USER_ACTIVITY)) {
3322*38e8c45fSAndroid Build Coastguard Worker             windowDisablingUserActivityInfo = info;
3323*38e8c45fSAndroid Build Coastguard Worker         }
3324*38e8c45fSAndroid Build Coastguard Worker     }
3325*38e8c45fSAndroid Build Coastguard Worker 
3326*38e8c45fSAndroid Build Coastguard Worker     switch (eventEntry.type) {
3327*38e8c45fSAndroid Build Coastguard Worker         case EventEntry::Type::MOTION: {
3328*38e8c45fSAndroid Build Coastguard Worker             const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
3329*38e8c45fSAndroid Build Coastguard Worker             if (motionEntry.action == AMOTION_EVENT_ACTION_CANCEL) {
3330*38e8c45fSAndroid Build Coastguard Worker                 return;
3331*38e8c45fSAndroid Build Coastguard Worker             }
3332*38e8c45fSAndroid Build Coastguard Worker             if (windowDisablingUserActivityInfo != nullptr) {
3333*38e8c45fSAndroid Build Coastguard Worker                 if (DEBUG_DISPATCH_CYCLE) {
3334*38e8c45fSAndroid Build Coastguard Worker                     ALOGD("Not poking user activity: disabled by window '%s'.",
3335*38e8c45fSAndroid Build Coastguard Worker                           windowDisablingUserActivityInfo->name.c_str());
3336*38e8c45fSAndroid Build Coastguard Worker                 }
3337*38e8c45fSAndroid Build Coastguard Worker                 return;
3338*38e8c45fSAndroid Build Coastguard Worker             }
3339*38e8c45fSAndroid Build Coastguard Worker             break;
3340*38e8c45fSAndroid Build Coastguard Worker         }
3341*38e8c45fSAndroid Build Coastguard Worker         case EventEntry::Type::KEY: {
3342*38e8c45fSAndroid Build Coastguard Worker             const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
3343*38e8c45fSAndroid Build Coastguard Worker             if (keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) {
3344*38e8c45fSAndroid Build Coastguard Worker                 return;
3345*38e8c45fSAndroid Build Coastguard Worker             }
3346*38e8c45fSAndroid Build Coastguard Worker             // Don't inhibit events that were intercepted or are not passed to
3347*38e8c45fSAndroid Build Coastguard Worker             // the apps, like system shortcuts
3348*38e8c45fSAndroid Build Coastguard Worker             if (windowDisablingUserActivityInfo != nullptr &&
3349*38e8c45fSAndroid Build Coastguard Worker                 keyEntry.interceptKeyResult != KeyEntry::InterceptKeyResult::SKIP) {
3350*38e8c45fSAndroid Build Coastguard Worker                 if (DEBUG_DISPATCH_CYCLE) {
3351*38e8c45fSAndroid Build Coastguard Worker                     ALOGD("Not poking user activity: disabled by window '%s'.",
3352*38e8c45fSAndroid Build Coastguard Worker                           windowDisablingUserActivityInfo->name.c_str());
3353*38e8c45fSAndroid Build Coastguard Worker                 }
3354*38e8c45fSAndroid Build Coastguard Worker                 return;
3355*38e8c45fSAndroid Build Coastguard Worker             }
3356*38e8c45fSAndroid Build Coastguard Worker             break;
3357*38e8c45fSAndroid Build Coastguard Worker         }
3358*38e8c45fSAndroid Build Coastguard Worker         default: {
3359*38e8c45fSAndroid Build Coastguard Worker             LOG_ALWAYS_FATAL("%s events are not user activity",
3360*38e8c45fSAndroid Build Coastguard Worker                              ftl::enum_string(eventEntry.type).c_str());
3361*38e8c45fSAndroid Build Coastguard Worker             break;
3362*38e8c45fSAndroid Build Coastguard Worker         }
3363*38e8c45fSAndroid Build Coastguard Worker     }
3364*38e8c45fSAndroid Build Coastguard Worker 
3365*38e8c45fSAndroid Build Coastguard Worker     mLastUserActivityTimes[eventType] = eventEntry.eventTime;
3366*38e8c45fSAndroid Build Coastguard Worker     auto command = [this, eventTime = eventEntry.eventTime, eventType, displayId]()
3367*38e8c45fSAndroid Build Coastguard Worker                            REQUIRES(mLock) {
3368*38e8c45fSAndroid Build Coastguard Worker                                scoped_unlock unlock(mLock);
3369*38e8c45fSAndroid Build Coastguard Worker                                mPolicy.pokeUserActivity(eventTime, eventType, displayId);
3370*38e8c45fSAndroid Build Coastguard Worker                            };
3371*38e8c45fSAndroid Build Coastguard Worker     postCommandLocked(std::move(command));
3372*38e8c45fSAndroid Build Coastguard Worker }
3373*38e8c45fSAndroid Build Coastguard Worker 
prepareDispatchCycleLocked(nsecs_t currentTime,const std::shared_ptr<Connection> & connection,std::shared_ptr<const EventEntry> eventEntry,const InputTarget & inputTarget)3374*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
3375*38e8c45fSAndroid Build Coastguard Worker                                                  const std::shared_ptr<Connection>& connection,
3376*38e8c45fSAndroid Build Coastguard Worker                                                  std::shared_ptr<const EventEntry> eventEntry,
3377*38e8c45fSAndroid Build Coastguard Worker                                                  const InputTarget& inputTarget) {
3378*38e8c45fSAndroid Build Coastguard Worker     ATRACE_NAME_IF(ATRACE_ENABLED(),
3379*38e8c45fSAndroid Build Coastguard Worker                    StringPrintf("prepareDispatchCycleLocked(inputChannel=%s, id=0x%" PRIx32 ")",
3380*38e8c45fSAndroid Build Coastguard Worker                                 connection->getInputChannelName().c_str(), eventEntry->id));
3381*38e8c45fSAndroid Build Coastguard Worker     if (DEBUG_DISPATCH_CYCLE) {
3382*38e8c45fSAndroid Build Coastguard Worker         ALOGD("channel '%s' ~ prepareDispatchCycle - flags=%s, "
3383*38e8c45fSAndroid Build Coastguard Worker               "globalScaleFactor=%f, pointerIds=%s %s",
3384*38e8c45fSAndroid Build Coastguard Worker               connection->getInputChannelName().c_str(), inputTarget.flags.string().c_str(),
3385*38e8c45fSAndroid Build Coastguard Worker               inputTarget.globalScaleFactor, bitsetToString(inputTarget.getPointerIds()).c_str(),
3386*38e8c45fSAndroid Build Coastguard Worker               inputTarget.getPointerInfoString().c_str());
3387*38e8c45fSAndroid Build Coastguard Worker     }
3388*38e8c45fSAndroid Build Coastguard Worker 
3389*38e8c45fSAndroid Build Coastguard Worker     // Skip this event if the connection status is not normal.
3390*38e8c45fSAndroid Build Coastguard Worker     // We don't want to enqueue additional outbound events if the connection is broken.
3391*38e8c45fSAndroid Build Coastguard Worker     if (connection->status != Connection::Status::NORMAL) {
3392*38e8c45fSAndroid Build Coastguard Worker         if (DEBUG_DISPATCH_CYCLE) {
3393*38e8c45fSAndroid Build Coastguard Worker             ALOGD("channel '%s' ~ Dropping event because the channel status is %s",
3394*38e8c45fSAndroid Build Coastguard Worker                   connection->getInputChannelName().c_str(),
3395*38e8c45fSAndroid Build Coastguard Worker                   ftl::enum_string(connection->status).c_str());
3396*38e8c45fSAndroid Build Coastguard Worker         }
3397*38e8c45fSAndroid Build Coastguard Worker         return;
3398*38e8c45fSAndroid Build Coastguard Worker     }
3399*38e8c45fSAndroid Build Coastguard Worker 
3400*38e8c45fSAndroid Build Coastguard Worker     // Split a motion event if needed.
3401*38e8c45fSAndroid Build Coastguard Worker     if (inputTarget.flags.test(InputTarget::Flags::SPLIT)) {
3402*38e8c45fSAndroid Build Coastguard Worker         LOG_ALWAYS_FATAL_IF(eventEntry->type != EventEntry::Type::MOTION,
3403*38e8c45fSAndroid Build Coastguard Worker                             "Entry type %s should not have Flags::SPLIT",
3404*38e8c45fSAndroid Build Coastguard Worker                             ftl::enum_string(eventEntry->type).c_str());
3405*38e8c45fSAndroid Build Coastguard Worker 
3406*38e8c45fSAndroid Build Coastguard Worker         const MotionEntry& originalMotionEntry = static_cast<const MotionEntry&>(*eventEntry);
3407*38e8c45fSAndroid Build Coastguard Worker         if (inputTarget.getPointerIds().count() != originalMotionEntry.getPointerCount()) {
3408*38e8c45fSAndroid Build Coastguard Worker             if (!inputTarget.firstDownTimeInTarget.has_value()) {
3409*38e8c45fSAndroid Build Coastguard Worker                 logDispatchStateLocked();
3410*38e8c45fSAndroid Build Coastguard Worker                 LOG(FATAL) << "Splitting motion events requires a down time to be set for the "
3411*38e8c45fSAndroid Build Coastguard Worker                               "target on connection "
3412*38e8c45fSAndroid Build Coastguard Worker                            << connection->getInputChannelName() << " for "
3413*38e8c45fSAndroid Build Coastguard Worker                            << originalMotionEntry.getDescription();
3414*38e8c45fSAndroid Build Coastguard Worker             }
3415*38e8c45fSAndroid Build Coastguard Worker             std::unique_ptr<MotionEntry> splitMotionEntry =
3416*38e8c45fSAndroid Build Coastguard Worker                     splitMotionEvent(originalMotionEntry, inputTarget.getPointerIds(),
3417*38e8c45fSAndroid Build Coastguard Worker                                      inputTarget.firstDownTimeInTarget.value());
3418*38e8c45fSAndroid Build Coastguard Worker             if (!splitMotionEntry) {
3419*38e8c45fSAndroid Build Coastguard Worker                 return; // split event was dropped
3420*38e8c45fSAndroid Build Coastguard Worker             }
3421*38e8c45fSAndroid Build Coastguard Worker             if (splitMotionEntry->action == AMOTION_EVENT_ACTION_CANCEL) {
3422*38e8c45fSAndroid Build Coastguard Worker                 std::string reason = std::string("reason=pointer cancel on split window");
3423*38e8c45fSAndroid Build Coastguard Worker                 android_log_event_list(LOGTAG_INPUT_CANCEL)
3424*38e8c45fSAndroid Build Coastguard Worker                         << connection->getInputChannelName().c_str() << reason << LOG_ID_EVENTS;
3425*38e8c45fSAndroid Build Coastguard Worker             }
3426*38e8c45fSAndroid Build Coastguard Worker             if (DEBUG_FOCUS) {
3427*38e8c45fSAndroid Build Coastguard Worker                 ALOGD("channel '%s' ~ Split motion event.",
3428*38e8c45fSAndroid Build Coastguard Worker                       connection->getInputChannelName().c_str());
3429*38e8c45fSAndroid Build Coastguard Worker                 logOutboundMotionDetails("  ", *splitMotionEntry);
3430*38e8c45fSAndroid Build Coastguard Worker             }
3431*38e8c45fSAndroid Build Coastguard Worker             enqueueDispatchEntryAndStartDispatchCycleLocked(currentTime, connection,
3432*38e8c45fSAndroid Build Coastguard Worker                                                             std::move(splitMotionEntry),
3433*38e8c45fSAndroid Build Coastguard Worker                                                             inputTarget);
3434*38e8c45fSAndroid Build Coastguard Worker             return;
3435*38e8c45fSAndroid Build Coastguard Worker         }
3436*38e8c45fSAndroid Build Coastguard Worker     }
3437*38e8c45fSAndroid Build Coastguard Worker 
3438*38e8c45fSAndroid Build Coastguard Worker     // Not splitting.  Enqueue dispatch entries for the event as is.
3439*38e8c45fSAndroid Build Coastguard Worker     enqueueDispatchEntryAndStartDispatchCycleLocked(currentTime, connection, eventEntry,
3440*38e8c45fSAndroid Build Coastguard Worker                                                     inputTarget);
3441*38e8c45fSAndroid Build Coastguard Worker }
3442*38e8c45fSAndroid Build Coastguard Worker 
enqueueDispatchEntryAndStartDispatchCycleLocked(nsecs_t currentTime,const std::shared_ptr<Connection> & connection,std::shared_ptr<const EventEntry> eventEntry,const InputTarget & inputTarget)3443*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::enqueueDispatchEntryAndStartDispatchCycleLocked(
3444*38e8c45fSAndroid Build Coastguard Worker         nsecs_t currentTime, const std::shared_ptr<Connection>& connection,
3445*38e8c45fSAndroid Build Coastguard Worker         std::shared_ptr<const EventEntry> eventEntry, const InputTarget& inputTarget) {
3446*38e8c45fSAndroid Build Coastguard Worker     ATRACE_NAME_IF(ATRACE_ENABLED(),
3447*38e8c45fSAndroid Build Coastguard Worker                    StringPrintf("enqueueDispatchEntryAndStartDispatchCycleLocked(inputChannel=%s, "
3448*38e8c45fSAndroid Build Coastguard Worker                                 "id=0x%" PRIx32 ")",
3449*38e8c45fSAndroid Build Coastguard Worker                                 connection->getInputChannelName().c_str(), eventEntry->id));
3450*38e8c45fSAndroid Build Coastguard Worker 
3451*38e8c45fSAndroid Build Coastguard Worker     const bool wasEmpty = connection->outboundQueue.empty();
3452*38e8c45fSAndroid Build Coastguard Worker 
3453*38e8c45fSAndroid Build Coastguard Worker     enqueueDispatchEntryLocked(connection, eventEntry, inputTarget);
3454*38e8c45fSAndroid Build Coastguard Worker 
3455*38e8c45fSAndroid Build Coastguard Worker     // If the outbound queue was previously empty, start the dispatch cycle going.
3456*38e8c45fSAndroid Build Coastguard Worker     if (wasEmpty && !connection->outboundQueue.empty()) {
3457*38e8c45fSAndroid Build Coastguard Worker         startDispatchCycleLocked(currentTime, connection);
3458*38e8c45fSAndroid Build Coastguard Worker     }
3459*38e8c45fSAndroid Build Coastguard Worker }
3460*38e8c45fSAndroid Build Coastguard Worker 
enqueueDispatchEntryLocked(const std::shared_ptr<Connection> & connection,std::shared_ptr<const EventEntry> eventEntry,const InputTarget & inputTarget)3461*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::enqueueDispatchEntryLocked(const std::shared_ptr<Connection>& connection,
3462*38e8c45fSAndroid Build Coastguard Worker                                                  std::shared_ptr<const EventEntry> eventEntry,
3463*38e8c45fSAndroid Build Coastguard Worker                                                  const InputTarget& inputTarget) {
3464*38e8c45fSAndroid Build Coastguard Worker     const bool isKeyOrMotion = eventEntry->type == EventEntry::Type::KEY ||
3465*38e8c45fSAndroid Build Coastguard Worker             eventEntry->type == EventEntry::Type::MOTION;
3466*38e8c45fSAndroid Build Coastguard Worker     if (isKeyOrMotion && !inputTarget.windowHandle && !connection->monitor) {
3467*38e8c45fSAndroid Build Coastguard Worker         LOG(FATAL) << "All InputTargets for non-monitors must be associated with a window; target: "
3468*38e8c45fSAndroid Build Coastguard Worker                    << inputTarget << " connection: " << connection->getInputChannelName()
3469*38e8c45fSAndroid Build Coastguard Worker                    << " entry: " << eventEntry->getDescription();
3470*38e8c45fSAndroid Build Coastguard Worker     }
3471*38e8c45fSAndroid Build Coastguard Worker     // This is a new event.
3472*38e8c45fSAndroid Build Coastguard Worker     // Enqueue a new dispatch entry onto the outbound queue for this connection.
3473*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<DispatchEntry> dispatchEntry =
3474*38e8c45fSAndroid Build Coastguard Worker             createDispatchEntry(mIdGenerator, inputTarget, eventEntry, inputTarget.flags,
3475*38e8c45fSAndroid Build Coastguard Worker                                 mWindowInfosVsyncId, mTracer.get());
3476*38e8c45fSAndroid Build Coastguard Worker 
3477*38e8c45fSAndroid Build Coastguard Worker     // Use the eventEntry from dispatchEntry since the entry may have changed and can now be a
3478*38e8c45fSAndroid Build Coastguard Worker     // different EventEntry than what was passed in.
3479*38e8c45fSAndroid Build Coastguard Worker     eventEntry = dispatchEntry->eventEntry;
3480*38e8c45fSAndroid Build Coastguard Worker     // Apply target flags and update the connection's input state.
3481*38e8c45fSAndroid Build Coastguard Worker     switch (eventEntry->type) {
3482*38e8c45fSAndroid Build Coastguard Worker         case EventEntry::Type::KEY: {
3483*38e8c45fSAndroid Build Coastguard Worker             const KeyEntry& keyEntry = static_cast<const KeyEntry&>(*eventEntry);
3484*38e8c45fSAndroid Build Coastguard Worker             if (!connection->inputState.trackKey(keyEntry, keyEntry.flags)) {
3485*38e8c45fSAndroid Build Coastguard Worker                 LOG(WARNING) << "channel " << connection->getInputChannelName()
3486*38e8c45fSAndroid Build Coastguard Worker                              << "~ dropping inconsistent event: " << *dispatchEntry;
3487*38e8c45fSAndroid Build Coastguard Worker                 return; // skip the inconsistent event
3488*38e8c45fSAndroid Build Coastguard Worker             }
3489*38e8c45fSAndroid Build Coastguard Worker             break;
3490*38e8c45fSAndroid Build Coastguard Worker         }
3491*38e8c45fSAndroid Build Coastguard Worker 
3492*38e8c45fSAndroid Build Coastguard Worker         case EventEntry::Type::MOTION: {
3493*38e8c45fSAndroid Build Coastguard Worker             std::shared_ptr<const MotionEntry> resolvedMotion =
3494*38e8c45fSAndroid Build Coastguard Worker                     std::static_pointer_cast<const MotionEntry>(eventEntry);
3495*38e8c45fSAndroid Build Coastguard Worker             {
3496*38e8c45fSAndroid Build Coastguard Worker                 // Determine the resolved motion entry.
3497*38e8c45fSAndroid Build Coastguard Worker                 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(*eventEntry);
3498*38e8c45fSAndroid Build Coastguard Worker                 int32_t resolvedAction = motionEntry.action;
3499*38e8c45fSAndroid Build Coastguard Worker                 int32_t resolvedFlags = motionEntry.flags;
3500*38e8c45fSAndroid Build Coastguard Worker 
3501*38e8c45fSAndroid Build Coastguard Worker                 if (inputTarget.dispatchMode == InputTarget::DispatchMode::OUTSIDE) {
3502*38e8c45fSAndroid Build Coastguard Worker                     resolvedAction = AMOTION_EVENT_ACTION_OUTSIDE;
3503*38e8c45fSAndroid Build Coastguard Worker                 } else if (inputTarget.dispatchMode == InputTarget::DispatchMode::HOVER_EXIT) {
3504*38e8c45fSAndroid Build Coastguard Worker                     resolvedAction = AMOTION_EVENT_ACTION_HOVER_EXIT;
3505*38e8c45fSAndroid Build Coastguard Worker                 } else if (inputTarget.dispatchMode == InputTarget::DispatchMode::HOVER_ENTER) {
3506*38e8c45fSAndroid Build Coastguard Worker                     resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
3507*38e8c45fSAndroid Build Coastguard Worker                 } else if (inputTarget.dispatchMode == InputTarget::DispatchMode::SLIPPERY_EXIT) {
3508*38e8c45fSAndroid Build Coastguard Worker                     resolvedAction = AMOTION_EVENT_ACTION_CANCEL;
3509*38e8c45fSAndroid Build Coastguard Worker                 } else if (inputTarget.dispatchMode == InputTarget::DispatchMode::SLIPPERY_ENTER) {
3510*38e8c45fSAndroid Build Coastguard Worker                     resolvedAction = AMOTION_EVENT_ACTION_DOWN;
3511*38e8c45fSAndroid Build Coastguard Worker                 }
3512*38e8c45fSAndroid Build Coastguard Worker                 if (resolvedAction == AMOTION_EVENT_ACTION_HOVER_MOVE &&
3513*38e8c45fSAndroid Build Coastguard Worker                     !connection->inputState.isHovering(motionEntry.deviceId, motionEntry.source,
3514*38e8c45fSAndroid Build Coastguard Worker                                                        motionEntry.displayId)) {
3515*38e8c45fSAndroid Build Coastguard Worker                     if (DEBUG_DISPATCH_CYCLE) {
3516*38e8c45fSAndroid Build Coastguard Worker                         LOG(DEBUG) << "channel '" << connection->getInputChannelName().c_str()
3517*38e8c45fSAndroid Build Coastguard Worker                                    << "' ~ enqueueDispatchEntryLocked: filling in missing hover "
3518*38e8c45fSAndroid Build Coastguard Worker                                       "enter event";
3519*38e8c45fSAndroid Build Coastguard Worker                     }
3520*38e8c45fSAndroid Build Coastguard Worker                     resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
3521*38e8c45fSAndroid Build Coastguard Worker                 }
3522*38e8c45fSAndroid Build Coastguard Worker 
3523*38e8c45fSAndroid Build Coastguard Worker                 if (resolvedAction == AMOTION_EVENT_ACTION_CANCEL) {
3524*38e8c45fSAndroid Build Coastguard Worker                     resolvedFlags |= AMOTION_EVENT_FLAG_CANCELED;
3525*38e8c45fSAndroid Build Coastguard Worker                 }
3526*38e8c45fSAndroid Build Coastguard Worker                 if (dispatchEntry->targetFlags.test(InputTarget::Flags::WINDOW_IS_OBSCURED)) {
3527*38e8c45fSAndroid Build Coastguard Worker                     resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
3528*38e8c45fSAndroid Build Coastguard Worker                 }
3529*38e8c45fSAndroid Build Coastguard Worker                 if (dispatchEntry->targetFlags.test(
3530*38e8c45fSAndroid Build Coastguard Worker                             InputTarget::Flags::WINDOW_IS_PARTIALLY_OBSCURED)) {
3531*38e8c45fSAndroid Build Coastguard Worker                     resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
3532*38e8c45fSAndroid Build Coastguard Worker                 }
3533*38e8c45fSAndroid Build Coastguard Worker                 if (dispatchEntry->targetFlags.test(InputTarget::Flags::NO_FOCUS_CHANGE)) {
3534*38e8c45fSAndroid Build Coastguard Worker                     resolvedFlags |= AMOTION_EVENT_FLAG_NO_FOCUS_CHANGE;
3535*38e8c45fSAndroid Build Coastguard Worker                 }
3536*38e8c45fSAndroid Build Coastguard Worker 
3537*38e8c45fSAndroid Build Coastguard Worker                 dispatchEntry->resolvedFlags = resolvedFlags;
3538*38e8c45fSAndroid Build Coastguard Worker                 if (resolvedAction != motionEntry.action) {
3539*38e8c45fSAndroid Build Coastguard Worker                     std::optional<std::vector<PointerProperties>> usingProperties;
3540*38e8c45fSAndroid Build Coastguard Worker                     std::optional<std::vector<PointerCoords>> usingCoords;
3541*38e8c45fSAndroid Build Coastguard Worker                     if (resolvedAction == AMOTION_EVENT_ACTION_HOVER_EXIT ||
3542*38e8c45fSAndroid Build Coastguard Worker                         resolvedAction == AMOTION_EVENT_ACTION_CANCEL) {
3543*38e8c45fSAndroid Build Coastguard Worker                         // This is a HOVER_EXIT or an ACTION_CANCEL event that was synthesized by
3544*38e8c45fSAndroid Build Coastguard Worker                         // the dispatcher, and therefore the coordinates of this event are currently
3545*38e8c45fSAndroid Build Coastguard Worker                         // incorrect. These events should use the coordinates of the last dispatched
3546*38e8c45fSAndroid Build Coastguard Worker                         // ACTION_MOVE or HOVER_MOVE. We need to query InputState to get this data.
3547*38e8c45fSAndroid Build Coastguard Worker                         const bool hovering = resolvedAction == AMOTION_EVENT_ACTION_HOVER_EXIT;
3548*38e8c45fSAndroid Build Coastguard Worker                         std::optional<std::pair<std::vector<PointerProperties>,
3549*38e8c45fSAndroid Build Coastguard Worker                                                 std::vector<PointerCoords>>>
3550*38e8c45fSAndroid Build Coastguard Worker                                 pointerInfo =
3551*38e8c45fSAndroid Build Coastguard Worker                                         connection->inputState.getPointersOfLastEvent(motionEntry,
3552*38e8c45fSAndroid Build Coastguard Worker                                                                                       hovering);
3553*38e8c45fSAndroid Build Coastguard Worker                         if (pointerInfo) {
3554*38e8c45fSAndroid Build Coastguard Worker                             usingProperties = pointerInfo->first;
3555*38e8c45fSAndroid Build Coastguard Worker                             usingCoords = pointerInfo->second;
3556*38e8c45fSAndroid Build Coastguard Worker                         }
3557*38e8c45fSAndroid Build Coastguard Worker                     }
3558*38e8c45fSAndroid Build Coastguard Worker                     {
3559*38e8c45fSAndroid Build Coastguard Worker                         // Generate a new MotionEntry with a new eventId using the resolved action
3560*38e8c45fSAndroid Build Coastguard Worker                         // and flags, and set it as the resolved entry.
3561*38e8c45fSAndroid Build Coastguard Worker                         auto newEntry = std::make_shared<
3562*38e8c45fSAndroid Build Coastguard Worker                                 MotionEntry>(mIdGenerator.nextId(), motionEntry.injectionState,
3563*38e8c45fSAndroid Build Coastguard Worker                                              motionEntry.eventTime, motionEntry.deviceId,
3564*38e8c45fSAndroid Build Coastguard Worker                                              motionEntry.source, motionEntry.displayId,
3565*38e8c45fSAndroid Build Coastguard Worker                                              motionEntry.policyFlags, resolvedAction,
3566*38e8c45fSAndroid Build Coastguard Worker                                              motionEntry.actionButton, resolvedFlags,
3567*38e8c45fSAndroid Build Coastguard Worker                                              motionEntry.metaState, motionEntry.buttonState,
3568*38e8c45fSAndroid Build Coastguard Worker                                              motionEntry.classification, motionEntry.edgeFlags,
3569*38e8c45fSAndroid Build Coastguard Worker                                              motionEntry.xPrecision, motionEntry.yPrecision,
3570*38e8c45fSAndroid Build Coastguard Worker                                              motionEntry.xCursorPosition,
3571*38e8c45fSAndroid Build Coastguard Worker                                              motionEntry.yCursorPosition, motionEntry.downTime,
3572*38e8c45fSAndroid Build Coastguard Worker                                              usingProperties.value_or(
3573*38e8c45fSAndroid Build Coastguard Worker                                                      motionEntry.pointerProperties),
3574*38e8c45fSAndroid Build Coastguard Worker                                              usingCoords.value_or(motionEntry.pointerCoords));
3575*38e8c45fSAndroid Build Coastguard Worker                         if (mTracer) {
3576*38e8c45fSAndroid Build Coastguard Worker                             ensureEventTraced(motionEntry);
3577*38e8c45fSAndroid Build Coastguard Worker                             newEntry->traceTracker =
3578*38e8c45fSAndroid Build Coastguard Worker                                     mTracer->traceDerivedEvent(*newEntry,
3579*38e8c45fSAndroid Build Coastguard Worker                                                                *motionEntry.traceTracker);
3580*38e8c45fSAndroid Build Coastguard Worker                         }
3581*38e8c45fSAndroid Build Coastguard Worker                         resolvedMotion = newEntry;
3582*38e8c45fSAndroid Build Coastguard Worker                     }
3583*38e8c45fSAndroid Build Coastguard Worker                     if (ATRACE_ENABLED()) {
3584*38e8c45fSAndroid Build Coastguard Worker                         std::string message = StringPrintf("Transmute MotionEvent(id=0x%" PRIx32
3585*38e8c45fSAndroid Build Coastguard Worker                                                            ") to MotionEvent(id=0x%" PRIx32 ").",
3586*38e8c45fSAndroid Build Coastguard Worker                                                            motionEntry.id, resolvedMotion->id);
3587*38e8c45fSAndroid Build Coastguard Worker                         ATRACE_NAME(message.c_str());
3588*38e8c45fSAndroid Build Coastguard Worker                     }
3589*38e8c45fSAndroid Build Coastguard Worker 
3590*38e8c45fSAndroid Build Coastguard Worker                     // Set the resolved motion entry in the DispatchEntry.
3591*38e8c45fSAndroid Build Coastguard Worker                     dispatchEntry->eventEntry = resolvedMotion;
3592*38e8c45fSAndroid Build Coastguard Worker                     eventEntry = resolvedMotion;
3593*38e8c45fSAndroid Build Coastguard Worker                 }
3594*38e8c45fSAndroid Build Coastguard Worker             }
3595*38e8c45fSAndroid Build Coastguard Worker 
3596*38e8c45fSAndroid Build Coastguard Worker             // Check if we need to cancel any of the ongoing gestures. We don't support multiple
3597*38e8c45fSAndroid Build Coastguard Worker             // devices being active at the same time in the same window, so if a new device is
3598*38e8c45fSAndroid Build Coastguard Worker             // active, cancel the gesture from the old device.
3599*38e8c45fSAndroid Build Coastguard Worker             std::unique_ptr<EventEntry> cancelEvent =
3600*38e8c45fSAndroid Build Coastguard Worker                     connection->inputState.cancelConflictingInputStream(*resolvedMotion);
3601*38e8c45fSAndroid Build Coastguard Worker             if (cancelEvent != nullptr) {
3602*38e8c45fSAndroid Build Coastguard Worker                 LOG(INFO) << "Canceling pointers for device " << resolvedMotion->deviceId << " in "
3603*38e8c45fSAndroid Build Coastguard Worker                           << connection->getInputChannelName() << " with event "
3604*38e8c45fSAndroid Build Coastguard Worker                           << cancelEvent->getDescription();
3605*38e8c45fSAndroid Build Coastguard Worker                 if (mTracer) {
3606*38e8c45fSAndroid Build Coastguard Worker                     static_cast<MotionEntry&>(*cancelEvent).traceTracker =
3607*38e8c45fSAndroid Build Coastguard Worker                             mTracer->traceDerivedEvent(*cancelEvent, *resolvedMotion->traceTracker);
3608*38e8c45fSAndroid Build Coastguard Worker                 }
3609*38e8c45fSAndroid Build Coastguard Worker                 std::unique_ptr<DispatchEntry> cancelDispatchEntry =
3610*38e8c45fSAndroid Build Coastguard Worker                         createDispatchEntry(mIdGenerator, inputTarget, std::move(cancelEvent),
3611*38e8c45fSAndroid Build Coastguard Worker                                             ftl::Flags<InputTarget::Flags>(), mWindowInfosVsyncId,
3612*38e8c45fSAndroid Build Coastguard Worker                                             mTracer.get());
3613*38e8c45fSAndroid Build Coastguard Worker 
3614*38e8c45fSAndroid Build Coastguard Worker                 // Send these cancel events to the queue before sending the event from the new
3615*38e8c45fSAndroid Build Coastguard Worker                 // device.
3616*38e8c45fSAndroid Build Coastguard Worker                 connection->outboundQueue.emplace_back(std::move(cancelDispatchEntry));
3617*38e8c45fSAndroid Build Coastguard Worker             }
3618*38e8c45fSAndroid Build Coastguard Worker 
3619*38e8c45fSAndroid Build Coastguard Worker             if (!connection->inputState.trackMotion(*resolvedMotion,
3620*38e8c45fSAndroid Build Coastguard Worker                                                     dispatchEntry->resolvedFlags)) {
3621*38e8c45fSAndroid Build Coastguard Worker                 LOG(WARNING) << "channel " << connection->getInputChannelName()
3622*38e8c45fSAndroid Build Coastguard Worker                              << "~ dropping inconsistent event: " << *dispatchEntry;
3623*38e8c45fSAndroid Build Coastguard Worker                 return; // skip the inconsistent event
3624*38e8c45fSAndroid Build Coastguard Worker             }
3625*38e8c45fSAndroid Build Coastguard Worker             if ((dispatchEntry->resolvedFlags & AMOTION_EVENT_FLAG_NO_FOCUS_CHANGE) &&
3626*38e8c45fSAndroid Build Coastguard Worker                 (resolvedMotion->policyFlags & POLICY_FLAG_TRUSTED)) {
3627*38e8c45fSAndroid Build Coastguard Worker                 // Skip reporting pointer down outside focus to the policy.
3628*38e8c45fSAndroid Build Coastguard Worker                 break;
3629*38e8c45fSAndroid Build Coastguard Worker             }
3630*38e8c45fSAndroid Build Coastguard Worker 
3631*38e8c45fSAndroid Build Coastguard Worker             dispatchPointerDownOutsideFocus(resolvedMotion->source, resolvedMotion->action,
3632*38e8c45fSAndroid Build Coastguard Worker                                             inputTarget.connection->getToken());
3633*38e8c45fSAndroid Build Coastguard Worker 
3634*38e8c45fSAndroid Build Coastguard Worker             break;
3635*38e8c45fSAndroid Build Coastguard Worker         }
3636*38e8c45fSAndroid Build Coastguard Worker         case EventEntry::Type::FOCUS:
3637*38e8c45fSAndroid Build Coastguard Worker         case EventEntry::Type::TOUCH_MODE_CHANGED:
3638*38e8c45fSAndroid Build Coastguard Worker         case EventEntry::Type::POINTER_CAPTURE_CHANGED:
3639*38e8c45fSAndroid Build Coastguard Worker         case EventEntry::Type::DRAG: {
3640*38e8c45fSAndroid Build Coastguard Worker             break;
3641*38e8c45fSAndroid Build Coastguard Worker         }
3642*38e8c45fSAndroid Build Coastguard Worker         case EventEntry::Type::SENSOR: {
3643*38e8c45fSAndroid Build Coastguard Worker             LOG_ALWAYS_FATAL("SENSOR events should not go to apps via input channel");
3644*38e8c45fSAndroid Build Coastguard Worker             break;
3645*38e8c45fSAndroid Build Coastguard Worker         }
3646*38e8c45fSAndroid Build Coastguard Worker         case EventEntry::Type::DEVICE_RESET: {
3647*38e8c45fSAndroid Build Coastguard Worker             LOG_ALWAYS_FATAL("%s events should not go to apps",
3648*38e8c45fSAndroid Build Coastguard Worker                              ftl::enum_string(eventEntry->type).c_str());
3649*38e8c45fSAndroid Build Coastguard Worker             break;
3650*38e8c45fSAndroid Build Coastguard Worker         }
3651*38e8c45fSAndroid Build Coastguard Worker     }
3652*38e8c45fSAndroid Build Coastguard Worker 
3653*38e8c45fSAndroid Build Coastguard Worker     // Remember that we are waiting for this dispatch to complete.
3654*38e8c45fSAndroid Build Coastguard Worker     if (dispatchEntry->hasForegroundTarget()) {
3655*38e8c45fSAndroid Build Coastguard Worker         incrementPendingForegroundDispatches(*eventEntry);
3656*38e8c45fSAndroid Build Coastguard Worker     }
3657*38e8c45fSAndroid Build Coastguard Worker 
3658*38e8c45fSAndroid Build Coastguard Worker     // Enqueue the dispatch entry.
3659*38e8c45fSAndroid Build Coastguard Worker     connection->outboundQueue.emplace_back(std::move(dispatchEntry));
3660*38e8c45fSAndroid Build Coastguard Worker     traceOutboundQueueLength(*connection);
3661*38e8c45fSAndroid Build Coastguard Worker }
3662*38e8c45fSAndroid Build Coastguard Worker 
3663*38e8c45fSAndroid Build Coastguard Worker /**
3664*38e8c45fSAndroid Build Coastguard Worker  * This function is for debugging and metrics collection. It has two roles.
3665*38e8c45fSAndroid Build Coastguard Worker  *
3666*38e8c45fSAndroid Build Coastguard Worker  * The first role is to log input interaction with windows, which helps determine what the user was
3667*38e8c45fSAndroid Build Coastguard Worker  * interacting with. For example, if user is touching launcher, we will see an input_interaction log
3668*38e8c45fSAndroid Build Coastguard Worker  * that user started interacting with launcher window, as well as any other window that received
3669*38e8c45fSAndroid Build Coastguard Worker  * that gesture, such as the wallpaper or other spy windows. A new input_interaction is only logged
3670*38e8c45fSAndroid Build Coastguard Worker  * when the set of tokens that received the event changes. It is not logged again as long as the
3671*38e8c45fSAndroid Build Coastguard Worker  * user is interacting with the same windows.
3672*38e8c45fSAndroid Build Coastguard Worker  *
3673*38e8c45fSAndroid Build Coastguard Worker  * The second role is to track input device activity for metrics collection. For each input event,
3674*38e8c45fSAndroid Build Coastguard Worker  * we report the set of UIDs that the input device interacted with to the policy. Unlike for the
3675*38e8c45fSAndroid Build Coastguard Worker  * input_interaction logs, the device interaction is reported even when the set of interaction
3676*38e8c45fSAndroid Build Coastguard Worker  * tokens do not change.
3677*38e8c45fSAndroid Build Coastguard Worker  *
3678*38e8c45fSAndroid Build Coastguard Worker  * For these purposes, we do not count ACTION_OUTSIDE, ACTION_UP and ACTION_CANCEL actions as
3679*38e8c45fSAndroid Build Coastguard Worker  * interaction. This includes up and cancel events for both keys and motions.
3680*38e8c45fSAndroid Build Coastguard Worker  */
processInteractionsLocked(const EventEntry & entry,const std::vector<InputTarget> & targets)3681*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::processInteractionsLocked(const EventEntry& entry,
3682*38e8c45fSAndroid Build Coastguard Worker                                                 const std::vector<InputTarget>& targets) {
3683*38e8c45fSAndroid Build Coastguard Worker     int32_t deviceId;
3684*38e8c45fSAndroid Build Coastguard Worker     nsecs_t eventTime;
3685*38e8c45fSAndroid Build Coastguard Worker     // Skip ACTION_UP events, and all events other than keys and motions
3686*38e8c45fSAndroid Build Coastguard Worker     if (entry.type == EventEntry::Type::KEY) {
3687*38e8c45fSAndroid Build Coastguard Worker         const KeyEntry& keyEntry = static_cast<const KeyEntry&>(entry);
3688*38e8c45fSAndroid Build Coastguard Worker         if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
3689*38e8c45fSAndroid Build Coastguard Worker             return;
3690*38e8c45fSAndroid Build Coastguard Worker         }
3691*38e8c45fSAndroid Build Coastguard Worker         deviceId = keyEntry.deviceId;
3692*38e8c45fSAndroid Build Coastguard Worker         eventTime = keyEntry.eventTime;
3693*38e8c45fSAndroid Build Coastguard Worker     } else if (entry.type == EventEntry::Type::MOTION) {
3694*38e8c45fSAndroid Build Coastguard Worker         const MotionEntry& motionEntry = static_cast<const MotionEntry&>(entry);
3695*38e8c45fSAndroid Build Coastguard Worker         if (motionEntry.action == AMOTION_EVENT_ACTION_UP ||
3696*38e8c45fSAndroid Build Coastguard Worker             motionEntry.action == AMOTION_EVENT_ACTION_CANCEL ||
3697*38e8c45fSAndroid Build Coastguard Worker             MotionEvent::getActionMasked(motionEntry.action) == AMOTION_EVENT_ACTION_POINTER_UP) {
3698*38e8c45fSAndroid Build Coastguard Worker             return;
3699*38e8c45fSAndroid Build Coastguard Worker         }
3700*38e8c45fSAndroid Build Coastguard Worker         deviceId = motionEntry.deviceId;
3701*38e8c45fSAndroid Build Coastguard Worker         eventTime = motionEntry.eventTime;
3702*38e8c45fSAndroid Build Coastguard Worker     } else {
3703*38e8c45fSAndroid Build Coastguard Worker         return; // Not a key or a motion
3704*38e8c45fSAndroid Build Coastguard Worker     }
3705*38e8c45fSAndroid Build Coastguard Worker 
3706*38e8c45fSAndroid Build Coastguard Worker     std::set<gui::Uid> interactionUids;
3707*38e8c45fSAndroid Build Coastguard Worker     std::unordered_set<sp<IBinder>, StrongPointerHash<IBinder>> newConnectionTokens;
3708*38e8c45fSAndroid Build Coastguard Worker     std::vector<std::shared_ptr<Connection>> newConnections;
3709*38e8c45fSAndroid Build Coastguard Worker     for (const InputTarget& target : targets) {
3710*38e8c45fSAndroid Build Coastguard Worker         if (target.dispatchMode == InputTarget::DispatchMode::OUTSIDE) {
3711*38e8c45fSAndroid Build Coastguard Worker             continue; // Skip windows that receive ACTION_OUTSIDE
3712*38e8c45fSAndroid Build Coastguard Worker         }
3713*38e8c45fSAndroid Build Coastguard Worker 
3714*38e8c45fSAndroid Build Coastguard Worker         sp<IBinder> token = target.connection->getToken();
3715*38e8c45fSAndroid Build Coastguard Worker         newConnectionTokens.insert(std::move(token));
3716*38e8c45fSAndroid Build Coastguard Worker         newConnections.emplace_back(target.connection);
3717*38e8c45fSAndroid Build Coastguard Worker         if (target.windowHandle) {
3718*38e8c45fSAndroid Build Coastguard Worker             interactionUids.emplace(target.windowHandle->getInfo()->ownerUid);
3719*38e8c45fSAndroid Build Coastguard Worker         }
3720*38e8c45fSAndroid Build Coastguard Worker     }
3721*38e8c45fSAndroid Build Coastguard Worker 
3722*38e8c45fSAndroid Build Coastguard Worker     auto command = [this, deviceId, eventTime, uids = std::move(interactionUids)]()
3723*38e8c45fSAndroid Build Coastguard Worker                            REQUIRES(mLock) {
3724*38e8c45fSAndroid Build Coastguard Worker                                scoped_unlock unlock(mLock);
3725*38e8c45fSAndroid Build Coastguard Worker                                mPolicy.notifyDeviceInteraction(deviceId, eventTime, uids);
3726*38e8c45fSAndroid Build Coastguard Worker                            };
3727*38e8c45fSAndroid Build Coastguard Worker     postCommandLocked(std::move(command));
3728*38e8c45fSAndroid Build Coastguard Worker 
3729*38e8c45fSAndroid Build Coastguard Worker     if (newConnectionTokens == mInteractionConnectionTokens) {
3730*38e8c45fSAndroid Build Coastguard Worker         return; // no change
3731*38e8c45fSAndroid Build Coastguard Worker     }
3732*38e8c45fSAndroid Build Coastguard Worker     mInteractionConnectionTokens = newConnectionTokens;
3733*38e8c45fSAndroid Build Coastguard Worker 
3734*38e8c45fSAndroid Build Coastguard Worker     std::string targetList;
3735*38e8c45fSAndroid Build Coastguard Worker     for (const std::shared_ptr<Connection>& connection : newConnections) {
3736*38e8c45fSAndroid Build Coastguard Worker         targetList += connection->getInputChannelName() + ", ";
3737*38e8c45fSAndroid Build Coastguard Worker     }
3738*38e8c45fSAndroid Build Coastguard Worker     std::string message = "Interaction with: " + targetList;
3739*38e8c45fSAndroid Build Coastguard Worker     if (targetList.empty()) {
3740*38e8c45fSAndroid Build Coastguard Worker         message += "<none>";
3741*38e8c45fSAndroid Build Coastguard Worker     }
3742*38e8c45fSAndroid Build Coastguard Worker     android_log_event_list(LOGTAG_INPUT_INTERACTION) << message << LOG_ID_EVENTS;
3743*38e8c45fSAndroid Build Coastguard Worker }
3744*38e8c45fSAndroid Build Coastguard Worker 
dispatchPointerDownOutsideFocus(uint32_t source,int32_t action,const sp<IBinder> & token)3745*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::dispatchPointerDownOutsideFocus(uint32_t source, int32_t action,
3746*38e8c45fSAndroid Build Coastguard Worker                                                       const sp<IBinder>& token) {
3747*38e8c45fSAndroid Build Coastguard Worker     int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
3748*38e8c45fSAndroid Build Coastguard Worker     uint32_t maskedSource = source & AINPUT_SOURCE_CLASS_MASK;
3749*38e8c45fSAndroid Build Coastguard Worker     if (maskedSource != AINPUT_SOURCE_CLASS_POINTER || maskedAction != AMOTION_EVENT_ACTION_DOWN) {
3750*38e8c45fSAndroid Build Coastguard Worker         return;
3751*38e8c45fSAndroid Build Coastguard Worker     }
3752*38e8c45fSAndroid Build Coastguard Worker 
3753*38e8c45fSAndroid Build Coastguard Worker     sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
3754*38e8c45fSAndroid Build Coastguard Worker     if (focusedToken == token) {
3755*38e8c45fSAndroid Build Coastguard Worker         // ignore since token is focused
3756*38e8c45fSAndroid Build Coastguard Worker         return;
3757*38e8c45fSAndroid Build Coastguard Worker     }
3758*38e8c45fSAndroid Build Coastguard Worker 
3759*38e8c45fSAndroid Build Coastguard Worker     auto command = [this, token]() REQUIRES(mLock) {
3760*38e8c45fSAndroid Build Coastguard Worker         scoped_unlock unlock(mLock);
3761*38e8c45fSAndroid Build Coastguard Worker         mPolicy.onPointerDownOutsideFocus(token);
3762*38e8c45fSAndroid Build Coastguard Worker     };
3763*38e8c45fSAndroid Build Coastguard Worker     postCommandLocked(std::move(command));
3764*38e8c45fSAndroid Build Coastguard Worker }
3765*38e8c45fSAndroid Build Coastguard Worker 
publishMotionEvent(Connection & connection,DispatchEntry & dispatchEntry) const3766*38e8c45fSAndroid Build Coastguard Worker status_t InputDispatcher::publishMotionEvent(Connection& connection,
3767*38e8c45fSAndroid Build Coastguard Worker                                              DispatchEntry& dispatchEntry) const {
3768*38e8c45fSAndroid Build Coastguard Worker     const EventEntry& eventEntry = *(dispatchEntry.eventEntry);
3769*38e8c45fSAndroid Build Coastguard Worker     const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
3770*38e8c45fSAndroid Build Coastguard Worker 
3771*38e8c45fSAndroid Build Coastguard Worker     PointerCoords scaledCoords[MAX_POINTERS];
3772*38e8c45fSAndroid Build Coastguard Worker     const PointerCoords* usingCoords = motionEntry.pointerCoords.data();
3773*38e8c45fSAndroid Build Coastguard Worker 
3774*38e8c45fSAndroid Build Coastguard Worker     // TODO(b/316355518): Do not modify coords before dispatch.
3775*38e8c45fSAndroid Build Coastguard Worker     // Set the X and Y offset and X and Y scale depending on the input source.
3776*38e8c45fSAndroid Build Coastguard Worker     if ((motionEntry.source & AINPUT_SOURCE_CLASS_POINTER) &&
3777*38e8c45fSAndroid Build Coastguard Worker         !(dispatchEntry.targetFlags.test(InputTarget::Flags::ZERO_COORDS))) {
3778*38e8c45fSAndroid Build Coastguard Worker         float globalScaleFactor = dispatchEntry.globalScaleFactor;
3779*38e8c45fSAndroid Build Coastguard Worker         if (globalScaleFactor != 1.0f) {
3780*38e8c45fSAndroid Build Coastguard Worker             for (uint32_t i = 0; i < motionEntry.getPointerCount(); i++) {
3781*38e8c45fSAndroid Build Coastguard Worker                 scaledCoords[i] = motionEntry.pointerCoords[i];
3782*38e8c45fSAndroid Build Coastguard Worker                 // Don't apply window scale here since we don't want scale to affect raw
3783*38e8c45fSAndroid Build Coastguard Worker                 // coordinates. The scale will be sent back to the client and applied
3784*38e8c45fSAndroid Build Coastguard Worker                 // later when requesting relative coordinates.
3785*38e8c45fSAndroid Build Coastguard Worker                 scaledCoords[i].scale(globalScaleFactor, /*windowXScale=*/1, /*windowYScale=*/1);
3786*38e8c45fSAndroid Build Coastguard Worker             }
3787*38e8c45fSAndroid Build Coastguard Worker             usingCoords = scaledCoords;
3788*38e8c45fSAndroid Build Coastguard Worker         }
3789*38e8c45fSAndroid Build Coastguard Worker     }
3790*38e8c45fSAndroid Build Coastguard Worker 
3791*38e8c45fSAndroid Build Coastguard Worker     std::array<uint8_t, 32> hmac = getSignature(motionEntry, dispatchEntry);
3792*38e8c45fSAndroid Build Coastguard Worker 
3793*38e8c45fSAndroid Build Coastguard Worker     // Publish the motion event.
3794*38e8c45fSAndroid Build Coastguard Worker     return connection.inputPublisher
3795*38e8c45fSAndroid Build Coastguard Worker             .publishMotionEvent(dispatchEntry.seq, motionEntry.id, motionEntry.deviceId,
3796*38e8c45fSAndroid Build Coastguard Worker                                 motionEntry.source, motionEntry.displayId, std::move(hmac),
3797*38e8c45fSAndroid Build Coastguard Worker                                 motionEntry.action, motionEntry.actionButton,
3798*38e8c45fSAndroid Build Coastguard Worker                                 dispatchEntry.resolvedFlags, motionEntry.edgeFlags,
3799*38e8c45fSAndroid Build Coastguard Worker                                 motionEntry.metaState, motionEntry.buttonState,
3800*38e8c45fSAndroid Build Coastguard Worker                                 motionEntry.classification, dispatchEntry.transform,
3801*38e8c45fSAndroid Build Coastguard Worker                                 motionEntry.xPrecision, motionEntry.yPrecision,
3802*38e8c45fSAndroid Build Coastguard Worker                                 motionEntry.xCursorPosition, motionEntry.yCursorPosition,
3803*38e8c45fSAndroid Build Coastguard Worker                                 dispatchEntry.rawTransform, motionEntry.downTime,
3804*38e8c45fSAndroid Build Coastguard Worker                                 motionEntry.eventTime, motionEntry.getPointerCount(),
3805*38e8c45fSAndroid Build Coastguard Worker                                 motionEntry.pointerProperties.data(), usingCoords);
3806*38e8c45fSAndroid Build Coastguard Worker }
3807*38e8c45fSAndroid Build Coastguard Worker 
startDispatchCycleLocked(nsecs_t currentTime,const std::shared_ptr<Connection> & connection)3808*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
3809*38e8c45fSAndroid Build Coastguard Worker                                                const std::shared_ptr<Connection>& connection) {
3810*38e8c45fSAndroid Build Coastguard Worker     ATRACE_NAME_IF(ATRACE_ENABLED(),
3811*38e8c45fSAndroid Build Coastguard Worker                    StringPrintf("startDispatchCycleLocked(inputChannel=%s)",
3812*38e8c45fSAndroid Build Coastguard Worker                                 connection->getInputChannelName().c_str()));
3813*38e8c45fSAndroid Build Coastguard Worker     if (DEBUG_DISPATCH_CYCLE) {
3814*38e8c45fSAndroid Build Coastguard Worker         ALOGD("channel '%s' ~ startDispatchCycle", connection->getInputChannelName().c_str());
3815*38e8c45fSAndroid Build Coastguard Worker     }
3816*38e8c45fSAndroid Build Coastguard Worker 
3817*38e8c45fSAndroid Build Coastguard Worker     while (connection->status == Connection::Status::NORMAL && !connection->outboundQueue.empty()) {
3818*38e8c45fSAndroid Build Coastguard Worker         std::unique_ptr<DispatchEntry>& dispatchEntry = connection->outboundQueue.front();
3819*38e8c45fSAndroid Build Coastguard Worker         dispatchEntry->deliveryTime = currentTime;
3820*38e8c45fSAndroid Build Coastguard Worker         const std::chrono::nanoseconds timeout = getDispatchingTimeoutLocked(connection);
3821*38e8c45fSAndroid Build Coastguard Worker         dispatchEntry->timeoutTime = currentTime + timeout.count();
3822*38e8c45fSAndroid Build Coastguard Worker 
3823*38e8c45fSAndroid Build Coastguard Worker         // Publish the event.
3824*38e8c45fSAndroid Build Coastguard Worker         status_t status;
3825*38e8c45fSAndroid Build Coastguard Worker         const EventEntry& eventEntry = *(dispatchEntry->eventEntry);
3826*38e8c45fSAndroid Build Coastguard Worker         switch (eventEntry.type) {
3827*38e8c45fSAndroid Build Coastguard Worker             case EventEntry::Type::KEY: {
3828*38e8c45fSAndroid Build Coastguard Worker                 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
3829*38e8c45fSAndroid Build Coastguard Worker                 std::array<uint8_t, 32> hmac = getSignature(keyEntry, *dispatchEntry);
3830*38e8c45fSAndroid Build Coastguard Worker                 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
3831*38e8c45fSAndroid Build Coastguard Worker                     LOG(INFO) << "Publishing " << *dispatchEntry << " to "
3832*38e8c45fSAndroid Build Coastguard Worker                               << connection->getInputChannelName();
3833*38e8c45fSAndroid Build Coastguard Worker                 }
3834*38e8c45fSAndroid Build Coastguard Worker 
3835*38e8c45fSAndroid Build Coastguard Worker                 // Publish the key event.
3836*38e8c45fSAndroid Build Coastguard Worker                 status = connection->inputPublisher
3837*38e8c45fSAndroid Build Coastguard Worker                                  .publishKeyEvent(dispatchEntry->seq, keyEntry.id,
3838*38e8c45fSAndroid Build Coastguard Worker                                                   keyEntry.deviceId, keyEntry.source,
3839*38e8c45fSAndroid Build Coastguard Worker                                                   keyEntry.displayId, std::move(hmac),
3840*38e8c45fSAndroid Build Coastguard Worker                                                   keyEntry.action, dispatchEntry->resolvedFlags,
3841*38e8c45fSAndroid Build Coastguard Worker                                                   keyEntry.keyCode, keyEntry.scanCode,
3842*38e8c45fSAndroid Build Coastguard Worker                                                   keyEntry.metaState, keyEntry.repeatCount,
3843*38e8c45fSAndroid Build Coastguard Worker                                                   keyEntry.downTime, keyEntry.eventTime);
3844*38e8c45fSAndroid Build Coastguard Worker                 if (mTracer) {
3845*38e8c45fSAndroid Build Coastguard Worker                     ensureEventTraced(keyEntry);
3846*38e8c45fSAndroid Build Coastguard Worker                     mTracer->traceEventDispatch(*dispatchEntry, *keyEntry.traceTracker);
3847*38e8c45fSAndroid Build Coastguard Worker                 }
3848*38e8c45fSAndroid Build Coastguard Worker                 break;
3849*38e8c45fSAndroid Build Coastguard Worker             }
3850*38e8c45fSAndroid Build Coastguard Worker 
3851*38e8c45fSAndroid Build Coastguard Worker             case EventEntry::Type::MOTION: {
3852*38e8c45fSAndroid Build Coastguard Worker                 if (DEBUG_OUTBOUND_EVENT_DETAILS) {
3853*38e8c45fSAndroid Build Coastguard Worker                     LOG(INFO) << "Publishing " << *dispatchEntry << " to "
3854*38e8c45fSAndroid Build Coastguard Worker                               << connection->getInputChannelName();
3855*38e8c45fSAndroid Build Coastguard Worker                 }
3856*38e8c45fSAndroid Build Coastguard Worker                 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
3857*38e8c45fSAndroid Build Coastguard Worker                 status = publishMotionEvent(*connection, *dispatchEntry);
3858*38e8c45fSAndroid Build Coastguard Worker                 if (status == BAD_VALUE) {
3859*38e8c45fSAndroid Build Coastguard Worker                     logDispatchStateLocked();
3860*38e8c45fSAndroid Build Coastguard Worker                     LOG(FATAL) << "Publisher failed for " << motionEntry;
3861*38e8c45fSAndroid Build Coastguard Worker                 }
3862*38e8c45fSAndroid Build Coastguard Worker                 if (mTracer) {
3863*38e8c45fSAndroid Build Coastguard Worker                     ensureEventTraced(motionEntry);
3864*38e8c45fSAndroid Build Coastguard Worker                     mTracer->traceEventDispatch(*dispatchEntry, *motionEntry.traceTracker);
3865*38e8c45fSAndroid Build Coastguard Worker                 }
3866*38e8c45fSAndroid Build Coastguard Worker                 break;
3867*38e8c45fSAndroid Build Coastguard Worker             }
3868*38e8c45fSAndroid Build Coastguard Worker 
3869*38e8c45fSAndroid Build Coastguard Worker             case EventEntry::Type::FOCUS: {
3870*38e8c45fSAndroid Build Coastguard Worker                 const FocusEntry& focusEntry = static_cast<const FocusEntry&>(eventEntry);
3871*38e8c45fSAndroid Build Coastguard Worker                 status = connection->inputPublisher.publishFocusEvent(dispatchEntry->seq,
3872*38e8c45fSAndroid Build Coastguard Worker                                                                       focusEntry.id,
3873*38e8c45fSAndroid Build Coastguard Worker                                                                       focusEntry.hasFocus);
3874*38e8c45fSAndroid Build Coastguard Worker                 break;
3875*38e8c45fSAndroid Build Coastguard Worker             }
3876*38e8c45fSAndroid Build Coastguard Worker 
3877*38e8c45fSAndroid Build Coastguard Worker             case EventEntry::Type::TOUCH_MODE_CHANGED: {
3878*38e8c45fSAndroid Build Coastguard Worker                 const TouchModeEntry& touchModeEntry =
3879*38e8c45fSAndroid Build Coastguard Worker                         static_cast<const TouchModeEntry&>(eventEntry);
3880*38e8c45fSAndroid Build Coastguard Worker                 status = connection->inputPublisher
3881*38e8c45fSAndroid Build Coastguard Worker                                  .publishTouchModeEvent(dispatchEntry->seq, touchModeEntry.id,
3882*38e8c45fSAndroid Build Coastguard Worker                                                         touchModeEntry.inTouchMode);
3883*38e8c45fSAndroid Build Coastguard Worker 
3884*38e8c45fSAndroid Build Coastguard Worker                 break;
3885*38e8c45fSAndroid Build Coastguard Worker             }
3886*38e8c45fSAndroid Build Coastguard Worker 
3887*38e8c45fSAndroid Build Coastguard Worker             case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
3888*38e8c45fSAndroid Build Coastguard Worker                 const auto& captureEntry =
3889*38e8c45fSAndroid Build Coastguard Worker                         static_cast<const PointerCaptureChangedEntry&>(eventEntry);
3890*38e8c45fSAndroid Build Coastguard Worker                 status =
3891*38e8c45fSAndroid Build Coastguard Worker                         connection->inputPublisher
3892*38e8c45fSAndroid Build Coastguard Worker                                 .publishCaptureEvent(dispatchEntry->seq, captureEntry.id,
3893*38e8c45fSAndroid Build Coastguard Worker                                                      captureEntry.pointerCaptureRequest.isEnable());
3894*38e8c45fSAndroid Build Coastguard Worker                 break;
3895*38e8c45fSAndroid Build Coastguard Worker             }
3896*38e8c45fSAndroid Build Coastguard Worker 
3897*38e8c45fSAndroid Build Coastguard Worker             case EventEntry::Type::DRAG: {
3898*38e8c45fSAndroid Build Coastguard Worker                 const DragEntry& dragEntry = static_cast<const DragEntry&>(eventEntry);
3899*38e8c45fSAndroid Build Coastguard Worker                 status = connection->inputPublisher.publishDragEvent(dispatchEntry->seq,
3900*38e8c45fSAndroid Build Coastguard Worker                                                                      dragEntry.id, dragEntry.x,
3901*38e8c45fSAndroid Build Coastguard Worker                                                                      dragEntry.y,
3902*38e8c45fSAndroid Build Coastguard Worker                                                                      dragEntry.isExiting);
3903*38e8c45fSAndroid Build Coastguard Worker                 break;
3904*38e8c45fSAndroid Build Coastguard Worker             }
3905*38e8c45fSAndroid Build Coastguard Worker 
3906*38e8c45fSAndroid Build Coastguard Worker             case EventEntry::Type::DEVICE_RESET:
3907*38e8c45fSAndroid Build Coastguard Worker             case EventEntry::Type::SENSOR: {
3908*38e8c45fSAndroid Build Coastguard Worker                 LOG_ALWAYS_FATAL("Should never start dispatch cycles for %s events",
3909*38e8c45fSAndroid Build Coastguard Worker                                  ftl::enum_string(eventEntry.type).c_str());
3910*38e8c45fSAndroid Build Coastguard Worker                 return;
3911*38e8c45fSAndroid Build Coastguard Worker             }
3912*38e8c45fSAndroid Build Coastguard Worker         }
3913*38e8c45fSAndroid Build Coastguard Worker 
3914*38e8c45fSAndroid Build Coastguard Worker         // Check the result.
3915*38e8c45fSAndroid Build Coastguard Worker         if (status) {
3916*38e8c45fSAndroid Build Coastguard Worker             if (status == WOULD_BLOCK) {
3917*38e8c45fSAndroid Build Coastguard Worker                 if (connection->waitQueue.empty()) {
3918*38e8c45fSAndroid Build Coastguard Worker                     ALOGE("channel '%s' ~ Could not publish event because the pipe is full. "
3919*38e8c45fSAndroid Build Coastguard Worker                           "This is unexpected because the wait queue is empty, so the pipe "
3920*38e8c45fSAndroid Build Coastguard Worker                           "should be empty and we shouldn't have any problems writing an "
3921*38e8c45fSAndroid Build Coastguard Worker                           "event to it, status=%s(%d)",
3922*38e8c45fSAndroid Build Coastguard Worker                           connection->getInputChannelName().c_str(), statusToString(status).c_str(),
3923*38e8c45fSAndroid Build Coastguard Worker                           status);
3924*38e8c45fSAndroid Build Coastguard Worker                     abortBrokenDispatchCycleLocked(currentTime, connection, /*notify=*/true);
3925*38e8c45fSAndroid Build Coastguard Worker                 } else {
3926*38e8c45fSAndroid Build Coastguard Worker                     // Pipe is full and we are waiting for the app to finish process some events
3927*38e8c45fSAndroid Build Coastguard Worker                     // before sending more events to it.
3928*38e8c45fSAndroid Build Coastguard Worker                     if (DEBUG_DISPATCH_CYCLE) {
3929*38e8c45fSAndroid Build Coastguard Worker                         ALOGD("channel '%s' ~ Could not publish event because the pipe is full, "
3930*38e8c45fSAndroid Build Coastguard Worker                               "waiting for the application to catch up",
3931*38e8c45fSAndroid Build Coastguard Worker                               connection->getInputChannelName().c_str());
3932*38e8c45fSAndroid Build Coastguard Worker                     }
3933*38e8c45fSAndroid Build Coastguard Worker                 }
3934*38e8c45fSAndroid Build Coastguard Worker             } else {
3935*38e8c45fSAndroid Build Coastguard Worker                 ALOGE("channel '%s' ~ Could not publish event due to an unexpected error, "
3936*38e8c45fSAndroid Build Coastguard Worker                       "status=%s(%d)",
3937*38e8c45fSAndroid Build Coastguard Worker                       connection->getInputChannelName().c_str(), statusToString(status).c_str(),
3938*38e8c45fSAndroid Build Coastguard Worker                       status);
3939*38e8c45fSAndroid Build Coastguard Worker                 abortBrokenDispatchCycleLocked(currentTime, connection, /*notify=*/true);
3940*38e8c45fSAndroid Build Coastguard Worker             }
3941*38e8c45fSAndroid Build Coastguard Worker             return;
3942*38e8c45fSAndroid Build Coastguard Worker         }
3943*38e8c45fSAndroid Build Coastguard Worker 
3944*38e8c45fSAndroid Build Coastguard Worker         // Re-enqueue the event on the wait queue.
3945*38e8c45fSAndroid Build Coastguard Worker         const nsecs_t timeoutTime = dispatchEntry->timeoutTime;
3946*38e8c45fSAndroid Build Coastguard Worker         connection->waitQueue.emplace_back(std::move(dispatchEntry));
3947*38e8c45fSAndroid Build Coastguard Worker         connection->outboundQueue.erase(connection->outboundQueue.begin());
3948*38e8c45fSAndroid Build Coastguard Worker         traceOutboundQueueLength(*connection);
3949*38e8c45fSAndroid Build Coastguard Worker         if (connection->responsive) {
3950*38e8c45fSAndroid Build Coastguard Worker             mAnrTracker.insert(timeoutTime, connection->getToken());
3951*38e8c45fSAndroid Build Coastguard Worker         }
3952*38e8c45fSAndroid Build Coastguard Worker         traceWaitQueueLength(*connection);
3953*38e8c45fSAndroid Build Coastguard Worker     }
3954*38e8c45fSAndroid Build Coastguard Worker }
3955*38e8c45fSAndroid Build Coastguard Worker 
sign(const VerifiedInputEvent & event) const3956*38e8c45fSAndroid Build Coastguard Worker std::array<uint8_t, 32> InputDispatcher::sign(const VerifiedInputEvent& event) const {
3957*38e8c45fSAndroid Build Coastguard Worker     size_t size;
3958*38e8c45fSAndroid Build Coastguard Worker     switch (event.type) {
3959*38e8c45fSAndroid Build Coastguard Worker         case VerifiedInputEvent::Type::KEY: {
3960*38e8c45fSAndroid Build Coastguard Worker             size = sizeof(VerifiedKeyEvent);
3961*38e8c45fSAndroid Build Coastguard Worker             break;
3962*38e8c45fSAndroid Build Coastguard Worker         }
3963*38e8c45fSAndroid Build Coastguard Worker         case VerifiedInputEvent::Type::MOTION: {
3964*38e8c45fSAndroid Build Coastguard Worker             size = sizeof(VerifiedMotionEvent);
3965*38e8c45fSAndroid Build Coastguard Worker             break;
3966*38e8c45fSAndroid Build Coastguard Worker         }
3967*38e8c45fSAndroid Build Coastguard Worker     }
3968*38e8c45fSAndroid Build Coastguard Worker     const uint8_t* start = reinterpret_cast<const uint8_t*>(&event);
3969*38e8c45fSAndroid Build Coastguard Worker     return mHmacKeyManager.sign(start, size);
3970*38e8c45fSAndroid Build Coastguard Worker }
3971*38e8c45fSAndroid Build Coastguard Worker 
getSignature(const MotionEntry & motionEntry,const DispatchEntry & dispatchEntry) const3972*38e8c45fSAndroid Build Coastguard Worker const std::array<uint8_t, 32> InputDispatcher::getSignature(
3973*38e8c45fSAndroid Build Coastguard Worker         const MotionEntry& motionEntry, const DispatchEntry& dispatchEntry) const {
3974*38e8c45fSAndroid Build Coastguard Worker     const int32_t actionMasked = MotionEvent::getActionMasked(motionEntry.action);
3975*38e8c45fSAndroid Build Coastguard Worker     if (actionMasked != AMOTION_EVENT_ACTION_UP && actionMasked != AMOTION_EVENT_ACTION_DOWN) {
3976*38e8c45fSAndroid Build Coastguard Worker         // Only sign events up and down events as the purely move events
3977*38e8c45fSAndroid Build Coastguard Worker         // are tied to their up/down counterparts so signing would be redundant.
3978*38e8c45fSAndroid Build Coastguard Worker         return INVALID_HMAC;
3979*38e8c45fSAndroid Build Coastguard Worker     }
3980*38e8c45fSAndroid Build Coastguard Worker 
3981*38e8c45fSAndroid Build Coastguard Worker     VerifiedMotionEvent verifiedEvent =
3982*38e8c45fSAndroid Build Coastguard Worker             verifiedMotionEventFromMotionEntry(motionEntry, dispatchEntry.rawTransform);
3983*38e8c45fSAndroid Build Coastguard Worker     verifiedEvent.actionMasked = actionMasked;
3984*38e8c45fSAndroid Build Coastguard Worker     verifiedEvent.flags = dispatchEntry.resolvedFlags & VERIFIED_MOTION_EVENT_FLAGS;
3985*38e8c45fSAndroid Build Coastguard Worker     return sign(verifiedEvent);
3986*38e8c45fSAndroid Build Coastguard Worker }
3987*38e8c45fSAndroid Build Coastguard Worker 
getSignature(const KeyEntry & keyEntry,const DispatchEntry & dispatchEntry) const3988*38e8c45fSAndroid Build Coastguard Worker const std::array<uint8_t, 32> InputDispatcher::getSignature(
3989*38e8c45fSAndroid Build Coastguard Worker         const KeyEntry& keyEntry, const DispatchEntry& dispatchEntry) const {
3990*38e8c45fSAndroid Build Coastguard Worker     VerifiedKeyEvent verifiedEvent = verifiedKeyEventFromKeyEntry(keyEntry);
3991*38e8c45fSAndroid Build Coastguard Worker     verifiedEvent.flags = dispatchEntry.resolvedFlags & VERIFIED_KEY_EVENT_FLAGS;
3992*38e8c45fSAndroid Build Coastguard Worker     return sign(verifiedEvent);
3993*38e8c45fSAndroid Build Coastguard Worker }
3994*38e8c45fSAndroid Build Coastguard Worker 
finishDispatchCycleLocked(nsecs_t currentTime,const std::shared_ptr<Connection> & connection,uint32_t seq,bool handled,nsecs_t consumeTime)3995*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
3996*38e8c45fSAndroid Build Coastguard Worker                                                 const std::shared_ptr<Connection>& connection,
3997*38e8c45fSAndroid Build Coastguard Worker                                                 uint32_t seq, bool handled, nsecs_t consumeTime) {
3998*38e8c45fSAndroid Build Coastguard Worker     if (DEBUG_DISPATCH_CYCLE) {
3999*38e8c45fSAndroid Build Coastguard Worker         ALOGD("channel '%s' ~ finishDispatchCycle - seq=%u, handled=%s",
4000*38e8c45fSAndroid Build Coastguard Worker               connection->getInputChannelName().c_str(), seq, toString(handled));
4001*38e8c45fSAndroid Build Coastguard Worker     }
4002*38e8c45fSAndroid Build Coastguard Worker 
4003*38e8c45fSAndroid Build Coastguard Worker     if (connection->status != Connection::Status::NORMAL) {
4004*38e8c45fSAndroid Build Coastguard Worker         return;
4005*38e8c45fSAndroid Build Coastguard Worker     }
4006*38e8c45fSAndroid Build Coastguard Worker 
4007*38e8c45fSAndroid Build Coastguard Worker     // Notify other system components and prepare to start the next dispatch cycle.
4008*38e8c45fSAndroid Build Coastguard Worker     auto command = [this, currentTime, connection, seq, handled, consumeTime]() REQUIRES(mLock) {
4009*38e8c45fSAndroid Build Coastguard Worker         doDispatchCycleFinishedCommand(currentTime, connection, seq, handled, consumeTime);
4010*38e8c45fSAndroid Build Coastguard Worker     };
4011*38e8c45fSAndroid Build Coastguard Worker     postCommandLocked(std::move(command));
4012*38e8c45fSAndroid Build Coastguard Worker }
4013*38e8c45fSAndroid Build Coastguard Worker 
abortBrokenDispatchCycleLocked(nsecs_t currentTime,const std::shared_ptr<Connection> & connection,bool notify)4014*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::abortBrokenDispatchCycleLocked(nsecs_t currentTime,
4015*38e8c45fSAndroid Build Coastguard Worker                                                      const std::shared_ptr<Connection>& connection,
4016*38e8c45fSAndroid Build Coastguard Worker                                                      bool notify) {
4017*38e8c45fSAndroid Build Coastguard Worker     if (DEBUG_DISPATCH_CYCLE) {
4018*38e8c45fSAndroid Build Coastguard Worker         LOG(INFO) << "channel '" << connection->getInputChannelName() << "'~ " << __func__
4019*38e8c45fSAndroid Build Coastguard Worker                   << " - notify=" << toString(notify);
4020*38e8c45fSAndroid Build Coastguard Worker     }
4021*38e8c45fSAndroid Build Coastguard Worker 
4022*38e8c45fSAndroid Build Coastguard Worker     // Clear the dispatch queues.
4023*38e8c45fSAndroid Build Coastguard Worker     drainDispatchQueue(connection->outboundQueue);
4024*38e8c45fSAndroid Build Coastguard Worker     traceOutboundQueueLength(*connection);
4025*38e8c45fSAndroid Build Coastguard Worker     drainDispatchQueue(connection->waitQueue);
4026*38e8c45fSAndroid Build Coastguard Worker     traceWaitQueueLength(*connection);
4027*38e8c45fSAndroid Build Coastguard Worker 
4028*38e8c45fSAndroid Build Coastguard Worker     // The connection appears to be unrecoverably broken.
4029*38e8c45fSAndroid Build Coastguard Worker     // Ignore already broken or zombie connections.
4030*38e8c45fSAndroid Build Coastguard Worker     if (connection->status == Connection::Status::NORMAL) {
4031*38e8c45fSAndroid Build Coastguard Worker         connection->status = Connection::Status::BROKEN;
4032*38e8c45fSAndroid Build Coastguard Worker 
4033*38e8c45fSAndroid Build Coastguard Worker         if (notify) {
4034*38e8c45fSAndroid Build Coastguard Worker             // Notify other system components.
4035*38e8c45fSAndroid Build Coastguard Worker             ALOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
4036*38e8c45fSAndroid Build Coastguard Worker                   connection->getInputChannelName().c_str());
4037*38e8c45fSAndroid Build Coastguard Worker 
4038*38e8c45fSAndroid Build Coastguard Worker             auto command = [this, connection]() REQUIRES(mLock) {
4039*38e8c45fSAndroid Build Coastguard Worker                 scoped_unlock unlock(mLock);
4040*38e8c45fSAndroid Build Coastguard Worker                 mPolicy.notifyInputChannelBroken(connection->getToken());
4041*38e8c45fSAndroid Build Coastguard Worker             };
4042*38e8c45fSAndroid Build Coastguard Worker             postCommandLocked(std::move(command));
4043*38e8c45fSAndroid Build Coastguard Worker         }
4044*38e8c45fSAndroid Build Coastguard Worker     }
4045*38e8c45fSAndroid Build Coastguard Worker }
4046*38e8c45fSAndroid Build Coastguard Worker 
drainDispatchQueue(std::deque<std::unique_ptr<DispatchEntry>> & queue)4047*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::drainDispatchQueue(std::deque<std::unique_ptr<DispatchEntry>>& queue) {
4048*38e8c45fSAndroid Build Coastguard Worker     while (!queue.empty()) {
4049*38e8c45fSAndroid Build Coastguard Worker         releaseDispatchEntry(std::move(queue.front()));
4050*38e8c45fSAndroid Build Coastguard Worker         queue.pop_front();
4051*38e8c45fSAndroid Build Coastguard Worker     }
4052*38e8c45fSAndroid Build Coastguard Worker }
4053*38e8c45fSAndroid Build Coastguard Worker 
releaseDispatchEntry(std::unique_ptr<DispatchEntry> dispatchEntry)4054*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::releaseDispatchEntry(std::unique_ptr<DispatchEntry> dispatchEntry) {
4055*38e8c45fSAndroid Build Coastguard Worker     if (dispatchEntry->hasForegroundTarget()) {
4056*38e8c45fSAndroid Build Coastguard Worker         decrementPendingForegroundDispatches(*(dispatchEntry->eventEntry));
4057*38e8c45fSAndroid Build Coastguard Worker     }
4058*38e8c45fSAndroid Build Coastguard Worker }
4059*38e8c45fSAndroid Build Coastguard Worker 
handleReceiveCallback(int events,sp<IBinder> connectionToken)4060*38e8c45fSAndroid Build Coastguard Worker int InputDispatcher::handleReceiveCallback(int events, sp<IBinder> connectionToken) {
4061*38e8c45fSAndroid Build Coastguard Worker     std::scoped_lock _l(mLock);
4062*38e8c45fSAndroid Build Coastguard Worker     std::shared_ptr<Connection> connection = getConnectionLocked(connectionToken);
4063*38e8c45fSAndroid Build Coastguard Worker     if (connection == nullptr) {
4064*38e8c45fSAndroid Build Coastguard Worker         ALOGW("Received looper callback for unknown input channel token %p.  events=0x%x",
4065*38e8c45fSAndroid Build Coastguard Worker               connectionToken.get(), events);
4066*38e8c45fSAndroid Build Coastguard Worker         return 0; // remove the callback
4067*38e8c45fSAndroid Build Coastguard Worker     }
4068*38e8c45fSAndroid Build Coastguard Worker 
4069*38e8c45fSAndroid Build Coastguard Worker     bool notify;
4070*38e8c45fSAndroid Build Coastguard Worker     if (!(events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP))) {
4071*38e8c45fSAndroid Build Coastguard Worker         if (!(events & ALOOPER_EVENT_INPUT)) {
4072*38e8c45fSAndroid Build Coastguard Worker             ALOGW("channel '%s' ~ Received spurious callback for unhandled poll event.  "
4073*38e8c45fSAndroid Build Coastguard Worker                   "events=0x%x",
4074*38e8c45fSAndroid Build Coastguard Worker                   connection->getInputChannelName().c_str(), events);
4075*38e8c45fSAndroid Build Coastguard Worker             return 1;
4076*38e8c45fSAndroid Build Coastguard Worker         }
4077*38e8c45fSAndroid Build Coastguard Worker 
4078*38e8c45fSAndroid Build Coastguard Worker         nsecs_t currentTime = now();
4079*38e8c45fSAndroid Build Coastguard Worker         bool gotOne = false;
4080*38e8c45fSAndroid Build Coastguard Worker         status_t status = OK;
4081*38e8c45fSAndroid Build Coastguard Worker         for (;;) {
4082*38e8c45fSAndroid Build Coastguard Worker             Result<InputPublisher::ConsumerResponse> result =
4083*38e8c45fSAndroid Build Coastguard Worker                     connection->inputPublisher.receiveConsumerResponse();
4084*38e8c45fSAndroid Build Coastguard Worker             if (!result.ok()) {
4085*38e8c45fSAndroid Build Coastguard Worker                 status = result.error().code();
4086*38e8c45fSAndroid Build Coastguard Worker                 break;
4087*38e8c45fSAndroid Build Coastguard Worker             }
4088*38e8c45fSAndroid Build Coastguard Worker 
4089*38e8c45fSAndroid Build Coastguard Worker             if (std::holds_alternative<InputPublisher::Finished>(*result)) {
4090*38e8c45fSAndroid Build Coastguard Worker                 const InputPublisher::Finished& finish =
4091*38e8c45fSAndroid Build Coastguard Worker                         std::get<InputPublisher::Finished>(*result);
4092*38e8c45fSAndroid Build Coastguard Worker                 finishDispatchCycleLocked(currentTime, connection, finish.seq, finish.handled,
4093*38e8c45fSAndroid Build Coastguard Worker                                           finish.consumeTime);
4094*38e8c45fSAndroid Build Coastguard Worker             } else if (std::holds_alternative<InputPublisher::Timeline>(*result)) {
4095*38e8c45fSAndroid Build Coastguard Worker                 if (shouldReportMetricsForConnection(*connection)) {
4096*38e8c45fSAndroid Build Coastguard Worker                     const InputPublisher::Timeline& timeline =
4097*38e8c45fSAndroid Build Coastguard Worker                             std::get<InputPublisher::Timeline>(*result);
4098*38e8c45fSAndroid Build Coastguard Worker                     mLatencyTracker.trackGraphicsLatency(timeline.inputEventId,
4099*38e8c45fSAndroid Build Coastguard Worker                                                          connection->getToken(),
4100*38e8c45fSAndroid Build Coastguard Worker                                                          std::move(timeline.graphicsTimeline));
4101*38e8c45fSAndroid Build Coastguard Worker                 }
4102*38e8c45fSAndroid Build Coastguard Worker             }
4103*38e8c45fSAndroid Build Coastguard Worker             gotOne = true;
4104*38e8c45fSAndroid Build Coastguard Worker         }
4105*38e8c45fSAndroid Build Coastguard Worker         if (gotOne) {
4106*38e8c45fSAndroid Build Coastguard Worker             runCommandsLockedInterruptable();
4107*38e8c45fSAndroid Build Coastguard Worker             if (status == WOULD_BLOCK) {
4108*38e8c45fSAndroid Build Coastguard Worker                 return 1;
4109*38e8c45fSAndroid Build Coastguard Worker             }
4110*38e8c45fSAndroid Build Coastguard Worker         }
4111*38e8c45fSAndroid Build Coastguard Worker 
4112*38e8c45fSAndroid Build Coastguard Worker         notify = status != DEAD_OBJECT || !connection->monitor;
4113*38e8c45fSAndroid Build Coastguard Worker         if (notify) {
4114*38e8c45fSAndroid Build Coastguard Worker             ALOGE("channel '%s' ~ Failed to receive finished signal.  status=%s(%d)",
4115*38e8c45fSAndroid Build Coastguard Worker                   connection->getInputChannelName().c_str(), statusToString(status).c_str(),
4116*38e8c45fSAndroid Build Coastguard Worker                   status);
4117*38e8c45fSAndroid Build Coastguard Worker         }
4118*38e8c45fSAndroid Build Coastguard Worker     } else {
4119*38e8c45fSAndroid Build Coastguard Worker         // Monitor channels are never explicitly unregistered.
4120*38e8c45fSAndroid Build Coastguard Worker         // We do it automatically when the remote endpoint is closed so don't warn about them.
4121*38e8c45fSAndroid Build Coastguard Worker         const bool stillHaveWindowHandle = getWindowHandleLocked(connection->getToken()) != nullptr;
4122*38e8c45fSAndroid Build Coastguard Worker         notify = !connection->monitor && stillHaveWindowHandle;
4123*38e8c45fSAndroid Build Coastguard Worker         if (notify) {
4124*38e8c45fSAndroid Build Coastguard Worker             ALOGW("channel '%s' ~ Consumer closed input channel or an error occurred.  events=0x%x",
4125*38e8c45fSAndroid Build Coastguard Worker                   connection->getInputChannelName().c_str(), events);
4126*38e8c45fSAndroid Build Coastguard Worker         }
4127*38e8c45fSAndroid Build Coastguard Worker     }
4128*38e8c45fSAndroid Build Coastguard Worker 
4129*38e8c45fSAndroid Build Coastguard Worker     // Remove the channel.
4130*38e8c45fSAndroid Build Coastguard Worker     removeInputChannelLocked(connection->getToken(), notify);
4131*38e8c45fSAndroid Build Coastguard Worker     return 0; // remove the callback
4132*38e8c45fSAndroid Build Coastguard Worker }
4133*38e8c45fSAndroid Build Coastguard Worker 
synthesizeCancelationEventsForAllConnectionsLocked(const CancelationOptions & options)4134*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked(
4135*38e8c45fSAndroid Build Coastguard Worker         const CancelationOptions& options) {
4136*38e8c45fSAndroid Build Coastguard Worker     // Cancel windows (i.e. non-monitors).
4137*38e8c45fSAndroid Build Coastguard Worker     // A channel must have at least one window to receive any input. If a window was removed, the
4138*38e8c45fSAndroid Build Coastguard Worker     // event streams directed to the window will already have been canceled during window removal.
4139*38e8c45fSAndroid Build Coastguard Worker     // So there is no need to generate cancellations for connections without any windows.
4140*38e8c45fSAndroid Build Coastguard Worker     const auto [cancelPointers, cancelNonPointers] = expandCancellationMode(options.mode);
4141*38e8c45fSAndroid Build Coastguard Worker     // Generate cancellations for touched windows first. This is to avoid generating cancellations
4142*38e8c45fSAndroid Build Coastguard Worker     // through a non-touched window if there are more than one window for an input channel.
4143*38e8c45fSAndroid Build Coastguard Worker     if (cancelPointers) {
4144*38e8c45fSAndroid Build Coastguard Worker         for (const auto& [displayId, touchState] : mTouchStatesByDisplay) {
4145*38e8c45fSAndroid Build Coastguard Worker             if (options.displayId.has_value() && options.displayId != displayId) {
4146*38e8c45fSAndroid Build Coastguard Worker                 continue;
4147*38e8c45fSAndroid Build Coastguard Worker             }
4148*38e8c45fSAndroid Build Coastguard Worker             for (const auto& touchedWindow : touchState.windows) {
4149*38e8c45fSAndroid Build Coastguard Worker                 synthesizeCancelationEventsForWindowLocked(touchedWindow.windowHandle, options);
4150*38e8c45fSAndroid Build Coastguard Worker             }
4151*38e8c45fSAndroid Build Coastguard Worker         }
4152*38e8c45fSAndroid Build Coastguard Worker     }
4153*38e8c45fSAndroid Build Coastguard Worker     // Follow up by generating cancellations for all windows, because we don't explicitly track
4154*38e8c45fSAndroid Build Coastguard Worker     // the windows that have an ongoing focus event stream.
4155*38e8c45fSAndroid Build Coastguard Worker     if (cancelNonPointers) {
4156*38e8c45fSAndroid Build Coastguard Worker         for (const auto& [_, handles] : mWindowHandlesByDisplay) {
4157*38e8c45fSAndroid Build Coastguard Worker             for (const auto& windowHandle : handles) {
4158*38e8c45fSAndroid Build Coastguard Worker                 synthesizeCancelationEventsForWindowLocked(windowHandle, options);
4159*38e8c45fSAndroid Build Coastguard Worker             }
4160*38e8c45fSAndroid Build Coastguard Worker         }
4161*38e8c45fSAndroid Build Coastguard Worker     }
4162*38e8c45fSAndroid Build Coastguard Worker 
4163*38e8c45fSAndroid Build Coastguard Worker     // Cancel monitors.
4164*38e8c45fSAndroid Build Coastguard Worker     synthesizeCancelationEventsForMonitorsLocked(options);
4165*38e8c45fSAndroid Build Coastguard Worker }
4166*38e8c45fSAndroid Build Coastguard Worker 
synthesizeCancelationEventsForMonitorsLocked(const CancelationOptions & options)4167*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
4168*38e8c45fSAndroid Build Coastguard Worker         const CancelationOptions& options) {
4169*38e8c45fSAndroid Build Coastguard Worker     for (const auto& [_, monitors] : mGlobalMonitorsByDisplay) {
4170*38e8c45fSAndroid Build Coastguard Worker         for (const Monitor& monitor : monitors) {
4171*38e8c45fSAndroid Build Coastguard Worker             synthesizeCancelationEventsForConnectionLocked(monitor.connection, options,
4172*38e8c45fSAndroid Build Coastguard Worker                                                            /*window=*/nullptr);
4173*38e8c45fSAndroid Build Coastguard Worker         }
4174*38e8c45fSAndroid Build Coastguard Worker     }
4175*38e8c45fSAndroid Build Coastguard Worker }
4176*38e8c45fSAndroid Build Coastguard Worker 
synthesizeCancelationEventsForWindowLocked(const sp<WindowInfoHandle> & windowHandle,const CancelationOptions & options,const std::shared_ptr<Connection> & connection)4177*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::synthesizeCancelationEventsForWindowLocked(
4178*38e8c45fSAndroid Build Coastguard Worker         const sp<WindowInfoHandle>& windowHandle, const CancelationOptions& options,
4179*38e8c45fSAndroid Build Coastguard Worker         const std::shared_ptr<Connection>& connection) {
4180*38e8c45fSAndroid Build Coastguard Worker     if (windowHandle == nullptr) {
4181*38e8c45fSAndroid Build Coastguard Worker         LOG(FATAL) << __func__ << ": Window handle must not be null";
4182*38e8c45fSAndroid Build Coastguard Worker     }
4183*38e8c45fSAndroid Build Coastguard Worker     if (connection) {
4184*38e8c45fSAndroid Build Coastguard Worker         // The connection can be optionally provided to avoid multiple lookups.
4185*38e8c45fSAndroid Build Coastguard Worker         if (windowHandle->getToken() != connection->getToken()) {
4186*38e8c45fSAndroid Build Coastguard Worker             LOG(FATAL) << __func__
4187*38e8c45fSAndroid Build Coastguard Worker                        << ": Wrong connection provided for window: " << windowHandle->getName();
4188*38e8c45fSAndroid Build Coastguard Worker         }
4189*38e8c45fSAndroid Build Coastguard Worker     }
4190*38e8c45fSAndroid Build Coastguard Worker 
4191*38e8c45fSAndroid Build Coastguard Worker     std::shared_ptr<Connection> resolvedConnection =
4192*38e8c45fSAndroid Build Coastguard Worker             connection ? connection : getConnectionLocked(windowHandle->getToken());
4193*38e8c45fSAndroid Build Coastguard Worker     if (!resolvedConnection) {
4194*38e8c45fSAndroid Build Coastguard Worker         LOG(DEBUG) << __func__ << "No connection found for window: " << windowHandle->getName();
4195*38e8c45fSAndroid Build Coastguard Worker         return;
4196*38e8c45fSAndroid Build Coastguard Worker     }
4197*38e8c45fSAndroid Build Coastguard Worker     synthesizeCancelationEventsForConnectionLocked(resolvedConnection, options, windowHandle);
4198*38e8c45fSAndroid Build Coastguard Worker }
4199*38e8c45fSAndroid Build Coastguard Worker 
synthesizeCancelationEventsForConnectionLocked(const std::shared_ptr<Connection> & connection,const CancelationOptions & options,const sp<WindowInfoHandle> & window)4200*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
4201*38e8c45fSAndroid Build Coastguard Worker         const std::shared_ptr<Connection>& connection, const CancelationOptions& options,
4202*38e8c45fSAndroid Build Coastguard Worker         const sp<WindowInfoHandle>& window) {
4203*38e8c45fSAndroid Build Coastguard Worker     if (!connection->monitor && window == nullptr) {
4204*38e8c45fSAndroid Build Coastguard Worker         LOG(FATAL) << __func__
4205*38e8c45fSAndroid Build Coastguard Worker                    << ": Cannot send event to non-monitor channel without a window - channel: "
4206*38e8c45fSAndroid Build Coastguard Worker                    << connection->getInputChannelName();
4207*38e8c45fSAndroid Build Coastguard Worker     }
4208*38e8c45fSAndroid Build Coastguard Worker     if (connection->status != Connection::Status::NORMAL) {
4209*38e8c45fSAndroid Build Coastguard Worker         return;
4210*38e8c45fSAndroid Build Coastguard Worker     }
4211*38e8c45fSAndroid Build Coastguard Worker 
4212*38e8c45fSAndroid Build Coastguard Worker     nsecs_t currentTime = now();
4213*38e8c45fSAndroid Build Coastguard Worker 
4214*38e8c45fSAndroid Build Coastguard Worker     std::vector<std::unique_ptr<EventEntry>> cancelationEvents =
4215*38e8c45fSAndroid Build Coastguard Worker             connection->inputState.synthesizeCancelationEvents(currentTime, options);
4216*38e8c45fSAndroid Build Coastguard Worker 
4217*38e8c45fSAndroid Build Coastguard Worker     if (cancelationEvents.empty()) {
4218*38e8c45fSAndroid Build Coastguard Worker         return;
4219*38e8c45fSAndroid Build Coastguard Worker     }
4220*38e8c45fSAndroid Build Coastguard Worker 
4221*38e8c45fSAndroid Build Coastguard Worker     if (DEBUG_OUTBOUND_EVENT_DETAILS) {
4222*38e8c45fSAndroid Build Coastguard Worker         ALOGD("channel '%s' ~ Synthesized %zu cancelation events to bring channel back in sync "
4223*38e8c45fSAndroid Build Coastguard Worker               "with reality: %s, mode=%s.",
4224*38e8c45fSAndroid Build Coastguard Worker               connection->getInputChannelName().c_str(), cancelationEvents.size(), options.reason,
4225*38e8c45fSAndroid Build Coastguard Worker               ftl::enum_string(options.mode).c_str());
4226*38e8c45fSAndroid Build Coastguard Worker     }
4227*38e8c45fSAndroid Build Coastguard Worker 
4228*38e8c45fSAndroid Build Coastguard Worker     std::string reason = std::string("reason=").append(options.reason);
4229*38e8c45fSAndroid Build Coastguard Worker     android_log_event_list(LOGTAG_INPUT_CANCEL)
4230*38e8c45fSAndroid Build Coastguard Worker             << connection->getInputChannelName().c_str() << reason << LOG_ID_EVENTS;
4231*38e8c45fSAndroid Build Coastguard Worker 
4232*38e8c45fSAndroid Build Coastguard Worker     const bool wasEmpty = connection->outboundQueue.empty();
4233*38e8c45fSAndroid Build Coastguard Worker     // The target to use if we don't find a window associated with the channel.
4234*38e8c45fSAndroid Build Coastguard Worker     const InputTarget fallbackTarget{connection};
4235*38e8c45fSAndroid Build Coastguard Worker     const auto& token = connection->getToken();
4236*38e8c45fSAndroid Build Coastguard Worker 
4237*38e8c45fSAndroid Build Coastguard Worker     for (size_t i = 0; i < cancelationEvents.size(); i++) {
4238*38e8c45fSAndroid Build Coastguard Worker         std::unique_ptr<EventEntry> cancelationEventEntry = std::move(cancelationEvents[i]);
4239*38e8c45fSAndroid Build Coastguard Worker         std::vector<InputTarget> targets{};
4240*38e8c45fSAndroid Build Coastguard Worker 
4241*38e8c45fSAndroid Build Coastguard Worker         switch (cancelationEventEntry->type) {
4242*38e8c45fSAndroid Build Coastguard Worker             case EventEntry::Type::KEY: {
4243*38e8c45fSAndroid Build Coastguard Worker                 if (mTracer) {
4244*38e8c45fSAndroid Build Coastguard Worker                     static_cast<KeyEntry&>(*cancelationEventEntry).traceTracker =
4245*38e8c45fSAndroid Build Coastguard Worker                             mTracer->traceDerivedEvent(*cancelationEventEntry,
4246*38e8c45fSAndroid Build Coastguard Worker                                                        *options.traceTracker);
4247*38e8c45fSAndroid Build Coastguard Worker                 }
4248*38e8c45fSAndroid Build Coastguard Worker                 const auto& keyEntry = static_cast<const KeyEntry&>(*cancelationEventEntry);
4249*38e8c45fSAndroid Build Coastguard Worker                 if (window) {
4250*38e8c45fSAndroid Build Coastguard Worker                     addWindowTargetLocked(window, InputTarget::DispatchMode::AS_IS,
4251*38e8c45fSAndroid Build Coastguard Worker                                           /*targetFlags=*/{}, keyEntry.downTime, targets);
4252*38e8c45fSAndroid Build Coastguard Worker                 } else {
4253*38e8c45fSAndroid Build Coastguard Worker                     targets.emplace_back(fallbackTarget);
4254*38e8c45fSAndroid Build Coastguard Worker                 }
4255*38e8c45fSAndroid Build Coastguard Worker                 logOutboundKeyDetails("cancel - ", keyEntry);
4256*38e8c45fSAndroid Build Coastguard Worker                 break;
4257*38e8c45fSAndroid Build Coastguard Worker             }
4258*38e8c45fSAndroid Build Coastguard Worker             case EventEntry::Type::MOTION: {
4259*38e8c45fSAndroid Build Coastguard Worker                 if (mTracer) {
4260*38e8c45fSAndroid Build Coastguard Worker                     static_cast<MotionEntry&>(*cancelationEventEntry).traceTracker =
4261*38e8c45fSAndroid Build Coastguard Worker                             mTracer->traceDerivedEvent(*cancelationEventEntry,
4262*38e8c45fSAndroid Build Coastguard Worker                                                        *options.traceTracker);
4263*38e8c45fSAndroid Build Coastguard Worker                 }
4264*38e8c45fSAndroid Build Coastguard Worker                 const auto& motionEntry = static_cast<const MotionEntry&>(*cancelationEventEntry);
4265*38e8c45fSAndroid Build Coastguard Worker                 if (window) {
4266*38e8c45fSAndroid Build Coastguard Worker                     std::bitset<MAX_POINTER_ID + 1> pointerIds;
4267*38e8c45fSAndroid Build Coastguard Worker                     for (uint32_t pointerIndex = 0; pointerIndex < motionEntry.getPointerCount();
4268*38e8c45fSAndroid Build Coastguard Worker                          pointerIndex++) {
4269*38e8c45fSAndroid Build Coastguard Worker                         pointerIds.set(motionEntry.pointerProperties[pointerIndex].id);
4270*38e8c45fSAndroid Build Coastguard Worker                     }
4271*38e8c45fSAndroid Build Coastguard Worker                     if (mDragState && mDragState->dragWindow->getToken() == token &&
4272*38e8c45fSAndroid Build Coastguard Worker                         pointerIds.test(mDragState->pointerId)) {
4273*38e8c45fSAndroid Build Coastguard Worker                         LOG(INFO) << __func__
4274*38e8c45fSAndroid Build Coastguard Worker                                   << ": Canceling drag and drop because the pointers for the drag "
4275*38e8c45fSAndroid Build Coastguard Worker                                      "window are being canceled.";
4276*38e8c45fSAndroid Build Coastguard Worker                         sendDropWindowCommandLocked(nullptr, /*x=*/0, /*y=*/0);
4277*38e8c45fSAndroid Build Coastguard Worker                         mDragState.reset();
4278*38e8c45fSAndroid Build Coastguard Worker                     }
4279*38e8c45fSAndroid Build Coastguard Worker                     addPointerWindowTargetLocked(window, InputTarget::DispatchMode::AS_IS,
4280*38e8c45fSAndroid Build Coastguard Worker                                                  ftl::Flags<InputTarget::Flags>(), pointerIds,
4281*38e8c45fSAndroid Build Coastguard Worker                                                  motionEntry.downTime, targets);
4282*38e8c45fSAndroid Build Coastguard Worker                 } else {
4283*38e8c45fSAndroid Build Coastguard Worker                     targets.emplace_back(fallbackTarget);
4284*38e8c45fSAndroid Build Coastguard Worker                     const auto it = mDisplayInfos.find(motionEntry.displayId);
4285*38e8c45fSAndroid Build Coastguard Worker                     if (it != mDisplayInfos.end()) {
4286*38e8c45fSAndroid Build Coastguard Worker                         targets.back().displayTransform = it->second.transform;
4287*38e8c45fSAndroid Build Coastguard Worker                         targets.back().setDefaultPointerTransform(it->second.transform);
4288*38e8c45fSAndroid Build Coastguard Worker                     }
4289*38e8c45fSAndroid Build Coastguard Worker                 }
4290*38e8c45fSAndroid Build Coastguard Worker                 logOutboundMotionDetails("cancel - ", motionEntry);
4291*38e8c45fSAndroid Build Coastguard Worker                 break;
4292*38e8c45fSAndroid Build Coastguard Worker             }
4293*38e8c45fSAndroid Build Coastguard Worker             case EventEntry::Type::FOCUS:
4294*38e8c45fSAndroid Build Coastguard Worker             case EventEntry::Type::TOUCH_MODE_CHANGED:
4295*38e8c45fSAndroid Build Coastguard Worker             case EventEntry::Type::POINTER_CAPTURE_CHANGED:
4296*38e8c45fSAndroid Build Coastguard Worker             case EventEntry::Type::DRAG: {
4297*38e8c45fSAndroid Build Coastguard Worker                 LOG_ALWAYS_FATAL("Canceling %s events is not supported",
4298*38e8c45fSAndroid Build Coastguard Worker                                  ftl::enum_string(cancelationEventEntry->type).c_str());
4299*38e8c45fSAndroid Build Coastguard Worker                 break;
4300*38e8c45fSAndroid Build Coastguard Worker             }
4301*38e8c45fSAndroid Build Coastguard Worker             case EventEntry::Type::DEVICE_RESET:
4302*38e8c45fSAndroid Build Coastguard Worker             case EventEntry::Type::SENSOR: {
4303*38e8c45fSAndroid Build Coastguard Worker                 LOG_ALWAYS_FATAL("%s event should not be found inside Connections's queue",
4304*38e8c45fSAndroid Build Coastguard Worker                                  ftl::enum_string(cancelationEventEntry->type).c_str());
4305*38e8c45fSAndroid Build Coastguard Worker                 break;
4306*38e8c45fSAndroid Build Coastguard Worker             }
4307*38e8c45fSAndroid Build Coastguard Worker         }
4308*38e8c45fSAndroid Build Coastguard Worker 
4309*38e8c45fSAndroid Build Coastguard Worker         if (targets.size() != 1) LOG(FATAL) << __func__ << ": InputTarget not created";
4310*38e8c45fSAndroid Build Coastguard Worker         if (mTracer) {
4311*38e8c45fSAndroid Build Coastguard Worker             mTracer->dispatchToTargetHint(*options.traceTracker, targets[0]);
4312*38e8c45fSAndroid Build Coastguard Worker         }
4313*38e8c45fSAndroid Build Coastguard Worker         enqueueDispatchEntryLocked(connection, std::move(cancelationEventEntry), targets[0]);
4314*38e8c45fSAndroid Build Coastguard Worker     }
4315*38e8c45fSAndroid Build Coastguard Worker 
4316*38e8c45fSAndroid Build Coastguard Worker     // If the outbound queue was previously empty, start the dispatch cycle going.
4317*38e8c45fSAndroid Build Coastguard Worker     if (wasEmpty && !connection->outboundQueue.empty()) {
4318*38e8c45fSAndroid Build Coastguard Worker         startDispatchCycleLocked(currentTime, connection);
4319*38e8c45fSAndroid Build Coastguard Worker     }
4320*38e8c45fSAndroid Build Coastguard Worker }
4321*38e8c45fSAndroid Build Coastguard Worker 
synthesizePointerDownEventsForConnectionLocked(const nsecs_t downTime,const std::shared_ptr<Connection> & connection,ftl::Flags<InputTarget::Flags> targetFlags,const std::unique_ptr<trace::EventTrackerInterface> & traceTracker)4322*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::synthesizePointerDownEventsForConnectionLocked(
4323*38e8c45fSAndroid Build Coastguard Worker         const nsecs_t downTime, const std::shared_ptr<Connection>& connection,
4324*38e8c45fSAndroid Build Coastguard Worker         ftl::Flags<InputTarget::Flags> targetFlags,
4325*38e8c45fSAndroid Build Coastguard Worker         const std::unique_ptr<trace::EventTrackerInterface>& traceTracker) {
4326*38e8c45fSAndroid Build Coastguard Worker     if (connection->status != Connection::Status::NORMAL) {
4327*38e8c45fSAndroid Build Coastguard Worker         return;
4328*38e8c45fSAndroid Build Coastguard Worker     }
4329*38e8c45fSAndroid Build Coastguard Worker 
4330*38e8c45fSAndroid Build Coastguard Worker     std::vector<std::unique_ptr<EventEntry>> downEvents =
4331*38e8c45fSAndroid Build Coastguard Worker             connection->inputState.synthesizePointerDownEvents(downTime);
4332*38e8c45fSAndroid Build Coastguard Worker 
4333*38e8c45fSAndroid Build Coastguard Worker     if (downEvents.empty()) {
4334*38e8c45fSAndroid Build Coastguard Worker         return;
4335*38e8c45fSAndroid Build Coastguard Worker     }
4336*38e8c45fSAndroid Build Coastguard Worker 
4337*38e8c45fSAndroid Build Coastguard Worker     if (DEBUG_OUTBOUND_EVENT_DETAILS) {
4338*38e8c45fSAndroid Build Coastguard Worker         ALOGD("channel '%s' ~ Synthesized %zu down events to ensure consistent event stream.",
4339*38e8c45fSAndroid Build Coastguard Worker               connection->getInputChannelName().c_str(), downEvents.size());
4340*38e8c45fSAndroid Build Coastguard Worker     }
4341*38e8c45fSAndroid Build Coastguard Worker 
4342*38e8c45fSAndroid Build Coastguard Worker     const auto [_, touchedWindowState, displayId] =
4343*38e8c45fSAndroid Build Coastguard Worker             findTouchStateWindowAndDisplayLocked(connection->getToken());
4344*38e8c45fSAndroid Build Coastguard Worker     if (touchedWindowState == nullptr) {
4345*38e8c45fSAndroid Build Coastguard Worker         LOG(FATAL) << __func__ << ": Touch state is out of sync: No touched window for token";
4346*38e8c45fSAndroid Build Coastguard Worker     }
4347*38e8c45fSAndroid Build Coastguard Worker     const auto& windowHandle = touchedWindowState->windowHandle;
4348*38e8c45fSAndroid Build Coastguard Worker 
4349*38e8c45fSAndroid Build Coastguard Worker     const bool wasEmpty = connection->outboundQueue.empty();
4350*38e8c45fSAndroid Build Coastguard Worker     for (std::unique_ptr<EventEntry>& downEventEntry : downEvents) {
4351*38e8c45fSAndroid Build Coastguard Worker         std::vector<InputTarget> targets{};
4352*38e8c45fSAndroid Build Coastguard Worker         switch (downEventEntry->type) {
4353*38e8c45fSAndroid Build Coastguard Worker             case EventEntry::Type::MOTION: {
4354*38e8c45fSAndroid Build Coastguard Worker                 if (mTracer) {
4355*38e8c45fSAndroid Build Coastguard Worker                     static_cast<MotionEntry&>(*downEventEntry).traceTracker =
4356*38e8c45fSAndroid Build Coastguard Worker                             mTracer->traceDerivedEvent(*downEventEntry, *traceTracker);
4357*38e8c45fSAndroid Build Coastguard Worker                 }
4358*38e8c45fSAndroid Build Coastguard Worker                 const auto& motionEntry = static_cast<const MotionEntry&>(*downEventEntry);
4359*38e8c45fSAndroid Build Coastguard Worker                 if (windowHandle != nullptr) {
4360*38e8c45fSAndroid Build Coastguard Worker                     std::bitset<MAX_POINTER_ID + 1> pointerIds;
4361*38e8c45fSAndroid Build Coastguard Worker                     for (uint32_t pointerIndex = 0; pointerIndex < motionEntry.getPointerCount();
4362*38e8c45fSAndroid Build Coastguard Worker                          pointerIndex++) {
4363*38e8c45fSAndroid Build Coastguard Worker                         pointerIds.set(motionEntry.pointerProperties[pointerIndex].id);
4364*38e8c45fSAndroid Build Coastguard Worker                     }
4365*38e8c45fSAndroid Build Coastguard Worker                     addPointerWindowTargetLocked(windowHandle, InputTarget::DispatchMode::AS_IS,
4366*38e8c45fSAndroid Build Coastguard Worker                                                  targetFlags, pointerIds, motionEntry.downTime,
4367*38e8c45fSAndroid Build Coastguard Worker                                                  targets);
4368*38e8c45fSAndroid Build Coastguard Worker                 } else {
4369*38e8c45fSAndroid Build Coastguard Worker                     targets.emplace_back(connection, targetFlags);
4370*38e8c45fSAndroid Build Coastguard Worker                     const auto it = mDisplayInfos.find(motionEntry.displayId);
4371*38e8c45fSAndroid Build Coastguard Worker                     if (it != mDisplayInfos.end()) {
4372*38e8c45fSAndroid Build Coastguard Worker                         targets.back().displayTransform = it->second.transform;
4373*38e8c45fSAndroid Build Coastguard Worker                         targets.back().setDefaultPointerTransform(it->second.transform);
4374*38e8c45fSAndroid Build Coastguard Worker                     }
4375*38e8c45fSAndroid Build Coastguard Worker                 }
4376*38e8c45fSAndroid Build Coastguard Worker                 logOutboundMotionDetails("down - ", motionEntry);
4377*38e8c45fSAndroid Build Coastguard Worker                 break;
4378*38e8c45fSAndroid Build Coastguard Worker             }
4379*38e8c45fSAndroid Build Coastguard Worker 
4380*38e8c45fSAndroid Build Coastguard Worker             case EventEntry::Type::KEY:
4381*38e8c45fSAndroid Build Coastguard Worker             case EventEntry::Type::FOCUS:
4382*38e8c45fSAndroid Build Coastguard Worker             case EventEntry::Type::TOUCH_MODE_CHANGED:
4383*38e8c45fSAndroid Build Coastguard Worker             case EventEntry::Type::DEVICE_RESET:
4384*38e8c45fSAndroid Build Coastguard Worker             case EventEntry::Type::POINTER_CAPTURE_CHANGED:
4385*38e8c45fSAndroid Build Coastguard Worker             case EventEntry::Type::SENSOR:
4386*38e8c45fSAndroid Build Coastguard Worker             case EventEntry::Type::DRAG: {
4387*38e8c45fSAndroid Build Coastguard Worker                 LOG_ALWAYS_FATAL("%s event should not be found inside Connections's queue",
4388*38e8c45fSAndroid Build Coastguard Worker                                  ftl::enum_string(downEventEntry->type).c_str());
4389*38e8c45fSAndroid Build Coastguard Worker                 break;
4390*38e8c45fSAndroid Build Coastguard Worker             }
4391*38e8c45fSAndroid Build Coastguard Worker         }
4392*38e8c45fSAndroid Build Coastguard Worker 
4393*38e8c45fSAndroid Build Coastguard Worker         if (targets.size() != 1) LOG(FATAL) << __func__ << ": InputTarget not created";
4394*38e8c45fSAndroid Build Coastguard Worker         if (mTracer) {
4395*38e8c45fSAndroid Build Coastguard Worker             mTracer->dispatchToTargetHint(*traceTracker, targets[0]);
4396*38e8c45fSAndroid Build Coastguard Worker         }
4397*38e8c45fSAndroid Build Coastguard Worker         enqueueDispatchEntryLocked(connection, std::move(downEventEntry), targets[0]);
4398*38e8c45fSAndroid Build Coastguard Worker     }
4399*38e8c45fSAndroid Build Coastguard Worker 
4400*38e8c45fSAndroid Build Coastguard Worker     // If the outbound queue was previously empty, start the dispatch cycle going.
4401*38e8c45fSAndroid Build Coastguard Worker     if (wasEmpty && !connection->outboundQueue.empty()) {
4402*38e8c45fSAndroid Build Coastguard Worker         startDispatchCycleLocked(downTime, connection);
4403*38e8c45fSAndroid Build Coastguard Worker     }
4404*38e8c45fSAndroid Build Coastguard Worker }
4405*38e8c45fSAndroid Build Coastguard Worker 
splitMotionEvent(const MotionEntry & originalMotionEntry,std::bitset<MAX_POINTER_ID+1> pointerIds,nsecs_t splitDownTime)4406*38e8c45fSAndroid Build Coastguard Worker std::unique_ptr<MotionEntry> InputDispatcher::splitMotionEvent(
4407*38e8c45fSAndroid Build Coastguard Worker         const MotionEntry& originalMotionEntry, std::bitset<MAX_POINTER_ID + 1> pointerIds,
4408*38e8c45fSAndroid Build Coastguard Worker         nsecs_t splitDownTime) {
4409*38e8c45fSAndroid Build Coastguard Worker     const auto& [action, pointerProperties, pointerCoords] =
4410*38e8c45fSAndroid Build Coastguard Worker             MotionEvent::split(originalMotionEntry.action, originalMotionEntry.flags,
4411*38e8c45fSAndroid Build Coastguard Worker                                /*historySize=*/0, originalMotionEntry.pointerProperties,
4412*38e8c45fSAndroid Build Coastguard Worker                                originalMotionEntry.pointerCoords, pointerIds);
4413*38e8c45fSAndroid Build Coastguard Worker     if (pointerIds.count() != pointerCoords.size()) {
4414*38e8c45fSAndroid Build Coastguard Worker         // TODO(b/329107108): Determine why some IDs in pointerIds were not in originalMotionEntry.
4415*38e8c45fSAndroid Build Coastguard Worker         // This is bad.  We are missing some of the pointers that we expected to deliver.
4416*38e8c45fSAndroid Build Coastguard Worker         // Most likely this indicates that we received an ACTION_MOVE events that has
4417*38e8c45fSAndroid Build Coastguard Worker         // different pointer ids than we expected based on the previous ACTION_DOWN
4418*38e8c45fSAndroid Build Coastguard Worker         // or ACTION_POINTER_DOWN events that caused us to decide to split the pointers
4419*38e8c45fSAndroid Build Coastguard Worker         // in this way.
4420*38e8c45fSAndroid Build Coastguard Worker         ALOGW("Dropping split motion event because the pointer count is %zu but "
4421*38e8c45fSAndroid Build Coastguard Worker               "we expected there to be %zu pointers.  This probably means we received "
4422*38e8c45fSAndroid Build Coastguard Worker               "a broken sequence of pointer ids from the input device: %s",
4423*38e8c45fSAndroid Build Coastguard Worker               pointerCoords.size(), pointerIds.count(),
4424*38e8c45fSAndroid Build Coastguard Worker               originalMotionEntry.getDescription().c_str());
4425*38e8c45fSAndroid Build Coastguard Worker         return nullptr;
4426*38e8c45fSAndroid Build Coastguard Worker     }
4427*38e8c45fSAndroid Build Coastguard Worker 
4428*38e8c45fSAndroid Build Coastguard Worker     // TODO(b/327503168): Move this check inside MotionEvent::split once all callers handle it
4429*38e8c45fSAndroid Build Coastguard Worker     //   correctly.
4430*38e8c45fSAndroid Build Coastguard Worker     if (action == AMOTION_EVENT_ACTION_DOWN && splitDownTime != originalMotionEntry.eventTime) {
4431*38e8c45fSAndroid Build Coastguard Worker         logDispatchStateLocked();
4432*38e8c45fSAndroid Build Coastguard Worker         LOG_ALWAYS_FATAL("Split motion event has mismatching downTime and eventTime for "
4433*38e8c45fSAndroid Build Coastguard Worker                          "ACTION_DOWN, motionEntry=%s, splitDownTime=%" PRId64,
4434*38e8c45fSAndroid Build Coastguard Worker                          originalMotionEntry.getDescription().c_str(), splitDownTime);
4435*38e8c45fSAndroid Build Coastguard Worker     }
4436*38e8c45fSAndroid Build Coastguard Worker 
4437*38e8c45fSAndroid Build Coastguard Worker     int32_t newId = mIdGenerator.nextId();
4438*38e8c45fSAndroid Build Coastguard Worker     ATRACE_NAME_IF(ATRACE_ENABLED(),
4439*38e8c45fSAndroid Build Coastguard Worker                    StringPrintf("Split MotionEvent(id=0x%" PRIx32 ") to MotionEvent(id=0x%" PRIx32
4440*38e8c45fSAndroid Build Coastguard Worker                                 ").",
4441*38e8c45fSAndroid Build Coastguard Worker                                 originalMotionEntry.id, newId));
4442*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<MotionEntry> splitMotionEntry =
4443*38e8c45fSAndroid Build Coastguard Worker             std::make_unique<MotionEntry>(newId, originalMotionEntry.injectionState,
4444*38e8c45fSAndroid Build Coastguard Worker                                           originalMotionEntry.eventTime,
4445*38e8c45fSAndroid Build Coastguard Worker                                           originalMotionEntry.deviceId, originalMotionEntry.source,
4446*38e8c45fSAndroid Build Coastguard Worker                                           originalMotionEntry.displayId,
4447*38e8c45fSAndroid Build Coastguard Worker                                           originalMotionEntry.policyFlags, action,
4448*38e8c45fSAndroid Build Coastguard Worker                                           originalMotionEntry.actionButton,
4449*38e8c45fSAndroid Build Coastguard Worker                                           originalMotionEntry.flags, originalMotionEntry.metaState,
4450*38e8c45fSAndroid Build Coastguard Worker                                           originalMotionEntry.buttonState,
4451*38e8c45fSAndroid Build Coastguard Worker                                           originalMotionEntry.classification,
4452*38e8c45fSAndroid Build Coastguard Worker                                           originalMotionEntry.edgeFlags,
4453*38e8c45fSAndroid Build Coastguard Worker                                           originalMotionEntry.xPrecision,
4454*38e8c45fSAndroid Build Coastguard Worker                                           originalMotionEntry.yPrecision,
4455*38e8c45fSAndroid Build Coastguard Worker                                           originalMotionEntry.xCursorPosition,
4456*38e8c45fSAndroid Build Coastguard Worker                                           originalMotionEntry.yCursorPosition, splitDownTime,
4457*38e8c45fSAndroid Build Coastguard Worker                                           pointerProperties, pointerCoords);
4458*38e8c45fSAndroid Build Coastguard Worker     if (mTracer) {
4459*38e8c45fSAndroid Build Coastguard Worker         splitMotionEntry->traceTracker =
4460*38e8c45fSAndroid Build Coastguard Worker                 mTracer->traceDerivedEvent(*splitMotionEntry, *originalMotionEntry.traceTracker);
4461*38e8c45fSAndroid Build Coastguard Worker     }
4462*38e8c45fSAndroid Build Coastguard Worker 
4463*38e8c45fSAndroid Build Coastguard Worker     return splitMotionEntry;
4464*38e8c45fSAndroid Build Coastguard Worker }
4465*38e8c45fSAndroid Build Coastguard Worker 
notifyInputDevicesChanged(const NotifyInputDevicesChangedArgs & args)4466*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::notifyInputDevicesChanged(const NotifyInputDevicesChangedArgs& args) {
4467*38e8c45fSAndroid Build Coastguard Worker     std::scoped_lock _l(mLock);
4468*38e8c45fSAndroid Build Coastguard Worker     // Reset key repeating in case a keyboard device was added or removed or something.
4469*38e8c45fSAndroid Build Coastguard Worker     resetKeyRepeatLocked();
4470*38e8c45fSAndroid Build Coastguard Worker     mLatencyTracker.setInputDevices(args.inputDeviceInfos);
4471*38e8c45fSAndroid Build Coastguard Worker }
4472*38e8c45fSAndroid Build Coastguard Worker 
notifyKey(const NotifyKeyArgs & args)4473*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::notifyKey(const NotifyKeyArgs& args) {
4474*38e8c45fSAndroid Build Coastguard Worker     ALOGD_IF(debugInboundEventDetails(),
4475*38e8c45fSAndroid Build Coastguard Worker              "notifyKey - id=%" PRIx32 ", eventTime=%" PRId64
4476*38e8c45fSAndroid Build Coastguard Worker              ", deviceId=%d, source=%s, displayId=%s, policyFlags=0x%x, action=%s, flags=0x%x, "
4477*38e8c45fSAndroid Build Coastguard Worker              "keyCode=%s, scanCode=0x%x, metaState=0x%x, "
4478*38e8c45fSAndroid Build Coastguard Worker              "downTime=%" PRId64,
4479*38e8c45fSAndroid Build Coastguard Worker              args.id, args.eventTime, args.deviceId, inputEventSourceToString(args.source).c_str(),
4480*38e8c45fSAndroid Build Coastguard Worker              args.displayId.toString().c_str(), args.policyFlags,
4481*38e8c45fSAndroid Build Coastguard Worker              KeyEvent::actionToString(args.action), args.flags, KeyEvent::getLabel(args.keyCode),
4482*38e8c45fSAndroid Build Coastguard Worker              args.scanCode, args.metaState, args.downTime);
4483*38e8c45fSAndroid Build Coastguard Worker     Result<void> keyCheck = validateKeyEvent(args.action);
4484*38e8c45fSAndroid Build Coastguard Worker     if (!keyCheck.ok()) {
4485*38e8c45fSAndroid Build Coastguard Worker         LOG(ERROR) << "invalid key event: " << keyCheck.error();
4486*38e8c45fSAndroid Build Coastguard Worker         return;
4487*38e8c45fSAndroid Build Coastguard Worker     }
4488*38e8c45fSAndroid Build Coastguard Worker 
4489*38e8c45fSAndroid Build Coastguard Worker     uint32_t policyFlags = args.policyFlags;
4490*38e8c45fSAndroid Build Coastguard Worker     int32_t flags = args.flags;
4491*38e8c45fSAndroid Build Coastguard Worker     int32_t metaState = args.metaState;
4492*38e8c45fSAndroid Build Coastguard Worker     // InputDispatcher tracks and generates key repeats on behalf of
4493*38e8c45fSAndroid Build Coastguard Worker     // whatever notifies it, so repeatCount should always be set to 0
4494*38e8c45fSAndroid Build Coastguard Worker     constexpr int32_t repeatCount = 0;
4495*38e8c45fSAndroid Build Coastguard Worker     if ((policyFlags & POLICY_FLAG_VIRTUAL) || (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY)) {
4496*38e8c45fSAndroid Build Coastguard Worker         policyFlags |= POLICY_FLAG_VIRTUAL;
4497*38e8c45fSAndroid Build Coastguard Worker         flags |= AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
4498*38e8c45fSAndroid Build Coastguard Worker     }
4499*38e8c45fSAndroid Build Coastguard Worker     if (policyFlags & POLICY_FLAG_FUNCTION) {
4500*38e8c45fSAndroid Build Coastguard Worker         metaState |= AMETA_FUNCTION_ON;
4501*38e8c45fSAndroid Build Coastguard Worker     }
4502*38e8c45fSAndroid Build Coastguard Worker 
4503*38e8c45fSAndroid Build Coastguard Worker     policyFlags |= POLICY_FLAG_TRUSTED;
4504*38e8c45fSAndroid Build Coastguard Worker 
4505*38e8c45fSAndroid Build Coastguard Worker     int32_t keyCode = args.keyCode;
4506*38e8c45fSAndroid Build Coastguard Worker     KeyEvent event;
4507*38e8c45fSAndroid Build Coastguard Worker     event.initialize(args.id, args.deviceId, args.source, args.displayId, INVALID_HMAC, args.action,
4508*38e8c45fSAndroid Build Coastguard Worker                      flags, keyCode, args.scanCode, metaState, repeatCount, args.downTime,
4509*38e8c45fSAndroid Build Coastguard Worker                      args.eventTime);
4510*38e8c45fSAndroid Build Coastguard Worker 
4511*38e8c45fSAndroid Build Coastguard Worker     android::base::Timer t;
4512*38e8c45fSAndroid Build Coastguard Worker     mPolicy.interceptKeyBeforeQueueing(event, /*byref*/ policyFlags);
4513*38e8c45fSAndroid Build Coastguard Worker     if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
4514*38e8c45fSAndroid Build Coastguard Worker         ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
4515*38e8c45fSAndroid Build Coastguard Worker               std::to_string(t.duration().count()).c_str());
4516*38e8c45fSAndroid Build Coastguard Worker     }
4517*38e8c45fSAndroid Build Coastguard Worker 
4518*38e8c45fSAndroid Build Coastguard Worker     bool needWake = false;
4519*38e8c45fSAndroid Build Coastguard Worker     { // acquire lock
4520*38e8c45fSAndroid Build Coastguard Worker         mLock.lock();
4521*38e8c45fSAndroid Build Coastguard Worker 
4522*38e8c45fSAndroid Build Coastguard Worker         if (input_flags::keyboard_repeat_keys() && !mConfig.keyRepeatEnabled) {
4523*38e8c45fSAndroid Build Coastguard Worker             policyFlags |= POLICY_FLAG_DISABLE_KEY_REPEAT;
4524*38e8c45fSAndroid Build Coastguard Worker         }
4525*38e8c45fSAndroid Build Coastguard Worker 
4526*38e8c45fSAndroid Build Coastguard Worker         if (shouldSendKeyToInputFilterLocked(args)) {
4527*38e8c45fSAndroid Build Coastguard Worker             mLock.unlock();
4528*38e8c45fSAndroid Build Coastguard Worker 
4529*38e8c45fSAndroid Build Coastguard Worker             policyFlags |= POLICY_FLAG_FILTERED;
4530*38e8c45fSAndroid Build Coastguard Worker             if (!mPolicy.filterInputEvent(event, policyFlags)) {
4531*38e8c45fSAndroid Build Coastguard Worker                 return; // event was consumed by the filter
4532*38e8c45fSAndroid Build Coastguard Worker             }
4533*38e8c45fSAndroid Build Coastguard Worker 
4534*38e8c45fSAndroid Build Coastguard Worker             mLock.lock();
4535*38e8c45fSAndroid Build Coastguard Worker         }
4536*38e8c45fSAndroid Build Coastguard Worker 
4537*38e8c45fSAndroid Build Coastguard Worker         std::unique_ptr<KeyEntry> newEntry =
4538*38e8c45fSAndroid Build Coastguard Worker                 std::make_unique<KeyEntry>(args.id, /*injectionState=*/nullptr, args.eventTime,
4539*38e8c45fSAndroid Build Coastguard Worker                                            args.deviceId, args.source, args.displayId, policyFlags,
4540*38e8c45fSAndroid Build Coastguard Worker                                            args.action, flags, keyCode, args.scanCode, metaState,
4541*38e8c45fSAndroid Build Coastguard Worker                                            repeatCount, args.downTime);
4542*38e8c45fSAndroid Build Coastguard Worker         if (mTracer) {
4543*38e8c45fSAndroid Build Coastguard Worker             newEntry->traceTracker = mTracer->traceInboundEvent(*newEntry);
4544*38e8c45fSAndroid Build Coastguard Worker         }
4545*38e8c45fSAndroid Build Coastguard Worker 
4546*38e8c45fSAndroid Build Coastguard Worker         if (mPerDeviceInputLatencyMetricsFlag) {
4547*38e8c45fSAndroid Build Coastguard Worker             if (args.id != android::os::IInputConstants::INVALID_INPUT_EVENT_ID &&
4548*38e8c45fSAndroid Build Coastguard Worker                 IdGenerator::getSource(args.id) == IdGenerator::Source::INPUT_READER &&
4549*38e8c45fSAndroid Build Coastguard Worker                 !mInputFilterEnabled) {
4550*38e8c45fSAndroid Build Coastguard Worker                 mLatencyTracker.trackListener(args);
4551*38e8c45fSAndroid Build Coastguard Worker             }
4552*38e8c45fSAndroid Build Coastguard Worker         }
4553*38e8c45fSAndroid Build Coastguard Worker 
4554*38e8c45fSAndroid Build Coastguard Worker         needWake = enqueueInboundEventLocked(std::move(newEntry));
4555*38e8c45fSAndroid Build Coastguard Worker         mLock.unlock();
4556*38e8c45fSAndroid Build Coastguard Worker     } // release lock
4557*38e8c45fSAndroid Build Coastguard Worker 
4558*38e8c45fSAndroid Build Coastguard Worker     if (needWake) {
4559*38e8c45fSAndroid Build Coastguard Worker         mLooper->wake();
4560*38e8c45fSAndroid Build Coastguard Worker     }
4561*38e8c45fSAndroid Build Coastguard Worker }
4562*38e8c45fSAndroid Build Coastguard Worker 
shouldSendKeyToInputFilterLocked(const NotifyKeyArgs & args)4563*38e8c45fSAndroid Build Coastguard Worker bool InputDispatcher::shouldSendKeyToInputFilterLocked(const NotifyKeyArgs& args) {
4564*38e8c45fSAndroid Build Coastguard Worker     return mInputFilterEnabled;
4565*38e8c45fSAndroid Build Coastguard Worker }
4566*38e8c45fSAndroid Build Coastguard Worker 
notifyMotion(const NotifyMotionArgs & args)4567*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::notifyMotion(const NotifyMotionArgs& args) {
4568*38e8c45fSAndroid Build Coastguard Worker     if (debugInboundEventDetails()) {
4569*38e8c45fSAndroid Build Coastguard Worker         ALOGD("notifyMotion - id=%" PRIx32 " eventTime=%" PRId64 ", deviceId=%d, source=%s, "
4570*38e8c45fSAndroid Build Coastguard Worker               "displayId=%s, policyFlags=0x%x, "
4571*38e8c45fSAndroid Build Coastguard Worker               "action=%s, actionButton=0x%x, flags=0x%x, metaState=0x%x, buttonState=0x%x, "
4572*38e8c45fSAndroid Build Coastguard Worker               "xCursorPosition=%f, yCursorPosition=%f, downTime=%" PRId64,
4573*38e8c45fSAndroid Build Coastguard Worker               args.id, args.eventTime, args.deviceId, inputEventSourceToString(args.source).c_str(),
4574*38e8c45fSAndroid Build Coastguard Worker               args.displayId.toString().c_str(), args.policyFlags,
4575*38e8c45fSAndroid Build Coastguard Worker               MotionEvent::actionToString(args.action).c_str(), args.actionButton, args.flags,
4576*38e8c45fSAndroid Build Coastguard Worker               args.metaState, args.buttonState, args.xCursorPosition, args.yCursorPosition,
4577*38e8c45fSAndroid Build Coastguard Worker               args.downTime);
4578*38e8c45fSAndroid Build Coastguard Worker         for (uint32_t i = 0; i < args.getPointerCount(); i++) {
4579*38e8c45fSAndroid Build Coastguard Worker             ALOGD("  Pointer %d: id=%d, toolType=%s, x=%f, y=%f, pressure=%f, size=%f, "
4580*38e8c45fSAndroid Build Coastguard Worker                   "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, orientation=%f",
4581*38e8c45fSAndroid Build Coastguard Worker                   i, args.pointerProperties[i].id,
4582*38e8c45fSAndroid Build Coastguard Worker                   ftl::enum_string(args.pointerProperties[i].toolType).c_str(),
4583*38e8c45fSAndroid Build Coastguard Worker                   args.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
4584*38e8c45fSAndroid Build Coastguard Worker                   args.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
4585*38e8c45fSAndroid Build Coastguard Worker                   args.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
4586*38e8c45fSAndroid Build Coastguard Worker                   args.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
4587*38e8c45fSAndroid Build Coastguard Worker                   args.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
4588*38e8c45fSAndroid Build Coastguard Worker                   args.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
4589*38e8c45fSAndroid Build Coastguard Worker                   args.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
4590*38e8c45fSAndroid Build Coastguard Worker                   args.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
4591*38e8c45fSAndroid Build Coastguard Worker                   args.pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
4592*38e8c45fSAndroid Build Coastguard Worker         }
4593*38e8c45fSAndroid Build Coastguard Worker     }
4594*38e8c45fSAndroid Build Coastguard Worker 
4595*38e8c45fSAndroid Build Coastguard Worker     Result<void> motionCheck =
4596*38e8c45fSAndroid Build Coastguard Worker             validateMotionEvent(args.action, args.actionButton, args.getPointerCount(),
4597*38e8c45fSAndroid Build Coastguard Worker                                 args.pointerProperties.data());
4598*38e8c45fSAndroid Build Coastguard Worker     if (!motionCheck.ok()) {
4599*38e8c45fSAndroid Build Coastguard Worker         LOG(FATAL) << "Invalid event: " << args.dump() << "; reason: " << motionCheck.error();
4600*38e8c45fSAndroid Build Coastguard Worker         return;
4601*38e8c45fSAndroid Build Coastguard Worker     }
4602*38e8c45fSAndroid Build Coastguard Worker 
4603*38e8c45fSAndroid Build Coastguard Worker     if (DEBUG_VERIFY_EVENTS) {
4604*38e8c45fSAndroid Build Coastguard Worker         auto [it, _] =
4605*38e8c45fSAndroid Build Coastguard Worker                 mVerifiersByDisplay.try_emplace(args.displayId,
4606*38e8c45fSAndroid Build Coastguard Worker                                                 StringPrintf("display %s",
4607*38e8c45fSAndroid Build Coastguard Worker                                                              args.displayId.toString().c_str()));
4608*38e8c45fSAndroid Build Coastguard Worker         Result<void> result =
4609*38e8c45fSAndroid Build Coastguard Worker                 it->second.processMovement(args.deviceId, args.source, args.action,
4610*38e8c45fSAndroid Build Coastguard Worker                                            args.getPointerCount(), args.pointerProperties.data(),
4611*38e8c45fSAndroid Build Coastguard Worker                                            args.pointerCoords.data(), args.flags);
4612*38e8c45fSAndroid Build Coastguard Worker         if (!result.ok()) {
4613*38e8c45fSAndroid Build Coastguard Worker             LOG(FATAL) << "Bad stream: " << result.error() << " caused by " << args.dump();
4614*38e8c45fSAndroid Build Coastguard Worker         }
4615*38e8c45fSAndroid Build Coastguard Worker     }
4616*38e8c45fSAndroid Build Coastguard Worker 
4617*38e8c45fSAndroid Build Coastguard Worker     uint32_t policyFlags = args.policyFlags;
4618*38e8c45fSAndroid Build Coastguard Worker     policyFlags |= POLICY_FLAG_TRUSTED;
4619*38e8c45fSAndroid Build Coastguard Worker 
4620*38e8c45fSAndroid Build Coastguard Worker     android::base::Timer t;
4621*38e8c45fSAndroid Build Coastguard Worker     mPolicy.interceptMotionBeforeQueueing(args.displayId, args.source, args.action, args.eventTime,
4622*38e8c45fSAndroid Build Coastguard Worker                                           policyFlags);
4623*38e8c45fSAndroid Build Coastguard Worker     if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
4624*38e8c45fSAndroid Build Coastguard Worker         ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
4625*38e8c45fSAndroid Build Coastguard Worker               std::to_string(t.duration().count()).c_str());
4626*38e8c45fSAndroid Build Coastguard Worker     }
4627*38e8c45fSAndroid Build Coastguard Worker 
4628*38e8c45fSAndroid Build Coastguard Worker     bool needWake = false;
4629*38e8c45fSAndroid Build Coastguard Worker     { // acquire lock
4630*38e8c45fSAndroid Build Coastguard Worker         mLock.lock();
4631*38e8c45fSAndroid Build Coastguard Worker         if (!(policyFlags & POLICY_FLAG_PASS_TO_USER)) {
4632*38e8c45fSAndroid Build Coastguard Worker             // Set the flag anyway if we already have an ongoing gesture. That would allow us to
4633*38e8c45fSAndroid Build Coastguard Worker             // complete the processing of the current stroke.
4634*38e8c45fSAndroid Build Coastguard Worker             const auto touchStateIt = mTouchStatesByDisplay.find(args.displayId);
4635*38e8c45fSAndroid Build Coastguard Worker             if (touchStateIt != mTouchStatesByDisplay.end()) {
4636*38e8c45fSAndroid Build Coastguard Worker                 const TouchState& touchState = touchStateIt->second;
4637*38e8c45fSAndroid Build Coastguard Worker                 if (touchState.hasTouchingPointers(args.deviceId) ||
4638*38e8c45fSAndroid Build Coastguard Worker                     touchState.hasHoveringPointers(args.deviceId)) {
4639*38e8c45fSAndroid Build Coastguard Worker                     policyFlags |= POLICY_FLAG_PASS_TO_USER;
4640*38e8c45fSAndroid Build Coastguard Worker                 }
4641*38e8c45fSAndroid Build Coastguard Worker             }
4642*38e8c45fSAndroid Build Coastguard Worker         }
4643*38e8c45fSAndroid Build Coastguard Worker 
4644*38e8c45fSAndroid Build Coastguard Worker         if (shouldSendMotionToInputFilterLocked(args)) {
4645*38e8c45fSAndroid Build Coastguard Worker             ui::Transform displayTransform;
4646*38e8c45fSAndroid Build Coastguard Worker             if (const auto it = mDisplayInfos.find(args.displayId); it != mDisplayInfos.end()) {
4647*38e8c45fSAndroid Build Coastguard Worker                 displayTransform = it->second.transform;
4648*38e8c45fSAndroid Build Coastguard Worker             }
4649*38e8c45fSAndroid Build Coastguard Worker 
4650*38e8c45fSAndroid Build Coastguard Worker             mLock.unlock();
4651*38e8c45fSAndroid Build Coastguard Worker 
4652*38e8c45fSAndroid Build Coastguard Worker             MotionEvent event;
4653*38e8c45fSAndroid Build Coastguard Worker             event.initialize(args.id, args.deviceId, args.source, args.displayId, INVALID_HMAC,
4654*38e8c45fSAndroid Build Coastguard Worker                              args.action, args.actionButton, args.flags, args.edgeFlags,
4655*38e8c45fSAndroid Build Coastguard Worker                              args.metaState, args.buttonState, args.classification,
4656*38e8c45fSAndroid Build Coastguard Worker                              displayTransform, args.xPrecision, args.yPrecision,
4657*38e8c45fSAndroid Build Coastguard Worker                              args.xCursorPosition, args.yCursorPosition, displayTransform,
4658*38e8c45fSAndroid Build Coastguard Worker                              args.downTime, args.eventTime, args.getPointerCount(),
4659*38e8c45fSAndroid Build Coastguard Worker                              args.pointerProperties.data(), args.pointerCoords.data());
4660*38e8c45fSAndroid Build Coastguard Worker 
4661*38e8c45fSAndroid Build Coastguard Worker             policyFlags |= POLICY_FLAG_FILTERED;
4662*38e8c45fSAndroid Build Coastguard Worker             if (!mPolicy.filterInputEvent(event, policyFlags)) {
4663*38e8c45fSAndroid Build Coastguard Worker                 return; // event was consumed by the filter
4664*38e8c45fSAndroid Build Coastguard Worker             }
4665*38e8c45fSAndroid Build Coastguard Worker 
4666*38e8c45fSAndroid Build Coastguard Worker             mLock.lock();
4667*38e8c45fSAndroid Build Coastguard Worker         }
4668*38e8c45fSAndroid Build Coastguard Worker 
4669*38e8c45fSAndroid Build Coastguard Worker         // Just enqueue a new motion event.
4670*38e8c45fSAndroid Build Coastguard Worker         std::unique_ptr<MotionEntry> newEntry =
4671*38e8c45fSAndroid Build Coastguard Worker                 std::make_unique<MotionEntry>(args.id, /*injectionState=*/nullptr, args.eventTime,
4672*38e8c45fSAndroid Build Coastguard Worker                                               args.deviceId, args.source, args.displayId,
4673*38e8c45fSAndroid Build Coastguard Worker                                               policyFlags, args.action, args.actionButton,
4674*38e8c45fSAndroid Build Coastguard Worker                                               args.flags, args.metaState, args.buttonState,
4675*38e8c45fSAndroid Build Coastguard Worker                                               args.classification, args.edgeFlags, args.xPrecision,
4676*38e8c45fSAndroid Build Coastguard Worker                                               args.yPrecision, args.xCursorPosition,
4677*38e8c45fSAndroid Build Coastguard Worker                                               args.yCursorPosition, args.downTime,
4678*38e8c45fSAndroid Build Coastguard Worker                                               args.pointerProperties, args.pointerCoords);
4679*38e8c45fSAndroid Build Coastguard Worker         if (mTracer) {
4680*38e8c45fSAndroid Build Coastguard Worker             newEntry->traceTracker = mTracer->traceInboundEvent(*newEntry);
4681*38e8c45fSAndroid Build Coastguard Worker         }
4682*38e8c45fSAndroid Build Coastguard Worker 
4683*38e8c45fSAndroid Build Coastguard Worker         if (args.id != android::os::IInputConstants::INVALID_INPUT_EVENT_ID &&
4684*38e8c45fSAndroid Build Coastguard Worker             IdGenerator::getSource(args.id) == IdGenerator::Source::INPUT_READER &&
4685*38e8c45fSAndroid Build Coastguard Worker             !mInputFilterEnabled) {
4686*38e8c45fSAndroid Build Coastguard Worker             mLatencyTracker.trackListener(args);
4687*38e8c45fSAndroid Build Coastguard Worker         }
4688*38e8c45fSAndroid Build Coastguard Worker 
4689*38e8c45fSAndroid Build Coastguard Worker         needWake = enqueueInboundEventLocked(std::move(newEntry));
4690*38e8c45fSAndroid Build Coastguard Worker         mLock.unlock();
4691*38e8c45fSAndroid Build Coastguard Worker     } // release lock
4692*38e8c45fSAndroid Build Coastguard Worker 
4693*38e8c45fSAndroid Build Coastguard Worker     if (needWake) {
4694*38e8c45fSAndroid Build Coastguard Worker         mLooper->wake();
4695*38e8c45fSAndroid Build Coastguard Worker     }
4696*38e8c45fSAndroid Build Coastguard Worker }
4697*38e8c45fSAndroid Build Coastguard Worker 
notifySensor(const NotifySensorArgs & args)4698*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::notifySensor(const NotifySensorArgs& args) {
4699*38e8c45fSAndroid Build Coastguard Worker     if (debugInboundEventDetails()) {
4700*38e8c45fSAndroid Build Coastguard Worker         ALOGD("notifySensor - id=%" PRIx32 " eventTime=%" PRId64 ", deviceId=%d, source=0x%x, "
4701*38e8c45fSAndroid Build Coastguard Worker               " sensorType=%s",
4702*38e8c45fSAndroid Build Coastguard Worker               args.id, args.eventTime, args.deviceId, args.source,
4703*38e8c45fSAndroid Build Coastguard Worker               ftl::enum_string(args.sensorType).c_str());
4704*38e8c45fSAndroid Build Coastguard Worker     }
4705*38e8c45fSAndroid Build Coastguard Worker 
4706*38e8c45fSAndroid Build Coastguard Worker     bool needWake = false;
4707*38e8c45fSAndroid Build Coastguard Worker     { // acquire lock
4708*38e8c45fSAndroid Build Coastguard Worker         mLock.lock();
4709*38e8c45fSAndroid Build Coastguard Worker 
4710*38e8c45fSAndroid Build Coastguard Worker         // Just enqueue a new sensor event.
4711*38e8c45fSAndroid Build Coastguard Worker         std::unique_ptr<SensorEntry> newEntry =
4712*38e8c45fSAndroid Build Coastguard Worker                 std::make_unique<SensorEntry>(args.id, args.eventTime, args.deviceId, args.source,
4713*38e8c45fSAndroid Build Coastguard Worker                                               /* policyFlags=*/0, args.hwTimestamp, args.sensorType,
4714*38e8c45fSAndroid Build Coastguard Worker                                               args.accuracy, args.accuracyChanged, args.values);
4715*38e8c45fSAndroid Build Coastguard Worker 
4716*38e8c45fSAndroid Build Coastguard Worker         needWake = enqueueInboundEventLocked(std::move(newEntry));
4717*38e8c45fSAndroid Build Coastguard Worker         mLock.unlock();
4718*38e8c45fSAndroid Build Coastguard Worker     } // release lock
4719*38e8c45fSAndroid Build Coastguard Worker 
4720*38e8c45fSAndroid Build Coastguard Worker     if (needWake) {
4721*38e8c45fSAndroid Build Coastguard Worker         mLooper->wake();
4722*38e8c45fSAndroid Build Coastguard Worker     }
4723*38e8c45fSAndroid Build Coastguard Worker }
4724*38e8c45fSAndroid Build Coastguard Worker 
notifyVibratorState(const NotifyVibratorStateArgs & args)4725*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::notifyVibratorState(const NotifyVibratorStateArgs& args) {
4726*38e8c45fSAndroid Build Coastguard Worker     if (debugInboundEventDetails()) {
4727*38e8c45fSAndroid Build Coastguard Worker         ALOGD("notifyVibratorState - eventTime=%" PRId64 ", device=%d,  isOn=%d", args.eventTime,
4728*38e8c45fSAndroid Build Coastguard Worker               args.deviceId, args.isOn);
4729*38e8c45fSAndroid Build Coastguard Worker     }
4730*38e8c45fSAndroid Build Coastguard Worker     mPolicy.notifyVibratorState(args.deviceId, args.isOn);
4731*38e8c45fSAndroid Build Coastguard Worker }
4732*38e8c45fSAndroid Build Coastguard Worker 
shouldSendMotionToInputFilterLocked(const NotifyMotionArgs & args)4733*38e8c45fSAndroid Build Coastguard Worker bool InputDispatcher::shouldSendMotionToInputFilterLocked(const NotifyMotionArgs& args) {
4734*38e8c45fSAndroid Build Coastguard Worker     return mInputFilterEnabled;
4735*38e8c45fSAndroid Build Coastguard Worker }
4736*38e8c45fSAndroid Build Coastguard Worker 
notifySwitch(const NotifySwitchArgs & args)4737*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::notifySwitch(const NotifySwitchArgs& args) {
4738*38e8c45fSAndroid Build Coastguard Worker     if (debugInboundEventDetails()) {
4739*38e8c45fSAndroid Build Coastguard Worker         ALOGD("notifySwitch - eventTime=%" PRId64 ", policyFlags=0x%x, switchValues=0x%08x, "
4740*38e8c45fSAndroid Build Coastguard Worker               "switchMask=0x%08x",
4741*38e8c45fSAndroid Build Coastguard Worker               args.eventTime, args.policyFlags, args.switchValues, args.switchMask);
4742*38e8c45fSAndroid Build Coastguard Worker     }
4743*38e8c45fSAndroid Build Coastguard Worker 
4744*38e8c45fSAndroid Build Coastguard Worker     uint32_t policyFlags = args.policyFlags;
4745*38e8c45fSAndroid Build Coastguard Worker     policyFlags |= POLICY_FLAG_TRUSTED;
4746*38e8c45fSAndroid Build Coastguard Worker     mPolicy.notifySwitch(args.eventTime, args.switchValues, args.switchMask, policyFlags);
4747*38e8c45fSAndroid Build Coastguard Worker }
4748*38e8c45fSAndroid Build Coastguard Worker 
notifyDeviceReset(const NotifyDeviceResetArgs & args)4749*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::notifyDeviceReset(const NotifyDeviceResetArgs& args) {
4750*38e8c45fSAndroid Build Coastguard Worker     // TODO(b/308677868) Remove device reset from the InputListener interface
4751*38e8c45fSAndroid Build Coastguard Worker     if (debugInboundEventDetails()) {
4752*38e8c45fSAndroid Build Coastguard Worker         ALOGD("notifyDeviceReset - eventTime=%" PRId64 ", deviceId=%d", args.eventTime,
4753*38e8c45fSAndroid Build Coastguard Worker               args.deviceId);
4754*38e8c45fSAndroid Build Coastguard Worker     }
4755*38e8c45fSAndroid Build Coastguard Worker 
4756*38e8c45fSAndroid Build Coastguard Worker     bool needWake = false;
4757*38e8c45fSAndroid Build Coastguard Worker     { // acquire lock
4758*38e8c45fSAndroid Build Coastguard Worker         std::scoped_lock _l(mLock);
4759*38e8c45fSAndroid Build Coastguard Worker 
4760*38e8c45fSAndroid Build Coastguard Worker         std::unique_ptr<DeviceResetEntry> newEntry =
4761*38e8c45fSAndroid Build Coastguard Worker                 std::make_unique<DeviceResetEntry>(args.id, args.eventTime, args.deviceId);
4762*38e8c45fSAndroid Build Coastguard Worker         needWake = enqueueInboundEventLocked(std::move(newEntry));
4763*38e8c45fSAndroid Build Coastguard Worker 
4764*38e8c45fSAndroid Build Coastguard Worker         for (auto& [_, verifier] : mVerifiersByDisplay) {
4765*38e8c45fSAndroid Build Coastguard Worker             verifier.resetDevice(args.deviceId);
4766*38e8c45fSAndroid Build Coastguard Worker         }
4767*38e8c45fSAndroid Build Coastguard Worker     } // release lock
4768*38e8c45fSAndroid Build Coastguard Worker 
4769*38e8c45fSAndroid Build Coastguard Worker     if (needWake) {
4770*38e8c45fSAndroid Build Coastguard Worker         mLooper->wake();
4771*38e8c45fSAndroid Build Coastguard Worker     }
4772*38e8c45fSAndroid Build Coastguard Worker }
4773*38e8c45fSAndroid Build Coastguard Worker 
notifyPointerCaptureChanged(const NotifyPointerCaptureChangedArgs & args)4774*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::notifyPointerCaptureChanged(const NotifyPointerCaptureChangedArgs& args) {
4775*38e8c45fSAndroid Build Coastguard Worker     if (debugInboundEventDetails()) {
4776*38e8c45fSAndroid Build Coastguard Worker         ALOGD("notifyPointerCaptureChanged - eventTime=%" PRId64 ", enabled=%s", args.eventTime,
4777*38e8c45fSAndroid Build Coastguard Worker               args.request.isEnable() ? "true" : "false");
4778*38e8c45fSAndroid Build Coastguard Worker     }
4779*38e8c45fSAndroid Build Coastguard Worker 
4780*38e8c45fSAndroid Build Coastguard Worker     bool needWake = false;
4781*38e8c45fSAndroid Build Coastguard Worker     { // acquire lock
4782*38e8c45fSAndroid Build Coastguard Worker         std::scoped_lock _l(mLock);
4783*38e8c45fSAndroid Build Coastguard Worker         auto entry =
4784*38e8c45fSAndroid Build Coastguard Worker                 std::make_unique<PointerCaptureChangedEntry>(args.id, args.eventTime, args.request);
4785*38e8c45fSAndroid Build Coastguard Worker         needWake = enqueueInboundEventLocked(std::move(entry));
4786*38e8c45fSAndroid Build Coastguard Worker     } // release lock
4787*38e8c45fSAndroid Build Coastguard Worker 
4788*38e8c45fSAndroid Build Coastguard Worker     if (needWake) {
4789*38e8c45fSAndroid Build Coastguard Worker         mLooper->wake();
4790*38e8c45fSAndroid Build Coastguard Worker     }
4791*38e8c45fSAndroid Build Coastguard Worker }
4792*38e8c45fSAndroid Build Coastguard Worker 
shouldRejectInjectedMotionLocked(const MotionEvent & motionEvent,DeviceId deviceId,ui::LogicalDisplayId displayId,std::optional<gui::Uid> targetUid,int32_t flags)4793*38e8c45fSAndroid Build Coastguard Worker bool InputDispatcher::shouldRejectInjectedMotionLocked(const MotionEvent& motionEvent,
4794*38e8c45fSAndroid Build Coastguard Worker                                                        DeviceId deviceId,
4795*38e8c45fSAndroid Build Coastguard Worker                                                        ui::LogicalDisplayId displayId,
4796*38e8c45fSAndroid Build Coastguard Worker                                                        std::optional<gui::Uid> targetUid,
4797*38e8c45fSAndroid Build Coastguard Worker                                                        int32_t flags) {
4798*38e8c45fSAndroid Build Coastguard Worker     // Don't verify targeted injection, since it will only affect the caller's
4799*38e8c45fSAndroid Build Coastguard Worker     // window, and the windows are typically destroyed at the end of the test.
4800*38e8c45fSAndroid Build Coastguard Worker     if (targetUid.has_value()) {
4801*38e8c45fSAndroid Build Coastguard Worker         return false;
4802*38e8c45fSAndroid Build Coastguard Worker     }
4803*38e8c45fSAndroid Build Coastguard Worker 
4804*38e8c45fSAndroid Build Coastguard Worker     // Verify all other injected streams, whether the injection is coming from apps or from
4805*38e8c45fSAndroid Build Coastguard Worker     // input filter. Print an error if the stream becomes inconsistent with this event.
4806*38e8c45fSAndroid Build Coastguard Worker     // An inconsistent injected event sent could cause a crash in the later stages of
4807*38e8c45fSAndroid Build Coastguard Worker     // dispatching pipeline.
4808*38e8c45fSAndroid Build Coastguard Worker     auto [it, _] = mInputFilterVerifiersByDisplay.try_emplace(displayId,
4809*38e8c45fSAndroid Build Coastguard Worker                                                               std::string("Injection on ") +
4810*38e8c45fSAndroid Build Coastguard Worker                                                                       displayId.toString());
4811*38e8c45fSAndroid Build Coastguard Worker     InputVerifier& verifier = it->second;
4812*38e8c45fSAndroid Build Coastguard Worker 
4813*38e8c45fSAndroid Build Coastguard Worker     Result<void> result =
4814*38e8c45fSAndroid Build Coastguard Worker             verifier.processMovement(deviceId, motionEvent.getSource(), motionEvent.getAction(),
4815*38e8c45fSAndroid Build Coastguard Worker                                      motionEvent.getPointerCount(),
4816*38e8c45fSAndroid Build Coastguard Worker                                      motionEvent.getPointerProperties(),
4817*38e8c45fSAndroid Build Coastguard Worker                                      motionEvent.getSamplePointerCoords(), flags);
4818*38e8c45fSAndroid Build Coastguard Worker     if (!result.ok()) {
4819*38e8c45fSAndroid Build Coastguard Worker         logDispatchStateLocked();
4820*38e8c45fSAndroid Build Coastguard Worker         LOG(ERROR) << "Inconsistent event: " << motionEvent << ", reason: " << result.error();
4821*38e8c45fSAndroid Build Coastguard Worker         return true;
4822*38e8c45fSAndroid Build Coastguard Worker     }
4823*38e8c45fSAndroid Build Coastguard Worker     return false;
4824*38e8c45fSAndroid Build Coastguard Worker }
4825*38e8c45fSAndroid Build Coastguard Worker 
injectInputEvent(const InputEvent * event,std::optional<gui::Uid> targetUid,InputEventInjectionSync syncMode,std::chrono::milliseconds timeout,uint32_t policyFlags)4826*38e8c45fSAndroid Build Coastguard Worker InputEventInjectionResult InputDispatcher::injectInputEvent(const InputEvent* event,
4827*38e8c45fSAndroid Build Coastguard Worker                                                             std::optional<gui::Uid> targetUid,
4828*38e8c45fSAndroid Build Coastguard Worker                                                             InputEventInjectionSync syncMode,
4829*38e8c45fSAndroid Build Coastguard Worker                                                             std::chrono::milliseconds timeout,
4830*38e8c45fSAndroid Build Coastguard Worker                                                             uint32_t policyFlags) {
4831*38e8c45fSAndroid Build Coastguard Worker     Result<void> eventValidation = validateInputEvent(*event);
4832*38e8c45fSAndroid Build Coastguard Worker     if (!eventValidation.ok()) {
4833*38e8c45fSAndroid Build Coastguard Worker         LOG(INFO) << "Injection failed: invalid event: " << eventValidation.error();
4834*38e8c45fSAndroid Build Coastguard Worker         return InputEventInjectionResult::FAILED;
4835*38e8c45fSAndroid Build Coastguard Worker     }
4836*38e8c45fSAndroid Build Coastguard Worker 
4837*38e8c45fSAndroid Build Coastguard Worker     if (debugInboundEventDetails()) {
4838*38e8c45fSAndroid Build Coastguard Worker         LOG(INFO) << __func__ << ": targetUid=" << toString(targetUid, &uidString)
4839*38e8c45fSAndroid Build Coastguard Worker                   << ", syncMode=" << ftl::enum_string(syncMode) << ", timeout=" << timeout.count()
4840*38e8c45fSAndroid Build Coastguard Worker                   << "ms, policyFlags=0x" << std::hex << policyFlags << std::dec
4841*38e8c45fSAndroid Build Coastguard Worker                   << ", event=" << *event;
4842*38e8c45fSAndroid Build Coastguard Worker     }
4843*38e8c45fSAndroid Build Coastguard Worker     nsecs_t endTime = now() + std::chrono::duration_cast<std::chrono::nanoseconds>(timeout).count();
4844*38e8c45fSAndroid Build Coastguard Worker 
4845*38e8c45fSAndroid Build Coastguard Worker     policyFlags |= POLICY_FLAG_INJECTED | POLICY_FLAG_TRUSTED;
4846*38e8c45fSAndroid Build Coastguard Worker 
4847*38e8c45fSAndroid Build Coastguard Worker     // For all injected events, set device id = VIRTUAL_KEYBOARD_ID. The only exception is events
4848*38e8c45fSAndroid Build Coastguard Worker     // that have gone through the InputFilter. If the event passed through the InputFilter, assign
4849*38e8c45fSAndroid Build Coastguard Worker     // the provided device id. If the InputFilter is accessibility, and it modifies or synthesizes
4850*38e8c45fSAndroid Build Coastguard Worker     // the injected event, it is responsible for setting POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY.
4851*38e8c45fSAndroid Build Coastguard Worker     // For those events, we will set FLAG_IS_ACCESSIBILITY_EVENT to allow apps to distinguish them
4852*38e8c45fSAndroid Build Coastguard Worker     // from events that originate from actual hardware.
4853*38e8c45fSAndroid Build Coastguard Worker     DeviceId resolvedDeviceId = VIRTUAL_KEYBOARD_ID;
4854*38e8c45fSAndroid Build Coastguard Worker     if (policyFlags & POLICY_FLAG_FILTERED) {
4855*38e8c45fSAndroid Build Coastguard Worker         resolvedDeviceId = event->getDeviceId();
4856*38e8c45fSAndroid Build Coastguard Worker     }
4857*38e8c45fSAndroid Build Coastguard Worker 
4858*38e8c45fSAndroid Build Coastguard Worker     const bool isAsync = syncMode == InputEventInjectionSync::NONE;
4859*38e8c45fSAndroid Build Coastguard Worker     auto injectionState = std::make_shared<InjectionState>(targetUid, isAsync);
4860*38e8c45fSAndroid Build Coastguard Worker 
4861*38e8c45fSAndroid Build Coastguard Worker     std::queue<std::unique_ptr<EventEntry>> injectedEntries;
4862*38e8c45fSAndroid Build Coastguard Worker     switch (event->getType()) {
4863*38e8c45fSAndroid Build Coastguard Worker         case InputEventType::KEY: {
4864*38e8c45fSAndroid Build Coastguard Worker             const KeyEvent& incomingKey = static_cast<const KeyEvent&>(*event);
4865*38e8c45fSAndroid Build Coastguard Worker             const int32_t action = incomingKey.getAction();
4866*38e8c45fSAndroid Build Coastguard Worker             int32_t flags = incomingKey.getFlags();
4867*38e8c45fSAndroid Build Coastguard Worker             if (policyFlags & POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY) {
4868*38e8c45fSAndroid Build Coastguard Worker                 flags |= AKEY_EVENT_FLAG_IS_ACCESSIBILITY_EVENT;
4869*38e8c45fSAndroid Build Coastguard Worker             }
4870*38e8c45fSAndroid Build Coastguard Worker             int32_t keyCode = incomingKey.getKeyCode();
4871*38e8c45fSAndroid Build Coastguard Worker             int32_t metaState = incomingKey.getMetaState();
4872*38e8c45fSAndroid Build Coastguard Worker             KeyEvent keyEvent;
4873*38e8c45fSAndroid Build Coastguard Worker             keyEvent.initialize(incomingKey.getId(), resolvedDeviceId, incomingKey.getSource(),
4874*38e8c45fSAndroid Build Coastguard Worker                                 incomingKey.getDisplayId(), INVALID_HMAC, action, flags, keyCode,
4875*38e8c45fSAndroid Build Coastguard Worker                                 incomingKey.getScanCode(), metaState, incomingKey.getRepeatCount(),
4876*38e8c45fSAndroid Build Coastguard Worker                                 incomingKey.getDownTime(), incomingKey.getEventTime());
4877*38e8c45fSAndroid Build Coastguard Worker 
4878*38e8c45fSAndroid Build Coastguard Worker             if (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY) {
4879*38e8c45fSAndroid Build Coastguard Worker                 policyFlags |= POLICY_FLAG_VIRTUAL;
4880*38e8c45fSAndroid Build Coastguard Worker             }
4881*38e8c45fSAndroid Build Coastguard Worker 
4882*38e8c45fSAndroid Build Coastguard Worker             if (!(policyFlags & POLICY_FLAG_FILTERED)) {
4883*38e8c45fSAndroid Build Coastguard Worker                 android::base::Timer t;
4884*38e8c45fSAndroid Build Coastguard Worker                 mPolicy.interceptKeyBeforeQueueing(keyEvent, /*byref*/ policyFlags);
4885*38e8c45fSAndroid Build Coastguard Worker                 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
4886*38e8c45fSAndroid Build Coastguard Worker                     ALOGW("Excessive delay in interceptKeyBeforeQueueing; took %s ms",
4887*38e8c45fSAndroid Build Coastguard Worker                           std::to_string(t.duration().count()).c_str());
4888*38e8c45fSAndroid Build Coastguard Worker                 }
4889*38e8c45fSAndroid Build Coastguard Worker             }
4890*38e8c45fSAndroid Build Coastguard Worker 
4891*38e8c45fSAndroid Build Coastguard Worker             mLock.lock();
4892*38e8c45fSAndroid Build Coastguard Worker             std::unique_ptr<KeyEntry> injectedEntry =
4893*38e8c45fSAndroid Build Coastguard Worker                     std::make_unique<KeyEntry>(incomingKey.getId(), injectionState,
4894*38e8c45fSAndroid Build Coastguard Worker                                                incomingKey.getEventTime(), resolvedDeviceId,
4895*38e8c45fSAndroid Build Coastguard Worker                                                incomingKey.getSource(), incomingKey.getDisplayId(),
4896*38e8c45fSAndroid Build Coastguard Worker                                                policyFlags, action, flags, keyCode,
4897*38e8c45fSAndroid Build Coastguard Worker                                                incomingKey.getScanCode(), metaState,
4898*38e8c45fSAndroid Build Coastguard Worker                                                incomingKey.getRepeatCount(),
4899*38e8c45fSAndroid Build Coastguard Worker                                                incomingKey.getDownTime());
4900*38e8c45fSAndroid Build Coastguard Worker             if (mTracer) {
4901*38e8c45fSAndroid Build Coastguard Worker                 injectedEntry->traceTracker = mTracer->traceInboundEvent(*injectedEntry);
4902*38e8c45fSAndroid Build Coastguard Worker             }
4903*38e8c45fSAndroid Build Coastguard Worker             injectedEntries.push(std::move(injectedEntry));
4904*38e8c45fSAndroid Build Coastguard Worker             break;
4905*38e8c45fSAndroid Build Coastguard Worker         }
4906*38e8c45fSAndroid Build Coastguard Worker 
4907*38e8c45fSAndroid Build Coastguard Worker         case InputEventType::MOTION: {
4908*38e8c45fSAndroid Build Coastguard Worker             const MotionEvent& motionEvent = static_cast<const MotionEvent&>(*event);
4909*38e8c45fSAndroid Build Coastguard Worker             const bool isPointerEvent =
4910*38e8c45fSAndroid Build Coastguard Worker                     isFromSource(event->getSource(), AINPUT_SOURCE_CLASS_POINTER);
4911*38e8c45fSAndroid Build Coastguard Worker             // If a pointer event has no displayId specified, inject it to the default display.
4912*38e8c45fSAndroid Build Coastguard Worker             const ui::LogicalDisplayId displayId =
4913*38e8c45fSAndroid Build Coastguard Worker                     isPointerEvent && (event->getDisplayId() == ui::LogicalDisplayId::INVALID)
4914*38e8c45fSAndroid Build Coastguard Worker                     ? ui::LogicalDisplayId::DEFAULT
4915*38e8c45fSAndroid Build Coastguard Worker                     : event->getDisplayId();
4916*38e8c45fSAndroid Build Coastguard Worker             int32_t flags = motionEvent.getFlags();
4917*38e8c45fSAndroid Build Coastguard Worker 
4918*38e8c45fSAndroid Build Coastguard Worker             if (!(policyFlags & POLICY_FLAG_FILTERED)) {
4919*38e8c45fSAndroid Build Coastguard Worker                 nsecs_t eventTime = motionEvent.getEventTime();
4920*38e8c45fSAndroid Build Coastguard Worker                 android::base::Timer t;
4921*38e8c45fSAndroid Build Coastguard Worker                 mPolicy.interceptMotionBeforeQueueing(displayId, motionEvent.getSource(),
4922*38e8c45fSAndroid Build Coastguard Worker                                                       motionEvent.getAction(), eventTime,
4923*38e8c45fSAndroid Build Coastguard Worker                                                       /*byref*/ policyFlags);
4924*38e8c45fSAndroid Build Coastguard Worker                 if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
4925*38e8c45fSAndroid Build Coastguard Worker                     ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
4926*38e8c45fSAndroid Build Coastguard Worker                           std::to_string(t.duration().count()).c_str());
4927*38e8c45fSAndroid Build Coastguard Worker                 }
4928*38e8c45fSAndroid Build Coastguard Worker             }
4929*38e8c45fSAndroid Build Coastguard Worker 
4930*38e8c45fSAndroid Build Coastguard Worker             if (policyFlags & POLICY_FLAG_INJECTED_FROM_ACCESSIBILITY) {
4931*38e8c45fSAndroid Build Coastguard Worker                 flags |= AMOTION_EVENT_FLAG_IS_ACCESSIBILITY_EVENT;
4932*38e8c45fSAndroid Build Coastguard Worker             }
4933*38e8c45fSAndroid Build Coastguard Worker 
4934*38e8c45fSAndroid Build Coastguard Worker             mLock.lock();
4935*38e8c45fSAndroid Build Coastguard Worker 
4936*38e8c45fSAndroid Build Coastguard Worker             if (shouldRejectInjectedMotionLocked(motionEvent, resolvedDeviceId, displayId,
4937*38e8c45fSAndroid Build Coastguard Worker                                                  targetUid, flags)) {
4938*38e8c45fSAndroid Build Coastguard Worker                 mLock.unlock();
4939*38e8c45fSAndroid Build Coastguard Worker                 return InputEventInjectionResult::FAILED;
4940*38e8c45fSAndroid Build Coastguard Worker             }
4941*38e8c45fSAndroid Build Coastguard Worker 
4942*38e8c45fSAndroid Build Coastguard Worker             const nsecs_t* sampleEventTimes = motionEvent.getSampleEventTimes();
4943*38e8c45fSAndroid Build Coastguard Worker             const size_t pointerCount = motionEvent.getPointerCount();
4944*38e8c45fSAndroid Build Coastguard Worker             const std::vector<PointerProperties>
4945*38e8c45fSAndroid Build Coastguard Worker                     pointerProperties(motionEvent.getPointerProperties(),
4946*38e8c45fSAndroid Build Coastguard Worker                                       motionEvent.getPointerProperties() + pointerCount);
4947*38e8c45fSAndroid Build Coastguard Worker 
4948*38e8c45fSAndroid Build Coastguard Worker             const PointerCoords* samplePointerCoords = motionEvent.getSamplePointerCoords();
4949*38e8c45fSAndroid Build Coastguard Worker             std::unique_ptr<MotionEntry> injectedEntry =
4950*38e8c45fSAndroid Build Coastguard Worker                     std::make_unique<MotionEntry>(motionEvent.getId(), injectionState,
4951*38e8c45fSAndroid Build Coastguard Worker                                                   *sampleEventTimes, resolvedDeviceId,
4952*38e8c45fSAndroid Build Coastguard Worker                                                   motionEvent.getSource(), displayId, policyFlags,
4953*38e8c45fSAndroid Build Coastguard Worker                                                   motionEvent.getAction(),
4954*38e8c45fSAndroid Build Coastguard Worker                                                   motionEvent.getActionButton(), flags,
4955*38e8c45fSAndroid Build Coastguard Worker                                                   motionEvent.getMetaState(),
4956*38e8c45fSAndroid Build Coastguard Worker                                                   motionEvent.getButtonState(),
4957*38e8c45fSAndroid Build Coastguard Worker                                                   motionEvent.getClassification(),
4958*38e8c45fSAndroid Build Coastguard Worker                                                   motionEvent.getEdgeFlags(),
4959*38e8c45fSAndroid Build Coastguard Worker                                                   motionEvent.getXPrecision(),
4960*38e8c45fSAndroid Build Coastguard Worker                                                   motionEvent.getYPrecision(),
4961*38e8c45fSAndroid Build Coastguard Worker                                                   motionEvent.getRawXCursorPosition(),
4962*38e8c45fSAndroid Build Coastguard Worker                                                   motionEvent.getRawYCursorPosition(),
4963*38e8c45fSAndroid Build Coastguard Worker                                                   motionEvent.getDownTime(), pointerProperties,
4964*38e8c45fSAndroid Build Coastguard Worker                                                   std::vector<PointerCoords>(samplePointerCoords,
4965*38e8c45fSAndroid Build Coastguard Worker                                                                              samplePointerCoords +
4966*38e8c45fSAndroid Build Coastguard Worker                                                                                      pointerCount));
4967*38e8c45fSAndroid Build Coastguard Worker             transformMotionEntryForInjectionLocked(*injectedEntry, motionEvent.getTransform());
4968*38e8c45fSAndroid Build Coastguard Worker             if (mTracer) {
4969*38e8c45fSAndroid Build Coastguard Worker                 injectedEntry->traceTracker = mTracer->traceInboundEvent(*injectedEntry);
4970*38e8c45fSAndroid Build Coastguard Worker             }
4971*38e8c45fSAndroid Build Coastguard Worker             injectedEntries.push(std::move(injectedEntry));
4972*38e8c45fSAndroid Build Coastguard Worker             for (size_t i = motionEvent.getHistorySize(); i > 0; i--) {
4973*38e8c45fSAndroid Build Coastguard Worker                 sampleEventTimes += 1;
4974*38e8c45fSAndroid Build Coastguard Worker                 samplePointerCoords += motionEvent.getPointerCount();
4975*38e8c45fSAndroid Build Coastguard Worker                 std::unique_ptr<MotionEntry> nextInjectedEntry = std::make_unique<
4976*38e8c45fSAndroid Build Coastguard Worker                         MotionEntry>(motionEvent.getId(), injectionState, *sampleEventTimes,
4977*38e8c45fSAndroid Build Coastguard Worker                                      resolvedDeviceId, motionEvent.getSource(), displayId,
4978*38e8c45fSAndroid Build Coastguard Worker                                      policyFlags, motionEvent.getAction(),
4979*38e8c45fSAndroid Build Coastguard Worker                                      motionEvent.getActionButton(), flags,
4980*38e8c45fSAndroid Build Coastguard Worker                                      motionEvent.getMetaState(), motionEvent.getButtonState(),
4981*38e8c45fSAndroid Build Coastguard Worker                                      motionEvent.getClassification(), motionEvent.getEdgeFlags(),
4982*38e8c45fSAndroid Build Coastguard Worker                                      motionEvent.getXPrecision(), motionEvent.getYPrecision(),
4983*38e8c45fSAndroid Build Coastguard Worker                                      motionEvent.getRawXCursorPosition(),
4984*38e8c45fSAndroid Build Coastguard Worker                                      motionEvent.getRawYCursorPosition(), motionEvent.getDownTime(),
4985*38e8c45fSAndroid Build Coastguard Worker                                      pointerProperties,
4986*38e8c45fSAndroid Build Coastguard Worker                                      std::vector<PointerCoords>(samplePointerCoords,
4987*38e8c45fSAndroid Build Coastguard Worker                                                                 samplePointerCoords +
4988*38e8c45fSAndroid Build Coastguard Worker                                                                         pointerCount));
4989*38e8c45fSAndroid Build Coastguard Worker                 transformMotionEntryForInjectionLocked(*nextInjectedEntry,
4990*38e8c45fSAndroid Build Coastguard Worker                                                        motionEvent.getTransform());
4991*38e8c45fSAndroid Build Coastguard Worker                 if (mTracer) {
4992*38e8c45fSAndroid Build Coastguard Worker                     nextInjectedEntry->traceTracker =
4993*38e8c45fSAndroid Build Coastguard Worker                             mTracer->traceInboundEvent(*nextInjectedEntry);
4994*38e8c45fSAndroid Build Coastguard Worker                 }
4995*38e8c45fSAndroid Build Coastguard Worker                 injectedEntries.push(std::move(nextInjectedEntry));
4996*38e8c45fSAndroid Build Coastguard Worker             }
4997*38e8c45fSAndroid Build Coastguard Worker             break;
4998*38e8c45fSAndroid Build Coastguard Worker         }
4999*38e8c45fSAndroid Build Coastguard Worker 
5000*38e8c45fSAndroid Build Coastguard Worker         default:
5001*38e8c45fSAndroid Build Coastguard Worker             LOG(WARNING) << "Cannot inject " << ftl::enum_string(event->getType()) << " events";
5002*38e8c45fSAndroid Build Coastguard Worker             return InputEventInjectionResult::FAILED;
5003*38e8c45fSAndroid Build Coastguard Worker     }
5004*38e8c45fSAndroid Build Coastguard Worker 
5005*38e8c45fSAndroid Build Coastguard Worker     bool needWake = false;
5006*38e8c45fSAndroid Build Coastguard Worker     while (!injectedEntries.empty()) {
5007*38e8c45fSAndroid Build Coastguard Worker         if (DEBUG_INJECTION) {
5008*38e8c45fSAndroid Build Coastguard Worker             LOG(INFO) << "Injecting " << injectedEntries.front()->getDescription();
5009*38e8c45fSAndroid Build Coastguard Worker         }
5010*38e8c45fSAndroid Build Coastguard Worker         needWake |= enqueueInboundEventLocked(std::move(injectedEntries.front()));
5011*38e8c45fSAndroid Build Coastguard Worker         injectedEntries.pop();
5012*38e8c45fSAndroid Build Coastguard Worker     }
5013*38e8c45fSAndroid Build Coastguard Worker 
5014*38e8c45fSAndroid Build Coastguard Worker     mLock.unlock();
5015*38e8c45fSAndroid Build Coastguard Worker 
5016*38e8c45fSAndroid Build Coastguard Worker     if (needWake) {
5017*38e8c45fSAndroid Build Coastguard Worker         mLooper->wake();
5018*38e8c45fSAndroid Build Coastguard Worker     }
5019*38e8c45fSAndroid Build Coastguard Worker 
5020*38e8c45fSAndroid Build Coastguard Worker     InputEventInjectionResult injectionResult;
5021*38e8c45fSAndroid Build Coastguard Worker     { // acquire lock
5022*38e8c45fSAndroid Build Coastguard Worker         std::unique_lock _l(mLock);
5023*38e8c45fSAndroid Build Coastguard Worker 
5024*38e8c45fSAndroid Build Coastguard Worker         if (syncMode == InputEventInjectionSync::NONE) {
5025*38e8c45fSAndroid Build Coastguard Worker             injectionResult = InputEventInjectionResult::SUCCEEDED;
5026*38e8c45fSAndroid Build Coastguard Worker         } else {
5027*38e8c45fSAndroid Build Coastguard Worker             for (;;) {
5028*38e8c45fSAndroid Build Coastguard Worker                 injectionResult = injectionState->injectionResult;
5029*38e8c45fSAndroid Build Coastguard Worker                 if (injectionResult != InputEventInjectionResult::PENDING) {
5030*38e8c45fSAndroid Build Coastguard Worker                     break;
5031*38e8c45fSAndroid Build Coastguard Worker                 }
5032*38e8c45fSAndroid Build Coastguard Worker 
5033*38e8c45fSAndroid Build Coastguard Worker                 nsecs_t remainingTimeout = endTime - now();
5034*38e8c45fSAndroid Build Coastguard Worker                 if (remainingTimeout <= 0) {
5035*38e8c45fSAndroid Build Coastguard Worker                     if (DEBUG_INJECTION) {
5036*38e8c45fSAndroid Build Coastguard Worker                         ALOGD("injectInputEvent - Timed out waiting for injection result "
5037*38e8c45fSAndroid Build Coastguard Worker                               "to become available.");
5038*38e8c45fSAndroid Build Coastguard Worker                     }
5039*38e8c45fSAndroid Build Coastguard Worker                     injectionResult = InputEventInjectionResult::TIMED_OUT;
5040*38e8c45fSAndroid Build Coastguard Worker                     break;
5041*38e8c45fSAndroid Build Coastguard Worker                 }
5042*38e8c45fSAndroid Build Coastguard Worker 
5043*38e8c45fSAndroid Build Coastguard Worker                 mInjectionResultAvailable.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
5044*38e8c45fSAndroid Build Coastguard Worker             }
5045*38e8c45fSAndroid Build Coastguard Worker 
5046*38e8c45fSAndroid Build Coastguard Worker             if (injectionResult == InputEventInjectionResult::SUCCEEDED &&
5047*38e8c45fSAndroid Build Coastguard Worker                 syncMode == InputEventInjectionSync::WAIT_FOR_FINISHED) {
5048*38e8c45fSAndroid Build Coastguard Worker                 while (injectionState->pendingForegroundDispatches != 0) {
5049*38e8c45fSAndroid Build Coastguard Worker                     if (DEBUG_INJECTION) {
5050*38e8c45fSAndroid Build Coastguard Worker                         ALOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
5051*38e8c45fSAndroid Build Coastguard Worker                               injectionState->pendingForegroundDispatches);
5052*38e8c45fSAndroid Build Coastguard Worker                     }
5053*38e8c45fSAndroid Build Coastguard Worker                     nsecs_t remainingTimeout = endTime - now();
5054*38e8c45fSAndroid Build Coastguard Worker                     if (remainingTimeout <= 0) {
5055*38e8c45fSAndroid Build Coastguard Worker                         if (DEBUG_INJECTION) {
5056*38e8c45fSAndroid Build Coastguard Worker                             ALOGD("injectInputEvent - Timed out waiting for pending foreground "
5057*38e8c45fSAndroid Build Coastguard Worker                                   "dispatches to finish.");
5058*38e8c45fSAndroid Build Coastguard Worker                         }
5059*38e8c45fSAndroid Build Coastguard Worker                         injectionResult = InputEventInjectionResult::TIMED_OUT;
5060*38e8c45fSAndroid Build Coastguard Worker                         break;
5061*38e8c45fSAndroid Build Coastguard Worker                     }
5062*38e8c45fSAndroid Build Coastguard Worker 
5063*38e8c45fSAndroid Build Coastguard Worker                     mInjectionSyncFinished.wait_for(_l, std::chrono::nanoseconds(remainingTimeout));
5064*38e8c45fSAndroid Build Coastguard Worker                 }
5065*38e8c45fSAndroid Build Coastguard Worker             }
5066*38e8c45fSAndroid Build Coastguard Worker         }
5067*38e8c45fSAndroid Build Coastguard Worker     } // release lock
5068*38e8c45fSAndroid Build Coastguard Worker 
5069*38e8c45fSAndroid Build Coastguard Worker     if (DEBUG_INJECTION) {
5070*38e8c45fSAndroid Build Coastguard Worker         LOG(INFO) << "injectInputEvent - Finished with result "
5071*38e8c45fSAndroid Build Coastguard Worker                   << ftl::enum_string(injectionResult);
5072*38e8c45fSAndroid Build Coastguard Worker     }
5073*38e8c45fSAndroid Build Coastguard Worker 
5074*38e8c45fSAndroid Build Coastguard Worker     return injectionResult;
5075*38e8c45fSAndroid Build Coastguard Worker }
5076*38e8c45fSAndroid Build Coastguard Worker 
verifyInputEvent(const InputEvent & event)5077*38e8c45fSAndroid Build Coastguard Worker std::unique_ptr<VerifiedInputEvent> InputDispatcher::verifyInputEvent(const InputEvent& event) {
5078*38e8c45fSAndroid Build Coastguard Worker     std::array<uint8_t, 32> calculatedHmac;
5079*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<VerifiedInputEvent> result;
5080*38e8c45fSAndroid Build Coastguard Worker     switch (event.getType()) {
5081*38e8c45fSAndroid Build Coastguard Worker         case InputEventType::KEY: {
5082*38e8c45fSAndroid Build Coastguard Worker             const KeyEvent& keyEvent = static_cast<const KeyEvent&>(event);
5083*38e8c45fSAndroid Build Coastguard Worker             VerifiedKeyEvent verifiedKeyEvent = verifiedKeyEventFromKeyEvent(keyEvent);
5084*38e8c45fSAndroid Build Coastguard Worker             result = std::make_unique<VerifiedKeyEvent>(verifiedKeyEvent);
5085*38e8c45fSAndroid Build Coastguard Worker             calculatedHmac = sign(verifiedKeyEvent);
5086*38e8c45fSAndroid Build Coastguard Worker             break;
5087*38e8c45fSAndroid Build Coastguard Worker         }
5088*38e8c45fSAndroid Build Coastguard Worker         case InputEventType::MOTION: {
5089*38e8c45fSAndroid Build Coastguard Worker             const MotionEvent& motionEvent = static_cast<const MotionEvent&>(event);
5090*38e8c45fSAndroid Build Coastguard Worker             VerifiedMotionEvent verifiedMotionEvent =
5091*38e8c45fSAndroid Build Coastguard Worker                     verifiedMotionEventFromMotionEvent(motionEvent);
5092*38e8c45fSAndroid Build Coastguard Worker             result = std::make_unique<VerifiedMotionEvent>(verifiedMotionEvent);
5093*38e8c45fSAndroid Build Coastguard Worker             calculatedHmac = sign(verifiedMotionEvent);
5094*38e8c45fSAndroid Build Coastguard Worker             break;
5095*38e8c45fSAndroid Build Coastguard Worker         }
5096*38e8c45fSAndroid Build Coastguard Worker         default: {
5097*38e8c45fSAndroid Build Coastguard Worker             LOG(ERROR) << "Cannot verify events of type " << ftl::enum_string(event.getType());
5098*38e8c45fSAndroid Build Coastguard Worker             return nullptr;
5099*38e8c45fSAndroid Build Coastguard Worker         }
5100*38e8c45fSAndroid Build Coastguard Worker     }
5101*38e8c45fSAndroid Build Coastguard Worker     if (calculatedHmac == INVALID_HMAC) {
5102*38e8c45fSAndroid Build Coastguard Worker         return nullptr;
5103*38e8c45fSAndroid Build Coastguard Worker     }
5104*38e8c45fSAndroid Build Coastguard Worker     if (0 != CRYPTO_memcmp(calculatedHmac.data(), event.getHmac().data(), calculatedHmac.size())) {
5105*38e8c45fSAndroid Build Coastguard Worker         return nullptr;
5106*38e8c45fSAndroid Build Coastguard Worker     }
5107*38e8c45fSAndroid Build Coastguard Worker     return result;
5108*38e8c45fSAndroid Build Coastguard Worker }
5109*38e8c45fSAndroid Build Coastguard Worker 
setInjectionResult(const EventEntry & entry,InputEventInjectionResult injectionResult)5110*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::setInjectionResult(const EventEntry& entry,
5111*38e8c45fSAndroid Build Coastguard Worker                                          InputEventInjectionResult injectionResult) {
5112*38e8c45fSAndroid Build Coastguard Worker     if (!entry.injectionState) {
5113*38e8c45fSAndroid Build Coastguard Worker         // Not an injected event.
5114*38e8c45fSAndroid Build Coastguard Worker         return;
5115*38e8c45fSAndroid Build Coastguard Worker     }
5116*38e8c45fSAndroid Build Coastguard Worker 
5117*38e8c45fSAndroid Build Coastguard Worker     InjectionState& injectionState = *entry.injectionState;
5118*38e8c45fSAndroid Build Coastguard Worker     if (DEBUG_INJECTION) {
5119*38e8c45fSAndroid Build Coastguard Worker         LOG(INFO) << "Setting input event injection result to "
5120*38e8c45fSAndroid Build Coastguard Worker                   << ftl::enum_string(injectionResult);
5121*38e8c45fSAndroid Build Coastguard Worker     }
5122*38e8c45fSAndroid Build Coastguard Worker 
5123*38e8c45fSAndroid Build Coastguard Worker     if (injectionState.injectionIsAsync && !(entry.policyFlags & POLICY_FLAG_FILTERED)) {
5124*38e8c45fSAndroid Build Coastguard Worker         // Log the outcome since the injector did not wait for the injection result.
5125*38e8c45fSAndroid Build Coastguard Worker         switch (injectionResult) {
5126*38e8c45fSAndroid Build Coastguard Worker             case InputEventInjectionResult::SUCCEEDED:
5127*38e8c45fSAndroid Build Coastguard Worker                 ALOGV("Asynchronous input event injection succeeded.");
5128*38e8c45fSAndroid Build Coastguard Worker                 break;
5129*38e8c45fSAndroid Build Coastguard Worker             case InputEventInjectionResult::TARGET_MISMATCH:
5130*38e8c45fSAndroid Build Coastguard Worker                 ALOGV("Asynchronous input event injection target mismatch.");
5131*38e8c45fSAndroid Build Coastguard Worker                 break;
5132*38e8c45fSAndroid Build Coastguard Worker             case InputEventInjectionResult::FAILED:
5133*38e8c45fSAndroid Build Coastguard Worker                 ALOGW("Asynchronous input event injection failed.");
5134*38e8c45fSAndroid Build Coastguard Worker                 break;
5135*38e8c45fSAndroid Build Coastguard Worker             case InputEventInjectionResult::TIMED_OUT:
5136*38e8c45fSAndroid Build Coastguard Worker                 ALOGW("Asynchronous input event injection timed out.");
5137*38e8c45fSAndroid Build Coastguard Worker                 break;
5138*38e8c45fSAndroid Build Coastguard Worker             case InputEventInjectionResult::PENDING:
5139*38e8c45fSAndroid Build Coastguard Worker                 ALOGE("Setting result to 'PENDING' for asynchronous injection");
5140*38e8c45fSAndroid Build Coastguard Worker                 break;
5141*38e8c45fSAndroid Build Coastguard Worker         }
5142*38e8c45fSAndroid Build Coastguard Worker     }
5143*38e8c45fSAndroid Build Coastguard Worker 
5144*38e8c45fSAndroid Build Coastguard Worker     injectionState.injectionResult = injectionResult;
5145*38e8c45fSAndroid Build Coastguard Worker     mInjectionResultAvailable.notify_all();
5146*38e8c45fSAndroid Build Coastguard Worker }
5147*38e8c45fSAndroid Build Coastguard Worker 
transformMotionEntryForInjectionLocked(MotionEntry & entry,const ui::Transform & injectedTransform) const5148*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::transformMotionEntryForInjectionLocked(
5149*38e8c45fSAndroid Build Coastguard Worker         MotionEntry& entry, const ui::Transform& injectedTransform) const {
5150*38e8c45fSAndroid Build Coastguard Worker     // Input injection works in the logical display coordinate space, but the input pipeline works
5151*38e8c45fSAndroid Build Coastguard Worker     // display space, so we need to transform the injected events accordingly.
5152*38e8c45fSAndroid Build Coastguard Worker     const auto it = mDisplayInfos.find(entry.displayId);
5153*38e8c45fSAndroid Build Coastguard Worker     if (it == mDisplayInfos.end()) return;
5154*38e8c45fSAndroid Build Coastguard Worker     const auto& transformToDisplay = it->second.transform.inverse() * injectedTransform;
5155*38e8c45fSAndroid Build Coastguard Worker 
5156*38e8c45fSAndroid Build Coastguard Worker     if (entry.xCursorPosition != AMOTION_EVENT_INVALID_CURSOR_POSITION &&
5157*38e8c45fSAndroid Build Coastguard Worker         entry.yCursorPosition != AMOTION_EVENT_INVALID_CURSOR_POSITION) {
5158*38e8c45fSAndroid Build Coastguard Worker         const vec2 cursor =
5159*38e8c45fSAndroid Build Coastguard Worker                 MotionEvent::calculateTransformedXY(entry.source, transformToDisplay,
5160*38e8c45fSAndroid Build Coastguard Worker                                                     {entry.xCursorPosition, entry.yCursorPosition});
5161*38e8c45fSAndroid Build Coastguard Worker         entry.xCursorPosition = cursor.x;
5162*38e8c45fSAndroid Build Coastguard Worker         entry.yCursorPosition = cursor.y;
5163*38e8c45fSAndroid Build Coastguard Worker     }
5164*38e8c45fSAndroid Build Coastguard Worker     for (uint32_t i = 0; i < entry.getPointerCount(); i++) {
5165*38e8c45fSAndroid Build Coastguard Worker         entry.pointerCoords[i] =
5166*38e8c45fSAndroid Build Coastguard Worker                 MotionEvent::calculateTransformedCoords(entry.source, entry.flags,
5167*38e8c45fSAndroid Build Coastguard Worker                                                         transformToDisplay, entry.pointerCoords[i]);
5168*38e8c45fSAndroid Build Coastguard Worker     }
5169*38e8c45fSAndroid Build Coastguard Worker }
5170*38e8c45fSAndroid Build Coastguard Worker 
incrementPendingForegroundDispatches(const EventEntry & entry)5171*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::incrementPendingForegroundDispatches(const EventEntry& entry) {
5172*38e8c45fSAndroid Build Coastguard Worker     if (entry.injectionState) {
5173*38e8c45fSAndroid Build Coastguard Worker         entry.injectionState->pendingForegroundDispatches += 1;
5174*38e8c45fSAndroid Build Coastguard Worker     }
5175*38e8c45fSAndroid Build Coastguard Worker }
5176*38e8c45fSAndroid Build Coastguard Worker 
decrementPendingForegroundDispatches(const EventEntry & entry)5177*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::decrementPendingForegroundDispatches(const EventEntry& entry) {
5178*38e8c45fSAndroid Build Coastguard Worker     if (entry.injectionState) {
5179*38e8c45fSAndroid Build Coastguard Worker         entry.injectionState->pendingForegroundDispatches -= 1;
5180*38e8c45fSAndroid Build Coastguard Worker 
5181*38e8c45fSAndroid Build Coastguard Worker         if (entry.injectionState->pendingForegroundDispatches == 0) {
5182*38e8c45fSAndroid Build Coastguard Worker             mInjectionSyncFinished.notify_all();
5183*38e8c45fSAndroid Build Coastguard Worker         }
5184*38e8c45fSAndroid Build Coastguard Worker     }
5185*38e8c45fSAndroid Build Coastguard Worker }
5186*38e8c45fSAndroid Build Coastguard Worker 
getWindowHandlesLocked(ui::LogicalDisplayId displayId) const5187*38e8c45fSAndroid Build Coastguard Worker const std::vector<sp<WindowInfoHandle>>& InputDispatcher::getWindowHandlesLocked(
5188*38e8c45fSAndroid Build Coastguard Worker         ui::LogicalDisplayId displayId) const {
5189*38e8c45fSAndroid Build Coastguard Worker     static const std::vector<sp<WindowInfoHandle>> EMPTY_WINDOW_HANDLES;
5190*38e8c45fSAndroid Build Coastguard Worker     auto it = mWindowHandlesByDisplay.find(displayId);
5191*38e8c45fSAndroid Build Coastguard Worker     return it != mWindowHandlesByDisplay.end() ? it->second : EMPTY_WINDOW_HANDLES;
5192*38e8c45fSAndroid Build Coastguard Worker }
5193*38e8c45fSAndroid Build Coastguard Worker 
getWindowHandleLocked(const sp<IBinder> & windowHandleToken,std::optional<ui::LogicalDisplayId> displayId) const5194*38e8c45fSAndroid Build Coastguard Worker sp<WindowInfoHandle> InputDispatcher::getWindowHandleLocked(
5195*38e8c45fSAndroid Build Coastguard Worker         const sp<IBinder>& windowHandleToken, std::optional<ui::LogicalDisplayId> displayId) const {
5196*38e8c45fSAndroid Build Coastguard Worker     if (windowHandleToken == nullptr) {
5197*38e8c45fSAndroid Build Coastguard Worker         return nullptr;
5198*38e8c45fSAndroid Build Coastguard Worker     }
5199*38e8c45fSAndroid Build Coastguard Worker 
5200*38e8c45fSAndroid Build Coastguard Worker     if (!displayId) {
5201*38e8c45fSAndroid Build Coastguard Worker         // Look through all displays.
5202*38e8c45fSAndroid Build Coastguard Worker         for (const auto& [_, windowHandles] : mWindowHandlesByDisplay) {
5203*38e8c45fSAndroid Build Coastguard Worker             for (const sp<WindowInfoHandle>& windowHandle : windowHandles) {
5204*38e8c45fSAndroid Build Coastguard Worker                 if (windowHandle->getToken() == windowHandleToken) {
5205*38e8c45fSAndroid Build Coastguard Worker                     return windowHandle;
5206*38e8c45fSAndroid Build Coastguard Worker                 }
5207*38e8c45fSAndroid Build Coastguard Worker             }
5208*38e8c45fSAndroid Build Coastguard Worker         }
5209*38e8c45fSAndroid Build Coastguard Worker         return nullptr;
5210*38e8c45fSAndroid Build Coastguard Worker     }
5211*38e8c45fSAndroid Build Coastguard Worker 
5212*38e8c45fSAndroid Build Coastguard Worker     // Only look through the requested display.
5213*38e8c45fSAndroid Build Coastguard Worker     for (const sp<WindowInfoHandle>& windowHandle : getWindowHandlesLocked(*displayId)) {
5214*38e8c45fSAndroid Build Coastguard Worker         if (windowHandle->getToken() == windowHandleToken) {
5215*38e8c45fSAndroid Build Coastguard Worker             return windowHandle;
5216*38e8c45fSAndroid Build Coastguard Worker         }
5217*38e8c45fSAndroid Build Coastguard Worker     }
5218*38e8c45fSAndroid Build Coastguard Worker     return nullptr;
5219*38e8c45fSAndroid Build Coastguard Worker }
5220*38e8c45fSAndroid Build Coastguard Worker 
getWindowHandleLocked(const sp<WindowInfoHandle> & windowHandle) const5221*38e8c45fSAndroid Build Coastguard Worker sp<WindowInfoHandle> InputDispatcher::getWindowHandleLocked(
5222*38e8c45fSAndroid Build Coastguard Worker         const sp<WindowInfoHandle>& windowHandle) const {
5223*38e8c45fSAndroid Build Coastguard Worker     for (const auto& [displayId, windowHandles] : mWindowHandlesByDisplay) {
5224*38e8c45fSAndroid Build Coastguard Worker         for (const sp<WindowInfoHandle>& handle : windowHandles) {
5225*38e8c45fSAndroid Build Coastguard Worker             if (handle->getId() == windowHandle->getId() &&
5226*38e8c45fSAndroid Build Coastguard Worker                 handle->getToken() == windowHandle->getToken()) {
5227*38e8c45fSAndroid Build Coastguard Worker                 if (windowHandle->getInfo()->displayId != displayId) {
5228*38e8c45fSAndroid Build Coastguard Worker                     ALOGE("Found window %s in display %s"
5229*38e8c45fSAndroid Build Coastguard Worker                           ", but it should belong to display %s",
5230*38e8c45fSAndroid Build Coastguard Worker                           windowHandle->getName().c_str(), displayId.toString().c_str(),
5231*38e8c45fSAndroid Build Coastguard Worker                           windowHandle->getInfo()->displayId.toString().c_str());
5232*38e8c45fSAndroid Build Coastguard Worker                 }
5233*38e8c45fSAndroid Build Coastguard Worker                 return handle;
5234*38e8c45fSAndroid Build Coastguard Worker             }
5235*38e8c45fSAndroid Build Coastguard Worker         }
5236*38e8c45fSAndroid Build Coastguard Worker     }
5237*38e8c45fSAndroid Build Coastguard Worker     return nullptr;
5238*38e8c45fSAndroid Build Coastguard Worker }
5239*38e8c45fSAndroid Build Coastguard Worker 
getFocusedWindowHandleLocked(ui::LogicalDisplayId displayId) const5240*38e8c45fSAndroid Build Coastguard Worker sp<WindowInfoHandle> InputDispatcher::getFocusedWindowHandleLocked(
5241*38e8c45fSAndroid Build Coastguard Worker         ui::LogicalDisplayId displayId) const {
5242*38e8c45fSAndroid Build Coastguard Worker     sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(displayId);
5243*38e8c45fSAndroid Build Coastguard Worker     return getWindowHandleLocked(focusedToken, displayId);
5244*38e8c45fSAndroid Build Coastguard Worker }
5245*38e8c45fSAndroid Build Coastguard Worker 
getTransformLocked(ui::LogicalDisplayId displayId) const5246*38e8c45fSAndroid Build Coastguard Worker ui::Transform InputDispatcher::getTransformLocked(ui::LogicalDisplayId displayId) const {
5247*38e8c45fSAndroid Build Coastguard Worker     auto displayInfoIt = mDisplayInfos.find(displayId);
5248*38e8c45fSAndroid Build Coastguard Worker     return displayInfoIt != mDisplayInfos.end() ? displayInfoIt->second.transform
5249*38e8c45fSAndroid Build Coastguard Worker                                                 : kIdentityTransform;
5250*38e8c45fSAndroid Build Coastguard Worker }
5251*38e8c45fSAndroid Build Coastguard Worker 
canWindowReceiveMotionLocked(const sp<WindowInfoHandle> & window,const MotionEntry & motionEntry) const5252*38e8c45fSAndroid Build Coastguard Worker bool InputDispatcher::canWindowReceiveMotionLocked(const sp<WindowInfoHandle>& window,
5253*38e8c45fSAndroid Build Coastguard Worker                                                    const MotionEntry& motionEntry) const {
5254*38e8c45fSAndroid Build Coastguard Worker     const WindowInfo& info = *window->getInfo();
5255*38e8c45fSAndroid Build Coastguard Worker 
5256*38e8c45fSAndroid Build Coastguard Worker     // Skip spy window targets that are not valid for targeted injection.
5257*38e8c45fSAndroid Build Coastguard Worker     if (const auto err = verifyTargetedInjection(window, motionEntry); err) {
5258*38e8c45fSAndroid Build Coastguard Worker         return false;
5259*38e8c45fSAndroid Build Coastguard Worker     }
5260*38e8c45fSAndroid Build Coastguard Worker 
5261*38e8c45fSAndroid Build Coastguard Worker     if (info.inputConfig.test(WindowInfo::InputConfig::PAUSE_DISPATCHING)) {
5262*38e8c45fSAndroid Build Coastguard Worker         ALOGI("Not sending touch event to %s because it is paused", window->getName().c_str());
5263*38e8c45fSAndroid Build Coastguard Worker         return false;
5264*38e8c45fSAndroid Build Coastguard Worker     }
5265*38e8c45fSAndroid Build Coastguard Worker 
5266*38e8c45fSAndroid Build Coastguard Worker     if (info.inputConfig.test(WindowInfo::InputConfig::NO_INPUT_CHANNEL)) {
5267*38e8c45fSAndroid Build Coastguard Worker         ALOGW("Not sending touch gesture to %s because it has config NO_INPUT_CHANNEL",
5268*38e8c45fSAndroid Build Coastguard Worker               window->getName().c_str());
5269*38e8c45fSAndroid Build Coastguard Worker         return false;
5270*38e8c45fSAndroid Build Coastguard Worker     }
5271*38e8c45fSAndroid Build Coastguard Worker 
5272*38e8c45fSAndroid Build Coastguard Worker     std::shared_ptr<Connection> connection = getConnectionLocked(window->getToken());
5273*38e8c45fSAndroid Build Coastguard Worker     if (connection == nullptr) {
5274*38e8c45fSAndroid Build Coastguard Worker         ALOGW("Not sending touch to %s because there's no corresponding connection",
5275*38e8c45fSAndroid Build Coastguard Worker               window->getName().c_str());
5276*38e8c45fSAndroid Build Coastguard Worker         return false;
5277*38e8c45fSAndroid Build Coastguard Worker     }
5278*38e8c45fSAndroid Build Coastguard Worker 
5279*38e8c45fSAndroid Build Coastguard Worker     if (!connection->responsive) {
5280*38e8c45fSAndroid Build Coastguard Worker         ALOGW("Not sending touch to %s because it is not responsive", window->getName().c_str());
5281*38e8c45fSAndroid Build Coastguard Worker         return false;
5282*38e8c45fSAndroid Build Coastguard Worker     }
5283*38e8c45fSAndroid Build Coastguard Worker 
5284*38e8c45fSAndroid Build Coastguard Worker     // Drop events that can't be trusted due to occlusion
5285*38e8c45fSAndroid Build Coastguard Worker     const auto [x, y] = resolveTouchedPosition(motionEntry);
5286*38e8c45fSAndroid Build Coastguard Worker     TouchOcclusionInfo occlusionInfo = computeTouchOcclusionInfoLocked(window, x, y);
5287*38e8c45fSAndroid Build Coastguard Worker     if (!isTouchTrustedLocked(occlusionInfo)) {
5288*38e8c45fSAndroid Build Coastguard Worker         if (DEBUG_TOUCH_OCCLUSION) {
5289*38e8c45fSAndroid Build Coastguard Worker             ALOGD("Stack of obscuring windows during untrusted touch (%.1f, %.1f):", x, y);
5290*38e8c45fSAndroid Build Coastguard Worker             for (const auto& log : occlusionInfo.debugInfo) {
5291*38e8c45fSAndroid Build Coastguard Worker                 ALOGD("%s", log.c_str());
5292*38e8c45fSAndroid Build Coastguard Worker             }
5293*38e8c45fSAndroid Build Coastguard Worker         }
5294*38e8c45fSAndroid Build Coastguard Worker         ALOGW("Dropping untrusted touch event due to %s/%s", occlusionInfo.obscuringPackage.c_str(),
5295*38e8c45fSAndroid Build Coastguard Worker               occlusionInfo.obscuringUid.toString().c_str());
5296*38e8c45fSAndroid Build Coastguard Worker         return false;
5297*38e8c45fSAndroid Build Coastguard Worker     }
5298*38e8c45fSAndroid Build Coastguard Worker 
5299*38e8c45fSAndroid Build Coastguard Worker     // Drop touch events if requested by input feature
5300*38e8c45fSAndroid Build Coastguard Worker     if (shouldDropInput(motionEntry, window)) {
5301*38e8c45fSAndroid Build Coastguard Worker         return false;
5302*38e8c45fSAndroid Build Coastguard Worker     }
5303*38e8c45fSAndroid Build Coastguard Worker 
5304*38e8c45fSAndroid Build Coastguard Worker     // Ignore touches if stylus is down anywhere on screen
5305*38e8c45fSAndroid Build Coastguard Worker     if (info.inputConfig.test(WindowInfo::InputConfig::GLOBAL_STYLUS_BLOCKS_TOUCH) &&
5306*38e8c45fSAndroid Build Coastguard Worker         isStylusActiveInDisplay(info.displayId, mTouchStatesByDisplay)) {
5307*38e8c45fSAndroid Build Coastguard Worker         LOG(INFO) << "Dropping touch from " << window->getName() << " because stylus is active";
5308*38e8c45fSAndroid Build Coastguard Worker         return false;
5309*38e8c45fSAndroid Build Coastguard Worker     }
5310*38e8c45fSAndroid Build Coastguard Worker 
5311*38e8c45fSAndroid Build Coastguard Worker     return true;
5312*38e8c45fSAndroid Build Coastguard Worker }
5313*38e8c45fSAndroid Build Coastguard Worker 
updateWindowHandlesForDisplayLocked(const std::vector<sp<WindowInfoHandle>> & windowInfoHandles,ui::LogicalDisplayId displayId)5314*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::updateWindowHandlesForDisplayLocked(
5315*38e8c45fSAndroid Build Coastguard Worker         const std::vector<sp<WindowInfoHandle>>& windowInfoHandles,
5316*38e8c45fSAndroid Build Coastguard Worker         ui::LogicalDisplayId displayId) {
5317*38e8c45fSAndroid Build Coastguard Worker     if (windowInfoHandles.empty()) {
5318*38e8c45fSAndroid Build Coastguard Worker         // Remove all handles on a display if there are no windows left.
5319*38e8c45fSAndroid Build Coastguard Worker         mWindowHandlesByDisplay.erase(displayId);
5320*38e8c45fSAndroid Build Coastguard Worker         return;
5321*38e8c45fSAndroid Build Coastguard Worker     }
5322*38e8c45fSAndroid Build Coastguard Worker 
5323*38e8c45fSAndroid Build Coastguard Worker     // Since we compare the pointer of input window handles across window updates, we need
5324*38e8c45fSAndroid Build Coastguard Worker     // to make sure the handle object for the same window stays unchanged across updates.
5325*38e8c45fSAndroid Build Coastguard Worker     const std::vector<sp<WindowInfoHandle>>& oldHandles = getWindowHandlesLocked(displayId);
5326*38e8c45fSAndroid Build Coastguard Worker     std::unordered_map<int32_t /*id*/, sp<WindowInfoHandle>> oldHandlesById;
5327*38e8c45fSAndroid Build Coastguard Worker     for (const sp<WindowInfoHandle>& handle : oldHandles) {
5328*38e8c45fSAndroid Build Coastguard Worker         oldHandlesById[handle->getId()] = handle;
5329*38e8c45fSAndroid Build Coastguard Worker     }
5330*38e8c45fSAndroid Build Coastguard Worker 
5331*38e8c45fSAndroid Build Coastguard Worker     std::vector<sp<WindowInfoHandle>> newHandles;
5332*38e8c45fSAndroid Build Coastguard Worker     for (const sp<WindowInfoHandle>& handle : windowInfoHandles) {
5333*38e8c45fSAndroid Build Coastguard Worker         const WindowInfo* info = handle->getInfo();
5334*38e8c45fSAndroid Build Coastguard Worker         if (getConnectionLocked(handle->getToken()) == nullptr) {
5335*38e8c45fSAndroid Build Coastguard Worker             const bool noInputChannel =
5336*38e8c45fSAndroid Build Coastguard Worker                     info->inputConfig.test(WindowInfo::InputConfig::NO_INPUT_CHANNEL);
5337*38e8c45fSAndroid Build Coastguard Worker             const bool canReceiveInput =
5338*38e8c45fSAndroid Build Coastguard Worker                     !info->inputConfig.test(WindowInfo::InputConfig::NOT_TOUCHABLE) ||
5339*38e8c45fSAndroid Build Coastguard Worker                     !info->inputConfig.test(WindowInfo::InputConfig::NOT_FOCUSABLE);
5340*38e8c45fSAndroid Build Coastguard Worker             if (canReceiveInput && !noInputChannel) {
5341*38e8c45fSAndroid Build Coastguard Worker                 ALOGV("Window handle %s has no registered input channel",
5342*38e8c45fSAndroid Build Coastguard Worker                       handle->getName().c_str());
5343*38e8c45fSAndroid Build Coastguard Worker                 continue;
5344*38e8c45fSAndroid Build Coastguard Worker             }
5345*38e8c45fSAndroid Build Coastguard Worker         }
5346*38e8c45fSAndroid Build Coastguard Worker 
5347*38e8c45fSAndroid Build Coastguard Worker         if (info->displayId != displayId) {
5348*38e8c45fSAndroid Build Coastguard Worker             ALOGE("Window %s updated by wrong display %s, should belong to display %s",
5349*38e8c45fSAndroid Build Coastguard Worker                   handle->getName().c_str(), displayId.toString().c_str(),
5350*38e8c45fSAndroid Build Coastguard Worker                   info->displayId.toString().c_str());
5351*38e8c45fSAndroid Build Coastguard Worker             continue;
5352*38e8c45fSAndroid Build Coastguard Worker         }
5353*38e8c45fSAndroid Build Coastguard Worker 
5354*38e8c45fSAndroid Build Coastguard Worker         if ((oldHandlesById.find(handle->getId()) != oldHandlesById.end()) &&
5355*38e8c45fSAndroid Build Coastguard Worker             (oldHandlesById.at(handle->getId())->getToken() == handle->getToken())) {
5356*38e8c45fSAndroid Build Coastguard Worker             const sp<WindowInfoHandle>& oldHandle = oldHandlesById.at(handle->getId());
5357*38e8c45fSAndroid Build Coastguard Worker             oldHandle->updateFrom(handle);
5358*38e8c45fSAndroid Build Coastguard Worker             newHandles.push_back(oldHandle);
5359*38e8c45fSAndroid Build Coastguard Worker         } else {
5360*38e8c45fSAndroid Build Coastguard Worker             newHandles.push_back(handle);
5361*38e8c45fSAndroid Build Coastguard Worker         }
5362*38e8c45fSAndroid Build Coastguard Worker     }
5363*38e8c45fSAndroid Build Coastguard Worker 
5364*38e8c45fSAndroid Build Coastguard Worker     // Insert or replace
5365*38e8c45fSAndroid Build Coastguard Worker     mWindowHandlesByDisplay[displayId] = newHandles;
5366*38e8c45fSAndroid Build Coastguard Worker }
5367*38e8c45fSAndroid Build Coastguard Worker 
5368*38e8c45fSAndroid Build Coastguard Worker /**
5369*38e8c45fSAndroid Build Coastguard Worker  * Called from InputManagerService, update window handle list by displayId that can receive input.
5370*38e8c45fSAndroid Build Coastguard Worker  * A window handle contains information about InputChannel, Touch Region, Types, Focused,...
5371*38e8c45fSAndroid Build Coastguard Worker  * If set an empty list, remove all handles from the specific display.
5372*38e8c45fSAndroid Build Coastguard Worker  * For focused handle, check if need to change and send a cancel event to previous one.
5373*38e8c45fSAndroid Build Coastguard Worker  * For removed handle, check if need to send a cancel event if already in touch.
5374*38e8c45fSAndroid Build Coastguard Worker  */
setInputWindowsLocked(const std::vector<sp<WindowInfoHandle>> & windowInfoHandles,ui::LogicalDisplayId displayId)5375*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::setInputWindowsLocked(
5376*38e8c45fSAndroid Build Coastguard Worker         const std::vector<sp<WindowInfoHandle>>& windowInfoHandles,
5377*38e8c45fSAndroid Build Coastguard Worker         ui::LogicalDisplayId displayId) {
5378*38e8c45fSAndroid Build Coastguard Worker     if (DEBUG_FOCUS) {
5379*38e8c45fSAndroid Build Coastguard Worker         std::string windowList;
5380*38e8c45fSAndroid Build Coastguard Worker         for (const sp<WindowInfoHandle>& iwh : windowInfoHandles) {
5381*38e8c45fSAndroid Build Coastguard Worker             windowList += iwh->getName() + " ";
5382*38e8c45fSAndroid Build Coastguard Worker         }
5383*38e8c45fSAndroid Build Coastguard Worker         LOG(INFO) << "setInputWindows displayId=" << displayId << " " << windowList;
5384*38e8c45fSAndroid Build Coastguard Worker     }
5385*38e8c45fSAndroid Build Coastguard Worker     ScopedSyntheticEventTracer traceContext(mTracer);
5386*38e8c45fSAndroid Build Coastguard Worker 
5387*38e8c45fSAndroid Build Coastguard Worker     // Check preconditions for new input windows
5388*38e8c45fSAndroid Build Coastguard Worker     for (const sp<WindowInfoHandle>& window : windowInfoHandles) {
5389*38e8c45fSAndroid Build Coastguard Worker         const WindowInfo& info = *window->getInfo();
5390*38e8c45fSAndroid Build Coastguard Worker 
5391*38e8c45fSAndroid Build Coastguard Worker         // Ensure all tokens are null if the window has feature NO_INPUT_CHANNEL
5392*38e8c45fSAndroid Build Coastguard Worker         const bool noInputWindow = info.inputConfig.test(WindowInfo::InputConfig::NO_INPUT_CHANNEL);
5393*38e8c45fSAndroid Build Coastguard Worker         if (noInputWindow && window->getToken() != nullptr) {
5394*38e8c45fSAndroid Build Coastguard Worker             ALOGE("%s has feature NO_INPUT_WINDOW, but a non-null token. Clearing",
5395*38e8c45fSAndroid Build Coastguard Worker                   window->getName().c_str());
5396*38e8c45fSAndroid Build Coastguard Worker             window->releaseChannel();
5397*38e8c45fSAndroid Build Coastguard Worker         }
5398*38e8c45fSAndroid Build Coastguard Worker 
5399*38e8c45fSAndroid Build Coastguard Worker         // Ensure all spy windows are trusted overlays
5400*38e8c45fSAndroid Build Coastguard Worker         LOG_ALWAYS_FATAL_IF(info.isSpy() &&
5401*38e8c45fSAndroid Build Coastguard Worker                                     !info.inputConfig.test(
5402*38e8c45fSAndroid Build Coastguard Worker                                             WindowInfo::InputConfig::TRUSTED_OVERLAY),
5403*38e8c45fSAndroid Build Coastguard Worker                             "%s has feature SPY, but is not a trusted overlay.",
5404*38e8c45fSAndroid Build Coastguard Worker                             window->getName().c_str());
5405*38e8c45fSAndroid Build Coastguard Worker 
5406*38e8c45fSAndroid Build Coastguard Worker         // Ensure all stylus interceptors are trusted overlays
5407*38e8c45fSAndroid Build Coastguard Worker         LOG_ALWAYS_FATAL_IF(info.interceptsStylus() &&
5408*38e8c45fSAndroid Build Coastguard Worker                                     !info.inputConfig.test(
5409*38e8c45fSAndroid Build Coastguard Worker                                             WindowInfo::InputConfig::TRUSTED_OVERLAY),
5410*38e8c45fSAndroid Build Coastguard Worker                             "%s has feature INTERCEPTS_STYLUS, but is not a trusted overlay.",
5411*38e8c45fSAndroid Build Coastguard Worker                             window->getName().c_str());
5412*38e8c45fSAndroid Build Coastguard Worker     }
5413*38e8c45fSAndroid Build Coastguard Worker 
5414*38e8c45fSAndroid Build Coastguard Worker     // Copy old handles for release if they are no longer present.
5415*38e8c45fSAndroid Build Coastguard Worker     const std::vector<sp<WindowInfoHandle>> oldWindowHandles = getWindowHandlesLocked(displayId);
5416*38e8c45fSAndroid Build Coastguard Worker     const sp<WindowInfoHandle> removedFocusedWindowHandle = getFocusedWindowHandleLocked(displayId);
5417*38e8c45fSAndroid Build Coastguard Worker 
5418*38e8c45fSAndroid Build Coastguard Worker     updateWindowHandlesForDisplayLocked(windowInfoHandles, displayId);
5419*38e8c45fSAndroid Build Coastguard Worker 
5420*38e8c45fSAndroid Build Coastguard Worker     const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesLocked(displayId);
5421*38e8c45fSAndroid Build Coastguard Worker 
5422*38e8c45fSAndroid Build Coastguard Worker     std::optional<FocusResolver::FocusChanges> changes =
5423*38e8c45fSAndroid Build Coastguard Worker             mFocusResolver.setInputWindows(displayId, windowHandles);
5424*38e8c45fSAndroid Build Coastguard Worker     if (changes) {
5425*38e8c45fSAndroid Build Coastguard Worker         onFocusChangedLocked(*changes, traceContext.getTracker(), removedFocusedWindowHandle);
5426*38e8c45fSAndroid Build Coastguard Worker     }
5427*38e8c45fSAndroid Build Coastguard Worker 
5428*38e8c45fSAndroid Build Coastguard Worker     if (const auto& it = mTouchStatesByDisplay.find(displayId); it != mTouchStatesByDisplay.end()) {
5429*38e8c45fSAndroid Build Coastguard Worker         TouchState& state = it->second;
5430*38e8c45fSAndroid Build Coastguard Worker         for (size_t i = 0; i < state.windows.size();) {
5431*38e8c45fSAndroid Build Coastguard Worker             TouchedWindow& touchedWindow = state.windows[i];
5432*38e8c45fSAndroid Build Coastguard Worker             if (getWindowHandleLocked(touchedWindow.windowHandle) != nullptr) {
5433*38e8c45fSAndroid Build Coastguard Worker                 i++;
5434*38e8c45fSAndroid Build Coastguard Worker                 continue;
5435*38e8c45fSAndroid Build Coastguard Worker             }
5436*38e8c45fSAndroid Build Coastguard Worker             LOG(INFO) << "Touched window was removed: " << touchedWindow.windowHandle->getName()
5437*38e8c45fSAndroid Build Coastguard Worker                       << " in display %" << displayId;
5438*38e8c45fSAndroid Build Coastguard Worker             CancelationOptions options(CancelationOptions::Mode::CANCEL_POINTER_EVENTS,
5439*38e8c45fSAndroid Build Coastguard Worker                                        "touched window was removed", traceContext.getTracker());
5440*38e8c45fSAndroid Build Coastguard Worker             synthesizeCancelationEventsForWindowLocked(touchedWindow.windowHandle, options);
5441*38e8c45fSAndroid Build Coastguard Worker             // Since we are about to drop the touch, cancel the events for the wallpaper as
5442*38e8c45fSAndroid Build Coastguard Worker             // well.
5443*38e8c45fSAndroid Build Coastguard Worker             if (touchedWindow.targetFlags.test(InputTarget::Flags::FOREGROUND) &&
5444*38e8c45fSAndroid Build Coastguard Worker                 touchedWindow.windowHandle->getInfo()->inputConfig.test(
5445*38e8c45fSAndroid Build Coastguard Worker                         gui::WindowInfo::InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER)) {
5446*38e8c45fSAndroid Build Coastguard Worker                 for (const DeviceId deviceId : touchedWindow.getTouchingDeviceIds()) {
5447*38e8c45fSAndroid Build Coastguard Worker                     if (const auto& ww = state.getWallpaperWindow(deviceId); ww != nullptr) {
5448*38e8c45fSAndroid Build Coastguard Worker                         options.deviceId = deviceId;
5449*38e8c45fSAndroid Build Coastguard Worker                         synthesizeCancelationEventsForWindowLocked(ww, options);
5450*38e8c45fSAndroid Build Coastguard Worker                     }
5451*38e8c45fSAndroid Build Coastguard Worker                 }
5452*38e8c45fSAndroid Build Coastguard Worker             }
5453*38e8c45fSAndroid Build Coastguard Worker             state.windows.erase(state.windows.begin() + i);
5454*38e8c45fSAndroid Build Coastguard Worker         }
5455*38e8c45fSAndroid Build Coastguard Worker 
5456*38e8c45fSAndroid Build Coastguard Worker         // If drag window is gone, it would receive a cancel event and broadcast the DRAG_END. We
5457*38e8c45fSAndroid Build Coastguard Worker         // could just clear the state here.
5458*38e8c45fSAndroid Build Coastguard Worker         if (mDragState && mDragState->dragWindow->getInfo()->displayId == displayId &&
5459*38e8c45fSAndroid Build Coastguard Worker             std::find(windowHandles.begin(), windowHandles.end(), mDragState->dragWindow) ==
5460*38e8c45fSAndroid Build Coastguard Worker                     windowHandles.end()) {
5461*38e8c45fSAndroid Build Coastguard Worker             ALOGI("Drag window went away: %s", mDragState->dragWindow->getName().c_str());
5462*38e8c45fSAndroid Build Coastguard Worker             sendDropWindowCommandLocked(nullptr, 0, 0);
5463*38e8c45fSAndroid Build Coastguard Worker             mDragState.reset();
5464*38e8c45fSAndroid Build Coastguard Worker         }
5465*38e8c45fSAndroid Build Coastguard Worker     }
5466*38e8c45fSAndroid Build Coastguard Worker 
5467*38e8c45fSAndroid Build Coastguard Worker     // Check if the hovering should stop because the window is no longer eligible to receive it
5468*38e8c45fSAndroid Build Coastguard Worker     // (for example, if the touchable region changed)
5469*38e8c45fSAndroid Build Coastguard Worker     if (const auto& it = mTouchStatesByDisplay.find(displayId); it != mTouchStatesByDisplay.end()) {
5470*38e8c45fSAndroid Build Coastguard Worker         TouchState& state = it->second;
5471*38e8c45fSAndroid Build Coastguard Worker         for (TouchedWindow& touchedWindow : state.windows) {
5472*38e8c45fSAndroid Build Coastguard Worker             std::vector<DeviceId> erasedDevices = touchedWindow.eraseHoveringPointersIf(
5473*38e8c45fSAndroid Build Coastguard Worker                     [this, displayId, &touchedWindow](const PointerProperties& properties, float x,
5474*38e8c45fSAndroid Build Coastguard Worker                                                       float y) REQUIRES(mLock) {
5475*38e8c45fSAndroid Build Coastguard Worker                         const bool isStylus = properties.toolType == ToolType::STYLUS;
5476*38e8c45fSAndroid Build Coastguard Worker                         const ui::Transform displayTransform = getTransformLocked(displayId);
5477*38e8c45fSAndroid Build Coastguard Worker                         const bool stillAcceptsTouch =
5478*38e8c45fSAndroid Build Coastguard Worker                                 windowAcceptsTouchAt(*touchedWindow.windowHandle->getInfo(),
5479*38e8c45fSAndroid Build Coastguard Worker                                                      displayId, x, y, isStylus, displayTransform);
5480*38e8c45fSAndroid Build Coastguard Worker                         return !stillAcceptsTouch;
5481*38e8c45fSAndroid Build Coastguard Worker                     });
5482*38e8c45fSAndroid Build Coastguard Worker 
5483*38e8c45fSAndroid Build Coastguard Worker             for (DeviceId deviceId : erasedDevices) {
5484*38e8c45fSAndroid Build Coastguard Worker                 CancelationOptions options(CancelationOptions::Mode::CANCEL_HOVER_EVENTS,
5485*38e8c45fSAndroid Build Coastguard Worker                                            "WindowInfo changed",
5486*38e8c45fSAndroid Build Coastguard Worker                                            traceContext.getTracker());
5487*38e8c45fSAndroid Build Coastguard Worker                 options.deviceId = deviceId;
5488*38e8c45fSAndroid Build Coastguard Worker                 synthesizeCancelationEventsForWindowLocked(touchedWindow.windowHandle, options);
5489*38e8c45fSAndroid Build Coastguard Worker             }
5490*38e8c45fSAndroid Build Coastguard Worker         }
5491*38e8c45fSAndroid Build Coastguard Worker     }
5492*38e8c45fSAndroid Build Coastguard Worker 
5493*38e8c45fSAndroid Build Coastguard Worker     // Release information for windows that are no longer present.
5494*38e8c45fSAndroid Build Coastguard Worker     // This ensures that unused input channels are released promptly.
5495*38e8c45fSAndroid Build Coastguard Worker     // Otherwise, they might stick around until the window handle is destroyed
5496*38e8c45fSAndroid Build Coastguard Worker     // which might not happen until the next GC.
5497*38e8c45fSAndroid Build Coastguard Worker     for (const sp<WindowInfoHandle>& oldWindowHandle : oldWindowHandles) {
5498*38e8c45fSAndroid Build Coastguard Worker         if (getWindowHandleLocked(oldWindowHandle) == nullptr) {
5499*38e8c45fSAndroid Build Coastguard Worker             if (DEBUG_FOCUS) {
5500*38e8c45fSAndroid Build Coastguard Worker                 ALOGD("Window went away: %s", oldWindowHandle->getName().c_str());
5501*38e8c45fSAndroid Build Coastguard Worker             }
5502*38e8c45fSAndroid Build Coastguard Worker             oldWindowHandle->releaseChannel();
5503*38e8c45fSAndroid Build Coastguard Worker         }
5504*38e8c45fSAndroid Build Coastguard Worker     }
5505*38e8c45fSAndroid Build Coastguard Worker }
5506*38e8c45fSAndroid Build Coastguard Worker 
setFocusedApplication(ui::LogicalDisplayId displayId,const std::shared_ptr<InputApplicationHandle> & inputApplicationHandle)5507*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::setFocusedApplication(
5508*38e8c45fSAndroid Build Coastguard Worker         ui::LogicalDisplayId displayId,
5509*38e8c45fSAndroid Build Coastguard Worker         const std::shared_ptr<InputApplicationHandle>& inputApplicationHandle) {
5510*38e8c45fSAndroid Build Coastguard Worker     if (DEBUG_FOCUS) {
5511*38e8c45fSAndroid Build Coastguard Worker         ALOGD("setFocusedApplication displayId=%s %s", displayId.toString().c_str(),
5512*38e8c45fSAndroid Build Coastguard Worker               inputApplicationHandle ? inputApplicationHandle->getName().c_str() : "<nullptr>");
5513*38e8c45fSAndroid Build Coastguard Worker     }
5514*38e8c45fSAndroid Build Coastguard Worker     { // acquire lock
5515*38e8c45fSAndroid Build Coastguard Worker         std::scoped_lock _l(mLock);
5516*38e8c45fSAndroid Build Coastguard Worker         setFocusedApplicationLocked(displayId, inputApplicationHandle);
5517*38e8c45fSAndroid Build Coastguard Worker     } // release lock
5518*38e8c45fSAndroid Build Coastguard Worker 
5519*38e8c45fSAndroid Build Coastguard Worker     // Wake up poll loop since it may need to make new input dispatching choices.
5520*38e8c45fSAndroid Build Coastguard Worker     mLooper->wake();
5521*38e8c45fSAndroid Build Coastguard Worker }
5522*38e8c45fSAndroid Build Coastguard Worker 
setFocusedApplicationLocked(ui::LogicalDisplayId displayId,const std::shared_ptr<InputApplicationHandle> & inputApplicationHandle)5523*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::setFocusedApplicationLocked(
5524*38e8c45fSAndroid Build Coastguard Worker         ui::LogicalDisplayId displayId,
5525*38e8c45fSAndroid Build Coastguard Worker         const std::shared_ptr<InputApplicationHandle>& inputApplicationHandle) {
5526*38e8c45fSAndroid Build Coastguard Worker     std::shared_ptr<InputApplicationHandle> oldFocusedApplicationHandle =
5527*38e8c45fSAndroid Build Coastguard Worker             getValueByKey(mFocusedApplicationHandlesByDisplay, displayId);
5528*38e8c45fSAndroid Build Coastguard Worker 
5529*38e8c45fSAndroid Build Coastguard Worker     if (sharedPointersEqual(oldFocusedApplicationHandle, inputApplicationHandle)) {
5530*38e8c45fSAndroid Build Coastguard Worker         return; // This application is already focused. No need to wake up or change anything.
5531*38e8c45fSAndroid Build Coastguard Worker     }
5532*38e8c45fSAndroid Build Coastguard Worker 
5533*38e8c45fSAndroid Build Coastguard Worker     // Set the new application handle.
5534*38e8c45fSAndroid Build Coastguard Worker     if (inputApplicationHandle != nullptr) {
5535*38e8c45fSAndroid Build Coastguard Worker         mFocusedApplicationHandlesByDisplay[displayId] = inputApplicationHandle;
5536*38e8c45fSAndroid Build Coastguard Worker     } else {
5537*38e8c45fSAndroid Build Coastguard Worker         mFocusedApplicationHandlesByDisplay.erase(displayId);
5538*38e8c45fSAndroid Build Coastguard Worker     }
5539*38e8c45fSAndroid Build Coastguard Worker 
5540*38e8c45fSAndroid Build Coastguard Worker     // No matter what the old focused application was, stop waiting on it because it is
5541*38e8c45fSAndroid Build Coastguard Worker     // no longer focused.
5542*38e8c45fSAndroid Build Coastguard Worker     resetNoFocusedWindowTimeoutLocked();
5543*38e8c45fSAndroid Build Coastguard Worker }
5544*38e8c45fSAndroid Build Coastguard Worker 
setMinTimeBetweenUserActivityPokes(std::chrono::milliseconds interval)5545*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::setMinTimeBetweenUserActivityPokes(std::chrono::milliseconds interval) {
5546*38e8c45fSAndroid Build Coastguard Worker     if (interval.count() < 0) {
5547*38e8c45fSAndroid Build Coastguard Worker         LOG_ALWAYS_FATAL("Minimum time between user activity pokes should be >= 0");
5548*38e8c45fSAndroid Build Coastguard Worker     }
5549*38e8c45fSAndroid Build Coastguard Worker     std::scoped_lock _l(mLock);
5550*38e8c45fSAndroid Build Coastguard Worker     mMinTimeBetweenUserActivityPokes = interval;
5551*38e8c45fSAndroid Build Coastguard Worker }
5552*38e8c45fSAndroid Build Coastguard Worker 
5553*38e8c45fSAndroid Build Coastguard Worker /**
5554*38e8c45fSAndroid Build Coastguard Worker  * Sets the focused display, which is responsible for receiving focus-dispatched input events where
5555*38e8c45fSAndroid Build Coastguard Worker  * the display not specified.
5556*38e8c45fSAndroid Build Coastguard Worker  *
5557*38e8c45fSAndroid Build Coastguard Worker  * We track any unreleased events for each window. If a window loses the ability to receive the
5558*38e8c45fSAndroid Build Coastguard Worker  * released event, we will send a cancel event to it. So when the focused display is changed, we
5559*38e8c45fSAndroid Build Coastguard Worker  * cancel all the unreleased display-unspecified events for the focused window on the old focused
5560*38e8c45fSAndroid Build Coastguard Worker  * display. The display-specified events won't be affected.
5561*38e8c45fSAndroid Build Coastguard Worker  */
setFocusedDisplay(ui::LogicalDisplayId displayId)5562*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::setFocusedDisplay(ui::LogicalDisplayId displayId) {
5563*38e8c45fSAndroid Build Coastguard Worker     if (DEBUG_FOCUS) {
5564*38e8c45fSAndroid Build Coastguard Worker         ALOGD("setFocusedDisplay displayId=%s", displayId.toString().c_str());
5565*38e8c45fSAndroid Build Coastguard Worker     }
5566*38e8c45fSAndroid Build Coastguard Worker     { // acquire lock
5567*38e8c45fSAndroid Build Coastguard Worker         std::scoped_lock _l(mLock);
5568*38e8c45fSAndroid Build Coastguard Worker         ScopedSyntheticEventTracer traceContext(mTracer);
5569*38e8c45fSAndroid Build Coastguard Worker 
5570*38e8c45fSAndroid Build Coastguard Worker         if (mFocusedDisplayId != displayId) {
5571*38e8c45fSAndroid Build Coastguard Worker             sp<IBinder> oldFocusedWindowToken =
5572*38e8c45fSAndroid Build Coastguard Worker                     mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
5573*38e8c45fSAndroid Build Coastguard Worker             if (oldFocusedWindowToken != nullptr) {
5574*38e8c45fSAndroid Build Coastguard Worker                 const auto windowHandle =
5575*38e8c45fSAndroid Build Coastguard Worker                         getWindowHandleLocked(oldFocusedWindowToken, mFocusedDisplayId);
5576*38e8c45fSAndroid Build Coastguard Worker                 if (windowHandle == nullptr) {
5577*38e8c45fSAndroid Build Coastguard Worker                     LOG(FATAL) << __func__ << ": Previously focused token did not have a window";
5578*38e8c45fSAndroid Build Coastguard Worker                 }
5579*38e8c45fSAndroid Build Coastguard Worker                 CancelationOptions
5580*38e8c45fSAndroid Build Coastguard Worker                         options(CancelationOptions::Mode::CANCEL_NON_POINTER_EVENTS,
5581*38e8c45fSAndroid Build Coastguard Worker                                 "The display which contains this window no longer has focus.",
5582*38e8c45fSAndroid Build Coastguard Worker                                 traceContext.getTracker());
5583*38e8c45fSAndroid Build Coastguard Worker                 options.displayId = ui::LogicalDisplayId::INVALID;
5584*38e8c45fSAndroid Build Coastguard Worker                 synthesizeCancelationEventsForWindowLocked(windowHandle, options);
5585*38e8c45fSAndroid Build Coastguard Worker             }
5586*38e8c45fSAndroid Build Coastguard Worker             mFocusedDisplayId = displayId;
5587*38e8c45fSAndroid Build Coastguard Worker             // Enqueue a command to run outside the lock to tell the policy that the focused display
5588*38e8c45fSAndroid Build Coastguard Worker             // changed.
5589*38e8c45fSAndroid Build Coastguard Worker             auto command = [this]() REQUIRES(mLock) {
5590*38e8c45fSAndroid Build Coastguard Worker                 scoped_unlock unlock(mLock);
5591*38e8c45fSAndroid Build Coastguard Worker                 mPolicy.notifyFocusedDisplayChanged(mFocusedDisplayId);
5592*38e8c45fSAndroid Build Coastguard Worker             };
5593*38e8c45fSAndroid Build Coastguard Worker             postCommandLocked(std::move(command));
5594*38e8c45fSAndroid Build Coastguard Worker 
5595*38e8c45fSAndroid Build Coastguard Worker             // Only a window on the focused display can have Pointer Capture, so disable the active
5596*38e8c45fSAndroid Build Coastguard Worker             // Pointer Capture session if there is one, since the focused display changed.
5597*38e8c45fSAndroid Build Coastguard Worker             disablePointerCaptureForcedLocked();
5598*38e8c45fSAndroid Build Coastguard Worker 
5599*38e8c45fSAndroid Build Coastguard Worker             // Find new focused window and validate
5600*38e8c45fSAndroid Build Coastguard Worker             sp<IBinder> newFocusedWindowToken = mFocusResolver.getFocusedWindowToken(displayId);
5601*38e8c45fSAndroid Build Coastguard Worker             sendFocusChangedCommandLocked(oldFocusedWindowToken, newFocusedWindowToken);
5602*38e8c45fSAndroid Build Coastguard Worker 
5603*38e8c45fSAndroid Build Coastguard Worker             if (newFocusedWindowToken == nullptr) {
5604*38e8c45fSAndroid Build Coastguard Worker                 ALOGW("Focused display #%s does not have a focused window.",
5605*38e8c45fSAndroid Build Coastguard Worker                       displayId.toString().c_str());
5606*38e8c45fSAndroid Build Coastguard Worker                 if (mFocusResolver.hasFocusedWindowTokens()) {
5607*38e8c45fSAndroid Build Coastguard Worker                     ALOGE("But another display has a focused window\n%s",
5608*38e8c45fSAndroid Build Coastguard Worker                           mFocusResolver.dumpFocusedWindows().c_str());
5609*38e8c45fSAndroid Build Coastguard Worker                 }
5610*38e8c45fSAndroid Build Coastguard Worker             }
5611*38e8c45fSAndroid Build Coastguard Worker         }
5612*38e8c45fSAndroid Build Coastguard Worker     } // release lock
5613*38e8c45fSAndroid Build Coastguard Worker 
5614*38e8c45fSAndroid Build Coastguard Worker     // Wake up poll loop since it may need to make new input dispatching choices.
5615*38e8c45fSAndroid Build Coastguard Worker     mLooper->wake();
5616*38e8c45fSAndroid Build Coastguard Worker }
5617*38e8c45fSAndroid Build Coastguard Worker 
setInputDispatchMode(bool enabled,bool frozen)5618*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
5619*38e8c45fSAndroid Build Coastguard Worker     if (DEBUG_FOCUS) {
5620*38e8c45fSAndroid Build Coastguard Worker         ALOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
5621*38e8c45fSAndroid Build Coastguard Worker     }
5622*38e8c45fSAndroid Build Coastguard Worker 
5623*38e8c45fSAndroid Build Coastguard Worker     bool changed;
5624*38e8c45fSAndroid Build Coastguard Worker     { // acquire lock
5625*38e8c45fSAndroid Build Coastguard Worker         std::scoped_lock _l(mLock);
5626*38e8c45fSAndroid Build Coastguard Worker 
5627*38e8c45fSAndroid Build Coastguard Worker         if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
5628*38e8c45fSAndroid Build Coastguard Worker             if (mDispatchFrozen && !frozen) {
5629*38e8c45fSAndroid Build Coastguard Worker                 resetNoFocusedWindowTimeoutLocked();
5630*38e8c45fSAndroid Build Coastguard Worker             }
5631*38e8c45fSAndroid Build Coastguard Worker 
5632*38e8c45fSAndroid Build Coastguard Worker             if (mDispatchEnabled && !enabled) {
5633*38e8c45fSAndroid Build Coastguard Worker                 resetAndDropEverythingLocked("dispatcher is being disabled");
5634*38e8c45fSAndroid Build Coastguard Worker             }
5635*38e8c45fSAndroid Build Coastguard Worker 
5636*38e8c45fSAndroid Build Coastguard Worker             mDispatchEnabled = enabled;
5637*38e8c45fSAndroid Build Coastguard Worker             mDispatchFrozen = frozen;
5638*38e8c45fSAndroid Build Coastguard Worker             changed = true;
5639*38e8c45fSAndroid Build Coastguard Worker         } else {
5640*38e8c45fSAndroid Build Coastguard Worker             changed = false;
5641*38e8c45fSAndroid Build Coastguard Worker         }
5642*38e8c45fSAndroid Build Coastguard Worker     } // release lock
5643*38e8c45fSAndroid Build Coastguard Worker 
5644*38e8c45fSAndroid Build Coastguard Worker     if (changed) {
5645*38e8c45fSAndroid Build Coastguard Worker         // Wake up poll loop since it may need to make new input dispatching choices.
5646*38e8c45fSAndroid Build Coastguard Worker         mLooper->wake();
5647*38e8c45fSAndroid Build Coastguard Worker     }
5648*38e8c45fSAndroid Build Coastguard Worker }
5649*38e8c45fSAndroid Build Coastguard Worker 
setInputFilterEnabled(bool enabled)5650*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::setInputFilterEnabled(bool enabled) {
5651*38e8c45fSAndroid Build Coastguard Worker     if (DEBUG_FOCUS) {
5652*38e8c45fSAndroid Build Coastguard Worker         ALOGD("setInputFilterEnabled: enabled=%d", enabled);
5653*38e8c45fSAndroid Build Coastguard Worker     }
5654*38e8c45fSAndroid Build Coastguard Worker 
5655*38e8c45fSAndroid Build Coastguard Worker     { // acquire lock
5656*38e8c45fSAndroid Build Coastguard Worker         std::scoped_lock _l(mLock);
5657*38e8c45fSAndroid Build Coastguard Worker 
5658*38e8c45fSAndroid Build Coastguard Worker         if (mInputFilterEnabled == enabled) {
5659*38e8c45fSAndroid Build Coastguard Worker             return;
5660*38e8c45fSAndroid Build Coastguard Worker         }
5661*38e8c45fSAndroid Build Coastguard Worker 
5662*38e8c45fSAndroid Build Coastguard Worker         mInputFilterEnabled = enabled;
5663*38e8c45fSAndroid Build Coastguard Worker         resetAndDropEverythingLocked("input filter is being enabled or disabled");
5664*38e8c45fSAndroid Build Coastguard Worker     } // release lock
5665*38e8c45fSAndroid Build Coastguard Worker 
5666*38e8c45fSAndroid Build Coastguard Worker     // Wake up poll loop since there might be work to do to drop everything.
5667*38e8c45fSAndroid Build Coastguard Worker     mLooper->wake();
5668*38e8c45fSAndroid Build Coastguard Worker }
5669*38e8c45fSAndroid Build Coastguard Worker 
setInTouchMode(bool inTouchMode,gui::Pid pid,gui::Uid uid,bool hasPermission,ui::LogicalDisplayId displayId)5670*38e8c45fSAndroid Build Coastguard Worker bool InputDispatcher::setInTouchMode(bool inTouchMode, gui::Pid pid, gui::Uid uid,
5671*38e8c45fSAndroid Build Coastguard Worker                                      bool hasPermission, ui::LogicalDisplayId displayId) {
5672*38e8c45fSAndroid Build Coastguard Worker     bool needWake = false;
5673*38e8c45fSAndroid Build Coastguard Worker     {
5674*38e8c45fSAndroid Build Coastguard Worker         std::scoped_lock lock(mLock);
5675*38e8c45fSAndroid Build Coastguard Worker         ALOGD_IF(DEBUG_TOUCH_MODE,
5676*38e8c45fSAndroid Build Coastguard Worker                  "Request to change touch mode to %s (calling pid=%s, uid=%s, "
5677*38e8c45fSAndroid Build Coastguard Worker                  "hasPermission=%s, target displayId=%s, mTouchModePerDisplay[displayId]=%s)",
5678*38e8c45fSAndroid Build Coastguard Worker                  toString(inTouchMode), pid.toString().c_str(), uid.toString().c_str(),
5679*38e8c45fSAndroid Build Coastguard Worker                  toString(hasPermission), displayId.toString().c_str(),
5680*38e8c45fSAndroid Build Coastguard Worker                  mTouchModePerDisplay.count(displayId) == 0
5681*38e8c45fSAndroid Build Coastguard Worker                          ? "not set"
5682*38e8c45fSAndroid Build Coastguard Worker                          : std::to_string(mTouchModePerDisplay[displayId]).c_str());
5683*38e8c45fSAndroid Build Coastguard Worker 
5684*38e8c45fSAndroid Build Coastguard Worker         auto touchModeIt = mTouchModePerDisplay.find(displayId);
5685*38e8c45fSAndroid Build Coastguard Worker         if (touchModeIt != mTouchModePerDisplay.end() && touchModeIt->second == inTouchMode) {
5686*38e8c45fSAndroid Build Coastguard Worker             return false;
5687*38e8c45fSAndroid Build Coastguard Worker         }
5688*38e8c45fSAndroid Build Coastguard Worker         if (!hasPermission) {
5689*38e8c45fSAndroid Build Coastguard Worker             if (!focusedWindowIsOwnedByLocked(pid, uid) &&
5690*38e8c45fSAndroid Build Coastguard Worker                 !recentWindowsAreOwnedByLocked(pid, uid)) {
5691*38e8c45fSAndroid Build Coastguard Worker                 ALOGD("Touch mode switch rejected, caller (pid=%s, uid=%s) doesn't own the focused "
5692*38e8c45fSAndroid Build Coastguard Worker                       "window nor none of the previously interacted window",
5693*38e8c45fSAndroid Build Coastguard Worker                       pid.toString().c_str(), uid.toString().c_str());
5694*38e8c45fSAndroid Build Coastguard Worker                 return false;
5695*38e8c45fSAndroid Build Coastguard Worker             }
5696*38e8c45fSAndroid Build Coastguard Worker         }
5697*38e8c45fSAndroid Build Coastguard Worker         mTouchModePerDisplay[displayId] = inTouchMode;
5698*38e8c45fSAndroid Build Coastguard Worker         auto entry = std::make_unique<TouchModeEntry>(mIdGenerator.nextId(), now(), inTouchMode,
5699*38e8c45fSAndroid Build Coastguard Worker                                                       displayId);
5700*38e8c45fSAndroid Build Coastguard Worker         needWake = enqueueInboundEventLocked(std::move(entry));
5701*38e8c45fSAndroid Build Coastguard Worker     } // release lock
5702*38e8c45fSAndroid Build Coastguard Worker 
5703*38e8c45fSAndroid Build Coastguard Worker     if (needWake) {
5704*38e8c45fSAndroid Build Coastguard Worker         mLooper->wake();
5705*38e8c45fSAndroid Build Coastguard Worker     }
5706*38e8c45fSAndroid Build Coastguard Worker     return true;
5707*38e8c45fSAndroid Build Coastguard Worker }
5708*38e8c45fSAndroid Build Coastguard Worker 
focusedWindowIsOwnedByLocked(gui::Pid pid,gui::Uid uid)5709*38e8c45fSAndroid Build Coastguard Worker bool InputDispatcher::focusedWindowIsOwnedByLocked(gui::Pid pid, gui::Uid uid) {
5710*38e8c45fSAndroid Build Coastguard Worker     const sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
5711*38e8c45fSAndroid Build Coastguard Worker     if (focusedToken == nullptr) {
5712*38e8c45fSAndroid Build Coastguard Worker         return false;
5713*38e8c45fSAndroid Build Coastguard Worker     }
5714*38e8c45fSAndroid Build Coastguard Worker     sp<WindowInfoHandle> windowHandle = getWindowHandleLocked(focusedToken);
5715*38e8c45fSAndroid Build Coastguard Worker     return isWindowOwnedBy(windowHandle, pid, uid);
5716*38e8c45fSAndroid Build Coastguard Worker }
5717*38e8c45fSAndroid Build Coastguard Worker 
recentWindowsAreOwnedByLocked(gui::Pid pid,gui::Uid uid)5718*38e8c45fSAndroid Build Coastguard Worker bool InputDispatcher::recentWindowsAreOwnedByLocked(gui::Pid pid, gui::Uid uid) {
5719*38e8c45fSAndroid Build Coastguard Worker     return std::find_if(mInteractionConnectionTokens.begin(), mInteractionConnectionTokens.end(),
5720*38e8c45fSAndroid Build Coastguard Worker                         [&](const sp<IBinder>& connectionToken) REQUIRES(mLock) {
5721*38e8c45fSAndroid Build Coastguard Worker                             const sp<WindowInfoHandle> windowHandle =
5722*38e8c45fSAndroid Build Coastguard Worker                                     getWindowHandleLocked(connectionToken);
5723*38e8c45fSAndroid Build Coastguard Worker                             return isWindowOwnedBy(windowHandle, pid, uid);
5724*38e8c45fSAndroid Build Coastguard Worker                         }) != mInteractionConnectionTokens.end();
5725*38e8c45fSAndroid Build Coastguard Worker }
5726*38e8c45fSAndroid Build Coastguard Worker 
setMaximumObscuringOpacityForTouch(float opacity)5727*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::setMaximumObscuringOpacityForTouch(float opacity) {
5728*38e8c45fSAndroid Build Coastguard Worker     if (opacity < 0 || opacity > 1) {
5729*38e8c45fSAndroid Build Coastguard Worker         LOG_ALWAYS_FATAL("Maximum obscuring opacity for touch should be >= 0 and <= 1");
5730*38e8c45fSAndroid Build Coastguard Worker         return;
5731*38e8c45fSAndroid Build Coastguard Worker     }
5732*38e8c45fSAndroid Build Coastguard Worker 
5733*38e8c45fSAndroid Build Coastguard Worker     std::scoped_lock lock(mLock);
5734*38e8c45fSAndroid Build Coastguard Worker     mMaximumObscuringOpacityForTouch = opacity;
5735*38e8c45fSAndroid Build Coastguard Worker }
5736*38e8c45fSAndroid Build Coastguard Worker 
5737*38e8c45fSAndroid Build Coastguard Worker std::tuple<TouchState*, TouchedWindow*, ui::LogicalDisplayId>
findTouchStateWindowAndDisplayLocked(const sp<IBinder> & token)5738*38e8c45fSAndroid Build Coastguard Worker InputDispatcher::findTouchStateWindowAndDisplayLocked(const sp<IBinder>& token) {
5739*38e8c45fSAndroid Build Coastguard Worker     for (auto& [displayId, state] : mTouchStatesByDisplay) {
5740*38e8c45fSAndroid Build Coastguard Worker         for (TouchedWindow& w : state.windows) {
5741*38e8c45fSAndroid Build Coastguard Worker             if (w.windowHandle->getToken() == token) {
5742*38e8c45fSAndroid Build Coastguard Worker                 return std::make_tuple(&state, &w, displayId);
5743*38e8c45fSAndroid Build Coastguard Worker             }
5744*38e8c45fSAndroid Build Coastguard Worker         }
5745*38e8c45fSAndroid Build Coastguard Worker     }
5746*38e8c45fSAndroid Build Coastguard Worker     return std::make_tuple(nullptr, nullptr, ui::LogicalDisplayId::DEFAULT);
5747*38e8c45fSAndroid Build Coastguard Worker }
5748*38e8c45fSAndroid Build Coastguard Worker 
5749*38e8c45fSAndroid Build Coastguard Worker std::tuple<const TouchState*, const TouchedWindow*, ui::LogicalDisplayId>
findTouchStateWindowAndDisplayLocked(const sp<IBinder> & token) const5750*38e8c45fSAndroid Build Coastguard Worker InputDispatcher::findTouchStateWindowAndDisplayLocked(const sp<IBinder>& token) const {
5751*38e8c45fSAndroid Build Coastguard Worker     return const_cast<InputDispatcher*>(this)->findTouchStateWindowAndDisplayLocked(token);
5752*38e8c45fSAndroid Build Coastguard Worker }
5753*38e8c45fSAndroid Build Coastguard Worker 
windowHasTouchingPointersLocked(const sp<WindowInfoHandle> & windowHandle,DeviceId deviceId) const5754*38e8c45fSAndroid Build Coastguard Worker bool InputDispatcher::windowHasTouchingPointersLocked(const sp<WindowInfoHandle>& windowHandle,
5755*38e8c45fSAndroid Build Coastguard Worker                                                       DeviceId deviceId) const {
5756*38e8c45fSAndroid Build Coastguard Worker     const auto& [touchState, touchedWindow, _] =
5757*38e8c45fSAndroid Build Coastguard Worker             findTouchStateWindowAndDisplayLocked(windowHandle->getToken());
5758*38e8c45fSAndroid Build Coastguard Worker     if (touchState == nullptr) {
5759*38e8c45fSAndroid Build Coastguard Worker         // No touching pointers at all
5760*38e8c45fSAndroid Build Coastguard Worker         return false;
5761*38e8c45fSAndroid Build Coastguard Worker     }
5762*38e8c45fSAndroid Build Coastguard Worker     return touchState->hasTouchingPointers(deviceId);
5763*38e8c45fSAndroid Build Coastguard Worker }
5764*38e8c45fSAndroid Build Coastguard Worker 
transferTouchGesture(const sp<IBinder> & fromToken,const sp<IBinder> & toToken,bool isDragDrop)5765*38e8c45fSAndroid Build Coastguard Worker bool InputDispatcher::transferTouchGesture(const sp<IBinder>& fromToken, const sp<IBinder>& toToken,
5766*38e8c45fSAndroid Build Coastguard Worker                                            bool isDragDrop) {
5767*38e8c45fSAndroid Build Coastguard Worker     if (fromToken == toToken) {
5768*38e8c45fSAndroid Build Coastguard Worker         if (DEBUG_FOCUS) {
5769*38e8c45fSAndroid Build Coastguard Worker             ALOGD("Trivial transfer to same window.");
5770*38e8c45fSAndroid Build Coastguard Worker         }
5771*38e8c45fSAndroid Build Coastguard Worker         return true;
5772*38e8c45fSAndroid Build Coastguard Worker     }
5773*38e8c45fSAndroid Build Coastguard Worker 
5774*38e8c45fSAndroid Build Coastguard Worker     { // acquire lock
5775*38e8c45fSAndroid Build Coastguard Worker         std::scoped_lock _l(mLock);
5776*38e8c45fSAndroid Build Coastguard Worker 
5777*38e8c45fSAndroid Build Coastguard Worker         // Find the target touch state and touched window by fromToken.
5778*38e8c45fSAndroid Build Coastguard Worker         auto [state, touchedWindow, displayId] = findTouchStateWindowAndDisplayLocked(fromToken);
5779*38e8c45fSAndroid Build Coastguard Worker 
5780*38e8c45fSAndroid Build Coastguard Worker         if (state == nullptr || touchedWindow == nullptr) {
5781*38e8c45fSAndroid Build Coastguard Worker             ALOGD("Touch transfer failed because from window is not being touched.");
5782*38e8c45fSAndroid Build Coastguard Worker             return false;
5783*38e8c45fSAndroid Build Coastguard Worker         }
5784*38e8c45fSAndroid Build Coastguard Worker         std::set<DeviceId> deviceIds = touchedWindow->getTouchingDeviceIds();
5785*38e8c45fSAndroid Build Coastguard Worker         if (deviceIds.size() != 1) {
5786*38e8c45fSAndroid Build Coastguard Worker             LOG(INFO) << "Can't transfer touch. Currently touching devices: " << dumpSet(deviceIds)
5787*38e8c45fSAndroid Build Coastguard Worker                       << " for window: " << touchedWindow->dump();
5788*38e8c45fSAndroid Build Coastguard Worker             return false;
5789*38e8c45fSAndroid Build Coastguard Worker         }
5790*38e8c45fSAndroid Build Coastguard Worker         const DeviceId deviceId = *deviceIds.begin();
5791*38e8c45fSAndroid Build Coastguard Worker 
5792*38e8c45fSAndroid Build Coastguard Worker         const sp<WindowInfoHandle> fromWindowHandle = touchedWindow->windowHandle;
5793*38e8c45fSAndroid Build Coastguard Worker         const sp<WindowInfoHandle> toWindowHandle = getWindowHandleLocked(toToken, displayId);
5794*38e8c45fSAndroid Build Coastguard Worker         if (!toWindowHandle) {
5795*38e8c45fSAndroid Build Coastguard Worker             ALOGW("Cannot transfer touch because the transfer target window was not found.");
5796*38e8c45fSAndroid Build Coastguard Worker             return false;
5797*38e8c45fSAndroid Build Coastguard Worker         }
5798*38e8c45fSAndroid Build Coastguard Worker 
5799*38e8c45fSAndroid Build Coastguard Worker         if (DEBUG_FOCUS) {
5800*38e8c45fSAndroid Build Coastguard Worker             ALOGD("%s: fromWindowHandle=%s, toWindowHandle=%s", __func__,
5801*38e8c45fSAndroid Build Coastguard Worker                   touchedWindow->windowHandle->getName().c_str(),
5802*38e8c45fSAndroid Build Coastguard Worker                   toWindowHandle->getName().c_str());
5803*38e8c45fSAndroid Build Coastguard Worker         }
5804*38e8c45fSAndroid Build Coastguard Worker 
5805*38e8c45fSAndroid Build Coastguard Worker         // Erase old window.
5806*38e8c45fSAndroid Build Coastguard Worker         ftl::Flags<InputTarget::Flags> oldTargetFlags = touchedWindow->targetFlags;
5807*38e8c45fSAndroid Build Coastguard Worker         std::vector<PointerProperties> pointers = touchedWindow->getTouchingPointers(deviceId);
5808*38e8c45fSAndroid Build Coastguard Worker         state->removeWindowByToken(fromToken);
5809*38e8c45fSAndroid Build Coastguard Worker 
5810*38e8c45fSAndroid Build Coastguard Worker         // Add new window.
5811*38e8c45fSAndroid Build Coastguard Worker         nsecs_t downTimeInTarget = now();
5812*38e8c45fSAndroid Build Coastguard Worker         ftl::Flags<InputTarget::Flags> newTargetFlags =
5813*38e8c45fSAndroid Build Coastguard Worker                 oldTargetFlags & (InputTarget::Flags::SPLIT);
5814*38e8c45fSAndroid Build Coastguard Worker         if (canReceiveForegroundTouches(*toWindowHandle->getInfo())) {
5815*38e8c45fSAndroid Build Coastguard Worker             newTargetFlags |= InputTarget::Flags::FOREGROUND;
5816*38e8c45fSAndroid Build Coastguard Worker         }
5817*38e8c45fSAndroid Build Coastguard Worker         // Transferring touch focus using this API should not effect the focused window.
5818*38e8c45fSAndroid Build Coastguard Worker         newTargetFlags |= InputTarget::Flags::NO_FOCUS_CHANGE;
5819*38e8c45fSAndroid Build Coastguard Worker         state->addOrUpdateWindow(toWindowHandle, InputTarget::DispatchMode::AS_IS, newTargetFlags,
5820*38e8c45fSAndroid Build Coastguard Worker                                  deviceId, pointers, downTimeInTarget);
5821*38e8c45fSAndroid Build Coastguard Worker 
5822*38e8c45fSAndroid Build Coastguard Worker         // Store the dragging window.
5823*38e8c45fSAndroid Build Coastguard Worker         if (isDragDrop) {
5824*38e8c45fSAndroid Build Coastguard Worker             if (pointers.size() != 1) {
5825*38e8c45fSAndroid Build Coastguard Worker                 ALOGW("The drag and drop cannot be started when there is no pointer or more than 1"
5826*38e8c45fSAndroid Build Coastguard Worker                       " pointer on the window.");
5827*38e8c45fSAndroid Build Coastguard Worker                 return false;
5828*38e8c45fSAndroid Build Coastguard Worker             }
5829*38e8c45fSAndroid Build Coastguard Worker             // Track the pointer id for drag window and generate the drag state.
5830*38e8c45fSAndroid Build Coastguard Worker             const size_t id = pointers.begin()->id;
5831*38e8c45fSAndroid Build Coastguard Worker             mDragState = std::make_unique<DragState>(toWindowHandle, deviceId, id);
5832*38e8c45fSAndroid Build Coastguard Worker         }
5833*38e8c45fSAndroid Build Coastguard Worker 
5834*38e8c45fSAndroid Build Coastguard Worker         // Synthesize cancel for old window and down for new window.
5835*38e8c45fSAndroid Build Coastguard Worker         ScopedSyntheticEventTracer traceContext(mTracer);
5836*38e8c45fSAndroid Build Coastguard Worker         std::shared_ptr<Connection> fromConnection = getConnectionLocked(fromToken);
5837*38e8c45fSAndroid Build Coastguard Worker         std::shared_ptr<Connection> toConnection = getConnectionLocked(toToken);
5838*38e8c45fSAndroid Build Coastguard Worker         if (fromConnection != nullptr && toConnection != nullptr) {
5839*38e8c45fSAndroid Build Coastguard Worker             fromConnection->inputState.mergePointerStateTo(toConnection->inputState);
5840*38e8c45fSAndroid Build Coastguard Worker             CancelationOptions options(CancelationOptions::Mode::CANCEL_POINTER_EVENTS,
5841*38e8c45fSAndroid Build Coastguard Worker                                        "transferring touch from this window to another window",
5842*38e8c45fSAndroid Build Coastguard Worker                                        traceContext.getTracker());
5843*38e8c45fSAndroid Build Coastguard Worker             synthesizeCancelationEventsForWindowLocked(fromWindowHandle, options, fromConnection);
5844*38e8c45fSAndroid Build Coastguard Worker 
5845*38e8c45fSAndroid Build Coastguard Worker             // Check if the wallpaper window should deliver the corresponding event.
5846*38e8c45fSAndroid Build Coastguard Worker             transferWallpaperTouch(oldTargetFlags, newTargetFlags, fromWindowHandle, toWindowHandle,
5847*38e8c45fSAndroid Build Coastguard Worker                                    *state, deviceId, pointers, traceContext.getTracker());
5848*38e8c45fSAndroid Build Coastguard Worker 
5849*38e8c45fSAndroid Build Coastguard Worker             // Because new window may have a wallpaper window, it will merge input state from it
5850*38e8c45fSAndroid Build Coastguard Worker             // parent window, after this the firstNewPointerIdx in input state will be reset, then
5851*38e8c45fSAndroid Build Coastguard Worker             // it will cause new move event be thought inconsistent, so we should synthesize the
5852*38e8c45fSAndroid Build Coastguard Worker             // down event after it reset.
5853*38e8c45fSAndroid Build Coastguard Worker             synthesizePointerDownEventsForConnectionLocked(downTimeInTarget, toConnection,
5854*38e8c45fSAndroid Build Coastguard Worker                                                            newTargetFlags,
5855*38e8c45fSAndroid Build Coastguard Worker                                                            traceContext.getTracker());
5856*38e8c45fSAndroid Build Coastguard Worker         }
5857*38e8c45fSAndroid Build Coastguard Worker     } // release lock
5858*38e8c45fSAndroid Build Coastguard Worker 
5859*38e8c45fSAndroid Build Coastguard Worker     // Wake up poll loop since it may need to make new input dispatching choices.
5860*38e8c45fSAndroid Build Coastguard Worker     mLooper->wake();
5861*38e8c45fSAndroid Build Coastguard Worker     return true;
5862*38e8c45fSAndroid Build Coastguard Worker }
5863*38e8c45fSAndroid Build Coastguard Worker 
5864*38e8c45fSAndroid Build Coastguard Worker /**
5865*38e8c45fSAndroid Build Coastguard Worker  * Get the touched foreground window on the given display.
5866*38e8c45fSAndroid Build Coastguard Worker  * Return null if there are no windows touched on that display, or if more than one foreground
5867*38e8c45fSAndroid Build Coastguard Worker  * window is being touched.
5868*38e8c45fSAndroid Build Coastguard Worker  */
findTouchedForegroundWindowLocked(ui::LogicalDisplayId displayId) const5869*38e8c45fSAndroid Build Coastguard Worker sp<WindowInfoHandle> InputDispatcher::findTouchedForegroundWindowLocked(
5870*38e8c45fSAndroid Build Coastguard Worker         ui::LogicalDisplayId displayId) const {
5871*38e8c45fSAndroid Build Coastguard Worker     auto stateIt = mTouchStatesByDisplay.find(displayId);
5872*38e8c45fSAndroid Build Coastguard Worker     if (stateIt == mTouchStatesByDisplay.end()) {
5873*38e8c45fSAndroid Build Coastguard Worker         ALOGI("No touch state on display %s", displayId.toString().c_str());
5874*38e8c45fSAndroid Build Coastguard Worker         return nullptr;
5875*38e8c45fSAndroid Build Coastguard Worker     }
5876*38e8c45fSAndroid Build Coastguard Worker 
5877*38e8c45fSAndroid Build Coastguard Worker     const TouchState& state = stateIt->second;
5878*38e8c45fSAndroid Build Coastguard Worker     sp<WindowInfoHandle> touchedForegroundWindow;
5879*38e8c45fSAndroid Build Coastguard Worker     // If multiple foreground windows are touched, return nullptr
5880*38e8c45fSAndroid Build Coastguard Worker     for (const TouchedWindow& window : state.windows) {
5881*38e8c45fSAndroid Build Coastguard Worker         if (window.targetFlags.test(InputTarget::Flags::FOREGROUND)) {
5882*38e8c45fSAndroid Build Coastguard Worker             if (touchedForegroundWindow != nullptr) {
5883*38e8c45fSAndroid Build Coastguard Worker                 ALOGI("Two or more foreground windows: %s and %s",
5884*38e8c45fSAndroid Build Coastguard Worker                       touchedForegroundWindow->getName().c_str(),
5885*38e8c45fSAndroid Build Coastguard Worker                       window.windowHandle->getName().c_str());
5886*38e8c45fSAndroid Build Coastguard Worker                 return nullptr;
5887*38e8c45fSAndroid Build Coastguard Worker             }
5888*38e8c45fSAndroid Build Coastguard Worker             touchedForegroundWindow = window.windowHandle;
5889*38e8c45fSAndroid Build Coastguard Worker         }
5890*38e8c45fSAndroid Build Coastguard Worker     }
5891*38e8c45fSAndroid Build Coastguard Worker     return touchedForegroundWindow;
5892*38e8c45fSAndroid Build Coastguard Worker }
5893*38e8c45fSAndroid Build Coastguard Worker 
5894*38e8c45fSAndroid Build Coastguard Worker // Binder call
transferTouchOnDisplay(const sp<IBinder> & destChannelToken,ui::LogicalDisplayId displayId)5895*38e8c45fSAndroid Build Coastguard Worker bool InputDispatcher::transferTouchOnDisplay(const sp<IBinder>& destChannelToken,
5896*38e8c45fSAndroid Build Coastguard Worker                                              ui::LogicalDisplayId displayId) {
5897*38e8c45fSAndroid Build Coastguard Worker     sp<IBinder> fromToken;
5898*38e8c45fSAndroid Build Coastguard Worker     { // acquire lock
5899*38e8c45fSAndroid Build Coastguard Worker         std::scoped_lock _l(mLock);
5900*38e8c45fSAndroid Build Coastguard Worker         sp<WindowInfoHandle> toWindowHandle = getWindowHandleLocked(destChannelToken, displayId);
5901*38e8c45fSAndroid Build Coastguard Worker         if (toWindowHandle == nullptr) {
5902*38e8c45fSAndroid Build Coastguard Worker             ALOGW("Could not find window associated with token=%p on display %s",
5903*38e8c45fSAndroid Build Coastguard Worker                   destChannelToken.get(), displayId.toString().c_str());
5904*38e8c45fSAndroid Build Coastguard Worker             return false;
5905*38e8c45fSAndroid Build Coastguard Worker         }
5906*38e8c45fSAndroid Build Coastguard Worker 
5907*38e8c45fSAndroid Build Coastguard Worker         sp<WindowInfoHandle> from = findTouchedForegroundWindowLocked(displayId);
5908*38e8c45fSAndroid Build Coastguard Worker         if (from == nullptr) {
5909*38e8c45fSAndroid Build Coastguard Worker             ALOGE("Could not find a source window in %s for %p", __func__, destChannelToken.get());
5910*38e8c45fSAndroid Build Coastguard Worker             return false;
5911*38e8c45fSAndroid Build Coastguard Worker         }
5912*38e8c45fSAndroid Build Coastguard Worker 
5913*38e8c45fSAndroid Build Coastguard Worker         fromToken = from->getToken();
5914*38e8c45fSAndroid Build Coastguard Worker     } // release lock
5915*38e8c45fSAndroid Build Coastguard Worker 
5916*38e8c45fSAndroid Build Coastguard Worker     return transferTouchGesture(fromToken, destChannelToken);
5917*38e8c45fSAndroid Build Coastguard Worker }
5918*38e8c45fSAndroid Build Coastguard Worker 
resetAndDropEverythingLocked(const char * reason)5919*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::resetAndDropEverythingLocked(const char* reason) {
5920*38e8c45fSAndroid Build Coastguard Worker     if (DEBUG_FOCUS) {
5921*38e8c45fSAndroid Build Coastguard Worker         ALOGD("Resetting and dropping all events (%s).", reason);
5922*38e8c45fSAndroid Build Coastguard Worker     }
5923*38e8c45fSAndroid Build Coastguard Worker 
5924*38e8c45fSAndroid Build Coastguard Worker     ScopedSyntheticEventTracer traceContext(mTracer);
5925*38e8c45fSAndroid Build Coastguard Worker     CancelationOptions options(CancelationOptions::Mode::CANCEL_ALL_EVENTS, reason,
5926*38e8c45fSAndroid Build Coastguard Worker                                traceContext.getTracker());
5927*38e8c45fSAndroid Build Coastguard Worker     synthesizeCancelationEventsForAllConnectionsLocked(options);
5928*38e8c45fSAndroid Build Coastguard Worker 
5929*38e8c45fSAndroid Build Coastguard Worker     resetKeyRepeatLocked();
5930*38e8c45fSAndroid Build Coastguard Worker     releasePendingEventLocked();
5931*38e8c45fSAndroid Build Coastguard Worker     drainInboundQueueLocked();
5932*38e8c45fSAndroid Build Coastguard Worker     resetNoFocusedWindowTimeoutLocked();
5933*38e8c45fSAndroid Build Coastguard Worker 
5934*38e8c45fSAndroid Build Coastguard Worker     mAnrTracker.clear();
5935*38e8c45fSAndroid Build Coastguard Worker     mTouchStatesByDisplay.clear();
5936*38e8c45fSAndroid Build Coastguard Worker }
5937*38e8c45fSAndroid Build Coastguard Worker 
logDispatchStateLocked() const5938*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::logDispatchStateLocked() const {
5939*38e8c45fSAndroid Build Coastguard Worker     std::string dump;
5940*38e8c45fSAndroid Build Coastguard Worker     dumpDispatchStateLocked(dump);
5941*38e8c45fSAndroid Build Coastguard Worker 
5942*38e8c45fSAndroid Build Coastguard Worker     std::istringstream stream(dump);
5943*38e8c45fSAndroid Build Coastguard Worker     std::string line;
5944*38e8c45fSAndroid Build Coastguard Worker 
5945*38e8c45fSAndroid Build Coastguard Worker     while (std::getline(stream, line, '\n')) {
5946*38e8c45fSAndroid Build Coastguard Worker         ALOGI("%s", line.c_str());
5947*38e8c45fSAndroid Build Coastguard Worker     }
5948*38e8c45fSAndroid Build Coastguard Worker }
5949*38e8c45fSAndroid Build Coastguard Worker 
dumpPointerCaptureStateLocked() const5950*38e8c45fSAndroid Build Coastguard Worker std::string InputDispatcher::dumpPointerCaptureStateLocked() const {
5951*38e8c45fSAndroid Build Coastguard Worker     std::string dump;
5952*38e8c45fSAndroid Build Coastguard Worker 
5953*38e8c45fSAndroid Build Coastguard Worker     dump += StringPrintf(INDENT "Pointer Capture Requested: %s\n",
5954*38e8c45fSAndroid Build Coastguard Worker                          toString(mCurrentPointerCaptureRequest.isEnable()));
5955*38e8c45fSAndroid Build Coastguard Worker 
5956*38e8c45fSAndroid Build Coastguard Worker     std::string windowName = "None";
5957*38e8c45fSAndroid Build Coastguard Worker     if (mWindowTokenWithPointerCapture) {
5958*38e8c45fSAndroid Build Coastguard Worker         const sp<WindowInfoHandle> captureWindowHandle =
5959*38e8c45fSAndroid Build Coastguard Worker                 getWindowHandleLocked(mWindowTokenWithPointerCapture);
5960*38e8c45fSAndroid Build Coastguard Worker         windowName = captureWindowHandle ? captureWindowHandle->getName().c_str()
5961*38e8c45fSAndroid Build Coastguard Worker                                          : "token has capture without window";
5962*38e8c45fSAndroid Build Coastguard Worker     }
5963*38e8c45fSAndroid Build Coastguard Worker     dump += StringPrintf(INDENT "Current Window with Pointer Capture: %s\n", windowName.c_str());
5964*38e8c45fSAndroid Build Coastguard Worker 
5965*38e8c45fSAndroid Build Coastguard Worker     return dump;
5966*38e8c45fSAndroid Build Coastguard Worker }
5967*38e8c45fSAndroid Build Coastguard Worker 
dumpDispatchStateLocked(std::string & dump) const5968*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::dumpDispatchStateLocked(std::string& dump) const {
5969*38e8c45fSAndroid Build Coastguard Worker     dump += StringPrintf(INDENT "DispatchEnabled: %s\n", toString(mDispatchEnabled));
5970*38e8c45fSAndroid Build Coastguard Worker     dump += StringPrintf(INDENT "DispatchFrozen: %s\n", toString(mDispatchFrozen));
5971*38e8c45fSAndroid Build Coastguard Worker     dump += StringPrintf(INDENT "InputFilterEnabled: %s\n", toString(mInputFilterEnabled));
5972*38e8c45fSAndroid Build Coastguard Worker     dump += StringPrintf(INDENT "FocusedDisplayId: %s\n", mFocusedDisplayId.toString().c_str());
5973*38e8c45fSAndroid Build Coastguard Worker 
5974*38e8c45fSAndroid Build Coastguard Worker     if (!mFocusedApplicationHandlesByDisplay.empty()) {
5975*38e8c45fSAndroid Build Coastguard Worker         dump += StringPrintf(INDENT "FocusedApplications:\n");
5976*38e8c45fSAndroid Build Coastguard Worker         for (auto& it : mFocusedApplicationHandlesByDisplay) {
5977*38e8c45fSAndroid Build Coastguard Worker             const ui::LogicalDisplayId displayId = it.first;
5978*38e8c45fSAndroid Build Coastguard Worker             const std::shared_ptr<InputApplicationHandle>& applicationHandle = it.second;
5979*38e8c45fSAndroid Build Coastguard Worker             const std::chrono::duration timeout =
5980*38e8c45fSAndroid Build Coastguard Worker                     applicationHandle->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
5981*38e8c45fSAndroid Build Coastguard Worker             dump += StringPrintf(INDENT2 "displayId=%s, name='%s', dispatchingTimeout=%" PRId64
5982*38e8c45fSAndroid Build Coastguard Worker                                          "ms\n",
5983*38e8c45fSAndroid Build Coastguard Worker                                  displayId.toString().c_str(), applicationHandle->getName().c_str(),
5984*38e8c45fSAndroid Build Coastguard Worker                                  millis(timeout));
5985*38e8c45fSAndroid Build Coastguard Worker         }
5986*38e8c45fSAndroid Build Coastguard Worker     } else {
5987*38e8c45fSAndroid Build Coastguard Worker         dump += StringPrintf(INDENT "FocusedApplications: <none>\n");
5988*38e8c45fSAndroid Build Coastguard Worker     }
5989*38e8c45fSAndroid Build Coastguard Worker 
5990*38e8c45fSAndroid Build Coastguard Worker     dump += mFocusResolver.dump();
5991*38e8c45fSAndroid Build Coastguard Worker     dump += dumpPointerCaptureStateLocked();
5992*38e8c45fSAndroid Build Coastguard Worker 
5993*38e8c45fSAndroid Build Coastguard Worker     if (!mTouchStatesByDisplay.empty()) {
5994*38e8c45fSAndroid Build Coastguard Worker         dump += StringPrintf(INDENT "TouchStatesByDisplay:\n");
5995*38e8c45fSAndroid Build Coastguard Worker         for (const auto& [displayId, state] : mTouchStatesByDisplay) {
5996*38e8c45fSAndroid Build Coastguard Worker             std::string touchStateDump = addLinePrefix(state.dump(), INDENT2);
5997*38e8c45fSAndroid Build Coastguard Worker             dump += INDENT2 + displayId.toString() + " : " + touchStateDump;
5998*38e8c45fSAndroid Build Coastguard Worker         }
5999*38e8c45fSAndroid Build Coastguard Worker     } else {
6000*38e8c45fSAndroid Build Coastguard Worker         dump += INDENT "TouchStates: <no displays touched>\n";
6001*38e8c45fSAndroid Build Coastguard Worker     }
6002*38e8c45fSAndroid Build Coastguard Worker 
6003*38e8c45fSAndroid Build Coastguard Worker     if (mDragState) {
6004*38e8c45fSAndroid Build Coastguard Worker         dump += StringPrintf(INDENT "DragState:\n");
6005*38e8c45fSAndroid Build Coastguard Worker         mDragState->dump(dump, INDENT2);
6006*38e8c45fSAndroid Build Coastguard Worker     }
6007*38e8c45fSAndroid Build Coastguard Worker 
6008*38e8c45fSAndroid Build Coastguard Worker     if (!mWindowHandlesByDisplay.empty()) {
6009*38e8c45fSAndroid Build Coastguard Worker         for (const auto& [displayId, windowHandles] : mWindowHandlesByDisplay) {
6010*38e8c45fSAndroid Build Coastguard Worker             dump += StringPrintf(INDENT "Display: %s\n", displayId.toString().c_str());
6011*38e8c45fSAndroid Build Coastguard Worker             if (const auto& it = mDisplayInfos.find(displayId); it != mDisplayInfos.end()) {
6012*38e8c45fSAndroid Build Coastguard Worker                 const auto& displayInfo = it->second;
6013*38e8c45fSAndroid Build Coastguard Worker                 dump += StringPrintf(INDENT2 "logicalSize=%dx%d\n", displayInfo.logicalWidth,
6014*38e8c45fSAndroid Build Coastguard Worker                                      displayInfo.logicalHeight);
6015*38e8c45fSAndroid Build Coastguard Worker                 displayInfo.transform.dump(dump, "transform", INDENT4);
6016*38e8c45fSAndroid Build Coastguard Worker             } else {
6017*38e8c45fSAndroid Build Coastguard Worker                 dump += INDENT2 "No DisplayInfo found!\n";
6018*38e8c45fSAndroid Build Coastguard Worker             }
6019*38e8c45fSAndroid Build Coastguard Worker 
6020*38e8c45fSAndroid Build Coastguard Worker             if (!windowHandles.empty()) {
6021*38e8c45fSAndroid Build Coastguard Worker                 dump += INDENT2 "Windows:\n";
6022*38e8c45fSAndroid Build Coastguard Worker                 for (size_t i = 0; i < windowHandles.size(); i++) {
6023*38e8c45fSAndroid Build Coastguard Worker                     dump += StringPrintf(INDENT3 "%zu: %s", i,
6024*38e8c45fSAndroid Build Coastguard Worker                                          streamableToString(*windowHandles[i]).c_str());
6025*38e8c45fSAndroid Build Coastguard Worker                 }
6026*38e8c45fSAndroid Build Coastguard Worker             } else {
6027*38e8c45fSAndroid Build Coastguard Worker                 dump += INDENT2 "Windows: <none>\n";
6028*38e8c45fSAndroid Build Coastguard Worker             }
6029*38e8c45fSAndroid Build Coastguard Worker         }
6030*38e8c45fSAndroid Build Coastguard Worker     } else {
6031*38e8c45fSAndroid Build Coastguard Worker         dump += INDENT "Displays: <none>\n";
6032*38e8c45fSAndroid Build Coastguard Worker     }
6033*38e8c45fSAndroid Build Coastguard Worker 
6034*38e8c45fSAndroid Build Coastguard Worker     if (!mGlobalMonitorsByDisplay.empty()) {
6035*38e8c45fSAndroid Build Coastguard Worker         for (const auto& [displayId, monitors] : mGlobalMonitorsByDisplay) {
6036*38e8c45fSAndroid Build Coastguard Worker             dump += StringPrintf(INDENT "Global monitors on display %s:\n",
6037*38e8c45fSAndroid Build Coastguard Worker                                  displayId.toString().c_str());
6038*38e8c45fSAndroid Build Coastguard Worker             dumpMonitors(dump, monitors);
6039*38e8c45fSAndroid Build Coastguard Worker         }
6040*38e8c45fSAndroid Build Coastguard Worker     } else {
6041*38e8c45fSAndroid Build Coastguard Worker         dump += INDENT "Global Monitors: <none>\n";
6042*38e8c45fSAndroid Build Coastguard Worker     }
6043*38e8c45fSAndroid Build Coastguard Worker 
6044*38e8c45fSAndroid Build Coastguard Worker     const nsecs_t currentTime = now();
6045*38e8c45fSAndroid Build Coastguard Worker 
6046*38e8c45fSAndroid Build Coastguard Worker     // Dump recently dispatched or dropped events from oldest to newest.
6047*38e8c45fSAndroid Build Coastguard Worker     if (!mRecentQueue.empty()) {
6048*38e8c45fSAndroid Build Coastguard Worker         dump += StringPrintf(INDENT "RecentQueue: length=%zu\n", mRecentQueue.size());
6049*38e8c45fSAndroid Build Coastguard Worker         for (const std::shared_ptr<const EventEntry>& entry : mRecentQueue) {
6050*38e8c45fSAndroid Build Coastguard Worker             dump += INDENT2;
6051*38e8c45fSAndroid Build Coastguard Worker             dump += entry->getDescription();
6052*38e8c45fSAndroid Build Coastguard Worker             dump += StringPrintf(", age=%" PRId64 "ms\n", ns2ms(currentTime - entry->eventTime));
6053*38e8c45fSAndroid Build Coastguard Worker         }
6054*38e8c45fSAndroid Build Coastguard Worker     } else {
6055*38e8c45fSAndroid Build Coastguard Worker         dump += INDENT "RecentQueue: <empty>\n";
6056*38e8c45fSAndroid Build Coastguard Worker     }
6057*38e8c45fSAndroid Build Coastguard Worker 
6058*38e8c45fSAndroid Build Coastguard Worker     // Dump event currently being dispatched.
6059*38e8c45fSAndroid Build Coastguard Worker     if (mPendingEvent) {
6060*38e8c45fSAndroid Build Coastguard Worker         dump += INDENT "PendingEvent:\n";
6061*38e8c45fSAndroid Build Coastguard Worker         dump += INDENT2;
6062*38e8c45fSAndroid Build Coastguard Worker         dump += mPendingEvent->getDescription();
6063*38e8c45fSAndroid Build Coastguard Worker         dump += StringPrintf(", age=%" PRId64 "ms\n",
6064*38e8c45fSAndroid Build Coastguard Worker                              ns2ms(currentTime - mPendingEvent->eventTime));
6065*38e8c45fSAndroid Build Coastguard Worker     } else {
6066*38e8c45fSAndroid Build Coastguard Worker         dump += INDENT "PendingEvent: <none>\n";
6067*38e8c45fSAndroid Build Coastguard Worker     }
6068*38e8c45fSAndroid Build Coastguard Worker 
6069*38e8c45fSAndroid Build Coastguard Worker     // Dump inbound events from oldest to newest.
6070*38e8c45fSAndroid Build Coastguard Worker     if (!mInboundQueue.empty()) {
6071*38e8c45fSAndroid Build Coastguard Worker         dump += StringPrintf(INDENT "InboundQueue: length=%zu\n", mInboundQueue.size());
6072*38e8c45fSAndroid Build Coastguard Worker         for (const std::shared_ptr<const EventEntry>& entry : mInboundQueue) {
6073*38e8c45fSAndroid Build Coastguard Worker             dump += INDENT2;
6074*38e8c45fSAndroid Build Coastguard Worker             dump += entry->getDescription();
6075*38e8c45fSAndroid Build Coastguard Worker             dump += StringPrintf(", age=%" PRId64 "ms\n", ns2ms(currentTime - entry->eventTime));
6076*38e8c45fSAndroid Build Coastguard Worker         }
6077*38e8c45fSAndroid Build Coastguard Worker     } else {
6078*38e8c45fSAndroid Build Coastguard Worker         dump += INDENT "InboundQueue: <empty>\n";
6079*38e8c45fSAndroid Build Coastguard Worker     }
6080*38e8c45fSAndroid Build Coastguard Worker 
6081*38e8c45fSAndroid Build Coastguard Worker     if (!mCommandQueue.empty()) {
6082*38e8c45fSAndroid Build Coastguard Worker         dump += StringPrintf(INDENT "CommandQueue: size=%zu\n", mCommandQueue.size());
6083*38e8c45fSAndroid Build Coastguard Worker     } else {
6084*38e8c45fSAndroid Build Coastguard Worker         dump += INDENT "CommandQueue: <empty>\n";
6085*38e8c45fSAndroid Build Coastguard Worker     }
6086*38e8c45fSAndroid Build Coastguard Worker 
6087*38e8c45fSAndroid Build Coastguard Worker     if (!mConnectionsByToken.empty()) {
6088*38e8c45fSAndroid Build Coastguard Worker         dump += INDENT "Connections:\n";
6089*38e8c45fSAndroid Build Coastguard Worker         for (const auto& [token, connection] : mConnectionsByToken) {
6090*38e8c45fSAndroid Build Coastguard Worker             dump += StringPrintf(INDENT2 "%i: channelName='%s', "
6091*38e8c45fSAndroid Build Coastguard Worker                                          "status=%s, monitor=%s, responsive=%s\n",
6092*38e8c45fSAndroid Build Coastguard Worker                                  connection->inputPublisher.getChannel().getFd(),
6093*38e8c45fSAndroid Build Coastguard Worker                                  connection->getInputChannelName().c_str(),
6094*38e8c45fSAndroid Build Coastguard Worker                                  ftl::enum_string(connection->status).c_str(),
6095*38e8c45fSAndroid Build Coastguard Worker                                  toString(connection->monitor), toString(connection->responsive));
6096*38e8c45fSAndroid Build Coastguard Worker 
6097*38e8c45fSAndroid Build Coastguard Worker             if (!connection->outboundQueue.empty()) {
6098*38e8c45fSAndroid Build Coastguard Worker                 dump += StringPrintf(INDENT3 "OutboundQueue: length=%zu\n",
6099*38e8c45fSAndroid Build Coastguard Worker                                      connection->outboundQueue.size());
6100*38e8c45fSAndroid Build Coastguard Worker                 dump += dumpQueue(connection->outboundQueue, currentTime);
6101*38e8c45fSAndroid Build Coastguard Worker             }
6102*38e8c45fSAndroid Build Coastguard Worker 
6103*38e8c45fSAndroid Build Coastguard Worker             if (!connection->waitQueue.empty()) {
6104*38e8c45fSAndroid Build Coastguard Worker                 dump += StringPrintf(INDENT3 "WaitQueue: length=%zu\n",
6105*38e8c45fSAndroid Build Coastguard Worker                                      connection->waitQueue.size());
6106*38e8c45fSAndroid Build Coastguard Worker                 dump += dumpQueue(connection->waitQueue, currentTime);
6107*38e8c45fSAndroid Build Coastguard Worker             }
6108*38e8c45fSAndroid Build Coastguard Worker             std::string inputStateDump = streamableToString(connection->inputState);
6109*38e8c45fSAndroid Build Coastguard Worker             if (!inputStateDump.empty()) {
6110*38e8c45fSAndroid Build Coastguard Worker                 dump += INDENT3 "InputState: ";
6111*38e8c45fSAndroid Build Coastguard Worker                 dump += inputStateDump + "\n";
6112*38e8c45fSAndroid Build Coastguard Worker             }
6113*38e8c45fSAndroid Build Coastguard Worker         }
6114*38e8c45fSAndroid Build Coastguard Worker     } else {
6115*38e8c45fSAndroid Build Coastguard Worker         dump += INDENT "Connections: <none>\n";
6116*38e8c45fSAndroid Build Coastguard Worker     }
6117*38e8c45fSAndroid Build Coastguard Worker 
6118*38e8c45fSAndroid Build Coastguard Worker     if (!mTouchModePerDisplay.empty()) {
6119*38e8c45fSAndroid Build Coastguard Worker         dump += INDENT "TouchModePerDisplay:\n";
6120*38e8c45fSAndroid Build Coastguard Worker         for (const auto& [displayId, touchMode] : mTouchModePerDisplay) {
6121*38e8c45fSAndroid Build Coastguard Worker             dump += StringPrintf(INDENT2 "Display: %s TouchMode: %s\n",
6122*38e8c45fSAndroid Build Coastguard Worker                                  displayId.toString().c_str(), std::to_string(touchMode).c_str());
6123*38e8c45fSAndroid Build Coastguard Worker         }
6124*38e8c45fSAndroid Build Coastguard Worker     } else {
6125*38e8c45fSAndroid Build Coastguard Worker         dump += INDENT "TouchModePerDisplay: <none>\n";
6126*38e8c45fSAndroid Build Coastguard Worker     }
6127*38e8c45fSAndroid Build Coastguard Worker 
6128*38e8c45fSAndroid Build Coastguard Worker     dump += INDENT "Configuration:\n";
6129*38e8c45fSAndroid Build Coastguard Worker     dump += StringPrintf(INDENT2 "KeyRepeatDelay: %" PRId64 "ms\n", ns2ms(mConfig.keyRepeatDelay));
6130*38e8c45fSAndroid Build Coastguard Worker     dump += StringPrintf(INDENT2 "KeyRepeatTimeout: %" PRId64 "ms\n",
6131*38e8c45fSAndroid Build Coastguard Worker                          ns2ms(mConfig.keyRepeatTimeout));
6132*38e8c45fSAndroid Build Coastguard Worker     dump += mLatencyTracker.dump(INDENT2);
6133*38e8c45fSAndroid Build Coastguard Worker     dump += mInputEventTimelineProcessor->dump(INDENT2);
6134*38e8c45fSAndroid Build Coastguard Worker     dump += INDENT "InputTracer: ";
6135*38e8c45fSAndroid Build Coastguard Worker     dump += mTracer == nullptr ? "Disabled" : "Enabled";
6136*38e8c45fSAndroid Build Coastguard Worker }
6137*38e8c45fSAndroid Build Coastguard Worker 
dumpMonitors(std::string & dump,const std::vector<Monitor> & monitors) const6138*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::dumpMonitors(std::string& dump, const std::vector<Monitor>& monitors) const {
6139*38e8c45fSAndroid Build Coastguard Worker     const size_t numMonitors = monitors.size();
6140*38e8c45fSAndroid Build Coastguard Worker     for (size_t i = 0; i < numMonitors; i++) {
6141*38e8c45fSAndroid Build Coastguard Worker         const Monitor& monitor = monitors[i];
6142*38e8c45fSAndroid Build Coastguard Worker         const std::shared_ptr<Connection>& connection = monitor.connection;
6143*38e8c45fSAndroid Build Coastguard Worker         dump += StringPrintf(INDENT2 "%zu: '%s', ", i, connection->getInputChannelName().c_str());
6144*38e8c45fSAndroid Build Coastguard Worker         dump += "\n";
6145*38e8c45fSAndroid Build Coastguard Worker     }
6146*38e8c45fSAndroid Build Coastguard Worker }
6147*38e8c45fSAndroid Build Coastguard Worker 
6148*38e8c45fSAndroid Build Coastguard Worker class LooperEventCallback : public LooperCallback {
6149*38e8c45fSAndroid Build Coastguard Worker public:
LooperEventCallback(std::function<int (int events)> callback)6150*38e8c45fSAndroid Build Coastguard Worker     LooperEventCallback(std::function<int(int events)> callback) : mCallback(callback) {}
handleEvent(int,int events,void *)6151*38e8c45fSAndroid Build Coastguard Worker     int handleEvent(int /*fd*/, int events, void* /*data*/) override { return mCallback(events); }
6152*38e8c45fSAndroid Build Coastguard Worker 
6153*38e8c45fSAndroid Build Coastguard Worker private:
6154*38e8c45fSAndroid Build Coastguard Worker     std::function<int(int events)> mCallback;
6155*38e8c45fSAndroid Build Coastguard Worker };
6156*38e8c45fSAndroid Build Coastguard Worker 
createInputChannel(const std::string & name)6157*38e8c45fSAndroid Build Coastguard Worker Result<std::unique_ptr<InputChannel>> InputDispatcher::createInputChannel(const std::string& name) {
6158*38e8c45fSAndroid Build Coastguard Worker     if (DEBUG_CHANNEL_CREATION) {
6159*38e8c45fSAndroid Build Coastguard Worker         ALOGD("channel '%s' ~ createInputChannel", name.c_str());
6160*38e8c45fSAndroid Build Coastguard Worker     }
6161*38e8c45fSAndroid Build Coastguard Worker 
6162*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<InputChannel> serverChannel;
6163*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<InputChannel> clientChannel;
6164*38e8c45fSAndroid Build Coastguard Worker     status_t result = InputChannel::openInputChannelPair(name, serverChannel, clientChannel);
6165*38e8c45fSAndroid Build Coastguard Worker 
6166*38e8c45fSAndroid Build Coastguard Worker     if (result) {
6167*38e8c45fSAndroid Build Coastguard Worker         return base::Error(result) << "Failed to open input channel pair with name " << name;
6168*38e8c45fSAndroid Build Coastguard Worker     }
6169*38e8c45fSAndroid Build Coastguard Worker 
6170*38e8c45fSAndroid Build Coastguard Worker     { // acquire lock
6171*38e8c45fSAndroid Build Coastguard Worker         std::scoped_lock _l(mLock);
6172*38e8c45fSAndroid Build Coastguard Worker         const sp<IBinder>& token = serverChannel->getConnectionToken();
6173*38e8c45fSAndroid Build Coastguard Worker         const int fd = serverChannel->getFd();
6174*38e8c45fSAndroid Build Coastguard Worker         std::shared_ptr<Connection> connection =
6175*38e8c45fSAndroid Build Coastguard Worker                 std::make_shared<Connection>(std::move(serverChannel), /*monitor=*/false,
6176*38e8c45fSAndroid Build Coastguard Worker                                              mIdGenerator);
6177*38e8c45fSAndroid Build Coastguard Worker 
6178*38e8c45fSAndroid Build Coastguard Worker         auto [_, inserted] = mConnectionsByToken.try_emplace(token, connection);
6179*38e8c45fSAndroid Build Coastguard Worker         if (!inserted) {
6180*38e8c45fSAndroid Build Coastguard Worker             ALOGE("Created a new connection, but the token %p is already known", token.get());
6181*38e8c45fSAndroid Build Coastguard Worker         }
6182*38e8c45fSAndroid Build Coastguard Worker 
6183*38e8c45fSAndroid Build Coastguard Worker         std::function<int(int events)> callback = std::bind(&InputDispatcher::handleReceiveCallback,
6184*38e8c45fSAndroid Build Coastguard Worker                                                             this, std::placeholders::_1, token);
6185*38e8c45fSAndroid Build Coastguard Worker 
6186*38e8c45fSAndroid Build Coastguard Worker         mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, sp<LooperEventCallback>::make(callback),
6187*38e8c45fSAndroid Build Coastguard Worker                        nullptr);
6188*38e8c45fSAndroid Build Coastguard Worker     } // release lock
6189*38e8c45fSAndroid Build Coastguard Worker 
6190*38e8c45fSAndroid Build Coastguard Worker     // Wake the looper because some connections have changed.
6191*38e8c45fSAndroid Build Coastguard Worker     mLooper->wake();
6192*38e8c45fSAndroid Build Coastguard Worker     return clientChannel;
6193*38e8c45fSAndroid Build Coastguard Worker }
6194*38e8c45fSAndroid Build Coastguard Worker 
createInputMonitor(ui::LogicalDisplayId displayId,const std::string & name,gui::Pid pid)6195*38e8c45fSAndroid Build Coastguard Worker Result<std::unique_ptr<InputChannel>> InputDispatcher::createInputMonitor(
6196*38e8c45fSAndroid Build Coastguard Worker         ui::LogicalDisplayId displayId, const std::string& name, gui::Pid pid) {
6197*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<InputChannel> serverChannel;
6198*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<InputChannel> clientChannel;
6199*38e8c45fSAndroid Build Coastguard Worker     status_t result = InputChannel::openInputChannelPair(name, serverChannel, clientChannel);
6200*38e8c45fSAndroid Build Coastguard Worker     if (result) {
6201*38e8c45fSAndroid Build Coastguard Worker         return base::Error(result) << "Failed to open input channel pair with name " << name;
6202*38e8c45fSAndroid Build Coastguard Worker     }
6203*38e8c45fSAndroid Build Coastguard Worker 
6204*38e8c45fSAndroid Build Coastguard Worker     { // acquire lock
6205*38e8c45fSAndroid Build Coastguard Worker         std::scoped_lock _l(mLock);
6206*38e8c45fSAndroid Build Coastguard Worker 
6207*38e8c45fSAndroid Build Coastguard Worker         if (displayId < ui::LogicalDisplayId::DEFAULT) {
6208*38e8c45fSAndroid Build Coastguard Worker             return base::Error(BAD_VALUE) << "Attempted to create input monitor with name " << name
6209*38e8c45fSAndroid Build Coastguard Worker                                           << " without a specified display.";
6210*38e8c45fSAndroid Build Coastguard Worker         }
6211*38e8c45fSAndroid Build Coastguard Worker 
6212*38e8c45fSAndroid Build Coastguard Worker         const sp<IBinder>& token = serverChannel->getConnectionToken();
6213*38e8c45fSAndroid Build Coastguard Worker         const int fd = serverChannel->getFd();
6214*38e8c45fSAndroid Build Coastguard Worker         std::shared_ptr<Connection> connection =
6215*38e8c45fSAndroid Build Coastguard Worker                 std::make_shared<Connection>(std::move(serverChannel), /*monitor=*/true,
6216*38e8c45fSAndroid Build Coastguard Worker                                              mIdGenerator);
6217*38e8c45fSAndroid Build Coastguard Worker 
6218*38e8c45fSAndroid Build Coastguard Worker         auto [_, inserted] = mConnectionsByToken.emplace(token, connection);
6219*38e8c45fSAndroid Build Coastguard Worker         if (!inserted) {
6220*38e8c45fSAndroid Build Coastguard Worker             ALOGE("Created a new connection, but the token %p is already known", token.get());
6221*38e8c45fSAndroid Build Coastguard Worker         }
6222*38e8c45fSAndroid Build Coastguard Worker 
6223*38e8c45fSAndroid Build Coastguard Worker         std::function<int(int events)> callback = std::bind(&InputDispatcher::handleReceiveCallback,
6224*38e8c45fSAndroid Build Coastguard Worker                                                             this, std::placeholders::_1, token);
6225*38e8c45fSAndroid Build Coastguard Worker 
6226*38e8c45fSAndroid Build Coastguard Worker         mGlobalMonitorsByDisplay[displayId].emplace_back(connection, pid);
6227*38e8c45fSAndroid Build Coastguard Worker 
6228*38e8c45fSAndroid Build Coastguard Worker         mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, sp<LooperEventCallback>::make(callback),
6229*38e8c45fSAndroid Build Coastguard Worker                        nullptr);
6230*38e8c45fSAndroid Build Coastguard Worker     }
6231*38e8c45fSAndroid Build Coastguard Worker 
6232*38e8c45fSAndroid Build Coastguard Worker     // Wake the looper because some connections have changed.
6233*38e8c45fSAndroid Build Coastguard Worker     mLooper->wake();
6234*38e8c45fSAndroid Build Coastguard Worker     return clientChannel;
6235*38e8c45fSAndroid Build Coastguard Worker }
6236*38e8c45fSAndroid Build Coastguard Worker 
removeInputChannel(const sp<IBinder> & connectionToken)6237*38e8c45fSAndroid Build Coastguard Worker status_t InputDispatcher::removeInputChannel(const sp<IBinder>& connectionToken) {
6238*38e8c45fSAndroid Build Coastguard Worker     { // acquire lock
6239*38e8c45fSAndroid Build Coastguard Worker         std::scoped_lock _l(mLock);
6240*38e8c45fSAndroid Build Coastguard Worker 
6241*38e8c45fSAndroid Build Coastguard Worker         status_t status = removeInputChannelLocked(connectionToken, /*notify=*/false);
6242*38e8c45fSAndroid Build Coastguard Worker         if (status) {
6243*38e8c45fSAndroid Build Coastguard Worker             return status;
6244*38e8c45fSAndroid Build Coastguard Worker         }
6245*38e8c45fSAndroid Build Coastguard Worker     } // release lock
6246*38e8c45fSAndroid Build Coastguard Worker 
6247*38e8c45fSAndroid Build Coastguard Worker     // Wake the poll loop because removing the connection may have changed the current
6248*38e8c45fSAndroid Build Coastguard Worker     // synchronization state.
6249*38e8c45fSAndroid Build Coastguard Worker     mLooper->wake();
6250*38e8c45fSAndroid Build Coastguard Worker     return OK;
6251*38e8c45fSAndroid Build Coastguard Worker }
6252*38e8c45fSAndroid Build Coastguard Worker 
removeInputChannelLocked(const sp<IBinder> & connectionToken,bool notify)6253*38e8c45fSAndroid Build Coastguard Worker status_t InputDispatcher::removeInputChannelLocked(const sp<IBinder>& connectionToken,
6254*38e8c45fSAndroid Build Coastguard Worker                                                    bool notify) {
6255*38e8c45fSAndroid Build Coastguard Worker     std::shared_ptr<Connection> connection = getConnectionLocked(connectionToken);
6256*38e8c45fSAndroid Build Coastguard Worker     if (connection == nullptr) {
6257*38e8c45fSAndroid Build Coastguard Worker         // Connection can be removed via socket hang up or an explicit call to 'removeInputChannel'
6258*38e8c45fSAndroid Build Coastguard Worker         return BAD_VALUE;
6259*38e8c45fSAndroid Build Coastguard Worker     }
6260*38e8c45fSAndroid Build Coastguard Worker 
6261*38e8c45fSAndroid Build Coastguard Worker     removeConnectionLocked(connection);
6262*38e8c45fSAndroid Build Coastguard Worker 
6263*38e8c45fSAndroid Build Coastguard Worker     if (connection->monitor) {
6264*38e8c45fSAndroid Build Coastguard Worker         removeMonitorChannelLocked(connectionToken);
6265*38e8c45fSAndroid Build Coastguard Worker     }
6266*38e8c45fSAndroid Build Coastguard Worker 
6267*38e8c45fSAndroid Build Coastguard Worker     mLooper->removeFd(connection->inputPublisher.getChannel().getFd());
6268*38e8c45fSAndroid Build Coastguard Worker 
6269*38e8c45fSAndroid Build Coastguard Worker     nsecs_t currentTime = now();
6270*38e8c45fSAndroid Build Coastguard Worker     abortBrokenDispatchCycleLocked(currentTime, connection, notify);
6271*38e8c45fSAndroid Build Coastguard Worker 
6272*38e8c45fSAndroid Build Coastguard Worker     connection->status = Connection::Status::ZOMBIE;
6273*38e8c45fSAndroid Build Coastguard Worker     return OK;
6274*38e8c45fSAndroid Build Coastguard Worker }
6275*38e8c45fSAndroid Build Coastguard Worker 
removeMonitorChannelLocked(const sp<IBinder> & connectionToken)6276*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::removeMonitorChannelLocked(const sp<IBinder>& connectionToken) {
6277*38e8c45fSAndroid Build Coastguard Worker     for (auto it = mGlobalMonitorsByDisplay.begin(); it != mGlobalMonitorsByDisplay.end();) {
6278*38e8c45fSAndroid Build Coastguard Worker         auto& [displayId, monitors] = *it;
6279*38e8c45fSAndroid Build Coastguard Worker         std::erase_if(monitors, [connectionToken](const Monitor& monitor) {
6280*38e8c45fSAndroid Build Coastguard Worker             return monitor.connection->getToken() == connectionToken;
6281*38e8c45fSAndroid Build Coastguard Worker         });
6282*38e8c45fSAndroid Build Coastguard Worker 
6283*38e8c45fSAndroid Build Coastguard Worker         if (monitors.empty()) {
6284*38e8c45fSAndroid Build Coastguard Worker             it = mGlobalMonitorsByDisplay.erase(it);
6285*38e8c45fSAndroid Build Coastguard Worker         } else {
6286*38e8c45fSAndroid Build Coastguard Worker             ++it;
6287*38e8c45fSAndroid Build Coastguard Worker         }
6288*38e8c45fSAndroid Build Coastguard Worker     }
6289*38e8c45fSAndroid Build Coastguard Worker }
6290*38e8c45fSAndroid Build Coastguard Worker 
pilferPointers(const sp<IBinder> & token)6291*38e8c45fSAndroid Build Coastguard Worker status_t InputDispatcher::pilferPointers(const sp<IBinder>& token) {
6292*38e8c45fSAndroid Build Coastguard Worker     std::scoped_lock _l(mLock);
6293*38e8c45fSAndroid Build Coastguard Worker     return pilferPointersLocked(token);
6294*38e8c45fSAndroid Build Coastguard Worker }
6295*38e8c45fSAndroid Build Coastguard Worker 
pilferPointersLocked(const sp<IBinder> & token)6296*38e8c45fSAndroid Build Coastguard Worker status_t InputDispatcher::pilferPointersLocked(const sp<IBinder>& token) {
6297*38e8c45fSAndroid Build Coastguard Worker     const std::shared_ptr<Connection> requestingConnection = getConnectionLocked(token);
6298*38e8c45fSAndroid Build Coastguard Worker     if (!requestingConnection) {
6299*38e8c45fSAndroid Build Coastguard Worker         LOG(WARNING)
6300*38e8c45fSAndroid Build Coastguard Worker                 << "Attempted to pilfer pointers from an un-registered channel or invalid token";
6301*38e8c45fSAndroid Build Coastguard Worker         return BAD_VALUE;
6302*38e8c45fSAndroid Build Coastguard Worker     }
6303*38e8c45fSAndroid Build Coastguard Worker 
6304*38e8c45fSAndroid Build Coastguard Worker     auto [statePtr, windowPtr, displayId] = findTouchStateWindowAndDisplayLocked(token);
6305*38e8c45fSAndroid Build Coastguard Worker     if (statePtr == nullptr || windowPtr == nullptr) {
6306*38e8c45fSAndroid Build Coastguard Worker         LOG(WARNING)
6307*38e8c45fSAndroid Build Coastguard Worker                 << "Attempted to pilfer points from a channel without any on-going pointer streams."
6308*38e8c45fSAndroid Build Coastguard Worker                    " Ignoring.";
6309*38e8c45fSAndroid Build Coastguard Worker         return BAD_VALUE;
6310*38e8c45fSAndroid Build Coastguard Worker     }
6311*38e8c45fSAndroid Build Coastguard Worker     std::set<int32_t> deviceIds = windowPtr->getTouchingDeviceIds();
6312*38e8c45fSAndroid Build Coastguard Worker     if (deviceIds.empty()) {
6313*38e8c45fSAndroid Build Coastguard Worker         LOG(WARNING) << "Can't pilfer: no touching devices in window: " << windowPtr->dump();
6314*38e8c45fSAndroid Build Coastguard Worker         return BAD_VALUE;
6315*38e8c45fSAndroid Build Coastguard Worker     }
6316*38e8c45fSAndroid Build Coastguard Worker 
6317*38e8c45fSAndroid Build Coastguard Worker     ScopedSyntheticEventTracer traceContext(mTracer);
6318*38e8c45fSAndroid Build Coastguard Worker     for (const DeviceId deviceId : deviceIds) {
6319*38e8c45fSAndroid Build Coastguard Worker         TouchState& state = *statePtr;
6320*38e8c45fSAndroid Build Coastguard Worker         TouchedWindow& window = *windowPtr;
6321*38e8c45fSAndroid Build Coastguard Worker         // Send cancel events to all the input channels we're stealing from.
6322*38e8c45fSAndroid Build Coastguard Worker         CancelationOptions options(CancelationOptions::Mode::CANCEL_POINTER_EVENTS,
6323*38e8c45fSAndroid Build Coastguard Worker                                    "input channel stole pointer stream", traceContext.getTracker());
6324*38e8c45fSAndroid Build Coastguard Worker         options.deviceId = deviceId;
6325*38e8c45fSAndroid Build Coastguard Worker         options.displayId = displayId;
6326*38e8c45fSAndroid Build Coastguard Worker         std::vector<PointerProperties> pointers = window.getTouchingPointers(deviceId);
6327*38e8c45fSAndroid Build Coastguard Worker         std::bitset<MAX_POINTER_ID + 1> pointerIds = getPointerIds(pointers);
6328*38e8c45fSAndroid Build Coastguard Worker         options.pointerIds = pointerIds;
6329*38e8c45fSAndroid Build Coastguard Worker 
6330*38e8c45fSAndroid Build Coastguard Worker         std::string canceledWindows;
6331*38e8c45fSAndroid Build Coastguard Worker         for (const TouchedWindow& w : state.windows) {
6332*38e8c45fSAndroid Build Coastguard Worker             if (w.windowHandle->getToken() != token) {
6333*38e8c45fSAndroid Build Coastguard Worker                 synthesizeCancelationEventsForWindowLocked(w.windowHandle, options);
6334*38e8c45fSAndroid Build Coastguard Worker                 canceledWindows += canceledWindows.empty() ? "[" : ", ";
6335*38e8c45fSAndroid Build Coastguard Worker                 canceledWindows += w.windowHandle->getName();
6336*38e8c45fSAndroid Build Coastguard Worker             }
6337*38e8c45fSAndroid Build Coastguard Worker         }
6338*38e8c45fSAndroid Build Coastguard Worker         canceledWindows += canceledWindows.empty() ? "[]" : "]";
6339*38e8c45fSAndroid Build Coastguard Worker         LOG(INFO) << "Channel " << requestingConnection->getInputChannelName()
6340*38e8c45fSAndroid Build Coastguard Worker                   << " is stealing input gesture for device " << deviceId << " from "
6341*38e8c45fSAndroid Build Coastguard Worker                   << canceledWindows;
6342*38e8c45fSAndroid Build Coastguard Worker 
6343*38e8c45fSAndroid Build Coastguard Worker         // Prevent the gesture from being sent to any other windows.
6344*38e8c45fSAndroid Build Coastguard Worker         // This only blocks relevant pointers to be sent to other windows
6345*38e8c45fSAndroid Build Coastguard Worker         window.addPilferingPointers(deviceId, pointerIds);
6346*38e8c45fSAndroid Build Coastguard Worker 
6347*38e8c45fSAndroid Build Coastguard Worker         state.cancelPointersForWindowsExcept(deviceId, pointerIds, token);
6348*38e8c45fSAndroid Build Coastguard Worker     }
6349*38e8c45fSAndroid Build Coastguard Worker     return OK;
6350*38e8c45fSAndroid Build Coastguard Worker }
6351*38e8c45fSAndroid Build Coastguard Worker 
requestPointerCapture(const sp<IBinder> & windowToken,bool enabled)6352*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::requestPointerCapture(const sp<IBinder>& windowToken, bool enabled) {
6353*38e8c45fSAndroid Build Coastguard Worker     { // acquire lock
6354*38e8c45fSAndroid Build Coastguard Worker         std::scoped_lock _l(mLock);
6355*38e8c45fSAndroid Build Coastguard Worker         if (DEBUG_FOCUS) {
6356*38e8c45fSAndroid Build Coastguard Worker             const sp<WindowInfoHandle> windowHandle = getWindowHandleLocked(windowToken);
6357*38e8c45fSAndroid Build Coastguard Worker             ALOGI("Request to %s Pointer Capture from: %s.", enabled ? "enable" : "disable",
6358*38e8c45fSAndroid Build Coastguard Worker                   windowHandle != nullptr ? windowHandle->getName().c_str()
6359*38e8c45fSAndroid Build Coastguard Worker                                           : "token without window");
6360*38e8c45fSAndroid Build Coastguard Worker         }
6361*38e8c45fSAndroid Build Coastguard Worker 
6362*38e8c45fSAndroid Build Coastguard Worker         const sp<IBinder> focusedToken = mFocusResolver.getFocusedWindowToken(mFocusedDisplayId);
6363*38e8c45fSAndroid Build Coastguard Worker         if (focusedToken != windowToken) {
6364*38e8c45fSAndroid Build Coastguard Worker             ALOGW("Ignoring request to %s Pointer Capture: window does not have focus.",
6365*38e8c45fSAndroid Build Coastguard Worker                   enabled ? "enable" : "disable");
6366*38e8c45fSAndroid Build Coastguard Worker             return;
6367*38e8c45fSAndroid Build Coastguard Worker         }
6368*38e8c45fSAndroid Build Coastguard Worker 
6369*38e8c45fSAndroid Build Coastguard Worker         if (enabled == mCurrentPointerCaptureRequest.isEnable()) {
6370*38e8c45fSAndroid Build Coastguard Worker             ALOGW("Ignoring request to %s Pointer Capture: "
6371*38e8c45fSAndroid Build Coastguard Worker                   "window has %s requested pointer capture.",
6372*38e8c45fSAndroid Build Coastguard Worker                   enabled ? "enable" : "disable", enabled ? "already" : "not");
6373*38e8c45fSAndroid Build Coastguard Worker             return;
6374*38e8c45fSAndroid Build Coastguard Worker         }
6375*38e8c45fSAndroid Build Coastguard Worker 
6376*38e8c45fSAndroid Build Coastguard Worker         if (enabled) {
6377*38e8c45fSAndroid Build Coastguard Worker             if (std::find(mIneligibleDisplaysForPointerCapture.begin(),
6378*38e8c45fSAndroid Build Coastguard Worker                           mIneligibleDisplaysForPointerCapture.end(),
6379*38e8c45fSAndroid Build Coastguard Worker                           mFocusedDisplayId) != mIneligibleDisplaysForPointerCapture.end()) {
6380*38e8c45fSAndroid Build Coastguard Worker                 ALOGW("Ignoring request to enable Pointer Capture: display is not eligible");
6381*38e8c45fSAndroid Build Coastguard Worker                 return;
6382*38e8c45fSAndroid Build Coastguard Worker             }
6383*38e8c45fSAndroid Build Coastguard Worker         }
6384*38e8c45fSAndroid Build Coastguard Worker 
6385*38e8c45fSAndroid Build Coastguard Worker         setPointerCaptureLocked(enabled ? windowToken : nullptr);
6386*38e8c45fSAndroid Build Coastguard Worker     } // release lock
6387*38e8c45fSAndroid Build Coastguard Worker 
6388*38e8c45fSAndroid Build Coastguard Worker     // Wake the thread to process command entries.
6389*38e8c45fSAndroid Build Coastguard Worker     mLooper->wake();
6390*38e8c45fSAndroid Build Coastguard Worker }
6391*38e8c45fSAndroid Build Coastguard Worker 
setDisplayEligibilityForPointerCapture(ui::LogicalDisplayId displayId,bool isEligible)6392*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::setDisplayEligibilityForPointerCapture(ui::LogicalDisplayId displayId,
6393*38e8c45fSAndroid Build Coastguard Worker                                                              bool isEligible) {
6394*38e8c45fSAndroid Build Coastguard Worker     { // acquire lock
6395*38e8c45fSAndroid Build Coastguard Worker         std::scoped_lock _l(mLock);
6396*38e8c45fSAndroid Build Coastguard Worker         std::erase(mIneligibleDisplaysForPointerCapture, displayId);
6397*38e8c45fSAndroid Build Coastguard Worker         if (!isEligible) {
6398*38e8c45fSAndroid Build Coastguard Worker             mIneligibleDisplaysForPointerCapture.push_back(displayId);
6399*38e8c45fSAndroid Build Coastguard Worker         }
6400*38e8c45fSAndroid Build Coastguard Worker     } // release lock
6401*38e8c45fSAndroid Build Coastguard Worker }
6402*38e8c45fSAndroid Build Coastguard Worker 
findMonitorPidByTokenLocked(const sp<IBinder> & token)6403*38e8c45fSAndroid Build Coastguard Worker std::optional<gui::Pid> InputDispatcher::findMonitorPidByTokenLocked(const sp<IBinder>& token) {
6404*38e8c45fSAndroid Build Coastguard Worker     for (const auto& [_, monitors] : mGlobalMonitorsByDisplay) {
6405*38e8c45fSAndroid Build Coastguard Worker         for (const Monitor& monitor : monitors) {
6406*38e8c45fSAndroid Build Coastguard Worker             if (monitor.connection->getToken() == token) {
6407*38e8c45fSAndroid Build Coastguard Worker                 return monitor.pid;
6408*38e8c45fSAndroid Build Coastguard Worker             }
6409*38e8c45fSAndroid Build Coastguard Worker         }
6410*38e8c45fSAndroid Build Coastguard Worker     }
6411*38e8c45fSAndroid Build Coastguard Worker     return std::nullopt;
6412*38e8c45fSAndroid Build Coastguard Worker }
6413*38e8c45fSAndroid Build Coastguard Worker 
getConnectionLocked(const sp<IBinder> & inputConnectionToken) const6414*38e8c45fSAndroid Build Coastguard Worker std::shared_ptr<Connection> InputDispatcher::getConnectionLocked(
6415*38e8c45fSAndroid Build Coastguard Worker         const sp<IBinder>& inputConnectionToken) const {
6416*38e8c45fSAndroid Build Coastguard Worker     if (inputConnectionToken == nullptr) {
6417*38e8c45fSAndroid Build Coastguard Worker         return nullptr;
6418*38e8c45fSAndroid Build Coastguard Worker     }
6419*38e8c45fSAndroid Build Coastguard Worker 
6420*38e8c45fSAndroid Build Coastguard Worker     for (const auto& [token, connection] : mConnectionsByToken) {
6421*38e8c45fSAndroid Build Coastguard Worker         if (token == inputConnectionToken) {
6422*38e8c45fSAndroid Build Coastguard Worker             return connection;
6423*38e8c45fSAndroid Build Coastguard Worker         }
6424*38e8c45fSAndroid Build Coastguard Worker     }
6425*38e8c45fSAndroid Build Coastguard Worker 
6426*38e8c45fSAndroid Build Coastguard Worker     return nullptr;
6427*38e8c45fSAndroid Build Coastguard Worker }
6428*38e8c45fSAndroid Build Coastguard Worker 
getConnectionNameLocked(const sp<IBinder> & connectionToken) const6429*38e8c45fSAndroid Build Coastguard Worker std::string InputDispatcher::getConnectionNameLocked(const sp<IBinder>& connectionToken) const {
6430*38e8c45fSAndroid Build Coastguard Worker     std::shared_ptr<Connection> connection = getConnectionLocked(connectionToken);
6431*38e8c45fSAndroid Build Coastguard Worker     if (connection == nullptr) {
6432*38e8c45fSAndroid Build Coastguard Worker         return "<nullptr>";
6433*38e8c45fSAndroid Build Coastguard Worker     }
6434*38e8c45fSAndroid Build Coastguard Worker     return connection->getInputChannelName();
6435*38e8c45fSAndroid Build Coastguard Worker }
6436*38e8c45fSAndroid Build Coastguard Worker 
removeConnectionLocked(const std::shared_ptr<Connection> & connection)6437*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::removeConnectionLocked(const std::shared_ptr<Connection>& connection) {
6438*38e8c45fSAndroid Build Coastguard Worker     mAnrTracker.eraseToken(connection->getToken());
6439*38e8c45fSAndroid Build Coastguard Worker     mConnectionsByToken.erase(connection->getToken());
6440*38e8c45fSAndroid Build Coastguard Worker }
6441*38e8c45fSAndroid Build Coastguard Worker 
doDispatchCycleFinishedCommand(nsecs_t finishTime,const std::shared_ptr<Connection> & connection,uint32_t seq,bool handled,nsecs_t consumeTime)6442*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::doDispatchCycleFinishedCommand(nsecs_t finishTime,
6443*38e8c45fSAndroid Build Coastguard Worker                                                      const std::shared_ptr<Connection>& connection,
6444*38e8c45fSAndroid Build Coastguard Worker                                                      uint32_t seq, bool handled,
6445*38e8c45fSAndroid Build Coastguard Worker                                                      nsecs_t consumeTime) {
6446*38e8c45fSAndroid Build Coastguard Worker     // Handle post-event policy actions.
6447*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<const KeyEntry> fallbackKeyEntry;
6448*38e8c45fSAndroid Build Coastguard Worker 
6449*38e8c45fSAndroid Build Coastguard Worker     { // Start critical section
6450*38e8c45fSAndroid Build Coastguard Worker         auto dispatchEntryIt =
6451*38e8c45fSAndroid Build Coastguard Worker                 std::find_if(connection->waitQueue.begin(), connection->waitQueue.end(),
6452*38e8c45fSAndroid Build Coastguard Worker                              [seq](auto& e) { return e->seq == seq; });
6453*38e8c45fSAndroid Build Coastguard Worker         if (dispatchEntryIt == connection->waitQueue.end()) {
6454*38e8c45fSAndroid Build Coastguard Worker             return;
6455*38e8c45fSAndroid Build Coastguard Worker         }
6456*38e8c45fSAndroid Build Coastguard Worker 
6457*38e8c45fSAndroid Build Coastguard Worker         DispatchEntry& dispatchEntry = **dispatchEntryIt;
6458*38e8c45fSAndroid Build Coastguard Worker 
6459*38e8c45fSAndroid Build Coastguard Worker         const nsecs_t eventDuration = finishTime - dispatchEntry.deliveryTime;
6460*38e8c45fSAndroid Build Coastguard Worker         if (eventDuration > SLOW_EVENT_PROCESSING_WARNING_TIMEOUT) {
6461*38e8c45fSAndroid Build Coastguard Worker             ALOGI("%s spent %" PRId64 "ms processing %s", connection->getInputChannelName().c_str(),
6462*38e8c45fSAndroid Build Coastguard Worker                   ns2ms(eventDuration), dispatchEntry.eventEntry->getDescription().c_str());
6463*38e8c45fSAndroid Build Coastguard Worker         }
6464*38e8c45fSAndroid Build Coastguard Worker         if (shouldReportFinishedEvent(dispatchEntry, *connection)) {
6465*38e8c45fSAndroid Build Coastguard Worker             mLatencyTracker.trackFinishedEvent(dispatchEntry.eventEntry->id, connection->getToken(),
6466*38e8c45fSAndroid Build Coastguard Worker                                                dispatchEntry.deliveryTime, consumeTime, finishTime);
6467*38e8c45fSAndroid Build Coastguard Worker         }
6468*38e8c45fSAndroid Build Coastguard Worker 
6469*38e8c45fSAndroid Build Coastguard Worker         if (dispatchEntry.eventEntry->type == EventEntry::Type::KEY) {
6470*38e8c45fSAndroid Build Coastguard Worker             fallbackKeyEntry =
6471*38e8c45fSAndroid Build Coastguard Worker                     afterKeyEventLockedInterruptable(connection, &dispatchEntry, handled);
6472*38e8c45fSAndroid Build Coastguard Worker         }
6473*38e8c45fSAndroid Build Coastguard Worker     } // End critical section: The -LockedInterruptable methods may have released the lock.
6474*38e8c45fSAndroid Build Coastguard Worker 
6475*38e8c45fSAndroid Build Coastguard Worker     // Dequeue the event and start the next cycle.
6476*38e8c45fSAndroid Build Coastguard Worker     // Because the lock might have been released, it is possible that the
6477*38e8c45fSAndroid Build Coastguard Worker     // contents of the wait queue to have been drained, so we need to double-check
6478*38e8c45fSAndroid Build Coastguard Worker     // a few things.
6479*38e8c45fSAndroid Build Coastguard Worker     auto entryIt = std::find_if(connection->waitQueue.begin(), connection->waitQueue.end(),
6480*38e8c45fSAndroid Build Coastguard Worker                                 [seq](auto& e) { return e->seq == seq; });
6481*38e8c45fSAndroid Build Coastguard Worker     if (entryIt != connection->waitQueue.end()) {
6482*38e8c45fSAndroid Build Coastguard Worker         std::unique_ptr<DispatchEntry> dispatchEntry = std::move(*entryIt);
6483*38e8c45fSAndroid Build Coastguard Worker         connection->waitQueue.erase(entryIt);
6484*38e8c45fSAndroid Build Coastguard Worker 
6485*38e8c45fSAndroid Build Coastguard Worker         const sp<IBinder>& connectionToken = connection->getToken();
6486*38e8c45fSAndroid Build Coastguard Worker         mAnrTracker.erase(dispatchEntry->timeoutTime, connectionToken);
6487*38e8c45fSAndroid Build Coastguard Worker         if (!connection->responsive) {
6488*38e8c45fSAndroid Build Coastguard Worker             connection->responsive = isConnectionResponsive(*connection);
6489*38e8c45fSAndroid Build Coastguard Worker             if (connection->responsive) {
6490*38e8c45fSAndroid Build Coastguard Worker                 // The connection was unresponsive, and now it's responsive.
6491*38e8c45fSAndroid Build Coastguard Worker                 processConnectionResponsiveLocked(*connection);
6492*38e8c45fSAndroid Build Coastguard Worker             }
6493*38e8c45fSAndroid Build Coastguard Worker         }
6494*38e8c45fSAndroid Build Coastguard Worker         traceWaitQueueLength(*connection);
6495*38e8c45fSAndroid Build Coastguard Worker         if (fallbackKeyEntry && connection->status == Connection::Status::NORMAL) {
6496*38e8c45fSAndroid Build Coastguard Worker             const auto windowHandle = getWindowHandleLocked(connection->getToken());
6497*38e8c45fSAndroid Build Coastguard Worker             // Only dispatch fallbacks if there is a window for the connection.
6498*38e8c45fSAndroid Build Coastguard Worker             if (windowHandle != nullptr) {
6499*38e8c45fSAndroid Build Coastguard Worker                 const auto inputTarget =
6500*38e8c45fSAndroid Build Coastguard Worker                         createInputTargetLocked(windowHandle, InputTarget::DispatchMode::AS_IS,
6501*38e8c45fSAndroid Build Coastguard Worker                                                 dispatchEntry->targetFlags,
6502*38e8c45fSAndroid Build Coastguard Worker                                                 fallbackKeyEntry->downTime);
6503*38e8c45fSAndroid Build Coastguard Worker                 if (inputTarget.has_value()) {
6504*38e8c45fSAndroid Build Coastguard Worker                     enqueueDispatchEntryLocked(connection, std::move(fallbackKeyEntry),
6505*38e8c45fSAndroid Build Coastguard Worker                                                *inputTarget);
6506*38e8c45fSAndroid Build Coastguard Worker                 }
6507*38e8c45fSAndroid Build Coastguard Worker             }
6508*38e8c45fSAndroid Build Coastguard Worker         }
6509*38e8c45fSAndroid Build Coastguard Worker         releaseDispatchEntry(std::move(dispatchEntry));
6510*38e8c45fSAndroid Build Coastguard Worker     }
6511*38e8c45fSAndroid Build Coastguard Worker 
6512*38e8c45fSAndroid Build Coastguard Worker     // Start the next dispatch cycle for this connection.
6513*38e8c45fSAndroid Build Coastguard Worker     startDispatchCycleLocked(now(), connection);
6514*38e8c45fSAndroid Build Coastguard Worker }
6515*38e8c45fSAndroid Build Coastguard Worker 
sendFocusChangedCommandLocked(const sp<IBinder> & oldToken,const sp<IBinder> & newToken)6516*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::sendFocusChangedCommandLocked(const sp<IBinder>& oldToken,
6517*38e8c45fSAndroid Build Coastguard Worker                                                     const sp<IBinder>& newToken) {
6518*38e8c45fSAndroid Build Coastguard Worker     auto command = [this, oldToken, newToken]() REQUIRES(mLock) {
6519*38e8c45fSAndroid Build Coastguard Worker         scoped_unlock unlock(mLock);
6520*38e8c45fSAndroid Build Coastguard Worker         mPolicy.notifyFocusChanged(oldToken, newToken);
6521*38e8c45fSAndroid Build Coastguard Worker     };
6522*38e8c45fSAndroid Build Coastguard Worker     postCommandLocked(std::move(command));
6523*38e8c45fSAndroid Build Coastguard Worker }
6524*38e8c45fSAndroid Build Coastguard Worker 
sendDropWindowCommandLocked(const sp<IBinder> & token,float x,float y)6525*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::sendDropWindowCommandLocked(const sp<IBinder>& token, float x, float y) {
6526*38e8c45fSAndroid Build Coastguard Worker     auto command = [this, token, x, y]() REQUIRES(mLock) {
6527*38e8c45fSAndroid Build Coastguard Worker         scoped_unlock unlock(mLock);
6528*38e8c45fSAndroid Build Coastguard Worker         mPolicy.notifyDropWindow(token, x, y);
6529*38e8c45fSAndroid Build Coastguard Worker     };
6530*38e8c45fSAndroid Build Coastguard Worker     postCommandLocked(std::move(command));
6531*38e8c45fSAndroid Build Coastguard Worker }
6532*38e8c45fSAndroid Build Coastguard Worker 
onAnrLocked(const std::shared_ptr<Connection> & connection)6533*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::onAnrLocked(const std::shared_ptr<Connection>& connection) {
6534*38e8c45fSAndroid Build Coastguard Worker     if (connection == nullptr) {
6535*38e8c45fSAndroid Build Coastguard Worker         LOG_ALWAYS_FATAL("Caller must check for nullness");
6536*38e8c45fSAndroid Build Coastguard Worker     }
6537*38e8c45fSAndroid Build Coastguard Worker     // Since we are allowing the policy to extend the timeout, maybe the waitQueue
6538*38e8c45fSAndroid Build Coastguard Worker     // is already healthy again. Don't raise ANR in this situation
6539*38e8c45fSAndroid Build Coastguard Worker     if (connection->waitQueue.empty()) {
6540*38e8c45fSAndroid Build Coastguard Worker         ALOGI("Not raising ANR because the connection %s has recovered",
6541*38e8c45fSAndroid Build Coastguard Worker               connection->getInputChannelName().c_str());
6542*38e8c45fSAndroid Build Coastguard Worker         return;
6543*38e8c45fSAndroid Build Coastguard Worker     }
6544*38e8c45fSAndroid Build Coastguard Worker     /**
6545*38e8c45fSAndroid Build Coastguard Worker      * The "oldestEntry" is the entry that was first sent to the application. That entry, however,
6546*38e8c45fSAndroid Build Coastguard Worker      * may not be the one that caused the timeout to occur. One possibility is that window timeout
6547*38e8c45fSAndroid Build Coastguard Worker      * has changed. This could cause newer entries to time out before the already dispatched
6548*38e8c45fSAndroid Build Coastguard Worker      * entries. In that situation, the newest entries caused ANR. But in all likelihood, the app
6549*38e8c45fSAndroid Build Coastguard Worker      * processes the events linearly. So providing information about the oldest entry seems to be
6550*38e8c45fSAndroid Build Coastguard Worker      * most useful.
6551*38e8c45fSAndroid Build Coastguard Worker      */
6552*38e8c45fSAndroid Build Coastguard Worker     DispatchEntry& oldestEntry = *connection->waitQueue.front();
6553*38e8c45fSAndroid Build Coastguard Worker     const nsecs_t currentWait = now() - oldestEntry.deliveryTime;
6554*38e8c45fSAndroid Build Coastguard Worker     std::string reason =
6555*38e8c45fSAndroid Build Coastguard Worker             android::base::StringPrintf("%s is not responding. Waited %" PRId64 "ms for %s",
6556*38e8c45fSAndroid Build Coastguard Worker                                         connection->getInputChannelName().c_str(),
6557*38e8c45fSAndroid Build Coastguard Worker                                         ns2ms(currentWait),
6558*38e8c45fSAndroid Build Coastguard Worker                                         oldestEntry.eventEntry->getDescription().c_str());
6559*38e8c45fSAndroid Build Coastguard Worker     sp<IBinder> connectionToken = connection->getToken();
6560*38e8c45fSAndroid Build Coastguard Worker     updateLastAnrStateLocked(getWindowHandleLocked(connectionToken), reason);
6561*38e8c45fSAndroid Build Coastguard Worker 
6562*38e8c45fSAndroid Build Coastguard Worker     processConnectionUnresponsiveLocked(*connection, std::move(reason));
6563*38e8c45fSAndroid Build Coastguard Worker 
6564*38e8c45fSAndroid Build Coastguard Worker     // Stop waking up for events on this connection, it is already unresponsive
6565*38e8c45fSAndroid Build Coastguard Worker     cancelEventsForAnrLocked(connection);
6566*38e8c45fSAndroid Build Coastguard Worker }
6567*38e8c45fSAndroid Build Coastguard Worker 
onAnrLocked(std::shared_ptr<InputApplicationHandle> application)6568*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::onAnrLocked(std::shared_ptr<InputApplicationHandle> application) {
6569*38e8c45fSAndroid Build Coastguard Worker     std::string reason =
6570*38e8c45fSAndroid Build Coastguard Worker             StringPrintf("%s does not have a focused window", application->getName().c_str());
6571*38e8c45fSAndroid Build Coastguard Worker     updateLastAnrStateLocked(*application, reason);
6572*38e8c45fSAndroid Build Coastguard Worker 
6573*38e8c45fSAndroid Build Coastguard Worker     auto command = [this, app = std::move(application)]() REQUIRES(mLock) {
6574*38e8c45fSAndroid Build Coastguard Worker         scoped_unlock unlock(mLock);
6575*38e8c45fSAndroid Build Coastguard Worker         mPolicy.notifyNoFocusedWindowAnr(app);
6576*38e8c45fSAndroid Build Coastguard Worker     };
6577*38e8c45fSAndroid Build Coastguard Worker     postCommandLocked(std::move(command));
6578*38e8c45fSAndroid Build Coastguard Worker }
6579*38e8c45fSAndroid Build Coastguard Worker 
updateLastAnrStateLocked(const sp<WindowInfoHandle> & window,const std::string & reason)6580*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::updateLastAnrStateLocked(const sp<WindowInfoHandle>& window,
6581*38e8c45fSAndroid Build Coastguard Worker                                                const std::string& reason) {
6582*38e8c45fSAndroid Build Coastguard Worker     const std::string windowLabel = getApplicationWindowLabel(nullptr, window);
6583*38e8c45fSAndroid Build Coastguard Worker     updateLastAnrStateLocked(windowLabel, reason);
6584*38e8c45fSAndroid Build Coastguard Worker }
6585*38e8c45fSAndroid Build Coastguard Worker 
updateLastAnrStateLocked(const InputApplicationHandle & application,const std::string & reason)6586*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::updateLastAnrStateLocked(const InputApplicationHandle& application,
6587*38e8c45fSAndroid Build Coastguard Worker                                                const std::string& reason) {
6588*38e8c45fSAndroid Build Coastguard Worker     const std::string windowLabel = getApplicationWindowLabel(&application, nullptr);
6589*38e8c45fSAndroid Build Coastguard Worker     updateLastAnrStateLocked(windowLabel, reason);
6590*38e8c45fSAndroid Build Coastguard Worker }
6591*38e8c45fSAndroid Build Coastguard Worker 
updateLastAnrStateLocked(const std::string & windowLabel,const std::string & reason)6592*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::updateLastAnrStateLocked(const std::string& windowLabel,
6593*38e8c45fSAndroid Build Coastguard Worker                                                const std::string& reason) {
6594*38e8c45fSAndroid Build Coastguard Worker     // Capture a record of the InputDispatcher state at the time of the ANR.
6595*38e8c45fSAndroid Build Coastguard Worker     time_t t = time(nullptr);
6596*38e8c45fSAndroid Build Coastguard Worker     struct tm tm;
6597*38e8c45fSAndroid Build Coastguard Worker     localtime_r(&t, &tm);
6598*38e8c45fSAndroid Build Coastguard Worker     char timestr[64];
6599*38e8c45fSAndroid Build Coastguard Worker     strftime(timestr, sizeof(timestr), "%F %T", &tm);
6600*38e8c45fSAndroid Build Coastguard Worker     mLastAnrState.clear();
6601*38e8c45fSAndroid Build Coastguard Worker     mLastAnrState += INDENT "ANR:\n";
6602*38e8c45fSAndroid Build Coastguard Worker     mLastAnrState += StringPrintf(INDENT2 "Time: %s\n", timestr);
6603*38e8c45fSAndroid Build Coastguard Worker     mLastAnrState += StringPrintf(INDENT2 "Reason: %s\n", reason.c_str());
6604*38e8c45fSAndroid Build Coastguard Worker     mLastAnrState += StringPrintf(INDENT2 "Window: %s\n", windowLabel.c_str());
6605*38e8c45fSAndroid Build Coastguard Worker     dumpDispatchStateLocked(mLastAnrState);
6606*38e8c45fSAndroid Build Coastguard Worker }
6607*38e8c45fSAndroid Build Coastguard Worker 
doInterceptKeyBeforeDispatchingCommand(const sp<IBinder> & focusedWindowToken,const KeyEntry & entry)6608*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::doInterceptKeyBeforeDispatchingCommand(const sp<IBinder>& focusedWindowToken,
6609*38e8c45fSAndroid Build Coastguard Worker                                                              const KeyEntry& entry) {
6610*38e8c45fSAndroid Build Coastguard Worker     const KeyEvent event = createKeyEvent(entry);
6611*38e8c45fSAndroid Build Coastguard Worker     nsecs_t delay = 0;
6612*38e8c45fSAndroid Build Coastguard Worker     { // release lock
6613*38e8c45fSAndroid Build Coastguard Worker         scoped_unlock unlock(mLock);
6614*38e8c45fSAndroid Build Coastguard Worker         android::base::Timer t;
6615*38e8c45fSAndroid Build Coastguard Worker         delay = mPolicy.interceptKeyBeforeDispatching(focusedWindowToken, event, entry.policyFlags);
6616*38e8c45fSAndroid Build Coastguard Worker         if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
6617*38e8c45fSAndroid Build Coastguard Worker             ALOGW("Excessive delay in interceptKeyBeforeDispatching; took %s ms",
6618*38e8c45fSAndroid Build Coastguard Worker                   std::to_string(t.duration().count()).c_str());
6619*38e8c45fSAndroid Build Coastguard Worker         }
6620*38e8c45fSAndroid Build Coastguard Worker     } // acquire lock
6621*38e8c45fSAndroid Build Coastguard Worker 
6622*38e8c45fSAndroid Build Coastguard Worker     if (delay < 0) {
6623*38e8c45fSAndroid Build Coastguard Worker         entry.interceptKeyResult = KeyEntry::InterceptKeyResult::SKIP;
6624*38e8c45fSAndroid Build Coastguard Worker     } else if (delay == 0) {
6625*38e8c45fSAndroid Build Coastguard Worker         entry.interceptKeyResult = KeyEntry::InterceptKeyResult::CONTINUE;
6626*38e8c45fSAndroid Build Coastguard Worker     } else {
6627*38e8c45fSAndroid Build Coastguard Worker         entry.interceptKeyResult = KeyEntry::InterceptKeyResult::TRY_AGAIN_LATER;
6628*38e8c45fSAndroid Build Coastguard Worker         entry.interceptKeyWakeupTime = now() + delay;
6629*38e8c45fSAndroid Build Coastguard Worker     }
6630*38e8c45fSAndroid Build Coastguard Worker }
6631*38e8c45fSAndroid Build Coastguard Worker 
sendWindowUnresponsiveCommandLocked(const sp<IBinder> & token,std::optional<gui::Pid> pid,std::string reason)6632*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::sendWindowUnresponsiveCommandLocked(const sp<IBinder>& token,
6633*38e8c45fSAndroid Build Coastguard Worker                                                           std::optional<gui::Pid> pid,
6634*38e8c45fSAndroid Build Coastguard Worker                                                           std::string reason) {
6635*38e8c45fSAndroid Build Coastguard Worker     auto command = [this, token, pid, r = std::move(reason)]() REQUIRES(mLock) {
6636*38e8c45fSAndroid Build Coastguard Worker         scoped_unlock unlock(mLock);
6637*38e8c45fSAndroid Build Coastguard Worker         mPolicy.notifyWindowUnresponsive(token, pid, r);
6638*38e8c45fSAndroid Build Coastguard Worker     };
6639*38e8c45fSAndroid Build Coastguard Worker     postCommandLocked(std::move(command));
6640*38e8c45fSAndroid Build Coastguard Worker }
6641*38e8c45fSAndroid Build Coastguard Worker 
sendWindowResponsiveCommandLocked(const sp<IBinder> & token,std::optional<gui::Pid> pid)6642*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::sendWindowResponsiveCommandLocked(const sp<IBinder>& token,
6643*38e8c45fSAndroid Build Coastguard Worker                                                         std::optional<gui::Pid> pid) {
6644*38e8c45fSAndroid Build Coastguard Worker     auto command = [this, token, pid]() REQUIRES(mLock) {
6645*38e8c45fSAndroid Build Coastguard Worker         scoped_unlock unlock(mLock);
6646*38e8c45fSAndroid Build Coastguard Worker         mPolicy.notifyWindowResponsive(token, pid);
6647*38e8c45fSAndroid Build Coastguard Worker     };
6648*38e8c45fSAndroid Build Coastguard Worker     postCommandLocked(std::move(command));
6649*38e8c45fSAndroid Build Coastguard Worker }
6650*38e8c45fSAndroid Build Coastguard Worker 
6651*38e8c45fSAndroid Build Coastguard Worker /**
6652*38e8c45fSAndroid Build Coastguard Worker  * Tell the policy that a connection has become unresponsive so that it can start ANR.
6653*38e8c45fSAndroid Build Coastguard Worker  * Check whether the connection of interest is a monitor or a window, and add the corresponding
6654*38e8c45fSAndroid Build Coastguard Worker  * command entry to the command queue.
6655*38e8c45fSAndroid Build Coastguard Worker  */
processConnectionUnresponsiveLocked(const Connection & connection,std::string reason)6656*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::processConnectionUnresponsiveLocked(const Connection& connection,
6657*38e8c45fSAndroid Build Coastguard Worker                                                           std::string reason) {
6658*38e8c45fSAndroid Build Coastguard Worker     const sp<IBinder>& connectionToken = connection.getToken();
6659*38e8c45fSAndroid Build Coastguard Worker     std::optional<gui::Pid> pid;
6660*38e8c45fSAndroid Build Coastguard Worker     if (connection.monitor) {
6661*38e8c45fSAndroid Build Coastguard Worker         ALOGW("Monitor %s is unresponsive: %s", connection.getInputChannelName().c_str(),
6662*38e8c45fSAndroid Build Coastguard Worker               reason.c_str());
6663*38e8c45fSAndroid Build Coastguard Worker         pid = findMonitorPidByTokenLocked(connectionToken);
6664*38e8c45fSAndroid Build Coastguard Worker     } else {
6665*38e8c45fSAndroid Build Coastguard Worker         // The connection is a window
6666*38e8c45fSAndroid Build Coastguard Worker         ALOGW("Window %s is unresponsive: %s", connection.getInputChannelName().c_str(),
6667*38e8c45fSAndroid Build Coastguard Worker               reason.c_str());
6668*38e8c45fSAndroid Build Coastguard Worker         const sp<WindowInfoHandle> handle = getWindowHandleLocked(connectionToken);
6669*38e8c45fSAndroid Build Coastguard Worker         if (handle != nullptr) {
6670*38e8c45fSAndroid Build Coastguard Worker             pid = handle->getInfo()->ownerPid;
6671*38e8c45fSAndroid Build Coastguard Worker         }
6672*38e8c45fSAndroid Build Coastguard Worker     }
6673*38e8c45fSAndroid Build Coastguard Worker     sendWindowUnresponsiveCommandLocked(connectionToken, pid, std::move(reason));
6674*38e8c45fSAndroid Build Coastguard Worker }
6675*38e8c45fSAndroid Build Coastguard Worker 
6676*38e8c45fSAndroid Build Coastguard Worker /**
6677*38e8c45fSAndroid Build Coastguard Worker  * Tell the policy that a connection has become responsive so that it can stop ANR.
6678*38e8c45fSAndroid Build Coastguard Worker  */
processConnectionResponsiveLocked(const Connection & connection)6679*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::processConnectionResponsiveLocked(const Connection& connection) {
6680*38e8c45fSAndroid Build Coastguard Worker     const sp<IBinder>& connectionToken = connection.getToken();
6681*38e8c45fSAndroid Build Coastguard Worker     std::optional<gui::Pid> pid;
6682*38e8c45fSAndroid Build Coastguard Worker     if (connection.monitor) {
6683*38e8c45fSAndroid Build Coastguard Worker         pid = findMonitorPidByTokenLocked(connectionToken);
6684*38e8c45fSAndroid Build Coastguard Worker     } else {
6685*38e8c45fSAndroid Build Coastguard Worker         // The connection is a window
6686*38e8c45fSAndroid Build Coastguard Worker         const sp<WindowInfoHandle> handle = getWindowHandleLocked(connectionToken);
6687*38e8c45fSAndroid Build Coastguard Worker         if (handle != nullptr) {
6688*38e8c45fSAndroid Build Coastguard Worker             pid = handle->getInfo()->ownerPid;
6689*38e8c45fSAndroid Build Coastguard Worker         }
6690*38e8c45fSAndroid Build Coastguard Worker     }
6691*38e8c45fSAndroid Build Coastguard Worker     sendWindowResponsiveCommandLocked(connectionToken, pid);
6692*38e8c45fSAndroid Build Coastguard Worker }
6693*38e8c45fSAndroid Build Coastguard Worker 
afterKeyEventLockedInterruptable(const std::shared_ptr<Connection> & connection,DispatchEntry * dispatchEntry,bool handled)6694*38e8c45fSAndroid Build Coastguard Worker std::unique_ptr<const KeyEntry> InputDispatcher::afterKeyEventLockedInterruptable(
6695*38e8c45fSAndroid Build Coastguard Worker         const std::shared_ptr<Connection>& connection, DispatchEntry* dispatchEntry, bool handled) {
6696*38e8c45fSAndroid Build Coastguard Worker     // The dispatchEntry is currently valid, but it might point to a deleted object after we release
6697*38e8c45fSAndroid Build Coastguard Worker     // the lock. For simplicity, make copies of the data of interest here and assume that
6698*38e8c45fSAndroid Build Coastguard Worker     // 'dispatchEntry' is not valid after this section.
6699*38e8c45fSAndroid Build Coastguard Worker     // Hold a strong reference to the EventEntry to ensure it's valid for the duration of this
6700*38e8c45fSAndroid Build Coastguard Worker     // function, even if the DispatchEntry gets destroyed and releases its share of the ownership.
6701*38e8c45fSAndroid Build Coastguard Worker     std::shared_ptr<const EventEntry> eventEntry = dispatchEntry->eventEntry;
6702*38e8c45fSAndroid Build Coastguard Worker     const bool hasForegroundTarget = dispatchEntry->hasForegroundTarget();
6703*38e8c45fSAndroid Build Coastguard Worker     const KeyEntry& keyEntry = static_cast<const KeyEntry&>(*(eventEntry));
6704*38e8c45fSAndroid Build Coastguard Worker     // To prevent misuse, ensure dispatchEntry is no longer valid.
6705*38e8c45fSAndroid Build Coastguard Worker     dispatchEntry = nullptr;
6706*38e8c45fSAndroid Build Coastguard Worker     if (keyEntry.flags & AKEY_EVENT_FLAG_FALLBACK) {
6707*38e8c45fSAndroid Build Coastguard Worker         if (!handled) {
6708*38e8c45fSAndroid Build Coastguard Worker             // Report the key as unhandled, since the fallback was not handled.
6709*38e8c45fSAndroid Build Coastguard Worker             mReporter->reportUnhandledKey(keyEntry.id);
6710*38e8c45fSAndroid Build Coastguard Worker         }
6711*38e8c45fSAndroid Build Coastguard Worker         return {};
6712*38e8c45fSAndroid Build Coastguard Worker     }
6713*38e8c45fSAndroid Build Coastguard Worker 
6714*38e8c45fSAndroid Build Coastguard Worker     // Get the fallback key state.
6715*38e8c45fSAndroid Build Coastguard Worker     // Clear it out after dispatching the UP.
6716*38e8c45fSAndroid Build Coastguard Worker     int32_t originalKeyCode = keyEntry.keyCode;
6717*38e8c45fSAndroid Build Coastguard Worker     std::optional<int32_t> fallbackKeyCode = connection->inputState.getFallbackKey(originalKeyCode);
6718*38e8c45fSAndroid Build Coastguard Worker     if (keyEntry.action == AKEY_EVENT_ACTION_UP) {
6719*38e8c45fSAndroid Build Coastguard Worker         connection->inputState.removeFallbackKey(originalKeyCode);
6720*38e8c45fSAndroid Build Coastguard Worker     }
6721*38e8c45fSAndroid Build Coastguard Worker 
6722*38e8c45fSAndroid Build Coastguard Worker     if (handled || !hasForegroundTarget) {
6723*38e8c45fSAndroid Build Coastguard Worker         // If the application handles the original key for which we previously
6724*38e8c45fSAndroid Build Coastguard Worker         // generated a fallback or if the window is not a foreground window,
6725*38e8c45fSAndroid Build Coastguard Worker         // then cancel the associated fallback key, if any.
6726*38e8c45fSAndroid Build Coastguard Worker         if (fallbackKeyCode) {
6727*38e8c45fSAndroid Build Coastguard Worker             // Dispatch the unhandled key to the policy with the cancel flag.
6728*38e8c45fSAndroid Build Coastguard Worker             if (DEBUG_OUTBOUND_EVENT_DETAILS) {
6729*38e8c45fSAndroid Build Coastguard Worker                 ALOGD("Unhandled key event: Asking policy to cancel fallback action.  "
6730*38e8c45fSAndroid Build Coastguard Worker                       "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
6731*38e8c45fSAndroid Build Coastguard Worker                       keyEntry.keyCode, keyEntry.action, keyEntry.repeatCount,
6732*38e8c45fSAndroid Build Coastguard Worker                       keyEntry.policyFlags);
6733*38e8c45fSAndroid Build Coastguard Worker             }
6734*38e8c45fSAndroid Build Coastguard Worker             KeyEvent event = createKeyEvent(keyEntry);
6735*38e8c45fSAndroid Build Coastguard Worker             event.setFlags(event.getFlags() | AKEY_EVENT_FLAG_CANCELED);
6736*38e8c45fSAndroid Build Coastguard Worker 
6737*38e8c45fSAndroid Build Coastguard Worker             mLock.unlock();
6738*38e8c45fSAndroid Build Coastguard Worker 
6739*38e8c45fSAndroid Build Coastguard Worker             if (const auto unhandledKeyFallback =
6740*38e8c45fSAndroid Build Coastguard Worker                         mPolicy.dispatchUnhandledKey(connection->getToken(), event,
6741*38e8c45fSAndroid Build Coastguard Worker                                                      keyEntry.policyFlags);
6742*38e8c45fSAndroid Build Coastguard Worker                 unhandledKeyFallback) {
6743*38e8c45fSAndroid Build Coastguard Worker                 event = *unhandledKeyFallback;
6744*38e8c45fSAndroid Build Coastguard Worker             }
6745*38e8c45fSAndroid Build Coastguard Worker 
6746*38e8c45fSAndroid Build Coastguard Worker             mLock.lock();
6747*38e8c45fSAndroid Build Coastguard Worker 
6748*38e8c45fSAndroid Build Coastguard Worker             // Cancel the fallback key, but only if we still have a window for the channel.
6749*38e8c45fSAndroid Build Coastguard Worker             // It could have been removed during the policy call.
6750*38e8c45fSAndroid Build Coastguard Worker             if (*fallbackKeyCode != AKEYCODE_UNKNOWN) {
6751*38e8c45fSAndroid Build Coastguard Worker                 const auto windowHandle = getWindowHandleLocked(connection->getToken());
6752*38e8c45fSAndroid Build Coastguard Worker                 if (windowHandle != nullptr) {
6753*38e8c45fSAndroid Build Coastguard Worker                     CancelationOptions options(CancelationOptions::Mode::CANCEL_FALLBACK_EVENTS,
6754*38e8c45fSAndroid Build Coastguard Worker                                                "application handled the original non-fallback key "
6755*38e8c45fSAndroid Build Coastguard Worker                                                "or is no longer a foreground target, "
6756*38e8c45fSAndroid Build Coastguard Worker                                                "canceling previously dispatched fallback key",
6757*38e8c45fSAndroid Build Coastguard Worker                                                keyEntry.traceTracker);
6758*38e8c45fSAndroid Build Coastguard Worker                     options.keyCode = *fallbackKeyCode;
6759*38e8c45fSAndroid Build Coastguard Worker                     synthesizeCancelationEventsForWindowLocked(windowHandle, options, connection);
6760*38e8c45fSAndroid Build Coastguard Worker                 }
6761*38e8c45fSAndroid Build Coastguard Worker             }
6762*38e8c45fSAndroid Build Coastguard Worker             connection->inputState.removeFallbackKey(originalKeyCode);
6763*38e8c45fSAndroid Build Coastguard Worker         }
6764*38e8c45fSAndroid Build Coastguard Worker     } else {
6765*38e8c45fSAndroid Build Coastguard Worker         // If the application did not handle a non-fallback key, first check
6766*38e8c45fSAndroid Build Coastguard Worker         // that we are in a good state to perform unhandled key event processing
6767*38e8c45fSAndroid Build Coastguard Worker         // Then ask the policy what to do with it.
6768*38e8c45fSAndroid Build Coastguard Worker         bool initialDown = keyEntry.action == AKEY_EVENT_ACTION_DOWN && keyEntry.repeatCount == 0;
6769*38e8c45fSAndroid Build Coastguard Worker         if (!fallbackKeyCode && !initialDown) {
6770*38e8c45fSAndroid Build Coastguard Worker             if (DEBUG_OUTBOUND_EVENT_DETAILS) {
6771*38e8c45fSAndroid Build Coastguard Worker                 ALOGD("Unhandled key event: Skipping unhandled key event processing "
6772*38e8c45fSAndroid Build Coastguard Worker                       "since this is not an initial down.  "
6773*38e8c45fSAndroid Build Coastguard Worker                       "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
6774*38e8c45fSAndroid Build Coastguard Worker                       originalKeyCode, keyEntry.action, keyEntry.repeatCount, keyEntry.policyFlags);
6775*38e8c45fSAndroid Build Coastguard Worker             }
6776*38e8c45fSAndroid Build Coastguard Worker             return {};
6777*38e8c45fSAndroid Build Coastguard Worker         }
6778*38e8c45fSAndroid Build Coastguard Worker 
6779*38e8c45fSAndroid Build Coastguard Worker         // Dispatch the unhandled key to the policy.
6780*38e8c45fSAndroid Build Coastguard Worker         if (DEBUG_OUTBOUND_EVENT_DETAILS) {
6781*38e8c45fSAndroid Build Coastguard Worker             ALOGD("Unhandled key event: Asking policy to perform fallback action.  "
6782*38e8c45fSAndroid Build Coastguard Worker                   "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
6783*38e8c45fSAndroid Build Coastguard Worker                   keyEntry.keyCode, keyEntry.action, keyEntry.repeatCount, keyEntry.policyFlags);
6784*38e8c45fSAndroid Build Coastguard Worker         }
6785*38e8c45fSAndroid Build Coastguard Worker         KeyEvent event = createKeyEvent(keyEntry);
6786*38e8c45fSAndroid Build Coastguard Worker 
6787*38e8c45fSAndroid Build Coastguard Worker         mLock.unlock();
6788*38e8c45fSAndroid Build Coastguard Worker 
6789*38e8c45fSAndroid Build Coastguard Worker         bool fallback = false;
6790*38e8c45fSAndroid Build Coastguard Worker         if (auto fb = mPolicy.dispatchUnhandledKey(connection->getToken(), event,
6791*38e8c45fSAndroid Build Coastguard Worker                                                    keyEntry.policyFlags);
6792*38e8c45fSAndroid Build Coastguard Worker             fb) {
6793*38e8c45fSAndroid Build Coastguard Worker             fallback = true;
6794*38e8c45fSAndroid Build Coastguard Worker             event = *fb;
6795*38e8c45fSAndroid Build Coastguard Worker         }
6796*38e8c45fSAndroid Build Coastguard Worker 
6797*38e8c45fSAndroid Build Coastguard Worker         mLock.lock();
6798*38e8c45fSAndroid Build Coastguard Worker 
6799*38e8c45fSAndroid Build Coastguard Worker         if (connection->status != Connection::Status::NORMAL) {
6800*38e8c45fSAndroid Build Coastguard Worker             connection->inputState.removeFallbackKey(originalKeyCode);
6801*38e8c45fSAndroid Build Coastguard Worker             return {};
6802*38e8c45fSAndroid Build Coastguard Worker         }
6803*38e8c45fSAndroid Build Coastguard Worker 
6804*38e8c45fSAndroid Build Coastguard Worker         // Latch the fallback keycode for this key on an initial down.
6805*38e8c45fSAndroid Build Coastguard Worker         // The fallback keycode cannot change at any other point in the lifecycle.
6806*38e8c45fSAndroid Build Coastguard Worker         if (initialDown) {
6807*38e8c45fSAndroid Build Coastguard Worker             if (fallback) {
6808*38e8c45fSAndroid Build Coastguard Worker                 fallbackKeyCode = event.getKeyCode();
6809*38e8c45fSAndroid Build Coastguard Worker             } else {
6810*38e8c45fSAndroid Build Coastguard Worker                 fallbackKeyCode = AKEYCODE_UNKNOWN;
6811*38e8c45fSAndroid Build Coastguard Worker             }
6812*38e8c45fSAndroid Build Coastguard Worker             connection->inputState.setFallbackKey(originalKeyCode, *fallbackKeyCode);
6813*38e8c45fSAndroid Build Coastguard Worker         }
6814*38e8c45fSAndroid Build Coastguard Worker 
6815*38e8c45fSAndroid Build Coastguard Worker         LOG_IF(FATAL, !fallbackKeyCode)
6816*38e8c45fSAndroid Build Coastguard Worker                 << "fallbackKeyCode is not initialized. initialDown = " << initialDown;
6817*38e8c45fSAndroid Build Coastguard Worker 
6818*38e8c45fSAndroid Build Coastguard Worker         // Cancel the fallback key if the policy decides not to send it anymore.
6819*38e8c45fSAndroid Build Coastguard Worker         // We will continue to dispatch the key to the policy but we will no
6820*38e8c45fSAndroid Build Coastguard Worker         // longer dispatch a fallback key to the application.
6821*38e8c45fSAndroid Build Coastguard Worker         if (*fallbackKeyCode != AKEYCODE_UNKNOWN &&
6822*38e8c45fSAndroid Build Coastguard Worker             (!fallback || *fallbackKeyCode != event.getKeyCode())) {
6823*38e8c45fSAndroid Build Coastguard Worker             if (DEBUG_OUTBOUND_EVENT_DETAILS) {
6824*38e8c45fSAndroid Build Coastguard Worker                 if (fallback) {
6825*38e8c45fSAndroid Build Coastguard Worker                     ALOGD("Unhandled key event: Policy requested to send key %d"
6826*38e8c45fSAndroid Build Coastguard Worker                           "as a fallback for %d, but on the DOWN it had requested "
6827*38e8c45fSAndroid Build Coastguard Worker                           "to send %d instead.  Fallback canceled.",
6828*38e8c45fSAndroid Build Coastguard Worker                           event.getKeyCode(), originalKeyCode, *fallbackKeyCode);
6829*38e8c45fSAndroid Build Coastguard Worker                 } else {
6830*38e8c45fSAndroid Build Coastguard Worker                     ALOGD("Unhandled key event: Policy did not request fallback for %d, "
6831*38e8c45fSAndroid Build Coastguard Worker                           "but on the DOWN it had requested to send %d.  "
6832*38e8c45fSAndroid Build Coastguard Worker                           "Fallback canceled.",
6833*38e8c45fSAndroid Build Coastguard Worker                           originalKeyCode, *fallbackKeyCode);
6834*38e8c45fSAndroid Build Coastguard Worker                 }
6835*38e8c45fSAndroid Build Coastguard Worker             }
6836*38e8c45fSAndroid Build Coastguard Worker 
6837*38e8c45fSAndroid Build Coastguard Worker             const auto windowHandle = getWindowHandleLocked(connection->getToken());
6838*38e8c45fSAndroid Build Coastguard Worker             if (windowHandle != nullptr) {
6839*38e8c45fSAndroid Build Coastguard Worker                 CancelationOptions options(CancelationOptions::Mode::CANCEL_FALLBACK_EVENTS,
6840*38e8c45fSAndroid Build Coastguard Worker                                            "canceling fallback, policy no longer desires it",
6841*38e8c45fSAndroid Build Coastguard Worker                                            keyEntry.traceTracker);
6842*38e8c45fSAndroid Build Coastguard Worker                 options.keyCode = *fallbackKeyCode;
6843*38e8c45fSAndroid Build Coastguard Worker                 synthesizeCancelationEventsForWindowLocked(windowHandle, options, connection);
6844*38e8c45fSAndroid Build Coastguard Worker             }
6845*38e8c45fSAndroid Build Coastguard Worker 
6846*38e8c45fSAndroid Build Coastguard Worker             fallback = false;
6847*38e8c45fSAndroid Build Coastguard Worker             *fallbackKeyCode = AKEYCODE_UNKNOWN;
6848*38e8c45fSAndroid Build Coastguard Worker             if (keyEntry.action != AKEY_EVENT_ACTION_UP) {
6849*38e8c45fSAndroid Build Coastguard Worker                 connection->inputState.setFallbackKey(originalKeyCode, *fallbackKeyCode);
6850*38e8c45fSAndroid Build Coastguard Worker             }
6851*38e8c45fSAndroid Build Coastguard Worker         }
6852*38e8c45fSAndroid Build Coastguard Worker 
6853*38e8c45fSAndroid Build Coastguard Worker         if (DEBUG_OUTBOUND_EVENT_DETAILS) {
6854*38e8c45fSAndroid Build Coastguard Worker             {
6855*38e8c45fSAndroid Build Coastguard Worker                 std::string msg;
6856*38e8c45fSAndroid Build Coastguard Worker                 const std::map<int32_t, int32_t>& fallbackKeys =
6857*38e8c45fSAndroid Build Coastguard Worker                         connection->inputState.getFallbackKeys();
6858*38e8c45fSAndroid Build Coastguard Worker                 for (const auto& [key, value] : fallbackKeys) {
6859*38e8c45fSAndroid Build Coastguard Worker                     msg += StringPrintf(", %d->%d", key, value);
6860*38e8c45fSAndroid Build Coastguard Worker                 }
6861*38e8c45fSAndroid Build Coastguard Worker                 ALOGD("Unhandled key event: %zu currently tracked fallback keys%s.",
6862*38e8c45fSAndroid Build Coastguard Worker                       fallbackKeys.size(), msg.c_str());
6863*38e8c45fSAndroid Build Coastguard Worker             }
6864*38e8c45fSAndroid Build Coastguard Worker         }
6865*38e8c45fSAndroid Build Coastguard Worker 
6866*38e8c45fSAndroid Build Coastguard Worker         if (fallback) {
6867*38e8c45fSAndroid Build Coastguard Worker             // Return the fallback key that we want dispatched to the channel.
6868*38e8c45fSAndroid Build Coastguard Worker             std::unique_ptr<KeyEntry> newEntry =
6869*38e8c45fSAndroid Build Coastguard Worker                     std::make_unique<KeyEntry>(mIdGenerator.nextId(), keyEntry.injectionState,
6870*38e8c45fSAndroid Build Coastguard Worker                                                event.getEventTime(), event.getDeviceId(),
6871*38e8c45fSAndroid Build Coastguard Worker                                                event.getSource(), event.getDisplayId(),
6872*38e8c45fSAndroid Build Coastguard Worker                                                keyEntry.policyFlags, keyEntry.action,
6873*38e8c45fSAndroid Build Coastguard Worker                                                event.getFlags() | AKEY_EVENT_FLAG_FALLBACK,
6874*38e8c45fSAndroid Build Coastguard Worker                                                *fallbackKeyCode, event.getScanCode(),
6875*38e8c45fSAndroid Build Coastguard Worker                                                event.getMetaState(), event.getRepeatCount(),
6876*38e8c45fSAndroid Build Coastguard Worker                                                event.getDownTime());
6877*38e8c45fSAndroid Build Coastguard Worker             if (mTracer) {
6878*38e8c45fSAndroid Build Coastguard Worker                 newEntry->traceTracker =
6879*38e8c45fSAndroid Build Coastguard Worker                         mTracer->traceDerivedEvent(*newEntry, *keyEntry.traceTracker);
6880*38e8c45fSAndroid Build Coastguard Worker             }
6881*38e8c45fSAndroid Build Coastguard Worker             if (DEBUG_OUTBOUND_EVENT_DETAILS) {
6882*38e8c45fSAndroid Build Coastguard Worker                 ALOGD("Unhandled key event: Dispatching fallback key.  "
6883*38e8c45fSAndroid Build Coastguard Worker                       "originalKeyCode=%d, fallbackKeyCode=%d, fallbackMetaState=%08x",
6884*38e8c45fSAndroid Build Coastguard Worker                       originalKeyCode, *fallbackKeyCode, keyEntry.metaState);
6885*38e8c45fSAndroid Build Coastguard Worker             }
6886*38e8c45fSAndroid Build Coastguard Worker             return newEntry;
6887*38e8c45fSAndroid Build Coastguard Worker         } else {
6888*38e8c45fSAndroid Build Coastguard Worker             if (DEBUG_OUTBOUND_EVENT_DETAILS) {
6889*38e8c45fSAndroid Build Coastguard Worker                 ALOGD("Unhandled key event: No fallback key.");
6890*38e8c45fSAndroid Build Coastguard Worker             }
6891*38e8c45fSAndroid Build Coastguard Worker 
6892*38e8c45fSAndroid Build Coastguard Worker             // Report the key as unhandled, since there is no fallback key.
6893*38e8c45fSAndroid Build Coastguard Worker             mReporter->reportUnhandledKey(keyEntry.id);
6894*38e8c45fSAndroid Build Coastguard Worker         }
6895*38e8c45fSAndroid Build Coastguard Worker     }
6896*38e8c45fSAndroid Build Coastguard Worker     return {};
6897*38e8c45fSAndroid Build Coastguard Worker }
6898*38e8c45fSAndroid Build Coastguard Worker 
traceInboundQueueLengthLocked()6899*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::traceInboundQueueLengthLocked() {
6900*38e8c45fSAndroid Build Coastguard Worker     if (ATRACE_ENABLED()) {
6901*38e8c45fSAndroid Build Coastguard Worker         ATRACE_INT("iq", mInboundQueue.size());
6902*38e8c45fSAndroid Build Coastguard Worker     }
6903*38e8c45fSAndroid Build Coastguard Worker }
6904*38e8c45fSAndroid Build Coastguard Worker 
traceOutboundQueueLength(const Connection & connection)6905*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::traceOutboundQueueLength(const Connection& connection) {
6906*38e8c45fSAndroid Build Coastguard Worker     if (ATRACE_ENABLED()) {
6907*38e8c45fSAndroid Build Coastguard Worker         char counterName[40];
6908*38e8c45fSAndroid Build Coastguard Worker         snprintf(counterName, sizeof(counterName), "oq:%s",
6909*38e8c45fSAndroid Build Coastguard Worker                  connection.getInputChannelName().c_str());
6910*38e8c45fSAndroid Build Coastguard Worker         ATRACE_INT(counterName, connection.outboundQueue.size());
6911*38e8c45fSAndroid Build Coastguard Worker     }
6912*38e8c45fSAndroid Build Coastguard Worker }
6913*38e8c45fSAndroid Build Coastguard Worker 
traceWaitQueueLength(const Connection & connection)6914*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::traceWaitQueueLength(const Connection& connection) {
6915*38e8c45fSAndroid Build Coastguard Worker     if (ATRACE_ENABLED()) {
6916*38e8c45fSAndroid Build Coastguard Worker         char counterName[40];
6917*38e8c45fSAndroid Build Coastguard Worker         snprintf(counterName, sizeof(counterName), "wq:%s",
6918*38e8c45fSAndroid Build Coastguard Worker                  connection.getInputChannelName().c_str());
6919*38e8c45fSAndroid Build Coastguard Worker         ATRACE_INT(counterName, connection.waitQueue.size());
6920*38e8c45fSAndroid Build Coastguard Worker     }
6921*38e8c45fSAndroid Build Coastguard Worker }
6922*38e8c45fSAndroid Build Coastguard Worker 
dump(std::string & dump) const6923*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::dump(std::string& dump) const {
6924*38e8c45fSAndroid Build Coastguard Worker     std::scoped_lock _l(mLock);
6925*38e8c45fSAndroid Build Coastguard Worker 
6926*38e8c45fSAndroid Build Coastguard Worker     dump += "Input Dispatcher State:\n";
6927*38e8c45fSAndroid Build Coastguard Worker     dumpDispatchStateLocked(dump);
6928*38e8c45fSAndroid Build Coastguard Worker 
6929*38e8c45fSAndroid Build Coastguard Worker     if (!mLastAnrState.empty()) {
6930*38e8c45fSAndroid Build Coastguard Worker         dump += "\nInput Dispatcher State at time of last ANR:\n";
6931*38e8c45fSAndroid Build Coastguard Worker         dump += mLastAnrState;
6932*38e8c45fSAndroid Build Coastguard Worker     }
6933*38e8c45fSAndroid Build Coastguard Worker }
6934*38e8c45fSAndroid Build Coastguard Worker 
monitor()6935*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::monitor() {
6936*38e8c45fSAndroid Build Coastguard Worker     // Acquire and release the lock to ensure that the dispatcher has not deadlocked.
6937*38e8c45fSAndroid Build Coastguard Worker     std::unique_lock _l(mLock);
6938*38e8c45fSAndroid Build Coastguard Worker     mLooper->wake();
6939*38e8c45fSAndroid Build Coastguard Worker     mDispatcherIsAlive.wait(_l);
6940*38e8c45fSAndroid Build Coastguard Worker }
6941*38e8c45fSAndroid Build Coastguard Worker 
6942*38e8c45fSAndroid Build Coastguard Worker /**
6943*38e8c45fSAndroid Build Coastguard Worker  * Wake up the dispatcher and wait until it processes all events and commands.
6944*38e8c45fSAndroid Build Coastguard Worker  * The notification of mDispatcherEnteredIdle is guaranteed to happen after wake(), so
6945*38e8c45fSAndroid Build Coastguard Worker  * this method can be safely called from any thread, as long as you've ensured that
6946*38e8c45fSAndroid Build Coastguard Worker  * the work you are interested in completing has already been queued.
6947*38e8c45fSAndroid Build Coastguard Worker  */
waitForIdle() const6948*38e8c45fSAndroid Build Coastguard Worker bool InputDispatcher::waitForIdle() const {
6949*38e8c45fSAndroid Build Coastguard Worker     /**
6950*38e8c45fSAndroid Build Coastguard Worker      * Timeout should represent the longest possible time that a device might spend processing
6951*38e8c45fSAndroid Build Coastguard Worker      * events and commands.
6952*38e8c45fSAndroid Build Coastguard Worker      */
6953*38e8c45fSAndroid Build Coastguard Worker     constexpr std::chrono::duration TIMEOUT = 100ms;
6954*38e8c45fSAndroid Build Coastguard Worker     std::unique_lock lock(mLock);
6955*38e8c45fSAndroid Build Coastguard Worker     mLooper->wake();
6956*38e8c45fSAndroid Build Coastguard Worker     std::cv_status result = mDispatcherEnteredIdle.wait_for(lock, TIMEOUT);
6957*38e8c45fSAndroid Build Coastguard Worker     return result == std::cv_status::no_timeout;
6958*38e8c45fSAndroid Build Coastguard Worker }
6959*38e8c45fSAndroid Build Coastguard Worker 
6960*38e8c45fSAndroid Build Coastguard Worker /**
6961*38e8c45fSAndroid Build Coastguard Worker  * Sets focus to the window identified by the token. This must be called
6962*38e8c45fSAndroid Build Coastguard Worker  * after updating any input window handles.
6963*38e8c45fSAndroid Build Coastguard Worker  *
6964*38e8c45fSAndroid Build Coastguard Worker  * Params:
6965*38e8c45fSAndroid Build Coastguard Worker  *  request.token - input channel token used to identify the window that should gain focus.
6966*38e8c45fSAndroid Build Coastguard Worker  *  request.focusedToken - the token that the caller expects currently to be focused. If the
6967*38e8c45fSAndroid Build Coastguard Worker  *  specified token does not match the currently focused window, this request will be dropped.
6968*38e8c45fSAndroid Build Coastguard Worker  *  If the specified focused token matches the currently focused window, the call will succeed.
6969*38e8c45fSAndroid Build Coastguard Worker  *  Set this to "null" if this call should succeed no matter what the currently focused token is.
6970*38e8c45fSAndroid Build Coastguard Worker  *  request.timestamp - SYSTEM_TIME_MONOTONIC timestamp in nanos set by the client (wm)
6971*38e8c45fSAndroid Build Coastguard Worker  *  when requesting the focus change. This determines which request gets
6972*38e8c45fSAndroid Build Coastguard Worker  *  precedence if there is a focus change request from another source such as pointer down.
6973*38e8c45fSAndroid Build Coastguard Worker  */
setFocusedWindow(const FocusRequest & request)6974*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::setFocusedWindow(const FocusRequest& request) {
6975*38e8c45fSAndroid Build Coastguard Worker     { // acquire lock
6976*38e8c45fSAndroid Build Coastguard Worker         std::scoped_lock _l(mLock);
6977*38e8c45fSAndroid Build Coastguard Worker         std::optional<FocusResolver::FocusChanges> changes =
6978*38e8c45fSAndroid Build Coastguard Worker                 mFocusResolver.setFocusedWindow(request,
6979*38e8c45fSAndroid Build Coastguard Worker                                                 getWindowHandlesLocked(
6980*38e8c45fSAndroid Build Coastguard Worker                                                         ui::LogicalDisplayId{request.displayId}));
6981*38e8c45fSAndroid Build Coastguard Worker         ScopedSyntheticEventTracer traceContext(mTracer);
6982*38e8c45fSAndroid Build Coastguard Worker         if (changes) {
6983*38e8c45fSAndroid Build Coastguard Worker             onFocusChangedLocked(*changes, traceContext.getTracker());
6984*38e8c45fSAndroid Build Coastguard Worker         }
6985*38e8c45fSAndroid Build Coastguard Worker     } // release lock
6986*38e8c45fSAndroid Build Coastguard Worker     // Wake up poll loop since it may need to make new input dispatching choices.
6987*38e8c45fSAndroid Build Coastguard Worker     mLooper->wake();
6988*38e8c45fSAndroid Build Coastguard Worker }
6989*38e8c45fSAndroid Build Coastguard Worker 
onFocusChangedLocked(const FocusResolver::FocusChanges & changes,const std::unique_ptr<trace::EventTrackerInterface> & traceTracker,const sp<WindowInfoHandle> removedFocusedWindowHandle)6990*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::onFocusChangedLocked(
6991*38e8c45fSAndroid Build Coastguard Worker         const FocusResolver::FocusChanges& changes,
6992*38e8c45fSAndroid Build Coastguard Worker         const std::unique_ptr<trace::EventTrackerInterface>& traceTracker,
6993*38e8c45fSAndroid Build Coastguard Worker         const sp<WindowInfoHandle> removedFocusedWindowHandle) {
6994*38e8c45fSAndroid Build Coastguard Worker     if (changes.oldFocus) {
6995*38e8c45fSAndroid Build Coastguard Worker         const auto resolvedWindow = removedFocusedWindowHandle != nullptr
6996*38e8c45fSAndroid Build Coastguard Worker                 ? removedFocusedWindowHandle
6997*38e8c45fSAndroid Build Coastguard Worker                 : getWindowHandleLocked(changes.oldFocus, changes.displayId);
6998*38e8c45fSAndroid Build Coastguard Worker         if (resolvedWindow == nullptr) {
6999*38e8c45fSAndroid Build Coastguard Worker             LOG(FATAL) << __func__ << ": Previously focused token did not have a window";
7000*38e8c45fSAndroid Build Coastguard Worker         }
7001*38e8c45fSAndroid Build Coastguard Worker         CancelationOptions options(CancelationOptions::Mode::CANCEL_NON_POINTER_EVENTS,
7002*38e8c45fSAndroid Build Coastguard Worker                                    "focus left window", traceTracker);
7003*38e8c45fSAndroid Build Coastguard Worker         synthesizeCancelationEventsForWindowLocked(resolvedWindow, options);
7004*38e8c45fSAndroid Build Coastguard Worker         enqueueFocusEventLocked(changes.oldFocus, /*hasFocus=*/false, changes.reason);
7005*38e8c45fSAndroid Build Coastguard Worker     }
7006*38e8c45fSAndroid Build Coastguard Worker     if (changes.newFocus) {
7007*38e8c45fSAndroid Build Coastguard Worker         resetNoFocusedWindowTimeoutLocked();
7008*38e8c45fSAndroid Build Coastguard Worker         enqueueFocusEventLocked(changes.newFocus, /*hasFocus=*/true, changes.reason);
7009*38e8c45fSAndroid Build Coastguard Worker     }
7010*38e8c45fSAndroid Build Coastguard Worker 
7011*38e8c45fSAndroid Build Coastguard Worker     if (mFocusedDisplayId == changes.displayId) {
7012*38e8c45fSAndroid Build Coastguard Worker         // If a window has pointer capture, then it must have focus and must be on the top-focused
7013*38e8c45fSAndroid Build Coastguard Worker         // display. We need to ensure that this contract is upheld when pointer capture is being
7014*38e8c45fSAndroid Build Coastguard Worker         // disabled due to a loss of window focus. If the window loses focus before it loses pointer
7015*38e8c45fSAndroid Build Coastguard Worker         // capture, then the window can be in a state where it has pointer capture but not focus,
7016*38e8c45fSAndroid Build Coastguard Worker         // violating the contract. Therefore we must dispatch the pointer capture event before the
7017*38e8c45fSAndroid Build Coastguard Worker         // focus event. Since focus events are added to the front of the queue (above), we add the
7018*38e8c45fSAndroid Build Coastguard Worker         // pointer capture event to the front of the queue after the focus events are added. This
7019*38e8c45fSAndroid Build Coastguard Worker         // ensures the pointer capture event ends up at the front.
7020*38e8c45fSAndroid Build Coastguard Worker         disablePointerCaptureForcedLocked();
7021*38e8c45fSAndroid Build Coastguard Worker 
7022*38e8c45fSAndroid Build Coastguard Worker         sendFocusChangedCommandLocked(changes.oldFocus, changes.newFocus);
7023*38e8c45fSAndroid Build Coastguard Worker     }
7024*38e8c45fSAndroid Build Coastguard Worker }
7025*38e8c45fSAndroid Build Coastguard Worker 
disablePointerCaptureForcedLocked()7026*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::disablePointerCaptureForcedLocked() {
7027*38e8c45fSAndroid Build Coastguard Worker     if (!mCurrentPointerCaptureRequest.isEnable() && !mWindowTokenWithPointerCapture) {
7028*38e8c45fSAndroid Build Coastguard Worker         return;
7029*38e8c45fSAndroid Build Coastguard Worker     }
7030*38e8c45fSAndroid Build Coastguard Worker 
7031*38e8c45fSAndroid Build Coastguard Worker     ALOGD_IF(DEBUG_FOCUS, "Disabling Pointer Capture because the window lost focus.");
7032*38e8c45fSAndroid Build Coastguard Worker 
7033*38e8c45fSAndroid Build Coastguard Worker     if (mCurrentPointerCaptureRequest.isEnable()) {
7034*38e8c45fSAndroid Build Coastguard Worker         setPointerCaptureLocked(nullptr);
7035*38e8c45fSAndroid Build Coastguard Worker     }
7036*38e8c45fSAndroid Build Coastguard Worker 
7037*38e8c45fSAndroid Build Coastguard Worker     if (!mWindowTokenWithPointerCapture) {
7038*38e8c45fSAndroid Build Coastguard Worker         // No need to send capture changes because no window has capture.
7039*38e8c45fSAndroid Build Coastguard Worker         return;
7040*38e8c45fSAndroid Build Coastguard Worker     }
7041*38e8c45fSAndroid Build Coastguard Worker 
7042*38e8c45fSAndroid Build Coastguard Worker     if (mPendingEvent != nullptr) {
7043*38e8c45fSAndroid Build Coastguard Worker         // Move the pending event to the front of the queue. This will give the chance
7044*38e8c45fSAndroid Build Coastguard Worker         // for the pending event to be dropped if it is a captured event.
7045*38e8c45fSAndroid Build Coastguard Worker         mInboundQueue.push_front(mPendingEvent);
7046*38e8c45fSAndroid Build Coastguard Worker         mPendingEvent = nullptr;
7047*38e8c45fSAndroid Build Coastguard Worker     }
7048*38e8c45fSAndroid Build Coastguard Worker 
7049*38e8c45fSAndroid Build Coastguard Worker     auto entry = std::make_unique<PointerCaptureChangedEntry>(mIdGenerator.nextId(), now(),
7050*38e8c45fSAndroid Build Coastguard Worker                                                               mCurrentPointerCaptureRequest);
7051*38e8c45fSAndroid Build Coastguard Worker     mInboundQueue.push_front(std::move(entry));
7052*38e8c45fSAndroid Build Coastguard Worker }
7053*38e8c45fSAndroid Build Coastguard Worker 
setPointerCaptureLocked(const sp<IBinder> & windowToken)7054*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::setPointerCaptureLocked(const sp<IBinder>& windowToken) {
7055*38e8c45fSAndroid Build Coastguard Worker     mCurrentPointerCaptureRequest.window = windowToken;
7056*38e8c45fSAndroid Build Coastguard Worker     mCurrentPointerCaptureRequest.seq++;
7057*38e8c45fSAndroid Build Coastguard Worker     auto command = [this, request = mCurrentPointerCaptureRequest]() REQUIRES(mLock) {
7058*38e8c45fSAndroid Build Coastguard Worker         scoped_unlock unlock(mLock);
7059*38e8c45fSAndroid Build Coastguard Worker         mPolicy.setPointerCapture(request);
7060*38e8c45fSAndroid Build Coastguard Worker     };
7061*38e8c45fSAndroid Build Coastguard Worker     postCommandLocked(std::move(command));
7062*38e8c45fSAndroid Build Coastguard Worker }
7063*38e8c45fSAndroid Build Coastguard Worker 
displayRemoved(ui::LogicalDisplayId displayId)7064*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::displayRemoved(ui::LogicalDisplayId displayId) {
7065*38e8c45fSAndroid Build Coastguard Worker     { // acquire lock
7066*38e8c45fSAndroid Build Coastguard Worker         std::scoped_lock _l(mLock);
7067*38e8c45fSAndroid Build Coastguard Worker         // Set an empty list to remove all handles from the specific display.
7068*38e8c45fSAndroid Build Coastguard Worker         setInputWindowsLocked(/*windowInfoHandles=*/{}, displayId);
7069*38e8c45fSAndroid Build Coastguard Worker         setFocusedApplicationLocked(displayId, nullptr);
7070*38e8c45fSAndroid Build Coastguard Worker         // Call focus resolver to clean up stale requests. This must be called after input windows
7071*38e8c45fSAndroid Build Coastguard Worker         // have been removed for the removed display.
7072*38e8c45fSAndroid Build Coastguard Worker         mFocusResolver.displayRemoved(displayId);
7073*38e8c45fSAndroid Build Coastguard Worker         // Reset pointer capture eligibility, regardless of previous state.
7074*38e8c45fSAndroid Build Coastguard Worker         std::erase(mIneligibleDisplaysForPointerCapture, displayId);
7075*38e8c45fSAndroid Build Coastguard Worker         // Remove the associated touch mode state.
7076*38e8c45fSAndroid Build Coastguard Worker         mTouchModePerDisplay.erase(displayId);
7077*38e8c45fSAndroid Build Coastguard Worker         mVerifiersByDisplay.erase(displayId);
7078*38e8c45fSAndroid Build Coastguard Worker         mInputFilterVerifiersByDisplay.erase(displayId);
7079*38e8c45fSAndroid Build Coastguard Worker     } // release lock
7080*38e8c45fSAndroid Build Coastguard Worker 
7081*38e8c45fSAndroid Build Coastguard Worker     // Wake up poll loop since it may need to make new input dispatching choices.
7082*38e8c45fSAndroid Build Coastguard Worker     mLooper->wake();
7083*38e8c45fSAndroid Build Coastguard Worker }
7084*38e8c45fSAndroid Build Coastguard Worker 
onWindowInfosChanged(const gui::WindowInfosUpdate & update)7085*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::onWindowInfosChanged(const gui::WindowInfosUpdate& update) {
7086*38e8c45fSAndroid Build Coastguard Worker     if (auto result = validateWindowInfosUpdate(update); !result.ok()) {
7087*38e8c45fSAndroid Build Coastguard Worker         {
7088*38e8c45fSAndroid Build Coastguard Worker             // acquire lock
7089*38e8c45fSAndroid Build Coastguard Worker             std::scoped_lock _l(mLock);
7090*38e8c45fSAndroid Build Coastguard Worker             logDispatchStateLocked();
7091*38e8c45fSAndroid Build Coastguard Worker         }
7092*38e8c45fSAndroid Build Coastguard Worker         LOG_ALWAYS_FATAL("Incorrect WindowInfosUpdate provided: %s",
7093*38e8c45fSAndroid Build Coastguard Worker                          result.error().message().c_str());
7094*38e8c45fSAndroid Build Coastguard Worker     };
7095*38e8c45fSAndroid Build Coastguard Worker     // The listener sends the windows as a flattened array. Separate the windows by display for
7096*38e8c45fSAndroid Build Coastguard Worker     // more convenient parsing.
7097*38e8c45fSAndroid Build Coastguard Worker     std::unordered_map<ui::LogicalDisplayId, std::vector<sp<WindowInfoHandle>>> handlesPerDisplay;
7098*38e8c45fSAndroid Build Coastguard Worker     for (const auto& info : update.windowInfos) {
7099*38e8c45fSAndroid Build Coastguard Worker         handlesPerDisplay.emplace(info.displayId, std::vector<sp<WindowInfoHandle>>());
7100*38e8c45fSAndroid Build Coastguard Worker         handlesPerDisplay[info.displayId].push_back(sp<WindowInfoHandle>::make(info));
7101*38e8c45fSAndroid Build Coastguard Worker         if (input_flags::split_all_touches()) {
7102*38e8c45fSAndroid Build Coastguard Worker             handlesPerDisplay[info.displayId]
7103*38e8c45fSAndroid Build Coastguard Worker                     .back()
7104*38e8c45fSAndroid Build Coastguard Worker                     ->editInfo()
7105*38e8c45fSAndroid Build Coastguard Worker                     ->setInputConfig(android::gui::WindowInfo::InputConfig::PREVENT_SPLITTING,
7106*38e8c45fSAndroid Build Coastguard Worker                                      false);
7107*38e8c45fSAndroid Build Coastguard Worker         }
7108*38e8c45fSAndroid Build Coastguard Worker     }
7109*38e8c45fSAndroid Build Coastguard Worker 
7110*38e8c45fSAndroid Build Coastguard Worker     { // acquire lock
7111*38e8c45fSAndroid Build Coastguard Worker         std::scoped_lock _l(mLock);
7112*38e8c45fSAndroid Build Coastguard Worker 
7113*38e8c45fSAndroid Build Coastguard Worker         // Ensure that we have an entry created for all existing displays so that if a displayId has
7114*38e8c45fSAndroid Build Coastguard Worker         // no windows, we can tell that the windows were removed from the display.
7115*38e8c45fSAndroid Build Coastguard Worker         for (const auto& [displayId, _] : mWindowHandlesByDisplay) {
7116*38e8c45fSAndroid Build Coastguard Worker             handlesPerDisplay[displayId];
7117*38e8c45fSAndroid Build Coastguard Worker         }
7118*38e8c45fSAndroid Build Coastguard Worker 
7119*38e8c45fSAndroid Build Coastguard Worker         mDisplayInfos.clear();
7120*38e8c45fSAndroid Build Coastguard Worker         for (const auto& displayInfo : update.displayInfos) {
7121*38e8c45fSAndroid Build Coastguard Worker             mDisplayInfos.emplace(displayInfo.displayId, displayInfo);
7122*38e8c45fSAndroid Build Coastguard Worker         }
7123*38e8c45fSAndroid Build Coastguard Worker 
7124*38e8c45fSAndroid Build Coastguard Worker         for (const auto& [displayId, handles] : handlesPerDisplay) {
7125*38e8c45fSAndroid Build Coastguard Worker             setInputWindowsLocked(handles, displayId);
7126*38e8c45fSAndroid Build Coastguard Worker         }
7127*38e8c45fSAndroid Build Coastguard Worker 
7128*38e8c45fSAndroid Build Coastguard Worker         if (update.vsyncId < mWindowInfosVsyncId) {
7129*38e8c45fSAndroid Build Coastguard Worker             ALOGE("Received out of order window infos update. Last update vsync id: %" PRId64
7130*38e8c45fSAndroid Build Coastguard Worker                   ", current update vsync id: %" PRId64,
7131*38e8c45fSAndroid Build Coastguard Worker                   mWindowInfosVsyncId, update.vsyncId);
7132*38e8c45fSAndroid Build Coastguard Worker         }
7133*38e8c45fSAndroid Build Coastguard Worker         mWindowInfosVsyncId = update.vsyncId;
7134*38e8c45fSAndroid Build Coastguard Worker     }
7135*38e8c45fSAndroid Build Coastguard Worker     // Wake up poll loop since it may need to make new input dispatching choices.
7136*38e8c45fSAndroid Build Coastguard Worker     mLooper->wake();
7137*38e8c45fSAndroid Build Coastguard Worker }
7138*38e8c45fSAndroid Build Coastguard Worker 
shouldDropInput(const EventEntry & entry,const sp<android::gui::WindowInfoHandle> & windowHandle) const7139*38e8c45fSAndroid Build Coastguard Worker bool InputDispatcher::shouldDropInput(
7140*38e8c45fSAndroid Build Coastguard Worker         const EventEntry& entry, const sp<android::gui::WindowInfoHandle>& windowHandle) const {
7141*38e8c45fSAndroid Build Coastguard Worker     if (windowHandle->getInfo()->inputConfig.test(WindowInfo::InputConfig::DROP_INPUT) ||
7142*38e8c45fSAndroid Build Coastguard Worker         (windowHandle->getInfo()->inputConfig.test(
7143*38e8c45fSAndroid Build Coastguard Worker                  WindowInfo::InputConfig::DROP_INPUT_IF_OBSCURED) &&
7144*38e8c45fSAndroid Build Coastguard Worker          isWindowObscuredLocked(windowHandle))) {
7145*38e8c45fSAndroid Build Coastguard Worker         ALOGW("Dropping %s event targeting %s as requested by the input configuration {%s} on "
7146*38e8c45fSAndroid Build Coastguard Worker               "display %s.",
7147*38e8c45fSAndroid Build Coastguard Worker               ftl::enum_string(entry.type).c_str(), windowHandle->getName().c_str(),
7148*38e8c45fSAndroid Build Coastguard Worker               windowHandle->getInfo()->inputConfig.string().c_str(),
7149*38e8c45fSAndroid Build Coastguard Worker               windowHandle->getInfo()->displayId.toString().c_str());
7150*38e8c45fSAndroid Build Coastguard Worker         return true;
7151*38e8c45fSAndroid Build Coastguard Worker     }
7152*38e8c45fSAndroid Build Coastguard Worker     return false;
7153*38e8c45fSAndroid Build Coastguard Worker }
7154*38e8c45fSAndroid Build Coastguard Worker 
onWindowInfosChanged(const gui::WindowInfosUpdate & update)7155*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::DispatcherWindowListener::onWindowInfosChanged(
7156*38e8c45fSAndroid Build Coastguard Worker         const gui::WindowInfosUpdate& update) {
7157*38e8c45fSAndroid Build Coastguard Worker     mDispatcher.onWindowInfosChanged(update);
7158*38e8c45fSAndroid Build Coastguard Worker }
7159*38e8c45fSAndroid Build Coastguard Worker 
cancelCurrentTouch()7160*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::cancelCurrentTouch() {
7161*38e8c45fSAndroid Build Coastguard Worker     {
7162*38e8c45fSAndroid Build Coastguard Worker         std::scoped_lock _l(mLock);
7163*38e8c45fSAndroid Build Coastguard Worker         ScopedSyntheticEventTracer traceContext(mTracer);
7164*38e8c45fSAndroid Build Coastguard Worker         ALOGD("Canceling all ongoing pointer gestures on all displays.");
7165*38e8c45fSAndroid Build Coastguard Worker         CancelationOptions options(CancelationOptions::Mode::CANCEL_POINTER_EVENTS,
7166*38e8c45fSAndroid Build Coastguard Worker                                    "cancel current touch", traceContext.getTracker());
7167*38e8c45fSAndroid Build Coastguard Worker         synthesizeCancelationEventsForAllConnectionsLocked(options);
7168*38e8c45fSAndroid Build Coastguard Worker 
7169*38e8c45fSAndroid Build Coastguard Worker         mTouchStatesByDisplay.clear();
7170*38e8c45fSAndroid Build Coastguard Worker     }
7171*38e8c45fSAndroid Build Coastguard Worker     // Wake up poll loop since there might be work to do.
7172*38e8c45fSAndroid Build Coastguard Worker     mLooper->wake();
7173*38e8c45fSAndroid Build Coastguard Worker }
7174*38e8c45fSAndroid Build Coastguard Worker 
setMonitorDispatchingTimeoutForTest(std::chrono::nanoseconds timeout)7175*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::setMonitorDispatchingTimeoutForTest(std::chrono::nanoseconds timeout) {
7176*38e8c45fSAndroid Build Coastguard Worker     std::scoped_lock _l(mLock);
7177*38e8c45fSAndroid Build Coastguard Worker     mMonitorDispatchingTimeout = timeout;
7178*38e8c45fSAndroid Build Coastguard Worker }
7179*38e8c45fSAndroid Build Coastguard Worker 
slipWallpaperTouch(ftl::Flags<InputTarget::Flags> targetFlags,const sp<WindowInfoHandle> & oldWindowHandle,const sp<WindowInfoHandle> & newWindowHandle,TouchState & state,const MotionEntry & entry,std::vector<InputTarget> & targets) const7180*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::slipWallpaperTouch(ftl::Flags<InputTarget::Flags> targetFlags,
7181*38e8c45fSAndroid Build Coastguard Worker                                          const sp<WindowInfoHandle>& oldWindowHandle,
7182*38e8c45fSAndroid Build Coastguard Worker                                          const sp<WindowInfoHandle>& newWindowHandle,
7183*38e8c45fSAndroid Build Coastguard Worker                                          TouchState& state, const MotionEntry& entry,
7184*38e8c45fSAndroid Build Coastguard Worker                                          std::vector<InputTarget>& targets) const {
7185*38e8c45fSAndroid Build Coastguard Worker     LOG_IF(FATAL, entry.getPointerCount() != 1) << "Entry not eligible for slip: " << entry;
7186*38e8c45fSAndroid Build Coastguard Worker     const DeviceId deviceId = entry.deviceId;
7187*38e8c45fSAndroid Build Coastguard Worker     const PointerProperties& pointerProperties = entry.pointerProperties[0];
7188*38e8c45fSAndroid Build Coastguard Worker     std::vector<PointerProperties> pointers{pointerProperties};
7189*38e8c45fSAndroid Build Coastguard Worker     const bool oldHasWallpaper = oldWindowHandle->getInfo()->inputConfig.test(
7190*38e8c45fSAndroid Build Coastguard Worker             gui::WindowInfo::InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER);
7191*38e8c45fSAndroid Build Coastguard Worker     const bool newHasWallpaper = targetFlags.test(InputTarget::Flags::FOREGROUND) &&
7192*38e8c45fSAndroid Build Coastguard Worker             newWindowHandle->getInfo()->inputConfig.test(
7193*38e8c45fSAndroid Build Coastguard Worker                     gui::WindowInfo::InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER);
7194*38e8c45fSAndroid Build Coastguard Worker     const sp<WindowInfoHandle> oldWallpaper =
7195*38e8c45fSAndroid Build Coastguard Worker             oldHasWallpaper ? state.getWallpaperWindow(deviceId) : nullptr;
7196*38e8c45fSAndroid Build Coastguard Worker     const sp<WindowInfoHandle> newWallpaper =
7197*38e8c45fSAndroid Build Coastguard Worker             newHasWallpaper ? findWallpaperWindowBelow(newWindowHandle) : nullptr;
7198*38e8c45fSAndroid Build Coastguard Worker     if (oldWallpaper == newWallpaper) {
7199*38e8c45fSAndroid Build Coastguard Worker         return;
7200*38e8c45fSAndroid Build Coastguard Worker     }
7201*38e8c45fSAndroid Build Coastguard Worker 
7202*38e8c45fSAndroid Build Coastguard Worker     if (oldWallpaper != nullptr) {
7203*38e8c45fSAndroid Build Coastguard Worker         const TouchedWindow& oldTouchedWindow = state.getTouchedWindow(oldWallpaper);
7204*38e8c45fSAndroid Build Coastguard Worker         addPointerWindowTargetLocked(oldWallpaper, InputTarget::DispatchMode::SLIPPERY_EXIT,
7205*38e8c45fSAndroid Build Coastguard Worker                                      oldTouchedWindow.targetFlags, getPointerIds(pointers),
7206*38e8c45fSAndroid Build Coastguard Worker                                      oldTouchedWindow.getDownTimeInTarget(deviceId), targets);
7207*38e8c45fSAndroid Build Coastguard Worker         state.removeTouchingPointerFromWindow(deviceId, pointerProperties.id, oldWallpaper);
7208*38e8c45fSAndroid Build Coastguard Worker     }
7209*38e8c45fSAndroid Build Coastguard Worker 
7210*38e8c45fSAndroid Build Coastguard Worker     if (newWallpaper != nullptr) {
7211*38e8c45fSAndroid Build Coastguard Worker         state.addOrUpdateWindow(newWallpaper, InputTarget::DispatchMode::SLIPPERY_ENTER,
7212*38e8c45fSAndroid Build Coastguard Worker                                 InputTarget::Flags::WINDOW_IS_OBSCURED |
7213*38e8c45fSAndroid Build Coastguard Worker                                         InputTarget::Flags::WINDOW_IS_PARTIALLY_OBSCURED,
7214*38e8c45fSAndroid Build Coastguard Worker                                 deviceId, pointers, entry.eventTime);
7215*38e8c45fSAndroid Build Coastguard Worker     }
7216*38e8c45fSAndroid Build Coastguard Worker }
7217*38e8c45fSAndroid Build Coastguard Worker 
transferWallpaperTouch(ftl::Flags<InputTarget::Flags> oldTargetFlags,ftl::Flags<InputTarget::Flags> newTargetFlags,const sp<WindowInfoHandle> fromWindowHandle,const sp<WindowInfoHandle> toWindowHandle,TouchState & state,DeviceId deviceId,const std::vector<PointerProperties> & pointers,const std::unique_ptr<trace::EventTrackerInterface> & traceTracker)7218*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::transferWallpaperTouch(
7219*38e8c45fSAndroid Build Coastguard Worker         ftl::Flags<InputTarget::Flags> oldTargetFlags,
7220*38e8c45fSAndroid Build Coastguard Worker         ftl::Flags<InputTarget::Flags> newTargetFlags, const sp<WindowInfoHandle> fromWindowHandle,
7221*38e8c45fSAndroid Build Coastguard Worker         const sp<WindowInfoHandle> toWindowHandle, TouchState& state, DeviceId deviceId,
7222*38e8c45fSAndroid Build Coastguard Worker         const std::vector<PointerProperties>& pointers,
7223*38e8c45fSAndroid Build Coastguard Worker         const std::unique_ptr<trace::EventTrackerInterface>& traceTracker) {
7224*38e8c45fSAndroid Build Coastguard Worker     const bool oldHasWallpaper = oldTargetFlags.test(InputTarget::Flags::FOREGROUND) &&
7225*38e8c45fSAndroid Build Coastguard Worker             fromWindowHandle->getInfo()->inputConfig.test(
7226*38e8c45fSAndroid Build Coastguard Worker                     gui::WindowInfo::InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER);
7227*38e8c45fSAndroid Build Coastguard Worker     const bool newHasWallpaper = newTargetFlags.test(InputTarget::Flags::FOREGROUND) &&
7228*38e8c45fSAndroid Build Coastguard Worker             toWindowHandle->getInfo()->inputConfig.test(
7229*38e8c45fSAndroid Build Coastguard Worker                     gui::WindowInfo::InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER);
7230*38e8c45fSAndroid Build Coastguard Worker 
7231*38e8c45fSAndroid Build Coastguard Worker     const sp<WindowInfoHandle> oldWallpaper =
7232*38e8c45fSAndroid Build Coastguard Worker             oldHasWallpaper ? state.getWallpaperWindow(deviceId) : nullptr;
7233*38e8c45fSAndroid Build Coastguard Worker     const sp<WindowInfoHandle> newWallpaper =
7234*38e8c45fSAndroid Build Coastguard Worker             newHasWallpaper ? findWallpaperWindowBelow(toWindowHandle) : nullptr;
7235*38e8c45fSAndroid Build Coastguard Worker     if (oldWallpaper == newWallpaper) {
7236*38e8c45fSAndroid Build Coastguard Worker         return;
7237*38e8c45fSAndroid Build Coastguard Worker     }
7238*38e8c45fSAndroid Build Coastguard Worker 
7239*38e8c45fSAndroid Build Coastguard Worker     if (oldWallpaper != nullptr) {
7240*38e8c45fSAndroid Build Coastguard Worker         CancelationOptions options(CancelationOptions::Mode::CANCEL_POINTER_EVENTS,
7241*38e8c45fSAndroid Build Coastguard Worker                                    "transferring touch focus to another window", traceTracker);
7242*38e8c45fSAndroid Build Coastguard Worker         state.removeWindowByToken(oldWallpaper->getToken());
7243*38e8c45fSAndroid Build Coastguard Worker         synthesizeCancelationEventsForWindowLocked(oldWallpaper, options);
7244*38e8c45fSAndroid Build Coastguard Worker     }
7245*38e8c45fSAndroid Build Coastguard Worker 
7246*38e8c45fSAndroid Build Coastguard Worker     if (newWallpaper != nullptr) {
7247*38e8c45fSAndroid Build Coastguard Worker         nsecs_t downTimeInTarget = now();
7248*38e8c45fSAndroid Build Coastguard Worker         ftl::Flags<InputTarget::Flags> wallpaperFlags = newTargetFlags;
7249*38e8c45fSAndroid Build Coastguard Worker         wallpaperFlags |= oldTargetFlags & InputTarget::Flags::SPLIT;
7250*38e8c45fSAndroid Build Coastguard Worker         wallpaperFlags |= InputTarget::Flags::WINDOW_IS_OBSCURED |
7251*38e8c45fSAndroid Build Coastguard Worker                 InputTarget::Flags::WINDOW_IS_PARTIALLY_OBSCURED;
7252*38e8c45fSAndroid Build Coastguard Worker         state.addOrUpdateWindow(newWallpaper, InputTarget::DispatchMode::AS_IS, wallpaperFlags,
7253*38e8c45fSAndroid Build Coastguard Worker                                 deviceId, pointers, downTimeInTarget);
7254*38e8c45fSAndroid Build Coastguard Worker         std::shared_ptr<Connection> wallpaperConnection =
7255*38e8c45fSAndroid Build Coastguard Worker                 getConnectionLocked(newWallpaper->getToken());
7256*38e8c45fSAndroid Build Coastguard Worker         if (wallpaperConnection != nullptr) {
7257*38e8c45fSAndroid Build Coastguard Worker             std::shared_ptr<Connection> toConnection =
7258*38e8c45fSAndroid Build Coastguard Worker                     getConnectionLocked(toWindowHandle->getToken());
7259*38e8c45fSAndroid Build Coastguard Worker             toConnection->inputState.mergePointerStateTo(wallpaperConnection->inputState);
7260*38e8c45fSAndroid Build Coastguard Worker             synthesizePointerDownEventsForConnectionLocked(downTimeInTarget, wallpaperConnection,
7261*38e8c45fSAndroid Build Coastguard Worker                                                            wallpaperFlags, traceTracker);
7262*38e8c45fSAndroid Build Coastguard Worker         }
7263*38e8c45fSAndroid Build Coastguard Worker     }
7264*38e8c45fSAndroid Build Coastguard Worker }
7265*38e8c45fSAndroid Build Coastguard Worker 
findWallpaperWindowBelow(const sp<WindowInfoHandle> & windowHandle) const7266*38e8c45fSAndroid Build Coastguard Worker sp<WindowInfoHandle> InputDispatcher::findWallpaperWindowBelow(
7267*38e8c45fSAndroid Build Coastguard Worker         const sp<WindowInfoHandle>& windowHandle) const {
7268*38e8c45fSAndroid Build Coastguard Worker     const std::vector<sp<WindowInfoHandle>>& windowHandles =
7269*38e8c45fSAndroid Build Coastguard Worker             getWindowHandlesLocked(windowHandle->getInfo()->displayId);
7270*38e8c45fSAndroid Build Coastguard Worker     bool foundWindow = false;
7271*38e8c45fSAndroid Build Coastguard Worker     for (const sp<WindowInfoHandle>& otherHandle : windowHandles) {
7272*38e8c45fSAndroid Build Coastguard Worker         if (!foundWindow && otherHandle != windowHandle) {
7273*38e8c45fSAndroid Build Coastguard Worker             continue;
7274*38e8c45fSAndroid Build Coastguard Worker         }
7275*38e8c45fSAndroid Build Coastguard Worker         if (windowHandle == otherHandle) {
7276*38e8c45fSAndroid Build Coastguard Worker             foundWindow = true;
7277*38e8c45fSAndroid Build Coastguard Worker             continue;
7278*38e8c45fSAndroid Build Coastguard Worker         }
7279*38e8c45fSAndroid Build Coastguard Worker 
7280*38e8c45fSAndroid Build Coastguard Worker         if (otherHandle->getInfo()->inputConfig.test(WindowInfo::InputConfig::IS_WALLPAPER)) {
7281*38e8c45fSAndroid Build Coastguard Worker             return otherHandle;
7282*38e8c45fSAndroid Build Coastguard Worker         }
7283*38e8c45fSAndroid Build Coastguard Worker     }
7284*38e8c45fSAndroid Build Coastguard Worker     return nullptr;
7285*38e8c45fSAndroid Build Coastguard Worker }
7286*38e8c45fSAndroid Build Coastguard Worker 
setKeyRepeatConfiguration(std::chrono::nanoseconds timeout,std::chrono::nanoseconds delay,bool keyRepeatEnabled)7287*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::setKeyRepeatConfiguration(std::chrono::nanoseconds timeout,
7288*38e8c45fSAndroid Build Coastguard Worker                                                 std::chrono::nanoseconds delay,
7289*38e8c45fSAndroid Build Coastguard Worker                                                 bool keyRepeatEnabled) {
7290*38e8c45fSAndroid Build Coastguard Worker     std::scoped_lock _l(mLock);
7291*38e8c45fSAndroid Build Coastguard Worker 
7292*38e8c45fSAndroid Build Coastguard Worker     mConfig.keyRepeatTimeout = timeout.count();
7293*38e8c45fSAndroid Build Coastguard Worker     mConfig.keyRepeatDelay = delay.count();
7294*38e8c45fSAndroid Build Coastguard Worker     mConfig.keyRepeatEnabled = keyRepeatEnabled;
7295*38e8c45fSAndroid Build Coastguard Worker }
7296*38e8c45fSAndroid Build Coastguard Worker 
isPointerInWindow(const sp<android::IBinder> & token,ui::LogicalDisplayId displayId,DeviceId deviceId,int32_t pointerId)7297*38e8c45fSAndroid Build Coastguard Worker bool InputDispatcher::isPointerInWindow(const sp<android::IBinder>& token,
7298*38e8c45fSAndroid Build Coastguard Worker                                         ui::LogicalDisplayId displayId, DeviceId deviceId,
7299*38e8c45fSAndroid Build Coastguard Worker                                         int32_t pointerId) {
7300*38e8c45fSAndroid Build Coastguard Worker     std::scoped_lock _l(mLock);
7301*38e8c45fSAndroid Build Coastguard Worker     auto touchStateIt = mTouchStatesByDisplay.find(displayId);
7302*38e8c45fSAndroid Build Coastguard Worker     if (touchStateIt == mTouchStatesByDisplay.end()) {
7303*38e8c45fSAndroid Build Coastguard Worker         return false;
7304*38e8c45fSAndroid Build Coastguard Worker     }
7305*38e8c45fSAndroid Build Coastguard Worker     for (const TouchedWindow& window : touchStateIt->second.windows) {
7306*38e8c45fSAndroid Build Coastguard Worker         if (window.windowHandle->getToken() == token &&
7307*38e8c45fSAndroid Build Coastguard Worker             (window.hasTouchingPointer(deviceId, pointerId) ||
7308*38e8c45fSAndroid Build Coastguard Worker              window.hasHoveringPointer(deviceId, pointerId))) {
7309*38e8c45fSAndroid Build Coastguard Worker             return true;
7310*38e8c45fSAndroid Build Coastguard Worker         }
7311*38e8c45fSAndroid Build Coastguard Worker     }
7312*38e8c45fSAndroid Build Coastguard Worker     return false;
7313*38e8c45fSAndroid Build Coastguard Worker }
7314*38e8c45fSAndroid Build Coastguard Worker 
setInputMethodConnectionIsActive(bool isActive)7315*38e8c45fSAndroid Build Coastguard Worker void InputDispatcher::setInputMethodConnectionIsActive(bool isActive) {
7316*38e8c45fSAndroid Build Coastguard Worker     std::scoped_lock _l(mLock);
7317*38e8c45fSAndroid Build Coastguard Worker     if (mTracer) {
7318*38e8c45fSAndroid Build Coastguard Worker         mTracer->setInputMethodConnectionIsActive(isActive);
7319*38e8c45fSAndroid Build Coastguard Worker     }
7320*38e8c45fSAndroid Build Coastguard Worker }
7321*38e8c45fSAndroid Build Coastguard Worker 
7322*38e8c45fSAndroid Build Coastguard Worker } // namespace android::inputdispatcher
7323