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