1 /*
2  * Copyright (C) 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef _UI_INPUT_INPUTDISPATCHER_ENTRY_H
18 #define _UI_INPUT_INPUTDISPATCHER_ENTRY_H
19 
20 #include "InjectionState.h"
21 #include "InputTarget.h"
22 
23 #include <input/Input.h>
24 #include <input/InputApplication.h>
25 #include <stdint.h>
26 #include <utils/Timers.h>
27 #include <functional>
28 #include <string>
29 
30 namespace android::inputdispatcher {
31 
32 struct EventEntry {
33     enum class Type {
34         CONFIGURATION_CHANGED,
35         DEVICE_RESET,
36         FOCUS,
37         KEY,
38         MOTION,
39     };
40 
typeToStringEventEntry41     static const char* typeToString(Type type) {
42         switch (type) {
43             case Type::CONFIGURATION_CHANGED:
44                 return "CONFIGURATION_CHANGED";
45             case Type::DEVICE_RESET:
46                 return "DEVICE_RESET";
47             case Type::FOCUS:
48                 return "FOCUS";
49             case Type::KEY:
50                 return "KEY";
51             case Type::MOTION:
52                 return "MOTION";
53         }
54     }
55 
56     int32_t id;
57     mutable int32_t refCount;
58     Type type;
59     nsecs_t eventTime;
60     uint32_t policyFlags;
61     InjectionState* injectionState;
62 
63     bool dispatchInProgress; // initially false, set to true while dispatching
64 
65     /**
66      * Injected keys are events from an external (probably untrusted) application
67      * and are not related to real hardware state. They come in via
68      * InputDispatcher::injectInputEvent, which sets policy flag POLICY_FLAG_INJECTED.
69      */
isInjectedEventEntry70     inline bool isInjected() const { return injectionState != nullptr; }
71 
72     /**
73      * Synthesized events are either injected events, or events that come
74      * from real hardware, but aren't directly attributable to a specific hardware event.
75      * Key repeat is a synthesized event, because it is related to an actual hardware state
76      * (a key is currently pressed), but the repeat itself is generated by the framework.
77      */
isSynthesizedEventEntry78     inline bool isSynthesized() const {
79         return isInjected() || IdGenerator::getSource(id) != IdGenerator::Source::INPUT_READER;
80     }
81 
82     void release();
83 
84     virtual void appendDescription(std::string& msg) const = 0;
85 
86     std::string getDescription() const;
87 
88 protected:
89     EventEntry(int32_t id, Type type, nsecs_t eventTime, uint32_t policyFlags);
90     virtual ~EventEntry();
91     void releaseInjectionState();
92 };
93 
94 struct ConfigurationChangedEntry : EventEntry {
95     explicit ConfigurationChangedEntry(int32_t id, nsecs_t eventTime);
96     virtual void appendDescription(std::string& msg) const;
97 
98 protected:
99     virtual ~ConfigurationChangedEntry();
100 };
101 
102 struct DeviceResetEntry : EventEntry {
103     int32_t deviceId;
104 
105     DeviceResetEntry(int32_t id, nsecs_t eventTime, int32_t deviceId);
106     virtual void appendDescription(std::string& msg) const;
107 
108 protected:
109     virtual ~DeviceResetEntry();
110 };
111 
112 struct FocusEntry : EventEntry {
113     sp<IBinder> connectionToken;
114     bool hasFocus;
115 
116     FocusEntry(int32_t id, nsecs_t eventTime, sp<IBinder> connectionToken, bool hasFocus);
117     virtual void appendDescription(std::string& msg) const;
118 
119 protected:
120     virtual ~FocusEntry();
121 };
122 
123 struct KeyEntry : EventEntry {
124     int32_t deviceId;
125     uint32_t source;
126     int32_t displayId;
127     int32_t action;
128     int32_t flags;
129     int32_t keyCode;
130     int32_t scanCode;
131     int32_t metaState;
132     int32_t repeatCount;
133     nsecs_t downTime;
134 
135     bool syntheticRepeat; // set to true for synthetic key repeats
136 
137     enum InterceptKeyResult {
138         INTERCEPT_KEY_RESULT_UNKNOWN,
139         INTERCEPT_KEY_RESULT_SKIP,
140         INTERCEPT_KEY_RESULT_CONTINUE,
141         INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER,
142     };
143     InterceptKeyResult interceptKeyResult; // set based on the interception result
144     nsecs_t interceptKeyWakeupTime;        // used with INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER
145 
146     KeyEntry(int32_t id, nsecs_t eventTime, int32_t deviceId, uint32_t source, int32_t displayId,
147              uint32_t policyFlags, int32_t action, int32_t flags, int32_t keyCode, int32_t scanCode,
148              int32_t metaState, int32_t repeatCount, nsecs_t downTime);
149     virtual void appendDescription(std::string& msg) const;
150     void recycle();
151 
152 protected:
153     virtual ~KeyEntry();
154 };
155 
156 struct MotionEntry : EventEntry {
157     nsecs_t eventTime;
158     int32_t deviceId;
159     uint32_t source;
160     int32_t displayId;
161     int32_t action;
162     int32_t actionButton;
163     int32_t flags;
164     int32_t metaState;
165     int32_t buttonState;
166     MotionClassification classification;
167     int32_t edgeFlags;
168     float xPrecision;
169     float yPrecision;
170     float xCursorPosition;
171     float yCursorPosition;
172     nsecs_t downTime;
173     uint32_t pointerCount;
174     PointerProperties pointerProperties[MAX_POINTERS];
175     PointerCoords pointerCoords[MAX_POINTERS];
176 
177     MotionEntry(int32_t id, nsecs_t eventTime, int32_t deviceId, uint32_t source, int32_t displayId,
178                 uint32_t policyFlags, int32_t action, int32_t actionButton, int32_t flags,
179                 int32_t metaState, int32_t buttonState, MotionClassification classification,
180                 int32_t edgeFlags, float xPrecision, float yPrecision, float xCursorPosition,
181                 float yCursorPosition, nsecs_t downTime, uint32_t pointerCount,
182                 const PointerProperties* pointerProperties, const PointerCoords* pointerCoords,
183                 float xOffset, float yOffset);
184     virtual void appendDescription(std::string& msg) const;
185 
186 protected:
187     virtual ~MotionEntry();
188 };
189 
190 // Tracks the progress of dispatching a particular event to a particular connection.
191 struct DispatchEntry {
192     const uint32_t seq; // unique sequence number, never 0
193 
194     EventEntry* eventEntry; // the event to dispatch
195     int32_t targetFlags;
196     float xOffset;
197     float yOffset;
198     float globalScaleFactor;
199     float windowXScale = 1.0f;
200     float windowYScale = 1.0f;
201     // Both deliveryTime and timeoutTime are only populated when the entry is sent to the app,
202     // and will be undefined before that.
203     nsecs_t deliveryTime; // time when the event was actually delivered
204     // An ANR will be triggered if a response for this entry is not received by timeoutTime
205     nsecs_t timeoutTime;
206 
207     // Set to the resolved ID, action and flags when the event is enqueued.
208     int32_t resolvedEventId;
209     int32_t resolvedAction;
210     int32_t resolvedFlags;
211 
212     DispatchEntry(EventEntry* eventEntry, int32_t targetFlags, float xOffset, float yOffset,
213                   float globalScaleFactor, float windowXScale, float windowYScale);
214     ~DispatchEntry();
215 
hasForegroundTargetDispatchEntry216     inline bool hasForegroundTarget() const { return targetFlags & InputTarget::FLAG_FOREGROUND; }
217 
isSplitDispatchEntry218     inline bool isSplit() const { return targetFlags & InputTarget::FLAG_SPLIT; }
219 
220 private:
221     static volatile int32_t sNextSeqAtomic;
222 
223     static uint32_t nextSeq();
224 };
225 
226 VerifiedKeyEvent verifiedKeyEventFromKeyEntry(const KeyEntry& entry);
227 VerifiedMotionEvent verifiedMotionEventFromMotionEntry(const MotionEntry& entry);
228 
229 class InputDispatcher;
230 // A command entry captures state and behavior for an action to be performed in the
231 // dispatch loop after the initial processing has taken place.  It is essentially
232 // a kind of continuation used to postpone sensitive policy interactions to a point
233 // in the dispatch loop where it is safe to release the lock (generally after finishing
234 // the critical parts of the dispatch cycle).
235 //
236 // The special thing about commands is that they can voluntarily release and reacquire
237 // the dispatcher lock at will.  Initially when the command starts running, the
238 // dispatcher lock is held.  However, if the command needs to call into the policy to
239 // do some work, it can release the lock, do the work, then reacquire the lock again
240 // before returning.
241 //
242 // This mechanism is a bit clunky but it helps to preserve the invariant that the dispatch
243 // never calls into the policy while holding its lock.
244 //
245 // Commands are implicitly 'LockedInterruptible'.
246 struct CommandEntry;
247 typedef std::function<void(InputDispatcher&, CommandEntry*)> Command;
248 
249 class Connection;
250 struct CommandEntry {
251     explicit CommandEntry(Command command);
252     ~CommandEntry();
253 
254     Command command;
255 
256     // parameters for the command (usage varies by command)
257     sp<Connection> connection;
258     nsecs_t eventTime;
259     KeyEntry* keyEntry;
260     sp<InputApplicationHandle> inputApplicationHandle;
261     std::string reason;
262     int32_t userActivityEventType;
263     uint32_t seq;
264     bool handled;
265     sp<InputChannel> inputChannel;
266     sp<IBinder> oldToken;
267     sp<IBinder> newToken;
268 };
269 
270 } // namespace android::inputdispatcher
271 
272 #endif // _UI_INPUT_INPUTDISPATCHER_ENTRY_H
273