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 template <typename T>
33 struct Link {
34     T* next;
35     T* prev;
36 
37 protected:
LinkLink38     inline Link() : next(nullptr), prev(nullptr) {}
39 };
40 
41 struct EventEntry : Link<EventEntry> {
42     enum { TYPE_CONFIGURATION_CHANGED, TYPE_DEVICE_RESET, TYPE_KEY, TYPE_MOTION };
43 
44     uint32_t sequenceNum;
45     mutable int32_t refCount;
46     int32_t type;
47     nsecs_t eventTime;
48     uint32_t policyFlags;
49     InjectionState* injectionState;
50 
51     bool dispatchInProgress; // initially false, set to true while dispatching
52 
isInjectedEventEntry53     inline bool isInjected() const { return injectionState != nullptr; }
54 
55     void release();
56 
57     virtual void appendDescription(std::string& msg) const = 0;
58 
59 protected:
60     EventEntry(uint32_t sequenceNum, int32_t type, nsecs_t eventTime, uint32_t policyFlags);
61     virtual ~EventEntry();
62     void releaseInjectionState();
63 };
64 
65 struct ConfigurationChangedEntry : EventEntry {
66     explicit ConfigurationChangedEntry(uint32_t sequenceNum, nsecs_t eventTime);
67     virtual void appendDescription(std::string& msg) const;
68 
69 protected:
70     virtual ~ConfigurationChangedEntry();
71 };
72 
73 struct DeviceResetEntry : EventEntry {
74     int32_t deviceId;
75 
76     DeviceResetEntry(uint32_t sequenceNum, nsecs_t eventTime, int32_t deviceId);
77     virtual void appendDescription(std::string& msg) const;
78 
79 protected:
80     virtual ~DeviceResetEntry();
81 };
82 
83 struct KeyEntry : EventEntry {
84     int32_t deviceId;
85     uint32_t source;
86     int32_t displayId;
87     int32_t action;
88     int32_t flags;
89     int32_t keyCode;
90     int32_t scanCode;
91     int32_t metaState;
92     int32_t repeatCount;
93     nsecs_t downTime;
94 
95     bool syntheticRepeat; // set to true for synthetic key repeats
96 
97     enum InterceptKeyResult {
98         INTERCEPT_KEY_RESULT_UNKNOWN,
99         INTERCEPT_KEY_RESULT_SKIP,
100         INTERCEPT_KEY_RESULT_CONTINUE,
101         INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER,
102     };
103     InterceptKeyResult interceptKeyResult; // set based on the interception result
104     nsecs_t interceptKeyWakeupTime;        // used with INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER
105 
106     KeyEntry(uint32_t sequenceNum, nsecs_t eventTime, int32_t deviceId, uint32_t source,
107              int32_t displayId, uint32_t policyFlags, int32_t action, int32_t flags,
108              int32_t keyCode, int32_t scanCode, int32_t metaState, int32_t repeatCount,
109              nsecs_t downTime);
110     virtual void appendDescription(std::string& msg) const;
111     void recycle();
112 
113 protected:
114     virtual ~KeyEntry();
115 };
116 
117 struct MotionEntry : EventEntry {
118     nsecs_t eventTime;
119     int32_t deviceId;
120     uint32_t source;
121     int32_t displayId;
122     int32_t action;
123     int32_t actionButton;
124     int32_t flags;
125     int32_t metaState;
126     int32_t buttonState;
127     MotionClassification classification;
128     int32_t edgeFlags;
129     float xPrecision;
130     float yPrecision;
131     nsecs_t downTime;
132     uint32_t pointerCount;
133     PointerProperties pointerProperties[MAX_POINTERS];
134     PointerCoords pointerCoords[MAX_POINTERS];
135 
136     MotionEntry(uint32_t sequenceNum, nsecs_t eventTime, int32_t deviceId, uint32_t source,
137                 int32_t displayId, uint32_t policyFlags, int32_t action, int32_t actionButton,
138                 int32_t flags, int32_t metaState, int32_t buttonState,
139                 MotionClassification classification, int32_t edgeFlags, float xPrecision,
140                 float yPrecision, nsecs_t downTime, uint32_t pointerCount,
141                 const PointerProperties* pointerProperties, const PointerCoords* pointerCoords,
142                 float xOffset, float yOffset);
143     virtual void appendDescription(std::string& msg) const;
144 
145 protected:
146     virtual ~MotionEntry();
147 };
148 
149 // Tracks the progress of dispatching a particular event to a particular connection.
150 struct DispatchEntry : Link<DispatchEntry> {
151     const uint32_t seq; // unique sequence number, never 0
152 
153     EventEntry* eventEntry; // the event to dispatch
154     int32_t targetFlags;
155     float xOffset;
156     float yOffset;
157     float globalScaleFactor;
158     float windowXScale = 1.0f;
159     float windowYScale = 1.0f;
160     nsecs_t deliveryTime; // time when the event was actually delivered
161 
162     // Set to the resolved action and flags when the event is enqueued.
163     int32_t resolvedAction;
164     int32_t resolvedFlags;
165 
166     DispatchEntry(EventEntry* eventEntry, int32_t targetFlags, float xOffset, float yOffset,
167                   float globalScaleFactor, float windowXScale, float windowYScale);
168     ~DispatchEntry();
169 
hasForegroundTargetDispatchEntry170     inline bool hasForegroundTarget() const { return targetFlags & InputTarget::FLAG_FOREGROUND; }
171 
isSplitDispatchEntry172     inline bool isSplit() const { return targetFlags & InputTarget::FLAG_SPLIT; }
173 
174 private:
175     static volatile int32_t sNextSeqAtomic;
176 
177     static uint32_t nextSeq();
178 };
179 
180 class InputDispatcher;
181 // A command entry captures state and behavior for an action to be performed in the
182 // dispatch loop after the initial processing has taken place.  It is essentially
183 // a kind of continuation used to postpone sensitive policy interactions to a point
184 // in the dispatch loop where it is safe to release the lock (generally after finishing
185 // the critical parts of the dispatch cycle).
186 //
187 // The special thing about commands is that they can voluntarily release and reacquire
188 // the dispatcher lock at will.  Initially when the command starts running, the
189 // dispatcher lock is held.  However, if the command needs to call into the policy to
190 // do some work, it can release the lock, do the work, then reacquire the lock again
191 // before returning.
192 //
193 // This mechanism is a bit clunky but it helps to preserve the invariant that the dispatch
194 // never calls into the policy while holding its lock.
195 //
196 // Commands are implicitly 'LockedInterruptible'.
197 struct CommandEntry;
198 typedef void (InputDispatcher::*Command)(CommandEntry* commandEntry);
199 
200 class Connection;
201 struct CommandEntry : Link<CommandEntry> {
202     explicit CommandEntry(Command command);
203     ~CommandEntry();
204 
205     Command command;
206 
207     // parameters for the command (usage varies by command)
208     sp<Connection> connection;
209     nsecs_t eventTime;
210     KeyEntry* keyEntry;
211     sp<InputApplicationHandle> inputApplicationHandle;
212     std::string reason;
213     int32_t userActivityEventType;
214     uint32_t seq;
215     bool handled;
216     sp<InputChannel> inputChannel;
217     sp<IBinder> oldToken;
218     sp<IBinder> newToken;
219 };
220 
221 } // namespace android::inputdispatcher
222 
223 #endif // _UI_INPUT_INPUTDISPATCHER_ENTRY_H
224