Merge "Add support for arbitrary axes in MotionEvents."
This commit is contained in:
commit
a1e5401add
@ -28,6 +28,10 @@
|
||||
#include <utils/RefBase.h>
|
||||
#include <utils/String8.h>
|
||||
|
||||
#ifdef HAVE_ANDROID_OS
|
||||
class SkMatrix;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Additional private constants not defined in ndk/ui/input.h.
|
||||
*/
|
||||
@ -79,6 +83,10 @@ struct AInputDevice {
|
||||
|
||||
namespace android {
|
||||
|
||||
#ifdef HAVE_ANDROID_OS
|
||||
class Parcel;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Flags that flow alongside events in the input dispatch system to help with certain
|
||||
* policy decisions such as waking from device sleep.
|
||||
@ -162,15 +170,61 @@ struct InputConfiguration {
|
||||
* Pointer coordinate data.
|
||||
*/
|
||||
struct PointerCoords {
|
||||
float x;
|
||||
float y;
|
||||
float pressure;
|
||||
float size;
|
||||
float touchMajor;
|
||||
float touchMinor;
|
||||
float toolMajor;
|
||||
float toolMinor;
|
||||
float orientation;
|
||||
static const size_t MAX_AXES = 15; // 15 so that sizeof(PointerCoords) == 16 * 4 == 64
|
||||
|
||||
// Bitfield of axes that are present in this structure.
|
||||
uint32_t bits; // 32bits are enough for now, can raise to 64bit when needed
|
||||
|
||||
// Values of axes that are stored in this structure packed in order by axis id
|
||||
// for each axis that is present in the structure according to 'bits'.
|
||||
float values[MAX_AXES];
|
||||
|
||||
inline void clear() {
|
||||
bits = 0;
|
||||
}
|
||||
|
||||
inline float getAxisValue(int32_t axis) const {
|
||||
uint32_t axisBit = 1 << axis;
|
||||
if (!(bits & axisBit)) {
|
||||
return 0;
|
||||
}
|
||||
uint32_t index = __builtin_popcount(bits & (axisBit - 1));
|
||||
return values[index];
|
||||
}
|
||||
|
||||
inline void setAxisValue(int32_t axis, float value) {
|
||||
uint32_t axisBit = 1 << axis;
|
||||
uint32_t index = __builtin_popcount(bits & (axisBit - 1));
|
||||
if (!(bits & axisBit)) {
|
||||
uint32_t count = __builtin_popcount(bits);
|
||||
if (count >= MAX_AXES) {
|
||||
tooManyAxes(axis);
|
||||
return;
|
||||
}
|
||||
bits |= axisBit;
|
||||
for (uint32_t i = count; i > index; i--) {
|
||||
values[i] = values[i - 1];
|
||||
}
|
||||
}
|
||||
values[index] = value;
|
||||
}
|
||||
|
||||
inline float* editAxisValue(int32_t axis) {
|
||||
uint32_t axisBit = 1 << axis;
|
||||
if (!(bits & axisBit)) {
|
||||
return NULL;
|
||||
}
|
||||
uint32_t index = __builtin_popcount(bits & (axisBit - 1));
|
||||
return &values[index];
|
||||
}
|
||||
|
||||
#ifdef HAVE_ANDROID_OS
|
||||
status_t readFromParcel(Parcel* parcel);
|
||||
status_t writeToParcel(Parcel* parcel) const;
|
||||
#endif
|
||||
|
||||
private:
|
||||
void tooManyAxes(int axis);
|
||||
};
|
||||
|
||||
/*
|
||||
@ -185,12 +239,13 @@ public:
|
||||
inline int32_t getDeviceId() const { return mDeviceId; }
|
||||
|
||||
inline int32_t getSource() const { return mSource; }
|
||||
|
||||
|
||||
inline void setSource(int32_t source) { mSource = source; }
|
||||
|
||||
protected:
|
||||
void initialize(int32_t deviceId, int32_t source);
|
||||
void initialize(const InputEvent& from);
|
||||
|
||||
private:
|
||||
int32_t mDeviceId;
|
||||
int32_t mSource;
|
||||
};
|
||||
@ -241,7 +296,7 @@ public:
|
||||
nsecs_t eventTime);
|
||||
void initialize(const KeyEvent& from);
|
||||
|
||||
private:
|
||||
protected:
|
||||
int32_t mAction;
|
||||
int32_t mFlags;
|
||||
int32_t mKeyCode;
|
||||
@ -263,12 +318,18 @@ public:
|
||||
|
||||
inline int32_t getAction() const { return mAction; }
|
||||
|
||||
inline void setAction(int32_t action) { mAction = action; }
|
||||
|
||||
inline int32_t getFlags() const { return mFlags; }
|
||||
|
||||
inline int32_t getEdgeFlags() const { return mEdgeFlags; }
|
||||
|
||||
inline void setEdgeFlags(int32_t edgeFlags) { mEdgeFlags = edgeFlags; }
|
||||
|
||||
inline int32_t getMetaState() const { return mMetaState; }
|
||||
|
||||
inline void setMetaState(int32_t metaState) { mMetaState = metaState; }
|
||||
|
||||
inline float getXOffset() const { return mXOffset; }
|
||||
|
||||
inline float getYOffset() const { return mYOffset; }
|
||||
@ -285,48 +346,54 @@ public:
|
||||
|
||||
inline nsecs_t getEventTime() const { return mSampleEventTimes[getHistorySize()]; }
|
||||
|
||||
const PointerCoords* getRawPointerCoords(size_t pointerIndex) const;
|
||||
|
||||
float getRawAxisValue(int32_t axis, size_t pointerIndex) const;
|
||||
|
||||
inline float getRawX(size_t pointerIndex) const {
|
||||
return getCurrentPointerCoords(pointerIndex).x;
|
||||
return getRawAxisValue(AINPUT_MOTION_AXIS_X, pointerIndex);
|
||||
}
|
||||
|
||||
inline float getRawY(size_t pointerIndex) const {
|
||||
return getCurrentPointerCoords(pointerIndex).y;
|
||||
return getRawAxisValue(AINPUT_MOTION_AXIS_Y, pointerIndex);
|
||||
}
|
||||
|
||||
float getAxisValue(int32_t axis, size_t pointerIndex) const;
|
||||
|
||||
inline float getX(size_t pointerIndex) const {
|
||||
return getRawX(pointerIndex) + mXOffset;
|
||||
return getAxisValue(AINPUT_MOTION_AXIS_X, pointerIndex);
|
||||
}
|
||||
|
||||
inline float getY(size_t pointerIndex) const {
|
||||
return getRawY(pointerIndex) + mYOffset;
|
||||
return getAxisValue(AINPUT_MOTION_AXIS_Y, pointerIndex);
|
||||
}
|
||||
|
||||
inline float getPressure(size_t pointerIndex) const {
|
||||
return getCurrentPointerCoords(pointerIndex).pressure;
|
||||
return getAxisValue(AINPUT_MOTION_AXIS_PRESSURE, pointerIndex);
|
||||
}
|
||||
|
||||
inline float getSize(size_t pointerIndex) const {
|
||||
return getCurrentPointerCoords(pointerIndex).size;
|
||||
return getAxisValue(AINPUT_MOTION_AXIS_SIZE, pointerIndex);
|
||||
}
|
||||
|
||||
inline float getTouchMajor(size_t pointerIndex) const {
|
||||
return getCurrentPointerCoords(pointerIndex).touchMajor;
|
||||
return getAxisValue(AINPUT_MOTION_AXIS_TOUCH_MAJOR, pointerIndex);
|
||||
}
|
||||
|
||||
inline float getTouchMinor(size_t pointerIndex) const {
|
||||
return getCurrentPointerCoords(pointerIndex).touchMinor;
|
||||
return getAxisValue(AINPUT_MOTION_AXIS_TOUCH_MINOR, pointerIndex);
|
||||
}
|
||||
|
||||
inline float getToolMajor(size_t pointerIndex) const {
|
||||
return getCurrentPointerCoords(pointerIndex).toolMajor;
|
||||
return getAxisValue(AINPUT_MOTION_AXIS_TOOL_MAJOR, pointerIndex);
|
||||
}
|
||||
|
||||
inline float getToolMinor(size_t pointerIndex) const {
|
||||
return getCurrentPointerCoords(pointerIndex).toolMinor;
|
||||
return getAxisValue(AINPUT_MOTION_AXIS_TOOL_MINOR, pointerIndex);
|
||||
}
|
||||
|
||||
inline float getOrientation(size_t pointerIndex) const {
|
||||
return getCurrentPointerCoords(pointerIndex).orientation;
|
||||
return getAxisValue(AINPUT_MOTION_AXIS_ORIENTATION, pointerIndex);
|
||||
}
|
||||
|
||||
inline size_t getHistorySize() const { return mSampleEventTimes.size() - 1; }
|
||||
@ -335,48 +402,67 @@ public:
|
||||
return mSampleEventTimes[historicalIndex];
|
||||
}
|
||||
|
||||
const PointerCoords* getHistoricalRawPointerCoords(
|
||||
size_t pointerIndex, size_t historicalIndex) const;
|
||||
|
||||
float getHistoricalRawAxisValue(int32_t axis, size_t pointerIndex,
|
||||
size_t historicalIndex) const;
|
||||
|
||||
inline float getHistoricalRawX(size_t pointerIndex, size_t historicalIndex) const {
|
||||
return getHistoricalPointerCoords(pointerIndex, historicalIndex).x;
|
||||
return getHistoricalRawAxisValue(
|
||||
AINPUT_MOTION_AXIS_X, pointerIndex, historicalIndex);
|
||||
}
|
||||
|
||||
inline float getHistoricalRawY(size_t pointerIndex, size_t historicalIndex) const {
|
||||
return getHistoricalPointerCoords(pointerIndex, historicalIndex).y;
|
||||
return getHistoricalRawAxisValue(
|
||||
AINPUT_MOTION_AXIS_Y, pointerIndex, historicalIndex);
|
||||
}
|
||||
|
||||
float getHistoricalAxisValue(int32_t axis, size_t pointerIndex, size_t historicalIndex) const;
|
||||
|
||||
inline float getHistoricalX(size_t pointerIndex, size_t historicalIndex) const {
|
||||
return getHistoricalRawX(pointerIndex, historicalIndex) + mXOffset;
|
||||
return getHistoricalAxisValue(
|
||||
AINPUT_MOTION_AXIS_X, pointerIndex, historicalIndex);
|
||||
}
|
||||
|
||||
inline float getHistoricalY(size_t pointerIndex, size_t historicalIndex) const {
|
||||
return getHistoricalRawY(pointerIndex, historicalIndex) + mYOffset;
|
||||
return getHistoricalAxisValue(
|
||||
AINPUT_MOTION_AXIS_Y, pointerIndex, historicalIndex);
|
||||
}
|
||||
|
||||
inline float getHistoricalPressure(size_t pointerIndex, size_t historicalIndex) const {
|
||||
return getHistoricalPointerCoords(pointerIndex, historicalIndex).pressure;
|
||||
return getHistoricalAxisValue(
|
||||
AINPUT_MOTION_AXIS_PRESSURE, pointerIndex, historicalIndex);
|
||||
}
|
||||
|
||||
inline float getHistoricalSize(size_t pointerIndex, size_t historicalIndex) const {
|
||||
return getHistoricalPointerCoords(pointerIndex, historicalIndex).size;
|
||||
return getHistoricalAxisValue(
|
||||
AINPUT_MOTION_AXIS_SIZE, pointerIndex, historicalIndex);
|
||||
}
|
||||
|
||||
inline float getHistoricalTouchMajor(size_t pointerIndex, size_t historicalIndex) const {
|
||||
return getHistoricalPointerCoords(pointerIndex, historicalIndex).touchMajor;
|
||||
return getHistoricalAxisValue(
|
||||
AINPUT_MOTION_AXIS_TOUCH_MAJOR, pointerIndex, historicalIndex);
|
||||
}
|
||||
|
||||
inline float getHistoricalTouchMinor(size_t pointerIndex, size_t historicalIndex) const {
|
||||
return getHistoricalPointerCoords(pointerIndex, historicalIndex).touchMinor;
|
||||
return getHistoricalAxisValue(
|
||||
AINPUT_MOTION_AXIS_TOUCH_MINOR, pointerIndex, historicalIndex);
|
||||
}
|
||||
|
||||
inline float getHistoricalToolMajor(size_t pointerIndex, size_t historicalIndex) const {
|
||||
return getHistoricalPointerCoords(pointerIndex, historicalIndex).toolMajor;
|
||||
return getHistoricalAxisValue(
|
||||
AINPUT_MOTION_AXIS_TOOL_MAJOR, pointerIndex, historicalIndex);
|
||||
}
|
||||
|
||||
inline float getHistoricalToolMinor(size_t pointerIndex, size_t historicalIndex) const {
|
||||
return getHistoricalPointerCoords(pointerIndex, historicalIndex).toolMinor;
|
||||
return getHistoricalAxisValue(
|
||||
AINPUT_MOTION_AXIS_TOOL_MINOR, pointerIndex, historicalIndex);
|
||||
}
|
||||
|
||||
inline float getHistoricalOrientation(size_t pointerIndex, size_t historicalIndex) const {
|
||||
return getHistoricalPointerCoords(pointerIndex, historicalIndex).orientation;
|
||||
return getHistoricalAxisValue(
|
||||
AINPUT_MOTION_AXIS_ORIENTATION, pointerIndex, historicalIndex);
|
||||
}
|
||||
|
||||
void initialize(
|
||||
@ -396,12 +482,23 @@ public:
|
||||
const int32_t* pointerIds,
|
||||
const PointerCoords* pointerCoords);
|
||||
|
||||
void copyFrom(const MotionEvent* other, bool keepHistory);
|
||||
|
||||
void addSample(
|
||||
nsecs_t eventTime,
|
||||
const PointerCoords* pointerCoords);
|
||||
|
||||
void offsetLocation(float xOffset, float yOffset);
|
||||
|
||||
void scale(float scaleFactor);
|
||||
|
||||
#ifdef HAVE_ANDROID_OS
|
||||
void transform(const SkMatrix* matrix);
|
||||
|
||||
status_t readFromParcel(Parcel* parcel);
|
||||
status_t writeToParcel(Parcel* parcel) const;
|
||||
#endif
|
||||
|
||||
// Low-level accessors.
|
||||
inline const int32_t* getPointerIds() const { return mPointerIds.array(); }
|
||||
inline const nsecs_t* getSampleEventTimes() const { return mSampleEventTimes.array(); }
|
||||
@ -409,7 +506,7 @@ public:
|
||||
return mSamplePointerCoords.array();
|
||||
}
|
||||
|
||||
private:
|
||||
protected:
|
||||
int32_t mAction;
|
||||
int32_t mFlags;
|
||||
int32_t mEdgeFlags;
|
||||
@ -422,15 +519,6 @@ private:
|
||||
Vector<int32_t> mPointerIds;
|
||||
Vector<nsecs_t> mSampleEventTimes;
|
||||
Vector<PointerCoords> mSamplePointerCoords;
|
||||
|
||||
inline const PointerCoords& getCurrentPointerCoords(size_t pointerIndex) const {
|
||||
return mSamplePointerCoords[getHistorySize() * getPointerCount() + pointerIndex];
|
||||
}
|
||||
|
||||
inline const PointerCoords& getHistoricalPointerCoords(
|
||||
size_t pointerIndex, size_t historicalIndex) const {
|
||||
return mSamplePointerCoords[historicalIndex * getPointerCount() + pointerIndex];
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
@ -486,11 +574,11 @@ public:
|
||||
inline const String8 getName() const { return mName; }
|
||||
inline uint32_t getSources() const { return mSources; }
|
||||
|
||||
const MotionRange* getMotionRange(int32_t rangeType) const;
|
||||
const MotionRange* getMotionRange(int32_t axis) const;
|
||||
|
||||
void addSource(uint32_t source);
|
||||
void addMotionRange(int32_t rangeType, float min, float max, float flat, float fuzz);
|
||||
void addMotionRange(int32_t rangeType, const MotionRange& range);
|
||||
void addMotionRange(int32_t axis, float min, float max, float flat, float fuzz);
|
||||
void addMotionRange(int32_t axis, const MotionRange& range);
|
||||
|
||||
inline void setKeyboardType(int32_t keyboardType) { mKeyboardType = keyboardType; }
|
||||
inline int32_t getKeyboardType() const { return mKeyboardType; }
|
||||
|
@ -60,7 +60,12 @@ LOCAL_SHARED_LIBRARIES := \
|
||||
libEGL \
|
||||
libpixelflinger \
|
||||
libhardware \
|
||||
libhardware_legacy
|
||||
libhardware_legacy \
|
||||
libskia \
|
||||
libbinder
|
||||
|
||||
LOCAL_C_INCLUDES := \
|
||||
external/skia/include/core
|
||||
|
||||
LOCAL_MODULE:= libui
|
||||
|
||||
|
@ -15,6 +15,16 @@
|
||||
|
||||
#include <ui/Input.h>
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#ifdef HAVE_ANDROID_OS
|
||||
#include <binder/Parcel.h>
|
||||
|
||||
#include "SkPoint.h"
|
||||
#include "SkMatrix.h"
|
||||
#include "SkScalar.h"
|
||||
#endif
|
||||
|
||||
namespace android {
|
||||
|
||||
static const char* CONFIGURATION_FILE_DIR[] = {
|
||||
@ -237,6 +247,41 @@ void KeyEvent::initialize(const KeyEvent& from) {
|
||||
mEventTime = from.mEventTime;
|
||||
}
|
||||
|
||||
|
||||
// --- PointerCoords ---
|
||||
|
||||
#ifdef HAVE_ANDROID_OS
|
||||
status_t PointerCoords::readFromParcel(Parcel* parcel) {
|
||||
bits = parcel->readInt32();
|
||||
|
||||
uint32_t count = __builtin_popcount(bits);
|
||||
if (count > MAX_AXES) {
|
||||
return BAD_VALUE;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < count; i++) {
|
||||
values[i] = parcel->readInt32();
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
status_t PointerCoords::writeToParcel(Parcel* parcel) const {
|
||||
parcel->writeInt32(bits);
|
||||
|
||||
uint32_t count = __builtin_popcount(bits);
|
||||
for (uint32_t i = 0; i < count; i++) {
|
||||
parcel->writeInt32(values[i]);
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
void PointerCoords::tooManyAxes(int axis) {
|
||||
LOGW("Could not set value for axis %d because the PointerCoords structure is full and "
|
||||
"cannot contain more than %d axis values.", axis, int(MAX_AXES));
|
||||
}
|
||||
|
||||
|
||||
// --- MotionEvent ---
|
||||
|
||||
void MotionEvent::initialize(
|
||||
@ -272,6 +317,33 @@ void MotionEvent::initialize(
|
||||
addSample(eventTime, pointerCoords);
|
||||
}
|
||||
|
||||
void MotionEvent::copyFrom(const MotionEvent* other, bool keepHistory) {
|
||||
InputEvent::initialize(other->mDeviceId, other->mSource);
|
||||
mAction = other->mAction;
|
||||
mFlags = other->mFlags;
|
||||
mEdgeFlags = other->mEdgeFlags;
|
||||
mMetaState = other->mMetaState;
|
||||
mXOffset = other->mXOffset;
|
||||
mYOffset = other->mYOffset;
|
||||
mXPrecision = other->mXPrecision;
|
||||
mYPrecision = other->mYPrecision;
|
||||
mDownTime = other->mDownTime;
|
||||
mPointerIds = other->mPointerIds;
|
||||
|
||||
if (keepHistory) {
|
||||
mSampleEventTimes = other->mSampleEventTimes;
|
||||
mSamplePointerCoords = other->mSamplePointerCoords;
|
||||
} else {
|
||||
mSampleEventTimes.clear();
|
||||
mSampleEventTimes.push(other->getEventTime());
|
||||
mSamplePointerCoords.clear();
|
||||
size_t pointerCount = other->getPointerCount();
|
||||
size_t historySize = other->getHistorySize();
|
||||
mSamplePointerCoords.appendArray(other->mSamplePointerCoords.array()
|
||||
+ (historySize * pointerCount), pointerCount);
|
||||
}
|
||||
}
|
||||
|
||||
void MotionEvent::addSample(
|
||||
int64_t eventTime,
|
||||
const PointerCoords* pointerCoords) {
|
||||
@ -279,11 +351,224 @@ void MotionEvent::addSample(
|
||||
mSamplePointerCoords.appendArray(pointerCoords, getPointerCount());
|
||||
}
|
||||
|
||||
const PointerCoords* MotionEvent::getRawPointerCoords(size_t pointerIndex) const {
|
||||
return &mSamplePointerCoords[getHistorySize() * getPointerCount() + pointerIndex];
|
||||
}
|
||||
|
||||
float MotionEvent::getRawAxisValue(int32_t axis, size_t pointerIndex) const {
|
||||
return getRawPointerCoords(pointerIndex)->getAxisValue(axis);
|
||||
}
|
||||
|
||||
float MotionEvent::getAxisValue(int32_t axis, size_t pointerIndex) const {
|
||||
float value = getRawPointerCoords(pointerIndex)->getAxisValue(axis);
|
||||
switch (axis) {
|
||||
case AINPUT_MOTION_AXIS_X:
|
||||
value += mXOffset;
|
||||
break;
|
||||
case AINPUT_MOTION_AXIS_Y:
|
||||
value += mYOffset;
|
||||
break;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
const PointerCoords* MotionEvent::getHistoricalRawPointerCoords(
|
||||
size_t pointerIndex, size_t historicalIndex) const {
|
||||
return &mSamplePointerCoords[historicalIndex * getPointerCount() + pointerIndex];
|
||||
}
|
||||
|
||||
float MotionEvent::getHistoricalRawAxisValue(int32_t axis, size_t pointerIndex,
|
||||
size_t historicalIndex) const {
|
||||
return getHistoricalRawPointerCoords(pointerIndex, historicalIndex)->getAxisValue(axis);
|
||||
}
|
||||
|
||||
float MotionEvent::getHistoricalAxisValue(int32_t axis, size_t pointerIndex,
|
||||
size_t historicalIndex) const {
|
||||
float value = getHistoricalRawPointerCoords(pointerIndex, historicalIndex)->getAxisValue(axis);
|
||||
switch (axis) {
|
||||
case AINPUT_MOTION_AXIS_X:
|
||||
value += mXOffset;
|
||||
break;
|
||||
case AINPUT_MOTION_AXIS_Y:
|
||||
value += mYOffset;
|
||||
break;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
void MotionEvent::offsetLocation(float xOffset, float yOffset) {
|
||||
mXOffset += xOffset;
|
||||
mYOffset += yOffset;
|
||||
}
|
||||
|
||||
static inline void scaleAxisValue(PointerCoords& c, int axis, float scaleFactor) {
|
||||
float* value = c.editAxisValue(axis);
|
||||
if (value) {
|
||||
*value *= scaleFactor;
|
||||
}
|
||||
}
|
||||
|
||||
void MotionEvent::scale(float scaleFactor) {
|
||||
mXOffset *= scaleFactor;
|
||||
mYOffset *= scaleFactor;
|
||||
mXPrecision *= scaleFactor;
|
||||
mYPrecision *= scaleFactor;
|
||||
|
||||
size_t numSamples = mSamplePointerCoords.size();
|
||||
for (size_t i = 0; i < numSamples; i++) {
|
||||
PointerCoords& c = mSamplePointerCoords.editItemAt(i);
|
||||
// No need to scale pressure or size since they are normalized.
|
||||
// No need to scale orientation since it is meaningless to do so.
|
||||
scaleAxisValue(c, AINPUT_MOTION_AXIS_X, scaleFactor);
|
||||
scaleAxisValue(c, AINPUT_MOTION_AXIS_Y, scaleFactor);
|
||||
scaleAxisValue(c, AINPUT_MOTION_AXIS_TOUCH_MAJOR, scaleFactor);
|
||||
scaleAxisValue(c, AINPUT_MOTION_AXIS_TOUCH_MINOR, scaleFactor);
|
||||
scaleAxisValue(c, AINPUT_MOTION_AXIS_TOOL_MAJOR, scaleFactor);
|
||||
scaleAxisValue(c, AINPUT_MOTION_AXIS_TOOL_MINOR, scaleFactor);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_ANDROID_OS
|
||||
static inline float transformAngle(const SkMatrix* matrix, float angleRadians) {
|
||||
// Construct and transform a vector oriented at the specified clockwise angle from vertical.
|
||||
// Coordinate system: down is increasing Y, right is increasing X.
|
||||
SkPoint vector;
|
||||
vector.fX = SkFloatToScalar(sinf(angleRadians));
|
||||
vector.fY = SkFloatToScalar(-cosf(angleRadians));
|
||||
matrix->mapVectors(& vector, 1);
|
||||
|
||||
// Derive the transformed vector's clockwise angle from vertical.
|
||||
float result = atan2f(SkScalarToFloat(vector.fX), SkScalarToFloat(-vector.fY));
|
||||
if (result < - M_PI_2) {
|
||||
result += M_PI;
|
||||
} else if (result > M_PI_2) {
|
||||
result -= M_PI;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void MotionEvent::transform(const SkMatrix* matrix) {
|
||||
float oldXOffset = mXOffset;
|
||||
float oldYOffset = mYOffset;
|
||||
|
||||
// The tricky part of this implementation is to preserve the value of
|
||||
// rawX and rawY. So we apply the transformation to the first point
|
||||
// then derive an appropriate new X/Y offset that will preserve rawX and rawY.
|
||||
SkPoint point;
|
||||
float rawX = getRawX(0);
|
||||
float rawY = getRawY(0);
|
||||
matrix->mapXY(SkFloatToScalar(rawX + oldXOffset), SkFloatToScalar(rawY + oldYOffset),
|
||||
& point);
|
||||
float newX = SkScalarToFloat(point.fX);
|
||||
float newY = SkScalarToFloat(point.fY);
|
||||
float newXOffset = newX - rawX;
|
||||
float newYOffset = newY - rawY;
|
||||
|
||||
mXOffset = newXOffset;
|
||||
mYOffset = newYOffset;
|
||||
|
||||
// Apply the transformation to all samples.
|
||||
size_t numSamples = mSamplePointerCoords.size();
|
||||
for (size_t i = 0; i < numSamples; i++) {
|
||||
PointerCoords& c = mSamplePointerCoords.editItemAt(i);
|
||||
float* xPtr = c.editAxisValue(AINPUT_MOTION_AXIS_X);
|
||||
float* yPtr = c.editAxisValue(AINPUT_MOTION_AXIS_Y);
|
||||
if (xPtr && yPtr) {
|
||||
float x = *xPtr + oldXOffset;
|
||||
float y = *yPtr + oldYOffset;
|
||||
matrix->mapXY(SkFloatToScalar(x), SkFloatToScalar(y), & point);
|
||||
*xPtr = SkScalarToFloat(point.fX) - newXOffset;
|
||||
*yPtr = SkScalarToFloat(point.fY) - newYOffset;
|
||||
}
|
||||
|
||||
float* orientationPtr = c.editAxisValue(AINPUT_MOTION_AXIS_ORIENTATION);
|
||||
if (orientationPtr) {
|
||||
*orientationPtr = transformAngle(matrix, *orientationPtr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
status_t MotionEvent::readFromParcel(Parcel* parcel) {
|
||||
size_t pointerCount = parcel->readInt32();
|
||||
size_t sampleCount = parcel->readInt32();
|
||||
if (pointerCount == 0 || pointerCount > MAX_POINTERS || sampleCount == 0) {
|
||||
return BAD_VALUE;
|
||||
}
|
||||
|
||||
mDeviceId = parcel->readInt32();
|
||||
mSource = parcel->readInt32();
|
||||
mAction = parcel->readInt32();
|
||||
mFlags = parcel->readInt32();
|
||||
mEdgeFlags = parcel->readInt32();
|
||||
mMetaState = parcel->readInt32();
|
||||
mXOffset = parcel->readFloat();
|
||||
mYOffset = parcel->readFloat();
|
||||
mXPrecision = parcel->readFloat();
|
||||
mYPrecision = parcel->readFloat();
|
||||
mDownTime = parcel->readInt64();
|
||||
|
||||
mPointerIds.clear();
|
||||
mPointerIds.setCapacity(pointerCount);
|
||||
mSampleEventTimes.clear();
|
||||
mSampleEventTimes.setCapacity(sampleCount);
|
||||
mSamplePointerCoords.clear();
|
||||
mSamplePointerCoords.setCapacity(sampleCount * pointerCount);
|
||||
|
||||
for (size_t i = 0; i < pointerCount; i++) {
|
||||
mPointerIds.push(parcel->readInt32());
|
||||
}
|
||||
|
||||
while (sampleCount-- > 0) {
|
||||
mSampleEventTimes.push(parcel->readInt64());
|
||||
for (size_t i = 0; i < pointerCount; i++) {
|
||||
mSamplePointerCoords.push();
|
||||
status_t status = mSamplePointerCoords.editTop().readFromParcel(parcel);
|
||||
if (!status) {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
status_t MotionEvent::writeToParcel(Parcel* parcel) const {
|
||||
size_t pointerCount = mPointerIds.size();
|
||||
size_t sampleCount = mSampleEventTimes.size();
|
||||
|
||||
parcel->writeInt32(pointerCount);
|
||||
parcel->writeInt32(sampleCount);
|
||||
|
||||
parcel->writeInt32(mDeviceId);
|
||||
parcel->writeInt32(mSource);
|
||||
parcel->writeInt32(mAction);
|
||||
parcel->writeInt32(mFlags);
|
||||
parcel->writeInt32(mEdgeFlags);
|
||||
parcel->writeInt32(mMetaState);
|
||||
parcel->writeFloat(mXOffset);
|
||||
parcel->writeFloat(mYOffset);
|
||||
parcel->writeFloat(mXPrecision);
|
||||
parcel->writeFloat(mYPrecision);
|
||||
parcel->writeInt64(mDownTime);
|
||||
|
||||
for (size_t i = 0; i < pointerCount; i++) {
|
||||
parcel->writeInt32(mPointerIds.itemAt(i));
|
||||
}
|
||||
|
||||
const PointerCoords* pc = mSamplePointerCoords.array();
|
||||
for (size_t h = 0; h < sampleCount; h++) {
|
||||
parcel->writeInt64(mSampleEventTimes.itemAt(h));
|
||||
for (size_t i = 0; i < pointerCount; i++) {
|
||||
status_t status = (pc++)->writeToParcel(parcel);
|
||||
if (!status) {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// --- InputDeviceInfo ---
|
||||
|
||||
InputDeviceInfo::InputDeviceInfo() {
|
||||
@ -307,8 +592,8 @@ void InputDeviceInfo::initialize(int32_t id, const String8& name) {
|
||||
mMotionRanges.clear();
|
||||
}
|
||||
|
||||
const InputDeviceInfo::MotionRange* InputDeviceInfo::getMotionRange(int32_t rangeType) const {
|
||||
ssize_t index = mMotionRanges.indexOfKey(rangeType);
|
||||
const InputDeviceInfo::MotionRange* InputDeviceInfo::getMotionRange(int32_t axis) const {
|
||||
ssize_t index = mMotionRanges.indexOfKey(axis);
|
||||
return index >= 0 ? & mMotionRanges.valueAt(index) : NULL;
|
||||
}
|
||||
|
||||
@ -316,14 +601,14 @@ void InputDeviceInfo::addSource(uint32_t source) {
|
||||
mSources |= source;
|
||||
}
|
||||
|
||||
void InputDeviceInfo::addMotionRange(int32_t rangeType, float min, float max,
|
||||
void InputDeviceInfo::addMotionRange(int32_t axis, float min, float max,
|
||||
float flat, float fuzz) {
|
||||
MotionRange range = { min, max, flat, fuzz };
|
||||
addMotionRange(rangeType, range);
|
||||
addMotionRange(axis, range);
|
||||
}
|
||||
|
||||
void InputDeviceInfo::addMotionRange(int32_t rangeType, const MotionRange& range) {
|
||||
mMotionRanges.add(rangeType, range);
|
||||
void InputDeviceInfo::addMotionRange(int32_t axis, const MotionRange& range) {
|
||||
mMotionRanges.add(axis, range);
|
||||
}
|
||||
|
||||
} // namespace android
|
||||
|
@ -159,15 +159,17 @@ void InputPublisherAndConsumerTest::PublishAndConsumeMotionEvent(
|
||||
sampleEventTimes.push(i + 10);
|
||||
for (size_t j = 0; j < pointerCount; j++) {
|
||||
samplePointerCoords.push();
|
||||
samplePointerCoords.editTop().x = 100 * i + j;
|
||||
samplePointerCoords.editTop().y = 200 * i + j;
|
||||
samplePointerCoords.editTop().pressure = 0.5 * i + j;
|
||||
samplePointerCoords.editTop().size = 0.7 * i + j;
|
||||
samplePointerCoords.editTop().touchMajor = 1.5 * i + j;
|
||||
samplePointerCoords.editTop().touchMinor = 1.7 * i + j;
|
||||
samplePointerCoords.editTop().toolMajor = 2.5 * i + j;
|
||||
samplePointerCoords.editTop().toolMinor = 2.7 * i + j;
|
||||
samplePointerCoords.editTop().orientation = 3.5 * i + j;
|
||||
PointerCoords& pc = samplePointerCoords.editTop();
|
||||
pc.clear();
|
||||
pc.setAxisValue(AINPUT_MOTION_AXIS_X, 100 * i + j);
|
||||
pc.setAxisValue(AINPUT_MOTION_AXIS_Y, 200 * i + j);
|
||||
pc.setAxisValue(AINPUT_MOTION_AXIS_PRESSURE, 0.5 * i + j);
|
||||
pc.setAxisValue(AINPUT_MOTION_AXIS_SIZE, 0.7 * i + j);
|
||||
pc.setAxisValue(AINPUT_MOTION_AXIS_TOUCH_MAJOR, 1.5 * i + j);
|
||||
pc.setAxisValue(AINPUT_MOTION_AXIS_TOUCH_MINOR, 1.7 * i + j);
|
||||
pc.setAxisValue(AINPUT_MOTION_AXIS_TOOL_MAJOR, 2.5 * i + j);
|
||||
pc.setAxisValue(AINPUT_MOTION_AXIS_TOOL_MAJOR, 2.7 * i + j);
|
||||
pc.setAxisValue(AINPUT_MOTION_AXIS_ORIENTATION, 3.5 * i + j);
|
||||
}
|
||||
}
|
||||
|
||||
@ -239,27 +241,27 @@ void InputPublisherAndConsumerTest::PublishAndConsumeMotionEvent(
|
||||
for (size_t i = 0; i < pointerCount; i++) {
|
||||
SCOPED_TRACE(i);
|
||||
size_t offset = sampleIndex * pointerCount + i;
|
||||
EXPECT_EQ(samplePointerCoords[offset].x,
|
||||
EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AINPUT_MOTION_AXIS_X),
|
||||
motionEvent->getHistoricalRawX(i, sampleIndex));
|
||||
EXPECT_EQ(samplePointerCoords[offset].y,
|
||||
EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AINPUT_MOTION_AXIS_Y),
|
||||
motionEvent->getHistoricalRawY(i, sampleIndex));
|
||||
EXPECT_EQ(samplePointerCoords[offset].x + xOffset,
|
||||
EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AINPUT_MOTION_AXIS_X) + xOffset,
|
||||
motionEvent->getHistoricalX(i, sampleIndex));
|
||||
EXPECT_EQ(samplePointerCoords[offset].y + yOffset,
|
||||
EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AINPUT_MOTION_AXIS_Y) + yOffset,
|
||||
motionEvent->getHistoricalY(i, sampleIndex));
|
||||
EXPECT_EQ(samplePointerCoords[offset].pressure,
|
||||
EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AINPUT_MOTION_AXIS_PRESSURE),
|
||||
motionEvent->getHistoricalPressure(i, sampleIndex));
|
||||
EXPECT_EQ(samplePointerCoords[offset].size,
|
||||
EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AINPUT_MOTION_AXIS_SIZE),
|
||||
motionEvent->getHistoricalSize(i, sampleIndex));
|
||||
EXPECT_EQ(samplePointerCoords[offset].touchMajor,
|
||||
EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AINPUT_MOTION_AXIS_TOUCH_MAJOR),
|
||||
motionEvent->getHistoricalTouchMajor(i, sampleIndex));
|
||||
EXPECT_EQ(samplePointerCoords[offset].touchMinor,
|
||||
EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AINPUT_MOTION_AXIS_TOUCH_MINOR),
|
||||
motionEvent->getHistoricalTouchMinor(i, sampleIndex));
|
||||
EXPECT_EQ(samplePointerCoords[offset].toolMajor,
|
||||
EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AINPUT_MOTION_AXIS_TOOL_MAJOR),
|
||||
motionEvent->getHistoricalToolMajor(i, sampleIndex));
|
||||
EXPECT_EQ(samplePointerCoords[offset].toolMinor,
|
||||
EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AINPUT_MOTION_AXIS_TOOL_MINOR),
|
||||
motionEvent->getHistoricalToolMinor(i, sampleIndex));
|
||||
EXPECT_EQ(samplePointerCoords[offset].orientation,
|
||||
EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AINPUT_MOTION_AXIS_ORIENTATION),
|
||||
motionEvent->getHistoricalOrientation(i, sampleIndex));
|
||||
}
|
||||
}
|
||||
@ -269,17 +271,28 @@ void InputPublisherAndConsumerTest::PublishAndConsumeMotionEvent(
|
||||
for (size_t i = 0; i < pointerCount; i++) {
|
||||
SCOPED_TRACE(i);
|
||||
size_t offset = lastSampleIndex * pointerCount + i;
|
||||
EXPECT_EQ(samplePointerCoords[offset].x, motionEvent->getRawX(i));
|
||||
EXPECT_EQ(samplePointerCoords[offset].y, motionEvent->getRawY(i));
|
||||
EXPECT_EQ(samplePointerCoords[offset].x + xOffset, motionEvent->getX(i));
|
||||
EXPECT_EQ(samplePointerCoords[offset].y + yOffset, motionEvent->getY(i));
|
||||
EXPECT_EQ(samplePointerCoords[offset].pressure, motionEvent->getPressure(i));
|
||||
EXPECT_EQ(samplePointerCoords[offset].size, motionEvent->getSize(i));
|
||||
EXPECT_EQ(samplePointerCoords[offset].touchMajor, motionEvent->getTouchMajor(i));
|
||||
EXPECT_EQ(samplePointerCoords[offset].touchMinor, motionEvent->getTouchMinor(i));
|
||||
EXPECT_EQ(samplePointerCoords[offset].toolMajor, motionEvent->getToolMajor(i));
|
||||
EXPECT_EQ(samplePointerCoords[offset].toolMinor, motionEvent->getToolMinor(i));
|
||||
EXPECT_EQ(samplePointerCoords[offset].orientation, motionEvent->getOrientation(i));
|
||||
EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AINPUT_MOTION_AXIS_X),
|
||||
motionEvent->getRawX(i));
|
||||
EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AINPUT_MOTION_AXIS_Y),
|
||||
motionEvent->getRawY(i));
|
||||
EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AINPUT_MOTION_AXIS_X) + xOffset,
|
||||
motionEvent->getX(i));
|
||||
EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AINPUT_MOTION_AXIS_Y) + yOffset,
|
||||
motionEvent->getY(i));
|
||||
EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AINPUT_MOTION_AXIS_PRESSURE),
|
||||
motionEvent->getPressure(i));
|
||||
EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AINPUT_MOTION_AXIS_SIZE),
|
||||
motionEvent->getSize(i));
|
||||
EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AINPUT_MOTION_AXIS_TOUCH_MAJOR),
|
||||
motionEvent->getTouchMajor(i));
|
||||
EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AINPUT_MOTION_AXIS_TOUCH_MINOR),
|
||||
motionEvent->getTouchMinor(i));
|
||||
EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AINPUT_MOTION_AXIS_TOOL_MAJOR),
|
||||
motionEvent->getToolMajor(i));
|
||||
EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AINPUT_MOTION_AXIS_TOOL_MINOR),
|
||||
motionEvent->getToolMinor(i));
|
||||
EXPECT_EQ(samplePointerCoords[offset].getAxisValue(AINPUT_MOTION_AXIS_ORIENTATION),
|
||||
motionEvent->getOrientation(i));
|
||||
}
|
||||
|
||||
status = mConsumer->sendFinishedSignal(false);
|
||||
@ -328,7 +341,8 @@ TEST_F(InputPublisherAndConsumerTest, PublishMotionEvent_WhenNotReset_ReturnsErr
|
||||
|
||||
const size_t pointerCount = 1;
|
||||
int32_t pointerIds[pointerCount] = { 0 };
|
||||
PointerCoords pointerCoords[pointerCount] = { { 0, 0, 0, 0, 0, 0, 0, 0, 0 } };
|
||||
PointerCoords pointerCoords[pointerCount];
|
||||
pointerCoords[0].clear();
|
||||
|
||||
status = mPublisher->publishMotionEvent(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
pointerCount, pointerIds, pointerCoords);
|
||||
|
Loading…
Reference in New Issue
Block a user