blob: 336d5243ebc390b8985de634902b944573ddc6c4 [file] [log] [blame]
/*
* 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.
*/
#pragma once
#include <optional>
#include <string>
#include <stdint.h>
#include <ui/Rotation.h>
#include "CursorButtonAccumulator.h"
#include "CursorScrollAccumulator.h"
#include "EventHub.h"
#include "InputMapper.h"
#include "InputReaderBase.h"
#include "TouchButtonAccumulator.h"
namespace android {
// Maximum amount of latency to add to touch events while waiting for data from an
// external stylus.
static constexpr nsecs_t EXTERNAL_STYLUS_DATA_TIMEOUT = ms2ns(72);
// Maximum amount of time to wait on touch data before pushing out new pressure data.
static constexpr nsecs_t TOUCH_DATA_TIMEOUT = ms2ns(20);
/* Raw axis information from the driver. */
struct RawPointerAxes {
RawAbsoluteAxisInfo x{};
RawAbsoluteAxisInfo y{};
RawAbsoluteAxisInfo pressure{};
RawAbsoluteAxisInfo touchMajor{};
RawAbsoluteAxisInfo touchMinor{};
RawAbsoluteAxisInfo toolMajor{};
RawAbsoluteAxisInfo toolMinor{};
RawAbsoluteAxisInfo orientation{};
RawAbsoluteAxisInfo distance{};
RawAbsoluteAxisInfo tiltX{};
RawAbsoluteAxisInfo tiltY{};
RawAbsoluteAxisInfo trackingId{};
RawAbsoluteAxisInfo slot{};
inline int32_t getRawWidth() const { return x.maxValue - x.minValue + 1; }
inline int32_t getRawHeight() const { return y.maxValue - y.minValue + 1; }
inline void clear() { *this = RawPointerAxes(); }
};
using PropertiesArray = std::array<PointerProperties, MAX_POINTERS>;
using CoordsArray = std::array<PointerCoords, MAX_POINTERS>;
using IdToIndexArray = std::array<uint32_t, MAX_POINTER_ID + 1>;
/* Raw data for a collection of pointers including a pointer id mapping table. */
struct RawPointerData {
struct Pointer {
uint32_t id{0xFFFFFFFF};
int32_t x{};
int32_t y{};
int32_t pressure{};
int32_t touchMajor{};
int32_t touchMinor{};
int32_t toolMajor{};
int32_t toolMinor{};
int32_t orientation{};
int32_t distance{};
int32_t tiltX{};
int32_t tiltY{};
// A fully decoded ToolType constant.
ToolType toolType{ToolType::UNKNOWN};
bool isHovering{false};
};
uint32_t pointerCount{};
std::array<Pointer, MAX_POINTERS> pointers{};
BitSet32 hoveringIdBits{}, touchingIdBits{}, canceledIdBits{};
IdToIndexArray idToIndex{};
inline void clear() { *this = RawPointerData(); }
void getCentroidOfTouchingPointers(float* outX, float* outY) const;
inline void markIdBit(uint32_t id, bool isHovering) {
if (isHovering) {
hoveringIdBits.markBit(id);
} else {
touchingIdBits.markBit(id);
}
}
inline void clearIdBits() {
hoveringIdBits.clear();
touchingIdBits.clear();
canceledIdBits.clear();
}
inline const Pointer& pointerForId(uint32_t id) const { return pointers[idToIndex[id]]; }
inline bool isHovering(uint32_t pointerIndex) { return pointers[pointerIndex].isHovering; }
};
/* Cooked data for a collection of pointers including a pointer id mapping table. */
struct CookedPointerData {
uint32_t pointerCount{};
PropertiesArray pointerProperties{};
CoordsArray pointerCoords{};
BitSet32 hoveringIdBits{}, touchingIdBits{}, canceledIdBits{}, validIdBits{};
IdToIndexArray idToIndex{};
inline void clear() { *this = CookedPointerData(); }
inline const PointerCoords& pointerCoordsForId(uint32_t id) const {
return pointerCoords[idToIndex[id]];
}
inline PointerCoords& editPointerCoordsWithId(uint32_t id) {
return pointerCoords[idToIndex[id]];
}
inline PointerProperties& editPointerPropertiesWithId(uint32_t id) {
return pointerProperties[idToIndex[id]];
}
inline bool isHovering(uint32_t pointerIndex) const {
return hoveringIdBits.hasBit(pointerProperties[pointerIndex].id);
}
inline bool isTouching(uint32_t pointerIndex) const {
return touchingIdBits.hasBit(pointerProperties[pointerIndex].id);
}
inline bool hasPointerCoordsForId(uint32_t id) const { return validIdBits.hasBit(id); }
};
class TouchInputMapper : public InputMapper {
public:
explicit TouchInputMapper(InputDeviceContext& deviceContext);
~TouchInputMapper() override;
uint32_t getSources() const override;
void populateDeviceInfo(InputDeviceInfo& deviceInfo) override;
void dump(std::string& dump) override;
[[nodiscard]] std::list<NotifyArgs> configure(nsecs_t when,
const InputReaderConfiguration* config,
uint32_t changes) override;
[[nodiscard]] std::list<NotifyArgs> reset(nsecs_t when) override;
[[nodiscard]] std::list<NotifyArgs> process(const RawEvent* rawEvent) override;
int32_t getKeyCodeState(uint32_t sourceMask, int32_t keyCode) override;
int32_t getScanCodeState(uint32_t sourceMask, int32_t scanCode) override;
bool markSupportedKeyCodes(uint32_t sourceMask, const std::vector<int32_t>& keyCodes,
uint8_t* outFlags) override;
[[nodiscard]] std::list<NotifyArgs> cancelTouch(nsecs_t when, nsecs_t readTime) override;
[[nodiscard]] std::list<NotifyArgs> timeoutExpired(nsecs_t when) override;
[[nodiscard]] std::list<NotifyArgs> updateExternalStylusState(
const StylusState& state) override;
std::optional<int32_t> getAssociatedDisplayId() override;
protected:
CursorButtonAccumulator mCursorButtonAccumulator;
CursorScrollAccumulator mCursorScrollAccumulator;
TouchButtonAccumulator mTouchButtonAccumulator;
struct VirtualKey {
int32_t keyCode;
int32_t scanCode;
uint32_t flags;
// computed hit box, specified in touch screen coords based on known display size
int32_t hitLeft;
int32_t hitTop;
int32_t hitRight;
int32_t hitBottom;
inline bool isHit(int32_t x, int32_t y) const {
return x >= hitLeft && x <= hitRight && y >= hitTop && y <= hitBottom;
}
};
// Input sources and device mode.
uint32_t mSource;
enum class DeviceMode {
DISABLED, // input is disabled
DIRECT, // direct mapping (touchscreen)
UNSCALED, // unscaled mapping (touchpad)
NAVIGATION, // unscaled mapping with assist gesture (touch navigation)
POINTER, // pointer mapping (pointer)
ftl_last = POINTER
};
DeviceMode mDeviceMode;
// The reader's configuration.
InputReaderConfiguration mConfig;
// Immutable configuration parameters.
struct Parameters {
enum class DeviceType {
TOUCH_SCREEN,
TOUCH_NAVIGATION,
POINTER,
ftl_last = POINTER
};
DeviceType deviceType;
bool hasAssociatedDisplay;
bool associatedDisplayIsExternal;
bool orientationAware;
ui::Rotation orientation;
bool hasButtonUnderPad;
std::string uniqueDisplayId;
enum class GestureMode {
SINGLE_TOUCH,
MULTI_TOUCH,
ftl_last = MULTI_TOUCH
};
GestureMode gestureMode;
bool wake;
// The Universal Stylus Initiative (USI) protocol version supported by this device.
std::optional<InputDeviceUsiVersion> usiVersion;
// Allows touches while the display is off.
bool enableForInactiveViewport;
} mParameters;
// Immutable calibration parameters in parsed form.
struct Calibration {
// Size
enum class SizeCalibration {
DEFAULT,
NONE,
GEOMETRIC,
DIAMETER,
BOX,
AREA,
ftl_last = AREA
};
SizeCalibration sizeCalibration;
std::optional<float> sizeScale;
std::optional<float> sizeBias;
std::optional<bool> sizeIsSummed;
// Pressure
enum class PressureCalibration {
DEFAULT,
NONE,
PHYSICAL,
AMPLITUDE,
};
PressureCalibration pressureCalibration;
std::optional<float> pressureScale;
// Orientation
enum class OrientationCalibration {
DEFAULT,
NONE,
INTERPOLATED,
VECTOR,
};
OrientationCalibration orientationCalibration;
// Distance
enum class DistanceCalibration {
DEFAULT,
NONE,
SCALED,
};
DistanceCalibration distanceCalibration;
std::optional<float> distanceScale;
inline void applySizeScaleAndBias(float& outSize) const {
if (sizeScale) {
outSize *= *sizeScale;
}
if (sizeBias) {
outSize += *sizeBias;
}
if (outSize < 0) {
outSize = 0;
}
}
} mCalibration;
// Affine location transformation/calibration
struct TouchAffineTransformation mAffineTransform;
RawPointerAxes mRawPointerAxes;
struct RawState {
nsecs_t when{std::numeric_limits<nsecs_t>::min()};
nsecs_t readTime{};
// Raw pointer sample data.
RawPointerData rawPointerData{};
int32_t buttonState{};
// Scroll state.
int32_t rawVScroll{};
int32_t rawHScroll{};
inline void clear() { *this = RawState(); }
};
struct CookedState {
// Cooked pointer sample data.
CookedPointerData cookedPointerData{};
// Id bits used to differentiate fingers, stylus and mouse tools.
BitSet32 fingerIdBits{};
BitSet32 stylusIdBits{};
BitSet32 mouseIdBits{};
int32_t buttonState{};
inline void clear() { *this = CookedState(); }
};
std::vector<RawState> mRawStatesPending;
RawState mCurrentRawState;
CookedState mCurrentCookedState;
RawState mLastRawState;
CookedState mLastCookedState;
// State provided by an external stylus
StylusState mExternalStylusState;
// If an external stylus is capable of reporting pointer-specific data like pressure, we will
// attempt to fuse the pointer data reported by the stylus to the first touch pointer. This is
// the id of the pointer to which the external stylus data is fused.
std::optional<uint32_t> mFusedStylusPointerId;
nsecs_t mExternalStylusFusionTimeout;
bool mExternalStylusDataPending;
// A subset of the buttons in mCurrentRawState that came from an external stylus.
int32_t mExternalStylusButtonsApplied;
// True if we sent a HOVER_ENTER event.
bool mSentHoverEnter;
// Have we assigned pointer IDs for this stream
bool mHavePointerIds;
// Is the current stream of direct touch events aborted
bool mCurrentMotionAborted;
// The time the primary pointer last went down.
nsecs_t mDownTime;
// The pointer controller, or null if the device is not a pointer.
std::shared_ptr<PointerControllerInterface> mPointerController;
std::vector<VirtualKey> mVirtualKeys;
virtual void configureParameters();
virtual void dumpParameters(std::string& dump);
virtual void configureRawPointerAxes();
virtual void dumpRawPointerAxes(std::string& dump);
virtual void configureInputDevice(nsecs_t when, bool* outResetNeeded);
virtual void dumpDisplay(std::string& dump);
virtual void configureVirtualKeys();
virtual void dumpVirtualKeys(std::string& dump);
virtual void parseCalibration();
virtual void resolveCalibration();
virtual void dumpCalibration(std::string& dump);
virtual void updateAffineTransformation();
virtual void dumpAffineTransformation(std::string& dump);
virtual void resolveExternalStylusPresence();
virtual bool hasStylus() const = 0;
virtual bool hasExternalStylus() const;
virtual void syncTouch(nsecs_t when, RawState* outState) = 0;
private:
// The current viewport.
// The components of the viewport are specified in the display's rotated orientation.
DisplayViewport mViewport;
// We refer to the display as being in the "natural orientation" when there is no rotation
// applied. The display size obtained from the viewport in the natural orientation.
// Always starts at (0, 0).
ui::Size mDisplayBounds{ui::kInvalidSize};
// The physical frame is the rectangle in the rotated display's coordinate space that maps to
// the logical display frame.
Rect mPhysicalFrameInRotatedDisplay{Rect::INVALID_RECT};
// The orientation of the input device relative to that of the display panel. It specifies
// the rotation of the input device coordinates required to produce the display panel
// orientation, so it will depend on whether the device is orientation aware.
ui::Rotation mInputDeviceOrientation;
// The transform that maps the input device's raw coordinate space to the un-rotated display's
// coordinate space. InputReader generates events in the un-rotated display's coordinate space.
ui::Transform mRawToDisplay;
// The transform that maps the input device's raw coordinate space to the rotated display's
// coordinate space. This used to perform hit-testing of raw events with the physical frame in
// the rotated coordinate space. See mPhysicalFrameInRotatedDisplay.
ui::Transform mRawToRotatedDisplay;
// The transform used for non-planar raw axes, such as orientation and tilt.
ui::Transform mRawRotation;
float mGeometricScale;
float mPressureScale;
float mSizeScale;
float mOrientationScale;
float mDistanceScale;
bool mHaveTilt;
float mTiltXCenter;
float mTiltXScale;
float mTiltYCenter;
float mTiltYScale;
bool mExternalStylusConnected;
// Oriented motion ranges for input device info.
struct OrientedRanges {
InputDeviceInfo::MotionRange x;
InputDeviceInfo::MotionRange y;
InputDeviceInfo::MotionRange pressure;
std::optional<InputDeviceInfo::MotionRange> size;
std::optional<InputDeviceInfo::MotionRange> touchMajor;
std::optional<InputDeviceInfo::MotionRange> touchMinor;
std::optional<InputDeviceInfo::MotionRange> toolMajor;
std::optional<InputDeviceInfo::MotionRange> toolMinor;
std::optional<InputDeviceInfo::MotionRange> orientation;
std::optional<InputDeviceInfo::MotionRange> distance;
std::optional<InputDeviceInfo::MotionRange> tilt;
void clear() {
size = std::nullopt;
touchMajor = std::nullopt;
touchMinor = std::nullopt;
toolMajor = std::nullopt;
toolMinor = std::nullopt;
orientation = std::nullopt;
distance = std::nullopt;
tilt = std::nullopt;
}
} mOrientedRanges;
// Oriented dimensions and precision.
float mOrientedXPrecision;
float mOrientedYPrecision;
struct CurrentVirtualKeyState {
bool down;
bool ignored;
nsecs_t downTime;
int32_t keyCode;
int32_t scanCode;
} mCurrentVirtualKey;
// Scale factor for gesture or mouse based pointer movements.
float mPointerXMovementScale;
float mPointerYMovementScale;
// Scale factor for gesture based zooming and other freeform motions.
float mPointerXZoomScale;
float mPointerYZoomScale;
// The maximum swipe width between pointers to detect a swipe gesture
// in the number of pixels.Touches that are wider than this are translated
// into freeform gestures.
float mPointerGestureMaxSwipeWidth;
struct PointerDistanceHeapElement {
uint32_t currentPointerIndex : 8 {};
uint32_t lastPointerIndex : 8 {};
uint64_t distance : 48 {}; // squared distance
};
enum class PointerUsage {
NONE,
GESTURES,
STYLUS,
MOUSE,
};
PointerUsage mPointerUsage;
struct PointerGesture {
enum class Mode {
// No fingers, button is not pressed.
// Nothing happening.
NEUTRAL,
// No fingers, button is not pressed.
// Tap detected.
// Emits DOWN and UP events at the pointer location.
TAP,
// Exactly one finger dragging following a tap.
// Pointer follows the active finger.
// Emits DOWN, MOVE and UP events at the pointer location.
//
// Detect double-taps when the finger goes up while in TAP_DRAG mode.
TAP_DRAG,
// Button is pressed.
// Pointer follows the active finger if there is one. Other fingers are ignored.
// Emits DOWN, MOVE and UP events at the pointer location.
BUTTON_CLICK_OR_DRAG,
// Exactly one finger, button is not pressed.
// Pointer follows the active finger.
// Emits HOVER_MOVE events at the pointer location.
//
// Detect taps when the finger goes up while in HOVER mode.
HOVER,
// Exactly two fingers but neither have moved enough to clearly indicate
// whether a swipe or freeform gesture was intended. We consider the
// pointer to be pressed so this enables clicking or long-pressing on buttons.
// Pointer does not move.
// Emits DOWN, MOVE and UP events with a single stationary pointer coordinate.
PRESS,
// Exactly two fingers moving in the same direction, button is not pressed.
// Pointer does not move.
// Emits DOWN, MOVE and UP events with a single pointer coordinate that
// follows the midpoint between both fingers.
SWIPE,
// Two or more fingers moving in arbitrary directions, button is not pressed.
// Pointer does not move.
// Emits DOWN, POINTER_DOWN, MOVE, POINTER_UP and UP events that follow
// each finger individually relative to the initial centroid of the finger.
FREEFORM,
// Waiting for quiet time to end before starting the next gesture.
QUIET,
};
// When a gesture is sent to an unfocused window, return true if it can bring that window
// into focus, false otherwise.
static bool canGestureAffectWindowFocus(Mode mode) {
switch (mode) {
case Mode::TAP:
case Mode::TAP_DRAG:
case Mode::BUTTON_CLICK_OR_DRAG:
// Taps can affect window focus.
return true;
case Mode::FREEFORM:
case Mode::HOVER:
case Mode::NEUTRAL:
case Mode::PRESS:
case Mode::QUIET:
case Mode::SWIPE:
// Most gestures can be performed on an unfocused window, so they should not
// not affect window focus.
return false;
}
}
// Time the first finger went down.
nsecs_t firstTouchTime;
// The active pointer id from the raw touch data.
int32_t activeTouchId; // -1 if none
// The active pointer id from the gesture last delivered to the application.
int32_t activeGestureId; // -1 if none
// Pointer coords and ids for the current and previous pointer gesture.
Mode currentGestureMode;
BitSet32 currentGestureIdBits;
IdToIndexArray currentGestureIdToIndex{};
PropertiesArray currentGestureProperties{};
CoordsArray currentGestureCoords{};
Mode lastGestureMode;
BitSet32 lastGestureIdBits;
IdToIndexArray lastGestureIdToIndex{};
PropertiesArray lastGestureProperties{};
CoordsArray lastGestureCoords{};
// Time the pointer gesture last went down.
nsecs_t downTime;
// Time when the pointer went down for a TAP.
nsecs_t tapDownTime;
// Time when the pointer went up for a TAP.
nsecs_t tapUpTime;
// Location of initial tap.
float tapX, tapY;
// Time we started waiting for quiescence.
nsecs_t quietTime;
// Reference points for multitouch gestures.
float referenceTouchX; // reference touch X/Y coordinates in surface units
float referenceTouchY;
float referenceGestureX; // reference gesture X/Y coordinates in pixels
float referenceGestureY;
// Distance that each pointer has traveled which has not yet been
// subsumed into the reference gesture position.
BitSet32 referenceIdBits;
struct Delta {
float dx, dy;
};
Delta referenceDeltas[MAX_POINTER_ID + 1];
// Describes how touch ids are mapped to gesture ids for freeform gestures.
uint32_t freeformTouchToGestureIdMap[MAX_POINTER_ID + 1];
// A velocity tracker for determining whether to switch active pointers during drags.
VelocityTracker velocityTracker;
void reset() {
firstTouchTime = LLONG_MIN;
activeTouchId = -1;
activeGestureId = -1;
currentGestureMode = Mode::NEUTRAL;
currentGestureIdBits.clear();
lastGestureMode = Mode::NEUTRAL;
lastGestureIdBits.clear();
downTime = 0;
velocityTracker.clear();
resetTap();
resetQuietTime();
}
void resetTap() {
tapDownTime = LLONG_MIN;
tapUpTime = LLONG_MIN;
}
void resetQuietTime() { quietTime = LLONG_MIN; }
} mPointerGesture;
struct PointerSimple {
PointerCoords currentCoords;
PointerProperties currentProperties;
PointerCoords lastCoords;
PointerProperties lastProperties;
// True if the pointer is down.
bool down;
// True if the pointer is hovering.
bool hovering;
// Time the pointer last went down.
nsecs_t downTime;
// Values reported for the last pointer event.
uint32_t source;
int32_t displayId;
float lastCursorX;
float lastCursorY;
void reset() {
currentCoords.clear();
currentProperties.clear();
lastCoords.clear();
lastProperties.clear();
down = false;
hovering = false;
downTime = 0;
source = 0;
displayId = ADISPLAY_ID_NONE;
lastCursorX = 0.f;
lastCursorY = 0.f;
}
} mPointerSimple;
// The pointer and scroll velocity controls.
VelocityControl mPointerVelocityControl;
VelocityControl mWheelXVelocityControl;
VelocityControl mWheelYVelocityControl;
std::optional<DisplayViewport> findViewport();
void resetExternalStylus();
void clearStylusDataPendingFlags();
int32_t clampResolution(const char* axisName, int32_t resolution) const;
void initializeOrientedRanges();
void initializeSizeRanges();
[[nodiscard]] std::list<NotifyArgs> sync(nsecs_t when, nsecs_t readTime);
[[nodiscard]] std::list<NotifyArgs> consumeRawTouches(nsecs_t when, nsecs_t readTime,
uint32_t policyFlags, bool& outConsumed);
[[nodiscard]] std::list<NotifyArgs> processRawTouches(bool timeout);
[[nodiscard]] std::list<NotifyArgs> cookAndDispatch(nsecs_t when, nsecs_t readTime);
[[nodiscard]] NotifyKeyArgs dispatchVirtualKey(nsecs_t when, nsecs_t readTime,
uint32_t policyFlags, int32_t keyEventAction,
int32_t keyEventFlags);
[[nodiscard]] std::list<NotifyArgs> dispatchTouches(nsecs_t when, nsecs_t readTime,
uint32_t policyFlags);
[[nodiscard]] std::list<NotifyArgs> dispatchHoverExit(nsecs_t when, nsecs_t readTime,
uint32_t policyFlags);
[[nodiscard]] std::list<NotifyArgs> dispatchHoverEnterAndMove(nsecs_t when, nsecs_t readTime,
uint32_t policyFlags);
[[nodiscard]] std::list<NotifyArgs> dispatchButtonRelease(nsecs_t when, nsecs_t readTime,
uint32_t policyFlags);
[[nodiscard]] std::list<NotifyArgs> dispatchButtonPress(nsecs_t when, nsecs_t readTime,
uint32_t policyFlags);
[[nodiscard]] std::list<NotifyArgs> dispatchGestureButtonPress(nsecs_t when,
uint32_t policyFlags,
BitSet32 idBits,
nsecs_t readTime);
[[nodiscard]] std::list<NotifyArgs> dispatchGestureButtonRelease(nsecs_t when,
uint32_t policyFlags,
BitSet32 idBits,
nsecs_t readTime);
const BitSet32& findActiveIdBits(const CookedPointerData& cookedPointerData);
void cookPointerData();
[[nodiscard]] std::list<NotifyArgs> abortTouches(nsecs_t when, nsecs_t readTime,
uint32_t policyFlags);
[[nodiscard]] std::list<NotifyArgs> dispatchPointerUsage(nsecs_t when, nsecs_t readTime,
uint32_t policyFlags,
PointerUsage pointerUsage);
[[nodiscard]] std::list<NotifyArgs> abortPointerUsage(nsecs_t when, nsecs_t readTime,
uint32_t policyFlags);
[[nodiscard]] std::list<NotifyArgs> dispatchPointerGestures(nsecs_t when, nsecs_t readTime,
uint32_t policyFlags,
bool isTimeout);
[[nodiscard]] std::list<NotifyArgs> abortPointerGestures(nsecs_t when, nsecs_t readTime,
uint32_t policyFlags);
bool preparePointerGestures(nsecs_t when, bool* outCancelPreviousGesture,
bool* outFinishPreviousGesture, bool isTimeout);
// Returns true if we're in a period of "quiet time" when touchpad gestures should be ignored.
bool checkForTouchpadQuietTime(nsecs_t when);
std::pair<int32_t, float> getFastestFinger();
void prepareMultiFingerPointerGestures(nsecs_t when, bool* outCancelPreviousGesture,
bool* outFinishPreviousGesture);
// Moves the on-screen mouse pointer based on the movement of the pointer of the given ID
// between the last and current events. Uses a relative motion.
void moveMousePointerFromPointerDelta(nsecs_t when, uint32_t pointerId);
[[nodiscard]] std::list<NotifyArgs> dispatchPointerStylus(nsecs_t when, nsecs_t readTime,
uint32_t policyFlags);
[[nodiscard]] std::list<NotifyArgs> abortPointerStylus(nsecs_t when, nsecs_t readTime,
uint32_t policyFlags);
[[nodiscard]] std::list<NotifyArgs> dispatchPointerMouse(nsecs_t when, nsecs_t readTime,
uint32_t policyFlags);
[[nodiscard]] std::list<NotifyArgs> abortPointerMouse(nsecs_t when, nsecs_t readTime,
uint32_t policyFlags);
[[nodiscard]] std::list<NotifyArgs> dispatchPointerSimple(nsecs_t when, nsecs_t readTime,
uint32_t policyFlags, bool down,
bool hovering, int32_t displayId);
[[nodiscard]] std::list<NotifyArgs> abortPointerSimple(nsecs_t when, nsecs_t readTime,
uint32_t policyFlags);
// Attempts to assign a pointer id to the external stylus. Returns true if the state should be
// withheld from further processing while waiting for data from the stylus.
bool assignExternalStylusId(const RawState& state, bool timeout);
void applyExternalStylusButtonState(nsecs_t when);
void applyExternalStylusTouchState(nsecs_t when);
// Dispatches a motion event.
// If the changedId is >= 0 and the action is POINTER_DOWN or POINTER_UP, the
// method will take care of setting the index and transmuting the action to DOWN or UP
// it is the first / last pointer to go down / up.
[[nodiscard]] NotifyMotionArgs dispatchMotion(
nsecs_t when, nsecs_t readTime, uint32_t policyFlags, uint32_t source, int32_t action,
int32_t actionButton, int32_t flags, int32_t metaState, int32_t buttonState,
int32_t edgeFlags, const PropertiesArray& properties, const CoordsArray& coords,
const IdToIndexArray& idToIndex, BitSet32 idBits, int32_t changedId, float xPrecision,
float yPrecision, nsecs_t downTime, MotionClassification classification);
// Returns if this touch device is a touch screen with an associated display.
bool isTouchScreen();
// Updates touch spots if they are enabled. Should only be used when this device is a
// touchscreen.
void updateTouchSpots();
bool isPointInsidePhysicalFrame(int32_t x, int32_t y) const;
const VirtualKey* findVirtualKeyHit(int32_t x, int32_t y);
static void assignPointerIds(const RawState& last, RawState& current);
// Compute input transforms for DIRECT and POINTER modes.
void computeInputTransforms();
void configureDeviceType();
};
} // namespace android