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