diff options
| author | 2021-10-06 22:53:36 +0000 | |
|---|---|---|
| committer | 2021-10-06 22:53:36 +0000 | |
| commit | 097d2a50873100486d65a69cb1cbabf37fb3b188 (patch) | |
| tree | c2f19f92e4503b2de0afeebdd9bf7aeb1bb2e9c1 /libs/input/Input.cpp | |
| parent | cbfb18e134845deeace954bbba818acda48cb80f (diff) | |
| parent | adcb6a2733c1baf66e5ad72365965ab504f5f959 (diff) | |
Merge Android 12
Bug: 202323961
Merged-In: Ifb27b3eb12454fa96f07e6797745c697b4f831c4
Change-Id: I2a7f5931477fddb51564c2eabcdc96ce58888ce8
Diffstat (limited to 'libs/input/Input.cpp')
| -rw-r--r-- | libs/input/Input.cpp | 416 | 
1 files changed, 283 insertions, 133 deletions
diff --git a/libs/input/Input.cpp b/libs/input/Input.cpp index 31aa685391..d954d23507 100644 --- a/libs/input/Input.cpp +++ b/libs/input/Input.cpp @@ -17,21 +17,92 @@  #define LOG_TAG "Input"  //#define LOG_NDEBUG 0 +#include <attestation/HmacKeyManager.h>  #include <cutils/compiler.h> +#include <inttypes.h>  #include <limits.h>  #include <string.h> +#include <android-base/properties.h> +#include <android-base/stringprintf.h>  #include <input/Input.h>  #include <input/InputDevice.h>  #include <input/InputEventLabels.h> -#ifdef __ANDROID__ +#ifdef __linux__  #include <binder/Parcel.h> +#endif +#ifdef __ANDROID__  #include <sys/random.h>  #endif +using android::base::StringPrintf; +  namespace android { +namespace { + +// When per-window-input-rotation is enabled, InputFlinger works in the un-rotated display +// coordinates and SurfaceFlinger includes the display rotation in the input window transforms. +bool isPerWindowInputRotationEnabled() { +    static const bool PER_WINDOW_INPUT_ROTATION = +            base::GetBoolProperty("persist.debug.per_window_input_rotation", false); + +    return PER_WINDOW_INPUT_ROTATION; +} + +float transformAngle(const ui::Transform& transform, 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. +    float x = sinf(angleRadians); +    float y = -cosf(angleRadians); +    vec2 transformedPoint = transform.transform(x, y); + +    // Determine how the origin is transformed by the matrix so that we +    // can transform orientation vectors. +    const vec2 origin = transform.transform(0, 0); + +    transformedPoint.x -= origin.x; +    transformedPoint.y -= origin.y; + +    // Derive the transformed vector's clockwise angle from vertical. +    float result = atan2f(transformedPoint.x, -transformedPoint.y); +    if (result < -M_PI_2) { +        result += M_PI; +    } else if (result > M_PI_2) { +        result -= M_PI; +    } +    return result; +} + +// Rotates the given point to the transform's orientation. If the display width and height are +// provided, the point is rotated in the screen space. Otherwise, the point is rotated about the +// origin. This helper is used to avoid the extra overhead of creating new Transforms. +vec2 rotatePoint(const ui::Transform& transform, float x, float y, int32_t displayWidth = 0, +                 int32_t displayHeight = 0) { +    // 0x7 encapsulates all 3 rotations (see ui::Transform::RotationFlags) +    static const int ALL_ROTATIONS_MASK = 0x7; +    const uint32_t orientation = (transform.getOrientation() & ALL_ROTATIONS_MASK); +    if (orientation == ui::Transform::ROT_0) { +        return {x, y}; +    } + +    vec2 xy(x, y); +    if (orientation == ui::Transform::ROT_90) { +        xy.x = displayHeight - y; +        xy.y = x; +    } else if (orientation == ui::Transform::ROT_180) { +        xy.x = displayWidth - x; +        xy.y = displayHeight - y; +    } else if (orientation == ui::Transform::ROT_270) { +        xy.x = y; +        xy.y = displayWidth - x; +    } +    return xy; +} + +} // namespace +  const char* motionClassificationToString(MotionClassification classification) {      switch (classification) {          case MotionClassification::NONE: @@ -82,6 +153,12 @@ const char* inputEventTypeToString(int32_t type) {          case AINPUT_EVENT_TYPE_FOCUS: {              return "FOCUS";          } +        case AINPUT_EVENT_TYPE_CAPTURE: { +            return "CAPTURE"; +        } +        case AINPUT_EVENT_TYPE_DRAG: { +            return "DRAG"; +        }      }      return "UNKNOWN";  } @@ -135,11 +212,11 @@ int32_t InputEvent::nextId() {  // --- KeyEvent ---  const char* KeyEvent::getLabel(int32_t keyCode) { -    return getLabelByKeyCode(keyCode); +    return InputEventLookup::getLabelByKeyCode(keyCode);  }  int32_t KeyEvent::getKeyCodeFromLabel(const char* label) { -    return getKeyCodeByLabel(label); +    return InputEventLookup::getKeyCodeByLabel(label);  }  void KeyEvent::initialize(int32_t id, int32_t deviceId, uint32_t source, int32_t displayId, @@ -249,7 +326,7 @@ void PointerCoords::applyOffset(float xOffset, float yOffset) {      setAxisValue(AMOTION_EVENT_AXIS_Y, getY() + yOffset);  } -#ifdef __ANDROID__ +#ifdef __linux__  status_t PointerCoords::readFromParcel(Parcel* parcel) {      bits = parcel->readInt64(); @@ -301,6 +378,16 @@ void PointerCoords::copyFrom(const PointerCoords& other) {      }  } +void PointerCoords::transform(const ui::Transform& transform) { +    const vec2 xy = transform.transform(getXYValue()); +    setAxisValue(AMOTION_EVENT_AXIS_X, xy.x); +    setAxisValue(AMOTION_EVENT_AXIS_Y, xy.y); + +    if (BitSet64::hasBit(bits, AMOTION_EVENT_AXIS_ORIENTATION)) { +        const float val = getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION); +        setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, transformAngle(transform, val)); +    } +}  // --- PointerProperties --- @@ -320,10 +407,11 @@ void PointerProperties::copyFrom(const PointerProperties& other) {  void MotionEvent::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, +                             int32_t buttonState, MotionClassification classification, +                             const ui::Transform& transform, float xPrecision, float yPrecision, +                             float rawXCursorPosition, float rawYCursorPosition, +                             int32_t displayWidth, int32_t displayHeight, nsecs_t downTime, +                             nsecs_t eventTime, size_t pointerCount,                               const PointerProperties* pointerProperties,                               const PointerCoords* pointerCoords) {      InputEvent::initialize(id, deviceId, source, displayId, hmac); @@ -334,14 +422,13 @@ void MotionEvent::initialize(int32_t id, int32_t deviceId, uint32_t source, int3      mMetaState = metaState;      mButtonState = buttonState;      mClassification = classification; -    mXScale = xScale; -    mYScale = yScale; -    mXOffset = xOffset; -    mYOffset = yOffset; +    mTransform = transform;      mXPrecision = xPrecision;      mYPrecision = yPrecision;      mRawXCursorPosition = rawXCursorPosition;      mRawYCursorPosition = rawYCursorPosition; +    mDisplayWidth = displayWidth; +    mDisplayHeight = displayHeight;      mDownTime = downTime;      mPointerProperties.clear();      mPointerProperties.appendArray(pointerProperties, pointerCount); @@ -360,14 +447,13 @@ void MotionEvent::copyFrom(const MotionEvent* other, bool keepHistory) {      mMetaState = other->mMetaState;      mButtonState = other->mButtonState;      mClassification = other->mClassification; -    mXScale = other->mXScale; -    mYScale = other->mYScale; -    mXOffset = other->mXOffset; -    mYOffset = other->mYOffset; +    mTransform = other->mTransform;      mXPrecision = other->mXPrecision;      mYPrecision = other->mYPrecision;      mRawXCursorPosition = other->mRawXCursorPosition;      mRawYCursorPosition = other->mRawYCursorPosition; +    mDisplayWidth = other->mDisplayWidth; +    mDisplayHeight = other->mDisplayHeight;      mDownTime = other->mDownTime;      mPointerProperties = other->mPointerProperties; @@ -376,7 +462,7 @@ void MotionEvent::copyFrom(const MotionEvent* other, bool keepHistory) {          mSamplePointerCoords = other->mSamplePointerCoords;      } else {          mSampleEventTimes.clear(); -        mSampleEventTimes.push(other->getEventTime()); +        mSampleEventTimes.push_back(other->getEventTime());          mSamplePointerCoords.clear();          size_t pointerCount = other->getPointerCount();          size_t historySize = other->getHistorySize(); @@ -388,23 +474,25 @@ void MotionEvent::copyFrom(const MotionEvent* other, bool keepHistory) {  void MotionEvent::addSample(          int64_t eventTime,          const PointerCoords* pointerCoords) { -    mSampleEventTimes.push(eventTime); +    mSampleEventTimes.push_back(eventTime);      mSamplePointerCoords.appendArray(pointerCoords, getPointerCount());  }  float MotionEvent::getXCursorPosition() const { -    const float rawX = getRawXCursorPosition(); -    return rawX * mXScale + mXOffset; +    vec2 vals = mTransform.transform(getRawXCursorPosition(), getRawYCursorPosition()); +    return vals.x;  }  float MotionEvent::getYCursorPosition() const { -    const float rawY = getRawYCursorPosition(); -    return rawY * mYScale + mYOffset; +    vec2 vals = mTransform.transform(getRawXCursorPosition(), getRawYCursorPosition()); +    return vals.y;  }  void MotionEvent::setCursorPosition(float x, float y) { -    mRawXCursorPosition = (x - mXOffset) / mXScale; -    mRawYCursorPosition = (y - mYOffset) / mYScale; +    ui::Transform inverse = mTransform.inverse(); +    vec2 vals = inverse.transform(x, y); +    mRawXCursorPosition = vals.x; +    mRawYCursorPosition = vals.y;  }  const PointerCoords* MotionEvent::getRawPointerCoords(size_t pointerIndex) const { @@ -412,18 +500,11 @@ const PointerCoords* MotionEvent::getRawPointerCoords(size_t pointerIndex) const  }  float MotionEvent::getRawAxisValue(int32_t axis, size_t pointerIndex) const { -    return getRawPointerCoords(pointerIndex)->getAxisValue(axis); +    return getHistoricalRawAxisValue(axis, pointerIndex, getHistorySize());  }  float MotionEvent::getAxisValue(int32_t axis, size_t pointerIndex) const { -    float value = getRawPointerCoords(pointerIndex)->getAxisValue(axis); -    switch (axis) { -    case AMOTION_EVENT_AXIS_X: -        return value * mXScale + mXOffset; -    case AMOTION_EVENT_AXIS_Y: -        return value * mYScale + mYOffset; -    } -    return value; +    return getHistoricalAxisValue(axis, pointerIndex, getHistorySize());  }  const PointerCoords* MotionEvent::getHistoricalRawPointerCoords( @@ -432,20 +513,34 @@ const PointerCoords* MotionEvent::getHistoricalRawPointerCoords(  }  float MotionEvent::getHistoricalRawAxisValue(int32_t axis, size_t pointerIndex, -        size_t historicalIndex) const { -    return getHistoricalRawPointerCoords(pointerIndex, historicalIndex)->getAxisValue(axis); +                                             size_t historicalIndex) const { +    const PointerCoords* coords = getHistoricalRawPointerCoords(pointerIndex, historicalIndex); + +    if (!isPerWindowInputRotationEnabled()) return coords->getAxisValue(axis); + +    if (axis == AMOTION_EVENT_AXIS_X || axis == AMOTION_EVENT_AXIS_Y) { +        // For compatibility, convert raw coordinates into "oriented screen space". Once app +        // developers are educated about getRaw, we can consider removing this. +        const vec2 xy = rotatePoint(mTransform, coords->getX(), coords->getY(), mDisplayWidth, +                                    mDisplayHeight); +        static_assert(AMOTION_EVENT_AXIS_X == 0 && AMOTION_EVENT_AXIS_Y == 1); +        return xy[axis]; +    } + +    return coords->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 AMOTION_EVENT_AXIS_X: -        return value * mXScale + mXOffset; -    case AMOTION_EVENT_AXIS_Y: -        return value * mYScale + mYOffset; +    const PointerCoords* coords = getHistoricalRawPointerCoords(pointerIndex, historicalIndex); + +    if (axis == AMOTION_EVENT_AXIS_X || axis == AMOTION_EVENT_AXIS_Y) { +        const vec2 xy = mTransform.transform(coords->getXYValue()); +        static_assert(AMOTION_EVENT_AXIS_X == 0 && AMOTION_EVENT_AXIS_Y == 1); +        return xy[axis];      } -    return value; + +    return coords->getAxisValue(axis);  }  ssize_t MotionEvent::findPointerIndex(int32_t pointerId) const { @@ -459,99 +554,73 @@ ssize_t MotionEvent::findPointerIndex(int32_t pointerId) const {  }  void MotionEvent::offsetLocation(float xOffset, float yOffset) { -    mXOffset += xOffset; -    mYOffset += yOffset; +    float currXOffset = mTransform.tx(); +    float currYOffset = mTransform.ty(); +    mTransform.set(currXOffset + xOffset, currYOffset + yOffset);  }  void MotionEvent::scale(float globalScaleFactor) { -    mXOffset *= globalScaleFactor; -    mYOffset *= globalScaleFactor; +    mTransform.set(mTransform.tx() * globalScaleFactor, mTransform.ty() * globalScaleFactor);      mXPrecision *= globalScaleFactor;      mYPrecision *= globalScaleFactor;      size_t numSamples = mSamplePointerCoords.size();      for (size_t i = 0; i < numSamples; i++) { -        mSamplePointerCoords.editItemAt(i).scale(globalScaleFactor); +        mSamplePointerCoords.editItemAt(i).scale(globalScaleFactor, globalScaleFactor, +                                                 globalScaleFactor);      }  } -static void transformPoint(const float matrix[9], float x, float y, float *outX, float *outY) { -    // Apply perspective transform like Skia. -    float newX = matrix[0] * x + matrix[1] * y + matrix[2]; -    float newY = matrix[3] * x + matrix[4] * y + matrix[5]; -    float newZ = matrix[6] * x + matrix[7] * y + matrix[8]; -    if (newZ) { -        newZ = 1.0f / newZ; -    } -    *outX = newX * newZ; -    *outY = newY * newZ; -} +void MotionEvent::transform(const std::array<float, 9>& matrix) { +    // We want to preserve the raw axes values stored in the PointerCoords, so we just update the +    // transform using the values passed in. +    ui::Transform newTransform; +    newTransform.set(matrix); +    mTransform = newTransform * mTransform; -static float transformAngle(const float matrix[9], float angleRadians, -        float originX, float originY) { -    // Construct and transform a vector oriented at the specified clockwise angle from vertical. -    // Coordinate system: down is increasing Y, right is increasing X. -    float x = sinf(angleRadians); -    float y = -cosf(angleRadians); -    transformPoint(matrix, x, y, &x, &y); -    x -= originX; -    y -= originY; - -    // Derive the transformed vector's clockwise angle from vertical. -    float result = atan2f(x, -y); -    if (result < - M_PI_2) { -        result += M_PI; -    } else if (result > M_PI_2) { -        result -= M_PI; -    } -    return result; +    // We need to update the AXIS_ORIENTATION value here to maintain the old behavior where the +    // orientation angle is not affected by the initial transformation set in the MotionEvent. +    std::for_each(mSamplePointerCoords.begin(), mSamplePointerCoords.end(), +                  [&newTransform](PointerCoords& c) { +                      float orientation = c.getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION); +                      c.setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, +                                     transformAngle(newTransform, orientation)); +                  });  } -void MotionEvent::transform(const float matrix[9]) { -    // 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 for that point. -    float oldXOffset = mXOffset; -    float oldYOffset = mYOffset; -    float newX, newY; -    float scaledRawX = getRawX(0) * mXScale; -    float scaledRawY = getRawY(0) * mYScale; -    transformPoint(matrix, scaledRawX + oldXOffset, scaledRawY + oldYOffset, &newX, &newY); -    mXOffset = newX - scaledRawX; -    mYOffset = newY - scaledRawY; +void MotionEvent::applyTransform(const std::array<float, 9>& matrix) { +    ui::Transform transform; +    transform.set(matrix); -    // Determine how the origin is transformed by the matrix so that we -    // can transform orientation vectors. -    float originX, originY; -    transformPoint(matrix, 0, 0, &originX, &originY); +    // Apply the transformation to all samples. +    std::for_each(mSamplePointerCoords.begin(), mSamplePointerCoords.end(), +                  [&transform](PointerCoords& c) { c.transform(transform); }); +} -    // Apply the transformation to cursor position. -    if (isValidCursorPosition(mRawXCursorPosition, mRawYCursorPosition)) { -        float x = mRawXCursorPosition * mXScale + oldXOffset; -        float y = mRawYCursorPosition * mYScale + oldYOffset; -        transformPoint(matrix, x, y, &x, &y); -        mRawXCursorPosition = (x - mXOffset) / mXScale; -        mRawYCursorPosition = (y - mYOffset) / mYScale; -    } +#ifdef __linux__ +static status_t readFromParcel(ui::Transform& transform, const Parcel& parcel) { +    float dsdx, dtdx, tx, dtdy, dsdy, ty; +    status_t status = parcel.readFloat(&dsdx); +    status |= parcel.readFloat(&dtdx); +    status |= parcel.readFloat(&tx); +    status |= parcel.readFloat(&dtdy); +    status |= parcel.readFloat(&dsdy); +    status |= parcel.readFloat(&ty); -    // 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 x = c.getAxisValue(AMOTION_EVENT_AXIS_X) * mXScale + oldXOffset; -        float y = c.getAxisValue(AMOTION_EVENT_AXIS_Y) * mYScale + oldYOffset; -        transformPoint(matrix, x, y, &x, &y); -        c.setAxisValue(AMOTION_EVENT_AXIS_X, (x - mXOffset) / mXScale); -        c.setAxisValue(AMOTION_EVENT_AXIS_Y, (y - mYOffset) / mYScale); +    transform.set({dsdx, dtdx, tx, dtdy, dsdy, ty, 0, 0, 1}); +    return status; +} -        float orientation = c.getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION); -        c.setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, -                transformAngle(matrix, orientation, originX, originY)); -    } +static status_t writeToParcel(const ui::Transform& transform, Parcel& parcel) { +    status_t status = parcel.writeFloat(transform.dsdx()); +    status |= parcel.writeFloat(transform.dtdx()); +    status |= parcel.writeFloat(transform.tx()); +    status |= parcel.writeFloat(transform.dtdy()); +    status |= parcel.writeFloat(transform.dsdy()); +    status |= parcel.writeFloat(transform.ty()); +    return status;  } -#ifdef __ANDROID__  status_t MotionEvent::readFromParcel(Parcel* parcel) {      size_t pointerCount = parcel->readInt32();      size_t sampleCount = parcel->readInt32(); @@ -577,20 +646,23 @@ status_t MotionEvent::readFromParcel(Parcel* parcel) {      mMetaState = parcel->readInt32();      mButtonState = parcel->readInt32();      mClassification = static_cast<MotionClassification>(parcel->readByte()); -    mXScale = parcel->readFloat(); -    mYScale = parcel->readFloat(); -    mXOffset = parcel->readFloat(); -    mYOffset = parcel->readFloat(); + +    result = android::readFromParcel(mTransform, *parcel); +    if (result != OK) { +        return result; +    }      mXPrecision = parcel->readFloat();      mYPrecision = parcel->readFloat();      mRawXCursorPosition = parcel->readFloat();      mRawYCursorPosition = parcel->readFloat(); +    mDisplayWidth = parcel->readInt32(); +    mDisplayHeight = parcel->readInt32();      mDownTime = parcel->readInt64();      mPointerProperties.clear();      mPointerProperties.setCapacity(pointerCount);      mSampleEventTimes.clear(); -    mSampleEventTimes.setCapacity(sampleCount); +    mSampleEventTimes.reserve(sampleCount);      mSamplePointerCoords.clear();      mSamplePointerCoords.setCapacity(sampleCount * pointerCount); @@ -603,7 +675,7 @@ status_t MotionEvent::readFromParcel(Parcel* parcel) {      while (sampleCount > 0) {          sampleCount--; -        mSampleEventTimes.push(parcel->readInt64()); +        mSampleEventTimes.push_back(parcel->readInt64());          for (size_t i = 0; i < pointerCount; i++) {              mSamplePointerCoords.push();              status_t status = mSamplePointerCoords.editTop().readFromParcel(parcel); @@ -635,14 +707,17 @@ status_t MotionEvent::writeToParcel(Parcel* parcel) const {      parcel->writeInt32(mMetaState);      parcel->writeInt32(mButtonState);      parcel->writeByte(static_cast<int8_t>(mClassification)); -    parcel->writeFloat(mXScale); -    parcel->writeFloat(mYScale); -    parcel->writeFloat(mXOffset); -    parcel->writeFloat(mYOffset); + +    status_t result = android::writeToParcel(mTransform, *parcel); +    if (result != OK) { +        return result; +    }      parcel->writeFloat(mXPrecision);      parcel->writeFloat(mYPrecision);      parcel->writeFloat(mRawXCursorPosition);      parcel->writeFloat(mRawYCursorPosition); +    parcel->writeInt32(mDisplayWidth); +    parcel->writeInt32(mDisplayHeight);      parcel->writeInt64(mDownTime);      for (size_t i = 0; i < pointerCount; i++) { @@ -653,7 +728,7 @@ status_t MotionEvent::writeToParcel(Parcel* parcel) const {      const PointerCoords* pc = mSamplePointerCoords.array();      for (size_t h = 0; h < sampleCount; h++) { -        parcel->writeInt64(mSampleEventTimes.itemAt(h)); +        parcel->writeInt64(mSampleEventTimes[h]);          for (size_t i = 0; i < pointerCount; i++) {              status_t status = (pc++)->writeToParcel(parcel);              if (status) { @@ -683,30 +758,44 @@ bool MotionEvent::isTouchEvent(uint32_t source, int32_t action) {  }  const char* MotionEvent::getLabel(int32_t axis) { -    return getAxisLabel(axis); +    return InputEventLookup::getAxisLabel(axis);  }  int32_t MotionEvent::getAxisFromLabel(const char* label) { -    return getAxisByLabel(label); +    return InputEventLookup::getAxisByLabel(label);  } -const char* MotionEvent::actionToString(int32_t action) { +std::string MotionEvent::actionToString(int32_t action) {      // Convert MotionEvent action to string      switch (action & AMOTION_EVENT_ACTION_MASK) {          case AMOTION_EVENT_ACTION_DOWN:              return "DOWN"; -        case AMOTION_EVENT_ACTION_MOVE: -            return "MOVE";          case AMOTION_EVENT_ACTION_UP:              return "UP"; +        case AMOTION_EVENT_ACTION_MOVE: +            return "MOVE";          case AMOTION_EVENT_ACTION_CANCEL:              return "CANCEL"; +        case AMOTION_EVENT_ACTION_OUTSIDE: +            return "OUTSIDE";          case AMOTION_EVENT_ACTION_POINTER_DOWN:              return "POINTER_DOWN";          case AMOTION_EVENT_ACTION_POINTER_UP:              return "POINTER_UP"; -    } -    return "UNKNOWN"; +        case AMOTION_EVENT_ACTION_HOVER_MOVE: +            return "HOVER_MOVE"; +        case AMOTION_EVENT_ACTION_SCROLL: +            return "SCROLL"; +        case AMOTION_EVENT_ACTION_HOVER_ENTER: +            return "HOVER_ENTER"; +        case AMOTION_EVENT_ACTION_HOVER_EXIT: +            return "HOVER_EXIT"; +        case AMOTION_EVENT_ACTION_BUTTON_PRESS: +            return "BUTTON_PRESS"; +        case AMOTION_EVENT_ACTION_BUTTON_RELEASE: +            return "BUTTON_RELEASE"; +    } +    return android::base::StringPrintf("%" PRId32, action);  }  // --- FocusEvent --- @@ -724,6 +813,36 @@ void FocusEvent::initialize(const FocusEvent& from) {      mInTouchMode = from.mInTouchMode;  } +// --- CaptureEvent --- + +void CaptureEvent::initialize(int32_t id, bool pointerCaptureEnabled) { +    InputEvent::initialize(id, ReservedInputDeviceId::VIRTUAL_KEYBOARD_ID, AINPUT_SOURCE_UNKNOWN, +                           ADISPLAY_ID_NONE, INVALID_HMAC); +    mPointerCaptureEnabled = pointerCaptureEnabled; +} + +void CaptureEvent::initialize(const CaptureEvent& from) { +    InputEvent::initialize(from); +    mPointerCaptureEnabled = from.mPointerCaptureEnabled; +} + +// --- DragEvent --- + +void DragEvent::initialize(int32_t id, float x, float y, bool isExiting) { +    InputEvent::initialize(id, ReservedInputDeviceId::VIRTUAL_KEYBOARD_ID, AINPUT_SOURCE_UNKNOWN, +                           ADISPLAY_ID_NONE, INVALID_HMAC); +    mIsExiting = isExiting; +    mX = x; +    mY = y; +} + +void DragEvent::initialize(const DragEvent& from) { +    InputEvent::initialize(from); +    mIsExiting = from.mIsExiting; +    mX = from.mX; +    mY = from.mY; +} +  // --- PooledInputEventFactory ---  PooledInputEventFactory::PooledInputEventFactory(size_t maxPoolSize) : @@ -760,6 +879,24 @@ FocusEvent* PooledInputEventFactory::createFocusEvent() {      return event;  } +CaptureEvent* PooledInputEventFactory::createCaptureEvent() { +    if (mCaptureEventPool.empty()) { +        return new CaptureEvent(); +    } +    CaptureEvent* event = mCaptureEventPool.front().release(); +    mCaptureEventPool.pop(); +    return event; +} + +DragEvent* PooledInputEventFactory::createDragEvent() { +    if (mDragEventPool.empty()) { +        return new DragEvent(); +    } +    DragEvent* event = mDragEventPool.front().release(); +    mDragEventPool.pop(); +    return event; +} +  void PooledInputEventFactory::recycle(InputEvent* event) {      switch (event->getType()) {      case AINPUT_EVENT_TYPE_KEY: @@ -780,6 +917,19 @@ void PooledInputEventFactory::recycle(InputEvent* event) {              return;          }          break; +    case AINPUT_EVENT_TYPE_CAPTURE: +        if (mCaptureEventPool.size() < mMaxPoolSize) { +            mCaptureEventPool.push( +                    std::unique_ptr<CaptureEvent>(static_cast<CaptureEvent*>(event))); +            return; +        } +        break; +    case AINPUT_EVENT_TYPE_DRAG: +        if (mDragEventPool.size() < mMaxPoolSize) { +            mDragEventPool.push(std::unique_ptr<DragEvent>(static_cast<DragEvent*>(event))); +            return; +        } +        break;      }      delete event;  }  |