diff options
Diffstat (limited to 'include/input')
| -rw-r--r-- | include/input/DisplayViewport.h | 10 | ||||
| -rw-r--r-- | include/input/Input.h | 107 | ||||
| -rw-r--r-- | include/input/InputDevice.h | 7 | ||||
| -rw-r--r-- | include/input/InputTransport.h | 76 | ||||
| -rw-r--r-- | include/input/PrintTools.h | 70 |
5 files changed, 194 insertions, 76 deletions
diff --git a/include/input/DisplayViewport.h b/include/input/DisplayViewport.h index a6213f3ddd..9148fee532 100644 --- a/include/input/DisplayViewport.h +++ b/include/input/DisplayViewport.h @@ -18,7 +18,8 @@ #define _LIBINPUT_DISPLAY_VIEWPORT_H #include <android-base/stringprintf.h> -#include <ftl/NamedEnum.h> +#include <ftl/enum.h> +#include <ftl/string.h> #include <gui/constants.h> #include <input/Input.h> @@ -44,6 +45,8 @@ enum class ViewportType : int32_t { INTERNAL = 1, EXTERNAL = 2, VIRTUAL = 3, + + ftl_last = VIRTUAL }; /* @@ -132,9 +135,8 @@ struct DisplayViewport { "physicalFrame=[%d, %d, %d, %d], " "deviceSize=[%d, %d], " "isActive=[%d]", - NamedEnum::string(type).c_str(), displayId, uniqueId.c_str(), - physicalPort ? StringPrintf("%" PRIu8, *physicalPort).c_str() - : "<none>", + ftl::enum_string(type).c_str(), displayId, uniqueId.c_str(), + physicalPort ? ftl::to_string(*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 4adaa5b1c5..e7d68fc349 100644 --- a/include/input/Input.h +++ b/include/input/Input.h @@ -31,10 +31,8 @@ #include <stdint.h> #include <ui/Transform.h> #include <utils/BitSet.h> -#include <utils/KeyedVector.h> #include <utils/RefBase.h> #include <utils/Timers.h> -#include <utils/Vector.h> #include <array> #include <limits> #include <queue> @@ -88,7 +86,7 @@ enum { */ AMOTION_EVENT_FLAG_NO_FOCUS_CHANGE = 0x40, -#ifdef __linux__ +#if defined(__linux__) /** * This event was generated or modified by accessibility service. */ @@ -166,7 +164,7 @@ enum { * (We want at least 10 but some touch controllers obstensibly configured for 10 pointers * will occasionally emit 11. There is not much harm making this constant bigger.) */ -#define MAX_POINTERS 16 +static constexpr size_t MAX_POINTERS = 16; /* * Maximum number of samples supported per motion event. @@ -201,8 +199,17 @@ namespace android { class Parcel; #endif +/* + * Apply the given transform to the point without applying any translation/offset. + */ +vec2 transformWithoutTranslation(const ui::Transform& transform, const vec2& xy); + const char* inputEventTypeToString(int32_t type); +std::string inputEventSourceToString(int32_t source); + +bool isFromSource(uint32_t source, uint32_t test); + /* * Flags that flow alongside events in the input dispatch system to help with certain * policy decisions such as waking from device sleep. @@ -268,23 +275,21 @@ enum { /** * Classifications of the current gesture, if available. - * - * The following values must be kept in sync with MotionEvent.java */ enum class MotionClassification : uint8_t { /** * No classification is available. */ - NONE = 0, + NONE = AMOTION_EVENT_CLASSIFICATION_NONE, /** * Too early to classify the current gesture. Need more events. Look for changes in the * upcoming motion events. */ - AMBIGUOUS_GESTURE = 1, + AMBIGUOUS_GESTURE = AMOTION_EVENT_CLASSIFICATION_AMBIGUOUS_GESTURE, /** * The current gesture likely represents a user intentionally exerting force on the touchscreen. */ - DEEP_PRESS = 2, + DEEP_PRESS = AMOTION_EVENT_CLASSIFICATION_DEEP_PRESS, }; /** @@ -369,13 +374,10 @@ struct PointerCoords { float getAxisValue(int32_t axis) const; status_t setAxisValue(int32_t axis, float value); - void scale(float globalScale); - // Scale the pointer coordinates according to a global scale and a // window scale. The global scale will be applied to TOUCH/TOOL_MAJOR/MINOR // axes, however the window scaling will not. void scale(float globalScale, float windowXScale, float windowYScale); - void applyOffset(float xOffset, float yOffset); void transform(const ui::Transform& transform); @@ -526,13 +528,17 @@ public: inline int32_t getAction() const { return mAction; } - inline int32_t getActionMasked() const { return mAction & AMOTION_EVENT_ACTION_MASK; } + static int32_t getActionMasked(int32_t action) { return action & AMOTION_EVENT_ACTION_MASK; } - inline int32_t getActionIndex() const { - return (mAction & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) - >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT; + inline int32_t getActionMasked() const { return getActionMasked(mAction); } + + static uint8_t getActionIndex(int32_t action) { + return (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >> + AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT; } + inline int32_t getActionIndex() const { return getActionIndex(mAction); } + inline void setAction(int32_t action) { mAction = action; } inline int32_t getFlags() const { return mFlags; } @@ -561,7 +567,9 @@ public: inline float getYOffset() const { return mTransform.ty(); } - inline ui::Transform getTransform() const { return mTransform; } + inline const ui::Transform& getTransform() const { return mTransform; } + + int getSurfaceRotation() const; inline float getXPrecision() const { return mXPrecision; } @@ -577,9 +585,7 @@ public: void setCursorPosition(float x, float y); - uint32_t getDisplayOrientation() const { return mDisplayOrientation; } - - int2 getDisplaySize() const { return {mDisplayWidth, mDisplayHeight}; } + inline const ui::Transform& getRawTransform() const { return mRawTransform; } static inline bool isValidCursorPosition(float x, float y) { return !isnan(x) && !isnan(y); } @@ -755,8 +761,8 @@ public: int32_t flags, int32_t edgeFlags, int32_t metaState, int32_t buttonState, MotionClassification classification, const ui::Transform& transform, float xPrecision, float yPrecision, float rawXCursorPosition, - float rawYCursorPosition, uint32_t displayOrientation, int32_t displayWidth, - int32_t displayHeight, nsecs_t downTime, nsecs_t eventTime, size_t pointerCount, + float rawYCursorPosition, const ui::Transform& rawTransform, nsecs_t downTime, + nsecs_t eventTime, size_t pointerCount, const PointerProperties* pointerProperties, const PointerCoords* pointerCoords); void copyFrom(const MotionEvent* other, bool keepHistory); @@ -789,11 +795,11 @@ public: // Low-level accessors. inline const PointerProperties* getPointerProperties() const { - return mPointerProperties.array(); + return mPointerProperties.data(); } inline const nsecs_t* getSampleEventTimes() const { return mSampleEventTimes.data(); } inline const PointerCoords* getSamplePointerCoords() const { - return mSamplePointerCoords.array(); + return mSamplePointerCoords.data(); } static const char* getLabel(int32_t axis); @@ -801,6 +807,16 @@ public: static std::string actionToString(int32_t action); + // MotionEvent will transform various axes in different ways, based on the source. For + // example, the x and y axes will not have any offsets/translations applied if it comes from a + // relative mouse device (since SOURCE_RELATIVE_MOUSE is a non-pointer source). These methods + // are used to apply these transformations for different axes. + static vec2 calculateTransformedXY(uint32_t source, const ui::Transform&, const vec2& xy); + static float calculateTransformedAxisValue(int32_t axis, uint32_t source, const ui::Transform&, + const PointerCoords&); + static PointerCoords calculateTransformedCoords(uint32_t source, const ui::Transform&, + const PointerCoords&); + protected: int32_t mAction; int32_t mActionButton; @@ -814,15 +830,15 @@ protected: float mYPrecision; float mRawXCursorPosition; float mRawYCursorPosition; - uint32_t mDisplayOrientation; - int32_t mDisplayWidth; - int32_t mDisplayHeight; + ui::Transform mRawTransform; nsecs_t mDownTime; - Vector<PointerProperties> mPointerProperties; + std::vector<PointerProperties> mPointerProperties; std::vector<nsecs_t> mSampleEventTimes; - Vector<PointerCoords> mSamplePointerCoords; + std::vector<PointerCoords> mSamplePointerCoords; }; +std::ostream& operator<<(std::ostream& out, const MotionEvent& event); + /* * Focus events. */ @@ -834,15 +850,12 @@ public: inline bool getHasFocus() const { return mHasFocus; } - inline bool getInTouchMode() const { return mInTouchMode; } - - void initialize(int32_t id, bool hasFocus, bool inTouchMode); + void initialize(int32_t id, bool hasFocus); void initialize(const FocusEvent& from); protected: bool mHasFocus; - bool mInTouchMode; }; /* @@ -888,6 +901,25 @@ protected: float mX, mY; }; +/* + * Touch mode events. + */ +class TouchModeEvent : public InputEvent { +public: + virtual ~TouchModeEvent() {} + + virtual int32_t getType() const override { return AINPUT_EVENT_TYPE_TOUCH_MODE; } + + inline bool isInTouchMode() const { return mIsInTouchMode; } + + void initialize(int32_t id, bool isInTouchMode); + + void initialize(const TouchModeEvent& from); + +protected: + bool mIsInTouchMode; +}; + /** * Base class for verified events. * Do not create a VerifiedInputEvent explicitly. @@ -912,8 +944,8 @@ struct __attribute__((__packed__)) VerifiedInputEvent { */ struct __attribute__((__packed__)) VerifiedKeyEvent : public VerifiedInputEvent { int32_t action; - nsecs_t downTimeNanos; int32_t flags; + nsecs_t downTimeNanos; int32_t keyCode; int32_t scanCode; int32_t metaState; @@ -928,8 +960,8 @@ struct __attribute__((__packed__)) VerifiedMotionEvent : public VerifiedInputEve float rawX; float rawY; int32_t actionMasked; - nsecs_t downTimeNanos; int32_t flags; + nsecs_t downTimeNanos; int32_t metaState; int32_t buttonState; }; @@ -952,6 +984,7 @@ public: virtual FocusEvent* createFocusEvent() = 0; virtual CaptureEvent* createCaptureEvent() = 0; virtual DragEvent* createDragEvent() = 0; + virtual TouchModeEvent* createTouchModeEvent() = 0; }; /* @@ -968,6 +1001,7 @@ public: virtual FocusEvent* createFocusEvent() override { return &mFocusEvent; } virtual CaptureEvent* createCaptureEvent() override { return &mCaptureEvent; } virtual DragEvent* createDragEvent() override { return &mDragEvent; } + virtual TouchModeEvent* createTouchModeEvent() override { return &mTouchModeEvent; } private: KeyEvent mKeyEvent; @@ -975,6 +1009,7 @@ private: FocusEvent mFocusEvent; CaptureEvent mCaptureEvent; DragEvent mDragEvent; + TouchModeEvent mTouchModeEvent; }; /* @@ -990,6 +1025,7 @@ public: virtual FocusEvent* createFocusEvent() override; virtual CaptureEvent* createCaptureEvent() override; virtual DragEvent* createDragEvent() override; + virtual TouchModeEvent* createTouchModeEvent() override; void recycle(InputEvent* event); @@ -1001,6 +1037,7 @@ private: std::queue<std::unique_ptr<FocusEvent>> mFocusEventPool; std::queue<std::unique_ptr<CaptureEvent>> mCaptureEventPool; std::queue<std::unique_ptr<DragEvent>> mDragEventPool; + std::queue<std::unique_ptr<TouchModeEvent>> mTouchModeEventPool; }; /* diff --git a/include/input/InputDevice.h b/include/input/InputDevice.h index 22b9faaf7a..3585392c2b 100644 --- a/include/input/InputDevice.h +++ b/include/input/InputDevice.h @@ -84,6 +84,9 @@ enum class InputDeviceSensorType : int32_t { GAME_ROTATION_VECTOR = ASENSOR_TYPE_GAME_ROTATION_VECTOR, GYROSCOPE_UNCALIBRATED = ASENSOR_TYPE_GYROSCOPE_UNCALIBRATED, SIGNIFICANT_MOTION = ASENSOR_TYPE_SIGNIFICANT_MOTION, + + ftl_first = ACCELEROMETER, + ftl_last = SIGNIFICANT_MOTION }; enum class InputDeviceSensorAccuracy : int32_t { @@ -105,6 +108,8 @@ enum class InputDeviceLightType : int32_t { PLAYER_ID = 1, RGB = 2, MULTI_COLOR = 3, + + ftl_last = MULTI_COLOR }; struct InputDeviceSensorInfo { @@ -230,7 +235,7 @@ public: void addBatteryInfo(const InputDeviceBatteryInfo& info); void addLightInfo(const InputDeviceLightInfo& info); - inline void setKeyboardType(int32_t keyboardType) { mKeyboardType = keyboardType; } + void setKeyboardType(int32_t keyboardType); inline int32_t getKeyboardType() const { return mKeyboardType; } inline void setKeyCharacterMap(const std::shared_ptr<KeyCharacterMap> value) { diff --git a/include/input/InputTransport.h b/include/input/InputTransport.h index a790b5637f..5f9a37d69c 100644 --- a/include/input/InputTransport.h +++ b/include/input/InputTransport.h @@ -72,6 +72,9 @@ struct InputMessage { CAPTURE, DRAG, TIMELINE, + TOUCH_MODE, + + ftl_last = TOUCH_MODE }; struct Header { @@ -111,7 +114,7 @@ struct InputMessage { struct Motion { int32_t eventId; - uint32_t empty1; + uint32_t pointerCount; nsecs_t eventTime __attribute__((aligned(8))); int32_t deviceId; int32_t source; @@ -126,20 +129,22 @@ struct InputMessage { uint8_t empty2[3]; // 3 bytes to fill gap created by classification int32_t edgeFlags; nsecs_t downTime __attribute__((aligned(8))); - float dsdx; - float dtdx; - float dtdy; - float dsdy; - float tx; - float ty; + float dsdx; // Begin window transform + float dtdx; // + float dtdy; // + float dsdy; // + float tx; // + float ty; // End window transform float xPrecision; float yPrecision; float xCursorPosition; float yCursorPosition; - uint32_t displayOrientation; - int32_t displayWidth; - int32_t displayHeight; - uint32_t pointerCount; + float dsdxRaw; // Begin raw transform + float dtdxRaw; // + float dtdyRaw; // + float dsdyRaw; // + float txRaw; // + float tyRaw; // End raw transform /** * The "pointers" field must be the last field of the struct InputMessage. * When we send the struct InputMessage across the socket, we are not @@ -173,10 +178,9 @@ struct InputMessage { struct Focus { int32_t eventId; - // The following 3 fields take up 4 bytes total + // The following 2 fields take up 4 bytes total bool hasFocus; - bool inTouchMode; - uint8_t empty[2]; + uint8_t empty[3]; inline size_t size() const { return sizeof(Focus); } } focus; @@ -206,6 +210,15 @@ struct InputMessage { inline size_t size() const { return sizeof(Timeline); } } timeline; + + struct TouchMode { + int32_t eventId; + // The following 2 fields take up 4 bytes total + bool isInTouchMode; + uint8_t empty[3]; + + inline size_t size() const { return sizeof(TouchMode); } + } touchMode; } __attribute__((aligned(8))) body; bool isValid(size_t actualSize) const; @@ -355,9 +368,8 @@ public: int32_t metaState, int32_t buttonState, MotionClassification classification, const ui::Transform& transform, float xPrecision, float yPrecision, float xCursorPosition, - float yCursorPosition, uint32_t displayOrientation, - int32_t displayWidth, int32_t displayHeight, nsecs_t downTime, - nsecs_t eventTime, uint32_t pointerCount, + float yCursorPosition, const ui::Transform& rawTransform, + nsecs_t downTime, nsecs_t eventTime, uint32_t pointerCount, const PointerProperties* pointerProperties, const PointerCoords* pointerCoords); @@ -368,7 +380,7 @@ public: * 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); + status_t publishFocusEvent(uint32_t seq, int32_t eventId, bool hasFocus); /* Publishes a capture event to the input channel. * @@ -388,6 +400,15 @@ public: */ status_t publishDragEvent(uint32_t seq, int32_t eventId, float x, float y, bool isExiting); + /* Publishes a touch mode 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 publishTouchModeEvent(uint32_t seq, int32_t eventId, bool isInTouchMode); + struct Finished { uint32_t seq; bool handled; @@ -479,24 +500,6 @@ public: status_t sendTimeline(int32_t inputEventId, std::array<nsecs_t, GraphicsTimeline::SIZE> timeline); - /* Returns true if there is a deferred event waiting. - * - * Should be called after calling consume() to determine whether the consumer - * has a deferred event to be processed. Deferred events are somewhat special in - * that they have already been removed from the input channel. If the input channel - * becomes empty, the client may need to do extra work to ensure that it processes - * the deferred event despite the fact that the input channel's file descriptor - * is not readable. - * - * One option is simply to call consume() in a loop until it returns WOULD_BLOCK. - * This guarantees that all deferred events will be processed. - * - * Alternately, the caller can call hasDeferredEvent() to determine whether there is - * a deferred event waiting and then ensure that its event loop wakes up at least - * one more time to consume the deferred event. - */ - bool hasDeferredEvent() const; - /* Returns true if there is a pending batch. * * Should be called after calling consume() with consumeBatches == false to determine @@ -658,6 +661,7 @@ private: static void initializeFocusEvent(FocusEvent* event, const InputMessage* msg); static void initializeCaptureEvent(CaptureEvent* event, const InputMessage* msg); static void initializeDragEvent(DragEvent* event, const InputMessage* msg); + static void initializeTouchModeEvent(TouchModeEvent* 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/PrintTools.h b/include/input/PrintTools.h new file mode 100644 index 0000000000..0a75278494 --- /dev/null +++ b/include/input/PrintTools.h @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2022 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. + */ + +#pragma once + +#include <map> +#include <set> +#include <string> + +namespace android { + +template <typename T> +std::string constToString(const T& v) { + return std::to_string(v); +} + +/** + * Convert a set of integral types to string. + */ +template <typename T> +std::string dumpSet(const std::set<T>& v, std::string (*toString)(const T&) = constToString) { + std::string out; + for (const T& entry : v) { + out += out.empty() ? "{" : ", "; + out += toString(entry); + } + return out.empty() ? "{}" : (out + "}"); +} + +/** + * Convert a map to string. Both keys and values of the map should be integral type. + */ +template <typename K, typename V> +std::string dumpMap(const std::map<K, V>& map, std::string (*keyToString)(const K&) = constToString, + std::string (*valueToString)(const V&) = constToString) { + std::string out; + for (const auto& [k, v] : map) { + if (!out.empty()) { + out += "\n"; + } + out += keyToString(k) + ":" + valueToString(v); + } + return out; +} + +const char* toString(bool value); + +/** + * Add "prefix" to the beginning of each line in the provided string + * "str". + * The string 'str' is typically multi-line. + * The most common use case for this function is to add some padding + * when dumping state. + */ +std::string addLinePrefix(std::string str, const std::string& prefix); + +} // namespace android
\ No newline at end of file |