diff options
| author | 2020-09-09 20:21:16 -0700 | |
|---|---|---|
| committer | 2020-09-09 20:21:16 -0700 | |
| commit | ac07d0f5ab16bb9e8bbbabb589d1c7d36817baa9 (patch) | |
| tree | f7110d50445c67a337105034b1f2db3946a88fef /include/input | |
| parent | 171cac1b603e4bb83412eb596d05a500af5d7a76 (diff) | |
| parent | c83049d93712f12279dbeabfa1857c1921804979 (diff) | |
Merge Android R
Bug: 168057903
Merged-In: I1428ead11c6c2d6fd107a014df0082fdbfa9ba8a
Change-Id: I7e084a4c5a3fd06152ea6f1bfe17c53f95faba79
Diffstat (limited to 'include/input')
| -rw-r--r-- | include/input/DisplayViewport.h | 84 | ||||
| -rw-r--r-- | include/input/Input.h | 240 | ||||
| -rw-r--r-- | include/input/InputApplication.h | 5 | ||||
| -rw-r--r-- | include/input/InputDevice.h | 2 | ||||
| -rw-r--r-- | include/input/InputEventLabels.h | 14 | ||||
| -rw-r--r-- | include/input/InputTransport.h | 189 | ||||
| -rw-r--r-- | include/input/InputWindow.h | 129 | ||||
| -rw-r--r-- | include/input/LatencyStatistics.h | 59 | ||||
| -rw-r--r-- | include/input/TouchVideoFrame.h | 1 |
9 files changed, 500 insertions, 223 deletions
diff --git a/include/input/DisplayViewport.h b/include/input/DisplayViewport.h index fa456bb213..2427a075a1 100644 --- a/include/input/DisplayViewport.h +++ b/include/input/DisplayViewport.h @@ -17,16 +17,23 @@ #ifndef _LIBINPUT_DISPLAY_VIEWPORT_H #define _LIBINPUT_DISPLAY_VIEWPORT_H +#include <cinttypes> +#include <optional> + #include <android-base/stringprintf.h> -#include <ui/DisplayInfo.h> #include <input/Input.h> -#include <inttypes.h> -#include <optional> using android::base::StringPrintf; namespace android { +enum { + DISPLAY_ORIENTATION_0 = 0, + DISPLAY_ORIENTATION_90 = 1, + DISPLAY_ORIENTATION_180 = 2, + DISPLAY_ORIENTATION_270 = 3 +}; + /** * Describes the different type of viewports supported by input flinger. * Keep in sync with values in InputManagerService.java. @@ -67,36 +74,40 @@ struct DisplayViewport { int32_t physicalBottom; int32_t deviceWidth; int32_t deviceHeight; + bool isActive; std::string uniqueId; // The actual (hardware) port that the associated display is connected to. // Not all viewports will have this specified. std::optional<uint8_t> physicalPort; ViewportType type; - DisplayViewport() : - displayId(ADISPLAY_ID_NONE), orientation(DISPLAY_ORIENTATION_0), - logicalLeft(0), logicalTop(0), logicalRight(0), logicalBottom(0), - physicalLeft(0), physicalTop(0), physicalRight(0), physicalBottom(0), - deviceWidth(0), deviceHeight(0), uniqueId(), physicalPort(std::nullopt), - type(ViewportType::VIEWPORT_INTERNAL) { - } + DisplayViewport() + : displayId(ADISPLAY_ID_NONE), + orientation(DISPLAY_ORIENTATION_0), + logicalLeft(0), + logicalTop(0), + logicalRight(0), + logicalBottom(0), + physicalLeft(0), + physicalTop(0), + physicalRight(0), + physicalBottom(0), + deviceWidth(0), + deviceHeight(0), + isActive(false), + uniqueId(), + physicalPort(std::nullopt), + type(ViewportType::VIEWPORT_INTERNAL) {} bool operator==(const DisplayViewport& other) const { - return displayId == other.displayId - && orientation == other.orientation - && logicalLeft == other.logicalLeft - && logicalTop == other.logicalTop - && logicalRight == other.logicalRight - && logicalBottom == other.logicalBottom - && physicalLeft == other.physicalLeft - && physicalTop == other.physicalTop - && physicalRight == other.physicalRight - && physicalBottom == other.physicalBottom - && deviceWidth == other.deviceWidth - && deviceHeight == other.deviceHeight - && uniqueId == other.uniqueId - && physicalPort == other.physicalPort - && type == other.type; + return displayId == other.displayId && orientation == other.orientation && + logicalLeft == other.logicalLeft && logicalTop == other.logicalTop && + logicalRight == other.logicalRight && logicalBottom == other.logicalBottom && + physicalLeft == other.physicalLeft && physicalTop == other.physicalTop && + physicalRight == other.physicalRight && physicalBottom == other.physicalBottom && + deviceWidth == other.deviceWidth && deviceHeight == other.deviceHeight && + isActive == other.isActive && uniqueId == other.uniqueId && + physicalPort == other.physicalPort && type == other.type; } bool operator!=(const DisplayViewport& other) const { @@ -120,6 +131,7 @@ struct DisplayViewport { physicalBottom = height; deviceWidth = width; deviceHeight = height; + isActive = false; uniqueId.clear(); physicalPort = std::nullopt; type = ViewportType::VIEWPORT_INTERNAL; @@ -127,18 +139,16 @@ struct DisplayViewport { std::string toString() const { return StringPrintf("Viewport %s: displayId=%d, uniqueId=%s, port=%s, orientation=%d, " - "logicalFrame=[%d, %d, %d, %d], " - "physicalFrame=[%d, %d, %d, %d], " - "deviceSize=[%d, %d]", - viewportTypeToString(type), displayId, - uniqueId.c_str(), - physicalPort ? StringPrintf("%" PRIu8, *physicalPort).c_str() : "<none>", - orientation, - logicalLeft, logicalTop, - logicalRight, logicalBottom, - physicalLeft, physicalTop, - physicalRight, physicalBottom, - deviceWidth, deviceHeight); + "logicalFrame=[%d, %d, %d, %d], " + "physicalFrame=[%d, %d, %d, %d], " + "deviceSize=[%d, %d], " + "isActive=[%d]", + viewportTypeToString(type), displayId, uniqueId.c_str(), + physicalPort ? StringPrintf("%" PRIu8, *physicalPort).c_str() + : "<none>", + orientation, logicalLeft, logicalTop, logicalRight, logicalBottom, + physicalLeft, physicalTop, physicalRight, physicalBottom, deviceWidth, + deviceHeight, isActive); } }; diff --git a/include/input/Input.h b/include/input/Input.h index 805957a5ca..54b4e5a737 100644 --- a/include/input/Input.h +++ b/include/input/Input.h @@ -24,12 +24,16 @@ */ #include <android/input.h> +#include <math.h> +#include <stdint.h> #include <utils/BitSet.h> #include <utils/KeyedVector.h> #include <utils/RefBase.h> #include <utils/Timers.h> #include <utils/Vector.h> -#include <stdint.h> +#include <array> +#include <limits> +#include <queue> /* * Additional private constants not defined in ndk/ui/input.h. @@ -69,6 +73,19 @@ enum { AMOTION_EVENT_FLAG_TAINTED = 0x80000000, }; +/** + * Allowed VerifiedKeyEvent flags. All other flags from KeyEvent do not get verified. + * These values must be kept in sync with VerifiedKeyEvent.java + */ +constexpr int32_t VERIFIED_KEY_EVENT_FLAGS = AKEY_EVENT_FLAG_CANCELED; + +/** + * Allowed VerifiedMotionEventFlags. All other flags from MotionEvent do not get verified. + * These values must be kept in sync with VerifiedMotionEvent.java + */ +constexpr int32_t VERIFIED_MOTION_EVENT_FLAGS = + AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED | AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED; + enum { /* Used when a motion event is not associated with any display. * Typically used for non-pointer events. */ @@ -164,6 +181,8 @@ namespace android { class Parcel; #endif +const char* inputEventTypeToString(int32_t type); + /* * Flags that flow alongside events in the input dispatch system to help with certain * policy decisions such as waking from device sleep. @@ -246,6 +265,50 @@ enum class MotionClassification : uint8_t { */ const char* motionClassificationToString(MotionClassification classification); +/** + * Generator of unique numbers used to identify input events. + * + * Layout of ID: + * |--------------------------|---------------------------| + * | 2 bits for source | 30 bits for random number | + * |--------------------------|---------------------------| + */ +class IdGenerator { +private: + static constexpr uint32_t SOURCE_SHIFT = 30; + +public: + // Used to divide integer space to ensure no conflict among these sources./ + enum class Source : int32_t { + INPUT_READER = 0x0 << SOURCE_SHIFT, + INPUT_DISPATCHER = 0x1 << SOURCE_SHIFT, + OTHER = 0x3 << SOURCE_SHIFT, // E.g. app injected events + }; + IdGenerator(Source source); + + int32_t nextId() const; + + // Extract source from given id. + static inline Source getSource(int32_t id) { return static_cast<Source>(SOURCE_MASK & id); } + +private: + const Source mSource; + + static constexpr int32_t SOURCE_MASK = 0x3 << SOURCE_SHIFT; +}; + +/** + * Invalid value for cursor position. Used for non-mouse events, tests and injected events. Don't + * use it for direct comparison with any other value, because NaN isn't equal to itself according to + * IEEE 754. Use isnan() instead to check if a cursor position is valid. + */ +constexpr float AMOTION_EVENT_INVALID_CURSOR_POSITION = std::numeric_limits<float>::quiet_NaN(); + +/** + * Invalid value of HMAC - SHA256. Any events with this HMAC value will be marked as not verified. + */ +constexpr std::array<uint8_t, 32> INVALID_HMAC = {0}; + /* * Pointer coordinate data. */ @@ -334,24 +397,33 @@ public: virtual int32_t getType() const = 0; + inline int32_t getId() const { return mId; } + inline int32_t getDeviceId() const { return mDeviceId; } - inline int32_t getSource() const { return mSource; } + inline uint32_t getSource() const { return mSource; } - inline void setSource(int32_t source) { mSource = source; } + inline void setSource(uint32_t source) { mSource = source; } inline int32_t getDisplayId() const { return mDisplayId; } inline void setDisplayId(int32_t displayId) { mDisplayId = displayId; } + inline std::array<uint8_t, 32> getHmac() const { return mHmac; } + + static int32_t nextId(); protected: - void initialize(int32_t deviceId, int32_t source, int32_t displayId); + void initialize(int32_t id, int32_t deviceId, uint32_t source, int32_t displayId, + std::array<uint8_t, 32> hmac); + void initialize(const InputEvent& from); + int32_t mId; int32_t mDeviceId; - int32_t mSource; + uint32_t mSource; int32_t mDisplayId; + std::array<uint8_t, 32> mHmac; }; /* @@ -384,20 +456,14 @@ public: static const char* getLabel(int32_t keyCode); static int32_t getKeyCodeFromLabel(const char* label); - void initialize( - int32_t deviceId, - int32_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, - nsecs_t eventTime); + void initialize(int32_t id, int32_t deviceId, uint32_t source, int32_t displayId, + std::array<uint8_t, 32> hmac, int32_t action, int32_t flags, int32_t keyCode, + int32_t scanCode, int32_t metaState, int32_t repeatCount, nsecs_t downTime, + nsecs_t eventTime); void initialize(const KeyEvent& from); + static const char* actionToString(int32_t action); + protected: int32_t mAction; int32_t mFlags; @@ -451,6 +517,10 @@ public: inline void setActionButton(int32_t button) { mActionButton = button; } + inline float getXScale() const { return mXScale; } + + inline float getYScale() const { return mYScale; } + inline float getXOffset() const { return mXOffset; } inline float getYOffset() const { return mYOffset; } @@ -459,6 +529,18 @@ public: inline float getYPrecision() const { return mYPrecision; } + inline float getRawXCursorPosition() const { return mRawXCursorPosition; } + + float getXCursorPosition() const; + + inline float getRawYCursorPosition() const { return mRawYCursorPosition; } + + float getYCursorPosition() const; + + void setCursorPosition(float x, float y); + + static inline bool isValidCursorPosition(float x, float y) { return !isnan(x) && !isnan(y); } + inline nsecs_t getDownTime() const { return mDownTime; } inline void setDownTime(nsecs_t downTime) { mDownTime = downTime; } @@ -600,26 +682,14 @@ public: ssize_t findPointerIndex(int32_t pointerId) const; - void initialize( - int32_t deviceId, - int32_t source, - int32_t displayId, - int32_t action, - int32_t actionButton, - int32_t flags, - int32_t edgeFlags, - int32_t metaState, - int32_t buttonState, - MotionClassification classification, - float xOffset, - float yOffset, - float xPrecision, - float yPrecision, - nsecs_t downTime, - nsecs_t eventTime, - size_t pointerCount, - const PointerProperties* pointerProperties, - const PointerCoords* pointerCoords); + void initialize(int32_t id, int32_t deviceId, uint32_t source, int32_t displayId, + std::array<uint8_t, 32> hmac, int32_t action, int32_t actionButton, + int32_t flags, int32_t edgeFlags, int32_t metaState, int32_t buttonState, + MotionClassification classification, float xScale, float yScale, float xOffset, + float yOffset, float xPrecision, float yPrecision, float rawXCursorPosition, + float rawYCursorPosition, nsecs_t downTime, nsecs_t eventTime, + size_t pointerCount, const PointerProperties* pointerProperties, + const PointerCoords* pointerCoords); void copyFrom(const MotionEvent* other, bool keepHistory); @@ -640,7 +710,7 @@ public: status_t writeToParcel(Parcel* parcel) const; #endif - static bool isTouchEvent(int32_t source, int32_t action); + static bool isTouchEvent(uint32_t source, int32_t action); inline bool isTouchEvent() const { return isTouchEvent(mSource, mAction); } @@ -657,6 +727,8 @@ public: static const char* getLabel(int32_t axis); static int32_t getAxisFromLabel(const char* label); + static const char* actionToString(int32_t action); + protected: int32_t mAction; int32_t mActionButton; @@ -665,10 +737,14 @@ protected: int32_t mMetaState; int32_t mButtonState; MotionClassification mClassification; + float mXScale; + float mYScale; float mXOffset; float mYOffset; float mXPrecision; float mYPrecision; + float mRawXCursorPosition; + float mRawYCursorPosition; nsecs_t mDownTime; Vector<PointerProperties> mPointerProperties; Vector<nsecs_t> mSampleEventTimes; @@ -676,6 +752,77 @@ protected: }; /* + * Focus events. + */ +class FocusEvent : public InputEvent { +public: + virtual ~FocusEvent() {} + + virtual int32_t getType() const override { return AINPUT_EVENT_TYPE_FOCUS; } + + inline bool getHasFocus() const { return mHasFocus; } + + inline bool getInTouchMode() const { return mInTouchMode; } + + void initialize(int32_t id, bool hasFocus, bool inTouchMode); + + void initialize(const FocusEvent& from); + +protected: + bool mHasFocus; + bool mInTouchMode; +}; + +/** + * Base class for verified events. + * Do not create a VerifiedInputEvent explicitly. + * Use helper functions to create them from InputEvents. + */ +struct __attribute__((__packed__)) VerifiedInputEvent { + enum class Type : int32_t { + KEY = AINPUT_EVENT_TYPE_KEY, + MOTION = AINPUT_EVENT_TYPE_MOTION, + }; + + Type type; + int32_t deviceId; + nsecs_t eventTimeNanos; + uint32_t source; + int32_t displayId; +}; + +/** + * Same as KeyEvent, but only contains the data that can be verified. + * If you update this class, you must also update VerifiedKeyEvent.java + */ +struct __attribute__((__packed__)) VerifiedKeyEvent : public VerifiedInputEvent { + int32_t action; + nsecs_t downTimeNanos; + int32_t flags; + int32_t keyCode; + int32_t scanCode; + int32_t metaState; + int32_t repeatCount; +}; + +/** + * Same as MotionEvent, but only contains the data that can be verified. + * If you update this class, you must also update VerifiedMotionEvent.java + */ +struct __attribute__((__packed__)) VerifiedMotionEvent : public VerifiedInputEvent { + float rawX; + float rawY; + int32_t actionMasked; + nsecs_t downTimeNanos; + int32_t flags; + int32_t metaState; + int32_t buttonState; +}; + +VerifiedKeyEvent verifiedKeyEventFromKeyEvent(const KeyEvent& event); +VerifiedMotionEvent verifiedMotionEventFromMotionEvent(const MotionEvent& event); + +/* * Input event factory. */ class InputEventFactoryInterface { @@ -687,6 +834,7 @@ public: virtual KeyEvent* createKeyEvent() = 0; virtual MotionEvent* createMotionEvent() = 0; + virtual FocusEvent* createFocusEvent() = 0; }; /* @@ -698,12 +846,14 @@ public: PreallocatedInputEventFactory() { } virtual ~PreallocatedInputEventFactory() { } - virtual KeyEvent* createKeyEvent() { return & mKeyEvent; } - virtual MotionEvent* createMotionEvent() { return & mMotionEvent; } + virtual KeyEvent* createKeyEvent() override { return &mKeyEvent; } + virtual MotionEvent* createMotionEvent() override { return &mMotionEvent; } + virtual FocusEvent* createFocusEvent() override { return &mFocusEvent; } private: KeyEvent mKeyEvent; MotionEvent mMotionEvent; + FocusEvent mFocusEvent; }; /* @@ -714,16 +864,18 @@ public: explicit PooledInputEventFactory(size_t maxPoolSize = 20); virtual ~PooledInputEventFactory(); - virtual KeyEvent* createKeyEvent(); - virtual MotionEvent* createMotionEvent(); + virtual KeyEvent* createKeyEvent() override; + virtual MotionEvent* createMotionEvent() override; + virtual FocusEvent* createFocusEvent() override; void recycle(InputEvent* event); private: const size_t mMaxPoolSize; - Vector<KeyEvent*> mKeyEventPool; - Vector<MotionEvent*> mMotionEventPool; + std::queue<std::unique_ptr<KeyEvent>> mKeyEventPool; + std::queue<std::unique_ptr<MotionEvent>> mMotionEventPool; + std::queue<std::unique_ptr<FocusEvent>> mFocusEventPool; }; } // namespace android diff --git a/include/input/InputApplication.h b/include/input/InputApplication.h index 7f04611309..86de394a31 100644 --- a/include/input/InputApplication.h +++ b/include/input/InputApplication.h @@ -61,6 +61,11 @@ public: return mInfo.token ? mInfo.dispatchingTimeout : defaultValue; } + inline std::chrono::nanoseconds getDispatchingTimeout( + std::chrono::nanoseconds defaultValue) const { + return mInfo.token ? std::chrono::nanoseconds(mInfo.dispatchingTimeout) : defaultValue; + } + inline sp<IBinder> getApplicationToken() const { return mInfo.token; } diff --git a/include/input/InputDevice.h b/include/input/InputDevice.h index b6efc82fd4..20a17e3347 100644 --- a/include/input/InputDevice.h +++ b/include/input/InputDevice.h @@ -180,6 +180,8 @@ enum ReservedInputDeviceId : int32_t { VIRTUAL_KEYBOARD_ID = -1, // Device id of the "built-in" keyboard if there is one. BUILT_IN_KEYBOARD_ID = 0, + // First device id available for dynamic devices + END_RESERVED_ID = 1, }; } // namespace android diff --git a/include/input/InputEventLabels.h b/include/input/InputEventLabels.h index 59d16d15af..b327d76b1c 100644 --- a/include/input/InputEventLabels.h +++ b/include/input/InputEventLabels.h @@ -359,6 +359,9 @@ static const InputEventLabel AXES[] = { DEFINE_AXIS(BRAKE), DEFINE_AXIS(DISTANCE), DEFINE_AXIS(TILT), + DEFINE_AXIS(SCROLL), + DEFINE_AXIS(RELATIVE_X), + DEFINE_AXIS(RELATIVE_Y), DEFINE_AXIS(GENERIC_1), DEFINE_AXIS(GENERIC_2), DEFINE_AXIS(GENERIC_3), @@ -402,13 +405,12 @@ static const InputEventLabel LEDS[] = { { nullptr, 0 } }; -static const InputEventLabel FLAGS[] = { - DEFINE_FLAG(VIRTUAL), - DEFINE_FLAG(FUNCTION), - DEFINE_FLAG(GESTURE), +static const InputEventLabel FLAGS[] = {DEFINE_FLAG(VIRTUAL), + DEFINE_FLAG(FUNCTION), + DEFINE_FLAG(GESTURE), + DEFINE_FLAG(WAKE), - { nullptr, 0 } -}; + {nullptr, 0}}; static int lookupValueByLabel(const char* literal, const InputEventLabel *list) { while (list->literal) { diff --git a/include/input/InputTransport.h b/include/input/InputTransport.h index 63606e5911..7ca9031f77 100644 --- a/include/input/InputTransport.h +++ b/include/input/InputTransport.h @@ -31,13 +31,17 @@ #include <string> +#include <android-base/chrono_utils.h> + #include <binder/IBinder.h> #include <input/Input.h> +#include <utils/BitSet.h> #include <utils/Errors.h> -#include <utils/Timers.h> #include <utils/RefBase.h> +#include <utils/Timers.h> #include <utils/Vector.h> -#include <utils/BitSet.h> + +#include <android-base/unique_fd.h> namespace android { class Parcel; @@ -56,14 +60,15 @@ class Parcel; * in StructLayout_test should be made. */ struct InputMessage { - enum { - TYPE_KEY = 1, - TYPE_MOTION = 2, - TYPE_FINISHED = 3, + enum class Type : uint32_t { + KEY, + MOTION, + FINISHED, + FOCUS, }; struct Header { - uint32_t type; + Type type; // 4 bytes // We don't need this field in order to align the body below but we // leave it here because InputMessage::size() and other functions // compute the size of this structure as sizeof(Header) + sizeof(Body). @@ -71,14 +76,18 @@ struct InputMessage { } header; // Body *must* be 8 byte aligned. + // For keys and motions, rely on the fact that std::array takes up exactly as much space + // as the underlying data. This is not guaranteed by C++, but it simplifies the conversions. + static_assert(sizeof(std::array<uint8_t, 32>) == 32); union Body { struct Key { uint32_t seq; - uint32_t empty1; + int32_t eventId; nsecs_t eventTime __attribute__((aligned(8))); int32_t deviceId; int32_t source; int32_t displayId; + std::array<uint8_t, 32> hmac; int32_t action; int32_t flags; int32_t keyCode; @@ -88,38 +97,46 @@ struct InputMessage { uint32_t empty2; nsecs_t downTime __attribute__((aligned(8))); - inline size_t size() const { - return sizeof(Key); - } + inline size_t size() const { return sizeof(Key); } } key; struct Motion { uint32_t seq; - uint32_t empty1; + int32_t eventId; nsecs_t eventTime __attribute__((aligned(8))); int32_t deviceId; int32_t source; int32_t displayId; + std::array<uint8_t, 32> hmac; int32_t action; int32_t actionButton; int32_t flags; int32_t metaState; int32_t buttonState; MotionClassification classification; // base type: uint8_t - uint8_t empty2[3]; + uint8_t empty2[3]; // 3 bytes to fill gap created by classification int32_t edgeFlags; nsecs_t downTime __attribute__((aligned(8))); + float xScale; + float yScale; float xOffset; float yOffset; float xPrecision; float yPrecision; + float xCursorPosition; + float yCursorPosition; uint32_t pointerCount; uint32_t empty3; - // Note that PointerCoords requires 8 byte alignment. + /** + * The "pointers" field must be the last field of the struct InputMessage. + * When we send the struct InputMessage across the socket, we are not + * writing the entire "pointers" array, but only the pointerCount portion + * of it as an optimization. Adding a field after "pointers" would break this. + */ struct Pointer { PointerProperties properties; PointerCoords coords; - } pointers[MAX_POINTERS]; + } pointers[MAX_POINTERS] __attribute__((aligned(8))); int32_t getActionId() const { uint32_t index = (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) @@ -135,12 +152,21 @@ struct InputMessage { struct Finished { uint32_t seq; - bool handled; + uint32_t handled; // actually a bool, but we must maintain 8-byte alignment - inline size_t size() const { - return sizeof(Finished); - } + inline size_t size() const { return sizeof(Finished); } } finished; + + struct Focus { + uint32_t seq; + int32_t eventId; + uint32_t empty1; + // The following two fields take up 4 bytes total + uint16_t hasFocus; // actually a bool + uint16_t inTouchMode; // actually a bool, but we must maintain 8-byte alignment + + inline size_t size() const { return sizeof(Focus); } + } focus; } __attribute__((aligned(8))) body; bool isValid(size_t actualSize) const; @@ -161,60 +187,73 @@ protected: virtual ~InputChannel(); public: - InputChannel() = default; - InputChannel(const std::string& name, int fd); + static sp<InputChannel> create(const std::string& name, android::base::unique_fd fd, + sp<IBinder> token); - /* Creates a pair of input channels. + /** + * Create a pair of input channels. + * The two returned input channels are equivalent, and are labeled as "server" and "client" + * for convenience. The two input channels share the same token. * - * Returns OK on success. + * Return OK on success. */ static status_t openInputChannelPair(const std::string& name, sp<InputChannel>& outServerChannel, sp<InputChannel>& outClientChannel); inline std::string getName() const { return mName; } - inline int getFd() const { return mFd; } + inline int getFd() const { return mFd.get(); } - /* Sends a message to the other endpoint. + /* Send a message to the other endpoint. * * If the channel is full then the message is guaranteed not to have been sent at all. * Try again after the consumer has sent a finished signal indicating that it has * consumed some of the pending messages from the channel. * - * Returns OK on success. - * Returns WOULD_BLOCK if the channel is full. - * Returns DEAD_OBJECT if the channel's peer has been closed. + * Return OK on success. + * Return WOULD_BLOCK if the channel is full. + * Return DEAD_OBJECT if the channel's peer has been closed. * Other errors probably indicate that the channel is broken. */ status_t sendMessage(const InputMessage* msg); - /* Receives a message sent by the other endpoint. + /* Receive a message sent by the other endpoint. * * If there is no message present, try again after poll() indicates that the fd * is readable. * - * Returns OK on success. - * Returns WOULD_BLOCK if there is no message present. - * Returns DEAD_OBJECT if the channel's peer has been closed. + * Return OK on success. + * Return WOULD_BLOCK if there is no message present. + * Return DEAD_OBJECT if the channel's peer has been closed. * Other errors probably indicate that the channel is broken. */ status_t receiveMessage(InputMessage* msg); - /* Returns a new object that has a duplicate of this channel's fd. */ + /* Return a new object that has a duplicate of this channel's fd. */ sp<InputChannel> dup() const; status_t write(Parcel& out) const; - status_t read(const Parcel& from); + static sp<InputChannel> read(const Parcel& from); - sp<IBinder> getToken() const; - void setToken(const sp<IBinder>& token); + /** + * The connection token is used to identify the input connection, i.e. + * the pair of input channels that were created simultaneously. Input channels + * are always created in pairs, and the token can be used to find the server-side + * input channel from the client-side input channel, and vice versa. + * + * Do not use connection token to check equality of a specific input channel object + * to another, because two different (client and server) input channels will share the + * same connection token. + * + * Return the token that identifies this connection. + */ + sp<IBinder> getConnectionToken() const; private: - void setFd(int fd); - + InputChannel(const std::string& name, android::base::unique_fd fd, sp<IBinder> token); std::string mName; - int mFd = -1; + android::base::unique_fd mFd; - sp<IBinder> mToken = nullptr; + sp<IBinder> mToken; }; /* @@ -239,19 +278,10 @@ public: * Returns BAD_VALUE if seq is 0. * Other errors probably indicate that the channel is broken. */ - status_t publishKeyEvent( - uint32_t seq, - int32_t deviceId, - int32_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, - nsecs_t eventTime); + status_t publishKeyEvent(uint32_t seq, int32_t eventId, int32_t deviceId, int32_t source, + int32_t displayId, std::array<uint8_t, 32> hmac, int32_t action, + int32_t flags, int32_t keyCode, int32_t scanCode, int32_t metaState, + int32_t repeatCount, nsecs_t downTime, nsecs_t eventTime); /* Publishes a motion event to the input channel. * @@ -261,27 +291,25 @@ public: * Returns BAD_VALUE if seq is 0 or if pointerCount is less than 1 or greater than MAX_POINTERS. * Other errors probably indicate that the channel is broken. */ - status_t publishMotionEvent( - uint32_t seq, - int32_t deviceId, - int32_t source, - int32_t displayId, - int32_t action, - int32_t actionButton, - int32_t flags, - int32_t edgeFlags, - int32_t metaState, - int32_t buttonState, - MotionClassification classification, - float xOffset, - float yOffset, - float xPrecision, - float yPrecision, - nsecs_t downTime, - nsecs_t eventTime, - uint32_t pointerCount, - const PointerProperties* pointerProperties, - const PointerCoords* pointerCoords); + status_t publishMotionEvent(uint32_t seq, int32_t eventId, int32_t deviceId, int32_t source, + int32_t displayId, std::array<uint8_t, 32> hmac, int32_t action, + int32_t actionButton, int32_t flags, int32_t edgeFlags, + int32_t metaState, int32_t buttonState, + MotionClassification classification, float xScale, float yScale, + float xOffset, float yOffset, float xPrecision, float yPrecision, + float xCursorPosition, float yCursorPosition, nsecs_t downTime, + nsecs_t eventTime, uint32_t pointerCount, + const PointerProperties* pointerProperties, + const PointerCoords* pointerCoords); + + /* Publishes a focus event to the input channel. + * + * Returns OK on success. + * Returns WOULD_BLOCK if the channel is full. + * Returns DEAD_OBJECT if the channel's peer has been closed. + * Other errors probably indicate that the channel is broken. + */ + status_t publishFocusEvent(uint32_t seq, int32_t eventId, bool hasFocus, bool inTouchMode); /* Receives the finished signal from the consumer in reply to the original dispatch signal. * If a signal was received, returns the message sequence number, @@ -297,6 +325,7 @@ public: status_t receiveFinishedSignal(uint32_t* outSeq, bool* outHandled); private: + sp<InputChannel> mChannel; }; @@ -337,8 +366,8 @@ public: * Returns NO_MEMORY if the event could not be created. * Other errors probably indicate that the channel is broken. */ - status_t consume(InputEventFactoryInterface* factory, bool consumeBatches, - nsecs_t frameTime, uint32_t* outSeq, InputEvent** outEvent); + status_t consume(InputEventFactoryInterface* factory, bool consumeBatches, nsecs_t frameTime, + uint32_t* outSeq, InputEvent** outEvent); /* Sends a finished signal to the publisher to inform it that the message * with the specified sequence number has finished being process and whether @@ -375,6 +404,13 @@ public: */ bool hasPendingBatch() const; + /* Returns the source of first pending batch if exist. + * + * Should be called after calling consume() with consumeBatches == false to determine + * whether consume() should be called again later on with consumeBatches == true. + */ + int32_t getPendingBatchSource() const; + private: // True if touch resampling is enabled. const bool mResampleTouch; @@ -509,6 +545,7 @@ private: static void rewriteMessage(TouchState& state, InputMessage& msg); static void initializeKeyEvent(KeyEvent* event, const InputMessage* msg); static void initializeMotionEvent(MotionEvent* event, const InputMessage* msg); + static void initializeFocusEvent(FocusEvent* event, const InputMessage* msg); static void addSample(MotionEvent* event, const InputMessage* msg); static bool canAddSample(const Batch& batch, const InputMessage* msg); static ssize_t findSampleNoLaterThan(const Batch& batch, nsecs_t time); diff --git a/include/input/InputWindow.h b/include/input/InputWindow.h index 916af699e0..2dac5b62a7 100644 --- a/include/input/InputWindow.h +++ b/include/input/InputWindow.h @@ -63,52 +63,53 @@ struct InputWindowInfo { FLAG_DISMISS_KEYGUARD = 0x00400000, FLAG_SPLIT_TOUCH = 0x00800000, FLAG_SLIPPERY = 0x20000000, - FLAG_NEEDS_MENU_KEY = 0x40000000, }; // Window types from WindowManager.LayoutParams enum { FIRST_APPLICATION_WINDOW = 1, - TYPE_BASE_APPLICATION = 1, - TYPE_APPLICATION = 2, + TYPE_BASE_APPLICATION = 1, + TYPE_APPLICATION = 2, TYPE_APPLICATION_STARTING = 3, LAST_APPLICATION_WINDOW = 99, - FIRST_SUB_WINDOW = 1000, - TYPE_APPLICATION_PANEL = FIRST_SUB_WINDOW, - TYPE_APPLICATION_MEDIA = FIRST_SUB_WINDOW+1, - TYPE_APPLICATION_SUB_PANEL = FIRST_SUB_WINDOW+2, - TYPE_APPLICATION_ATTACHED_DIALOG = FIRST_SUB_WINDOW+3, - TYPE_APPLICATION_MEDIA_OVERLAY = FIRST_SUB_WINDOW+4, - LAST_SUB_WINDOW = 1999, - FIRST_SYSTEM_WINDOW = 2000, - TYPE_STATUS_BAR = FIRST_SYSTEM_WINDOW, - TYPE_SEARCH_BAR = FIRST_SYSTEM_WINDOW+1, - TYPE_PHONE = FIRST_SYSTEM_WINDOW+2, - TYPE_SYSTEM_ALERT = FIRST_SYSTEM_WINDOW+3, - TYPE_KEYGUARD = FIRST_SYSTEM_WINDOW+4, - TYPE_TOAST = FIRST_SYSTEM_WINDOW+5, - TYPE_SYSTEM_OVERLAY = FIRST_SYSTEM_WINDOW+6, - TYPE_PRIORITY_PHONE = FIRST_SYSTEM_WINDOW+7, - TYPE_SYSTEM_DIALOG = FIRST_SYSTEM_WINDOW+8, - TYPE_KEYGUARD_DIALOG = FIRST_SYSTEM_WINDOW+9, - TYPE_SYSTEM_ERROR = FIRST_SYSTEM_WINDOW+10, - TYPE_INPUT_METHOD = FIRST_SYSTEM_WINDOW+11, - TYPE_INPUT_METHOD_DIALOG= FIRST_SYSTEM_WINDOW+12, - TYPE_WALLPAPER = FIRST_SYSTEM_WINDOW+13, - TYPE_STATUS_BAR_PANEL = FIRST_SYSTEM_WINDOW+14, - TYPE_SECURE_SYSTEM_OVERLAY = FIRST_SYSTEM_WINDOW+15, - TYPE_DRAG = FIRST_SYSTEM_WINDOW+16, - TYPE_STATUS_BAR_SUB_PANEL = FIRST_SYSTEM_WINDOW+17, - TYPE_POINTER = FIRST_SYSTEM_WINDOW+18, - TYPE_NAVIGATION_BAR = FIRST_SYSTEM_WINDOW+19, - TYPE_VOLUME_OVERLAY = FIRST_SYSTEM_WINDOW+20, - TYPE_BOOT_PROGRESS = FIRST_SYSTEM_WINDOW+21, - TYPE_INPUT_CONSUMER = FIRST_SYSTEM_WINDOW+22, - TYPE_NAVIGATION_BAR_PANEL = FIRST_SYSTEM_WINDOW+24, - TYPE_MAGNIFICATION_OVERLAY = FIRST_SYSTEM_WINDOW+27, - TYPE_ACCESSIBILITY_OVERLAY = FIRST_SYSTEM_WINDOW+32, - TYPE_DOCK_DIVIDER = FIRST_SYSTEM_WINDOW+34, - LAST_SYSTEM_WINDOW = 2999, + FIRST_SUB_WINDOW = 1000, + TYPE_APPLICATION_PANEL = FIRST_SUB_WINDOW, + TYPE_APPLICATION_MEDIA = FIRST_SUB_WINDOW + 1, + TYPE_APPLICATION_SUB_PANEL = FIRST_SUB_WINDOW + 2, + TYPE_APPLICATION_ATTACHED_DIALOG = FIRST_SUB_WINDOW + 3, + TYPE_APPLICATION_MEDIA_OVERLAY = FIRST_SUB_WINDOW + 4, + LAST_SUB_WINDOW = 1999, + FIRST_SYSTEM_WINDOW = 2000, + TYPE_STATUS_BAR = FIRST_SYSTEM_WINDOW, + TYPE_SEARCH_BAR = FIRST_SYSTEM_WINDOW + 1, + TYPE_PHONE = FIRST_SYSTEM_WINDOW + 2, + TYPE_SYSTEM_ALERT = FIRST_SYSTEM_WINDOW + 3, + TYPE_KEYGUARD = FIRST_SYSTEM_WINDOW + 4, + TYPE_TOAST = FIRST_SYSTEM_WINDOW + 5, + TYPE_SYSTEM_OVERLAY = FIRST_SYSTEM_WINDOW + 6, + TYPE_PRIORITY_PHONE = FIRST_SYSTEM_WINDOW + 7, + TYPE_SYSTEM_DIALOG = FIRST_SYSTEM_WINDOW + 8, + TYPE_KEYGUARD_DIALOG = FIRST_SYSTEM_WINDOW + 9, + TYPE_SYSTEM_ERROR = FIRST_SYSTEM_WINDOW + 10, + TYPE_INPUT_METHOD = FIRST_SYSTEM_WINDOW + 11, + TYPE_INPUT_METHOD_DIALOG = FIRST_SYSTEM_WINDOW + 12, + TYPE_WALLPAPER = FIRST_SYSTEM_WINDOW + 13, + TYPE_STATUS_BAR_PANEL = FIRST_SYSTEM_WINDOW + 14, + TYPE_SECURE_SYSTEM_OVERLAY = FIRST_SYSTEM_WINDOW + 15, + TYPE_DRAG = FIRST_SYSTEM_WINDOW + 16, + TYPE_STATUS_BAR_SUB_PANEL = FIRST_SYSTEM_WINDOW + 17, + TYPE_POINTER = FIRST_SYSTEM_WINDOW + 18, + TYPE_NAVIGATION_BAR = FIRST_SYSTEM_WINDOW + 19, + TYPE_VOLUME_OVERLAY = FIRST_SYSTEM_WINDOW + 20, + TYPE_BOOT_PROGRESS = FIRST_SYSTEM_WINDOW + 21, + TYPE_INPUT_CONSUMER = FIRST_SYSTEM_WINDOW + 22, + TYPE_NAVIGATION_BAR_PANEL = FIRST_SYSTEM_WINDOW + 24, + TYPE_MAGNIFICATION_OVERLAY = FIRST_SYSTEM_WINDOW + 27, + TYPE_ACCESSIBILITY_OVERLAY = FIRST_SYSTEM_WINDOW + 32, + TYPE_DOCK_DIVIDER = FIRST_SYSTEM_WINDOW + 34, + TYPE_NOTIFICATION_SHADE = FIRST_SYSTEM_WINDOW + 40, + TYPE_TRUSTED_APPLICATION_OVERLAY = FIRST_SYSTEM_WINDOW + 42, + LAST_SYSTEM_WINDOW = 2999, }; enum { @@ -120,17 +121,21 @@ struct InputWindowInfo { /* These values are filled in by the WM and passed through SurfaceFlinger * unless specified otherwise. */ + // This value should NOT be used to uniquely identify the window. There may be different + // input windows that have the same token. sp<IBinder> token; + // This uniquely identifies the input window. + int32_t id = -1; std::string name; - int32_t layoutParamsFlags; - int32_t layoutParamsType; - nsecs_t dispatchingTimeout; + int32_t layoutParamsFlags = 0; + int32_t layoutParamsType = 0; + nsecs_t dispatchingTimeout = -1; /* These values are filled in by SurfaceFlinger. */ - int32_t frameLeft; - int32_t frameTop; - int32_t frameRight; - int32_t frameBottom; + int32_t frameLeft = -1; + int32_t frameTop = -1; + int32_t frameRight = -1; + int32_t frameBottom = -1; /* * SurfaceFlinger consumes this value to shrink the computed frame. This is @@ -142,7 +147,7 @@ struct InputWindowInfo { // A global scaling factor for all windows. Unlike windowScaleX/Y this results // in scaling of the TOUCH_MAJOR/TOUCH_MINOR axis. - float globalScaleFactor; + float globalScaleFactor = 1.0f; // Scaling factors applied to individual windows. float windowXScale = 1.0f; @@ -153,19 +158,18 @@ struct InputWindowInfo { * to absolute coordinates by SurfaceFlinger once the frame is computed. */ Region touchableRegion; - bool visible; - bool canReceiveKeys; - bool hasFocus; - bool hasWallpaper; - bool paused; - int32_t layer; - int32_t ownerPid; - int32_t ownerUid; - int32_t inputFeatures; - int32_t displayId; + bool visible = false; + bool canReceiveKeys = false; + bool hasFocus = false; + bool hasWallpaper = false; + bool paused = false; + int32_t ownerPid = -1; + int32_t ownerUid = -1; + int32_t inputFeatures = 0; + int32_t displayId = ADISPLAY_ID_NONE; int32_t portalToDisplayId = ADISPLAY_ID_NONE; InputApplicationInfo applicationInfo; - bool replaceTouchableRegionWithCrop; + bool replaceTouchableRegionWithCrop = false; wp<IBinder> touchableRegionCropHandle; void addTouchableRegion(const Rect& region); @@ -204,18 +208,25 @@ public: sp<IBinder> getToken() const; + int32_t getId() const { return mInfo.id; } + sp<IBinder> getApplicationToken() { return mInfo.applicationInfo.token; } inline std::string getName() const { - return mInfo.token ? mInfo.name : "<invalid>"; + return !mInfo.name.empty() ? mInfo.name : "<invalid>"; } inline nsecs_t getDispatchingTimeout(nsecs_t defaultValue) const { return mInfo.token ? mInfo.dispatchingTimeout : defaultValue; } + inline std::chrono::nanoseconds getDispatchingTimeout( + std::chrono::nanoseconds defaultValue) const { + return mInfo.token ? std::chrono::nanoseconds(mInfo.dispatchingTimeout) : defaultValue; + } + /** * Requests that the state of this object be updated to reflect * the most current available information about the application. diff --git a/include/input/LatencyStatistics.h b/include/input/LatencyStatistics.h new file mode 100644 index 0000000000..bd86266901 --- /dev/null +++ b/include/input/LatencyStatistics.h @@ -0,0 +1,59 @@ +/* + * 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_STATISTICS_H +#define _UI_INPUT_STATISTICS_H + +#include <android-base/chrono_utils.h> + +#include <stddef.h> + +namespace android { + +class LatencyStatistics { +private: + /* Minimum sample recorded */ + float mMin; + /* Maximum sample recorded */ + float mMax; + /* Sum of all samples recorded */ + float mSum; + /* Sum of all the squares of samples recorded */ + float mSum2; + /* Count of all samples recorded */ + size_t mCount; + /* The last time statistics were reported */ + std::chrono::steady_clock::time_point mLastReportTime; + /* Statistics Report Frequency */ + const std::chrono::seconds mReportPeriod; + +public: + LatencyStatistics(std::chrono::seconds period); + + void addValue(float); + void reset(); + bool shouldReport(); + + float getMean(); + float getMin(); + float getMax(); + float getStDev(); + size_t getCount(); +}; + +} // namespace android + +#endif // _UI_INPUT_STATISTICS_H diff --git a/include/input/TouchVideoFrame.h b/include/input/TouchVideoFrame.h index b49c623204..4fa2f86dc1 100644 --- a/include/input/TouchVideoFrame.h +++ b/include/input/TouchVideoFrame.h @@ -19,7 +19,6 @@ #include <stdint.h> #include <sys/time.h> -#include <ui/DisplayInfo.h> #include <vector> namespace android { |