/* * Copyright (C) 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef _UI_INPUT_INPUTDISPATCHER_ENTRY_H #define _UI_INPUT_INPUTDISPATCHER_ENTRY_H #include "InjectionState.h" #include "InputTarget.h" #include #include #include #include #include #include namespace android::inputdispatcher { struct EventEntry { enum class Type { CONFIGURATION_CHANGED, DEVICE_RESET, FOCUS, KEY, MOTION, SENSOR, POINTER_CAPTURE_CHANGED, DRAG, }; int32_t id; Type type; nsecs_t eventTime; uint32_t policyFlags; InjectionState* injectionState; bool dispatchInProgress; // initially false, set to true while dispatching /** * Injected keys are events from an external (probably untrusted) application * and are not related to real hardware state. They come in via * InputDispatcher::injectInputEvent, which sets policy flag POLICY_FLAG_INJECTED. */ inline bool isInjected() const { return injectionState != nullptr; } /** * Synthesized events are either injected events, or events that come * from real hardware, but aren't directly attributable to a specific hardware event. * Key repeat is a synthesized event, because it is related to an actual hardware state * (a key is currently pressed), but the repeat itself is generated by the framework. */ inline bool isSynthesized() const { return isInjected() || IdGenerator::getSource(id) != IdGenerator::Source::INPUT_READER; } virtual std::string getDescription() const = 0; EventEntry(int32_t id, Type type, nsecs_t eventTime, uint32_t policyFlags); virtual ~EventEntry(); protected: void releaseInjectionState(); }; struct ConfigurationChangedEntry : EventEntry { explicit ConfigurationChangedEntry(int32_t id, nsecs_t eventTime); std::string getDescription() const override; ~ConfigurationChangedEntry() override; }; struct DeviceResetEntry : EventEntry { int32_t deviceId; DeviceResetEntry(int32_t id, nsecs_t eventTime, int32_t deviceId); std::string getDescription() const override; ~DeviceResetEntry() override; }; struct FocusEntry : EventEntry { sp connectionToken; bool hasFocus; std::string reason; FocusEntry(int32_t id, nsecs_t eventTime, sp connectionToken, bool hasFocus, const std::string& reason); std::string getDescription() const override; ~FocusEntry() override; }; struct PointerCaptureChangedEntry : EventEntry { bool pointerCaptureEnabled; PointerCaptureChangedEntry(int32_t id, nsecs_t eventTime, bool hasPointerCapture); std::string getDescription() const override; ~PointerCaptureChangedEntry() override; }; struct DragEntry : EventEntry { sp connectionToken; bool isExiting; float x, y; DragEntry(int32_t id, nsecs_t eventTime, sp connectionToken, bool isExiting, float x, float y); std::string getDescription() const override; ~DragEntry() override; }; struct KeyEntry : EventEntry { int32_t deviceId; uint32_t source; int32_t displayId; int32_t action; int32_t flags; int32_t keyCode; int32_t scanCode; int32_t metaState; int32_t repeatCount; nsecs_t downTime; bool syntheticRepeat; // set to true for synthetic key repeats enum InterceptKeyResult { INTERCEPT_KEY_RESULT_UNKNOWN, INTERCEPT_KEY_RESULT_SKIP, INTERCEPT_KEY_RESULT_CONTINUE, INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER, }; InterceptKeyResult interceptKeyResult; // set based on the interception result nsecs_t interceptKeyWakeupTime; // used with INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER KeyEntry(int32_t id, nsecs_t eventTime, int32_t deviceId, uint32_t source, int32_t displayId, uint32_t policyFlags, int32_t action, int32_t flags, int32_t keyCode, int32_t scanCode, int32_t metaState, int32_t repeatCount, nsecs_t downTime); std::string getDescription() const override; void recycle(); ~KeyEntry() override; }; struct MotionEntry : EventEntry { int32_t deviceId; uint32_t source; int32_t displayId; int32_t action; int32_t actionButton; int32_t flags; int32_t metaState; int32_t buttonState; MotionClassification classification; int32_t edgeFlags; float xPrecision; float yPrecision; float xCursorPosition; float yCursorPosition; nsecs_t downTime; uint32_t pointerCount; PointerProperties pointerProperties[MAX_POINTERS]; PointerCoords pointerCoords[MAX_POINTERS]; MotionEntry(int32_t id, nsecs_t eventTime, int32_t deviceId, uint32_t source, int32_t displayId, uint32_t policyFlags, int32_t action, int32_t actionButton, int32_t flags, int32_t metaState, int32_t buttonState, MotionClassification classification, int32_t edgeFlags, float xPrecision, float yPrecision, float xCursorPosition, float yCursorPosition, nsecs_t downTime, uint32_t pointerCount, const PointerProperties* pointerProperties, const PointerCoords* pointerCoords, float xOffset, float yOffset); std::string getDescription() const override; virtual ~MotionEntry(); }; struct SensorEntry : EventEntry { int32_t deviceId; uint32_t source; InputDeviceSensorType sensorType; InputDeviceSensorAccuracy accuracy; bool accuracyChanged; nsecs_t hwTimestamp; std::vector values; SensorEntry(int32_t id, nsecs_t eventTime, int32_t deviceId, uint32_t source, uint32_t policyFlags, nsecs_t hwTimestamp, InputDeviceSensorType sensorType, InputDeviceSensorAccuracy accuracy, bool accuracyChanged, std::vector values); std::string getDescription() const override; ~SensorEntry() override; }; // Tracks the progress of dispatching a particular event to a particular connection. struct DispatchEntry { const uint32_t seq; // unique sequence number, never 0 std::shared_ptr eventEntry; // the event to dispatch int32_t targetFlags; ui::Transform transform; float globalScaleFactor; int2 displaySize; // Both deliveryTime and timeoutTime are only populated when the entry is sent to the app, // and will be undefined before that. nsecs_t deliveryTime; // time when the event was actually delivered // An ANR will be triggered if a response for this entry is not received by timeoutTime nsecs_t timeoutTime; // Set to the resolved ID, action and flags when the event is enqueued. int32_t resolvedEventId; int32_t resolvedAction; int32_t resolvedFlags; DispatchEntry(std::shared_ptr eventEntry, int32_t targetFlags, ui::Transform transform, float globalScaleFactor, int2 displaySize); inline bool hasForegroundTarget() const { return targetFlags & InputTarget::FLAG_FOREGROUND; } inline bool isSplit() const { return targetFlags & InputTarget::FLAG_SPLIT; } private: static volatile int32_t sNextSeqAtomic; static uint32_t nextSeq(); }; VerifiedKeyEvent verifiedKeyEventFromKeyEntry(const KeyEntry& entry); VerifiedMotionEvent verifiedMotionEventFromMotionEntry(const MotionEntry& entry); class InputDispatcher; // A command entry captures state and behavior for an action to be performed in the // dispatch loop after the initial processing has taken place. It is essentially // a kind of continuation used to postpone sensitive policy interactions to a point // in the dispatch loop where it is safe to release the lock (generally after finishing // the critical parts of the dispatch cycle). // // The special thing about commands is that they can voluntarily release and reacquire // the dispatcher lock at will. Initially when the command starts running, the // dispatcher lock is held. However, if the command needs to call into the policy to // do some work, it can release the lock, do the work, then reacquire the lock again // before returning. // // This mechanism is a bit clunky but it helps to preserve the invariant that the dispatch // never calls into the policy while holding its lock. // // Commands are implicitly 'LockedInterruptible'. struct CommandEntry; typedef std::function Command; class Connection; struct CommandEntry { explicit CommandEntry(Command command); ~CommandEntry(); Command command; // parameters for the command (usage varies by command) sp connection; nsecs_t eventTime; std::shared_ptr keyEntry; std::shared_ptr sensorEntry; std::shared_ptr inputApplicationHandle; std::string reason; int32_t userActivityEventType; uint32_t seq; bool handled; sp connectionToken; sp oldToken; sp newToken; std::string obscuringPackage; bool enabled; int32_t pid; nsecs_t consumeTime; // time when the event was consumed by InputConsumer int32_t displayId; float x; float y; }; } // namespace android::inputdispatcher #endif // _UI_INPUT_INPUTDISPATCHER_ENTRY_H