blob: b904caf67140ca909eda0c69850ac4204edae2bb [file] [log] [blame]
Garfield Tan73007b62019-08-29 17:28:41 -07001/*
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
30namespace android::inputdispatcher {
31
32template <typename T>
33struct Link {
34 T* next;
35 T* prev;
36
37protected:
38 inline Link() : next(nullptr), prev(nullptr) {}
39};
40
41struct 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
53 inline bool isInjected() const { return injectionState != nullptr; }
54
55 void release();
56
57 virtual void appendDescription(std::string& msg) const = 0;
58
59protected:
60 EventEntry(uint32_t sequenceNum, int32_t type, nsecs_t eventTime, uint32_t policyFlags);
61 virtual ~EventEntry();
62 void releaseInjectionState();
63};
64
65struct ConfigurationChangedEntry : EventEntry {
66 explicit ConfigurationChangedEntry(uint32_t sequenceNum, nsecs_t eventTime);
67 virtual void appendDescription(std::string& msg) const;
68
69protected:
70 virtual ~ConfigurationChangedEntry();
71};
72
73struct 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
79protected:
80 virtual ~DeviceResetEntry();
81};
82
83struct 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
113protected:
114 virtual ~KeyEntry();
115};
116
117struct 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
145protected:
146 virtual ~MotionEntry();
147};
148
149// Tracks the progress of dispatching a particular event to a particular connection.
150struct 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
170 inline bool hasForegroundTarget() const { return targetFlags & InputTarget::FLAG_FOREGROUND; }
171
172 inline bool isSplit() const { return targetFlags & InputTarget::FLAG_SPLIT; }
173
174private:
175 static volatile int32_t sNextSeqAtomic;
176
177 static uint32_t nextSeq();
178};
179
180class 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'.
197struct CommandEntry;
198typedef void (InputDispatcher::*Command)(CommandEntry* commandEntry);
199
200class Connection;
201struct 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