widget/gonk/libui/Input.cpp

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/widget/gonk/libui/Input.cpp	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,635 @@
     1.4 +/*
     1.5 + * Copyright (C) 2010 The Android Open Source Project
     1.6 + *
     1.7 + * Licensed under the Apache License, Version 2.0 (the "License");
     1.8 + * you may not use this file except in compliance with the License.
     1.9 + * You may obtain a copy of the License at
    1.10 + *
    1.11 + *      http://www.apache.org/licenses/LICENSE-2.0
    1.12 + *
    1.13 + * Unless required by applicable law or agreed to in writing, software
    1.14 + * distributed under the License is distributed on an "AS IS" BASIS,
    1.15 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    1.16 + * See the License for the specific language governing permissions and
    1.17 + * limitations under the License.
    1.18 + */
    1.19 +
    1.20 +#define LOG_TAG "Input"
    1.21 +//#define LOG_NDEBUG 0
    1.22 +#include "cutils_log.h"
    1.23 +
    1.24 +#include <math.h>
    1.25 +#include <limits.h>
    1.26 +
    1.27 +#include "Input.h"
    1.28 +
    1.29 +#ifdef HAVE_ANDROID_OS
    1.30 +#include <binder/Parcel.h>
    1.31 +
    1.32 +#include "SkPoint.h"
    1.33 +#include "SkMatrix.h"
    1.34 +#include "SkScalar.h"
    1.35 +#endif
    1.36 +
    1.37 +namespace android {
    1.38 +
    1.39 +// --- InputEvent ---
    1.40 +
    1.41 +void InputEvent::initialize(int32_t deviceId, int32_t source) {
    1.42 +    mDeviceId = deviceId;
    1.43 +    mSource = source;
    1.44 +}
    1.45 +
    1.46 +void InputEvent::initialize(const InputEvent& from) {
    1.47 +    mDeviceId = from.mDeviceId;
    1.48 +    mSource = from.mSource;
    1.49 +}
    1.50 +
    1.51 +// --- KeyEvent ---
    1.52 +
    1.53 +bool KeyEvent::hasDefaultAction(int32_t keyCode) {
    1.54 +    switch (keyCode) {
    1.55 +        case AKEYCODE_HOME:
    1.56 +        case AKEYCODE_BACK:
    1.57 +        case AKEYCODE_CALL:
    1.58 +        case AKEYCODE_ENDCALL:
    1.59 +        case AKEYCODE_VOLUME_UP:
    1.60 +        case AKEYCODE_VOLUME_DOWN:
    1.61 +        case AKEYCODE_VOLUME_MUTE:
    1.62 +        case AKEYCODE_POWER:
    1.63 +        case AKEYCODE_CAMERA:
    1.64 +        case AKEYCODE_HEADSETHOOK:
    1.65 +        case AKEYCODE_MENU:
    1.66 +        case AKEYCODE_NOTIFICATION:
    1.67 +        case AKEYCODE_FOCUS:
    1.68 +        case AKEYCODE_SEARCH:
    1.69 +        case AKEYCODE_MEDIA_PLAY:
    1.70 +        case AKEYCODE_MEDIA_PAUSE:
    1.71 +        case AKEYCODE_MEDIA_PLAY_PAUSE:
    1.72 +        case AKEYCODE_MEDIA_STOP:
    1.73 +        case AKEYCODE_MEDIA_NEXT:
    1.74 +        case AKEYCODE_MEDIA_PREVIOUS:
    1.75 +        case AKEYCODE_MEDIA_REWIND:
    1.76 +        case AKEYCODE_MEDIA_RECORD:
    1.77 +        case AKEYCODE_MEDIA_FAST_FORWARD:
    1.78 +        case AKEYCODE_MUTE:
    1.79 +        case AKEYCODE_BRIGHTNESS_DOWN:
    1.80 +        case AKEYCODE_BRIGHTNESS_UP:
    1.81 +            return true;
    1.82 +    }
    1.83 +    
    1.84 +    return false;
    1.85 +}
    1.86 +
    1.87 +bool KeyEvent::hasDefaultAction() const {
    1.88 +    return hasDefaultAction(getKeyCode());
    1.89 +}
    1.90 +
    1.91 +bool KeyEvent::isSystemKey(int32_t keyCode) {
    1.92 +    switch (keyCode) {
    1.93 +        case AKEYCODE_MENU:
    1.94 +        case AKEYCODE_SOFT_RIGHT:
    1.95 +        case AKEYCODE_HOME:
    1.96 +        case AKEYCODE_BACK:
    1.97 +        case AKEYCODE_CALL:
    1.98 +        case AKEYCODE_ENDCALL:
    1.99 +        case AKEYCODE_VOLUME_UP:
   1.100 +        case AKEYCODE_VOLUME_DOWN:
   1.101 +        case AKEYCODE_VOLUME_MUTE:
   1.102 +        case AKEYCODE_MUTE:
   1.103 +        case AKEYCODE_POWER:
   1.104 +        case AKEYCODE_HEADSETHOOK:
   1.105 +        case AKEYCODE_MEDIA_PLAY:
   1.106 +        case AKEYCODE_MEDIA_PAUSE:
   1.107 +        case AKEYCODE_MEDIA_PLAY_PAUSE:
   1.108 +        case AKEYCODE_MEDIA_STOP:
   1.109 +        case AKEYCODE_MEDIA_NEXT:
   1.110 +        case AKEYCODE_MEDIA_PREVIOUS:
   1.111 +        case AKEYCODE_MEDIA_REWIND:
   1.112 +        case AKEYCODE_MEDIA_RECORD:
   1.113 +        case AKEYCODE_MEDIA_FAST_FORWARD:
   1.114 +        case AKEYCODE_CAMERA:
   1.115 +        case AKEYCODE_FOCUS:
   1.116 +        case AKEYCODE_SEARCH:
   1.117 +        case AKEYCODE_BRIGHTNESS_DOWN:
   1.118 +        case AKEYCODE_BRIGHTNESS_UP:
   1.119 +            return true;
   1.120 +    }
   1.121 +    
   1.122 +    return false;
   1.123 +}
   1.124 +
   1.125 +bool KeyEvent::isSystemKey() const {
   1.126 +    return isSystemKey(getKeyCode());
   1.127 +}
   1.128 +
   1.129 +void KeyEvent::initialize(
   1.130 +        int32_t deviceId,
   1.131 +        int32_t source,
   1.132 +        int32_t action,
   1.133 +        int32_t flags,
   1.134 +        int32_t keyCode,
   1.135 +        int32_t scanCode,
   1.136 +        int32_t metaState,
   1.137 +        int32_t repeatCount,
   1.138 +        nsecs_t downTime,
   1.139 +        nsecs_t eventTime) {
   1.140 +    InputEvent::initialize(deviceId, source);
   1.141 +    mAction = action;
   1.142 +    mFlags = flags;
   1.143 +    mKeyCode = keyCode;
   1.144 +    mScanCode = scanCode;
   1.145 +    mMetaState = metaState;
   1.146 +    mRepeatCount = repeatCount;
   1.147 +    mDownTime = downTime;
   1.148 +    mEventTime = eventTime;
   1.149 +}
   1.150 +
   1.151 +void KeyEvent::initialize(const KeyEvent& from) {
   1.152 +    InputEvent::initialize(from);
   1.153 +    mAction = from.mAction;
   1.154 +    mFlags = from.mFlags;
   1.155 +    mKeyCode = from.mKeyCode;
   1.156 +    mScanCode = from.mScanCode;
   1.157 +    mMetaState = from.mMetaState;
   1.158 +    mRepeatCount = from.mRepeatCount;
   1.159 +    mDownTime = from.mDownTime;
   1.160 +    mEventTime = from.mEventTime;
   1.161 +}
   1.162 +
   1.163 +
   1.164 +// --- PointerCoords ---
   1.165 +
   1.166 +float PointerCoords::getAxisValue(int32_t axis) const {
   1.167 +    if (axis < 0 || axis > 63) {
   1.168 +        return 0;
   1.169 +    }
   1.170 +
   1.171 +    uint64_t axisBit = 1LL << axis;
   1.172 +    if (!(bits & axisBit)) {
   1.173 +        return 0;
   1.174 +    }
   1.175 +    uint32_t index = __builtin_popcountll(bits & (axisBit - 1LL));
   1.176 +    return values[index];
   1.177 +}
   1.178 +
   1.179 +status_t PointerCoords::setAxisValue(int32_t axis, float value) {
   1.180 +    if (axis < 0 || axis > 63) {
   1.181 +        return NAME_NOT_FOUND;
   1.182 +    }
   1.183 +
   1.184 +    uint64_t axisBit = 1LL << axis;
   1.185 +    uint32_t index = __builtin_popcountll(bits & (axisBit - 1LL));
   1.186 +    if (!(bits & axisBit)) {
   1.187 +        if (value == 0) {
   1.188 +            return OK; // axes with value 0 do not need to be stored
   1.189 +        }
   1.190 +        uint32_t count = __builtin_popcountll(bits);
   1.191 +        if (count >= MAX_AXES) {
   1.192 +            tooManyAxes(axis);
   1.193 +            return NO_MEMORY;
   1.194 +        }
   1.195 +        bits |= axisBit;
   1.196 +        for (uint32_t i = count; i > index; i--) {
   1.197 +            values[i] = values[i - 1];
   1.198 +        }
   1.199 +    }
   1.200 +    values[index] = value;
   1.201 +    return OK;
   1.202 +}
   1.203 +
   1.204 +static inline void scaleAxisValue(PointerCoords& c, int axis, float scaleFactor) {
   1.205 +    float value = c.getAxisValue(axis);
   1.206 +    if (value != 0) {
   1.207 +        c.setAxisValue(axis, value * scaleFactor);
   1.208 +    }
   1.209 +}
   1.210 +
   1.211 +void PointerCoords::scale(float scaleFactor) {
   1.212 +    // No need to scale pressure or size since they are normalized.
   1.213 +    // No need to scale orientation since it is meaningless to do so.
   1.214 +    scaleAxisValue(*this, AMOTION_EVENT_AXIS_X, scaleFactor);
   1.215 +    scaleAxisValue(*this, AMOTION_EVENT_AXIS_Y, scaleFactor);
   1.216 +    scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOUCH_MAJOR, scaleFactor);
   1.217 +    scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOUCH_MINOR, scaleFactor);
   1.218 +    scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOOL_MAJOR, scaleFactor);
   1.219 +    scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOOL_MINOR, scaleFactor);
   1.220 +}
   1.221 +
   1.222 +#ifdef HAVE_ANDROID_OS
   1.223 +status_t PointerCoords::readFromParcel(Parcel* parcel) {
   1.224 +    bits = parcel->readInt64();
   1.225 +
   1.226 +    uint32_t count = __builtin_popcountll(bits);
   1.227 +    if (count > MAX_AXES) {
   1.228 +        return BAD_VALUE;
   1.229 +    }
   1.230 +
   1.231 +    for (uint32_t i = 0; i < count; i++) {
   1.232 +        values[i] = parcel->readFloat();
   1.233 +    }
   1.234 +    return OK;
   1.235 +}
   1.236 +
   1.237 +status_t PointerCoords::writeToParcel(Parcel* parcel) const {
   1.238 +    parcel->writeInt64(bits);
   1.239 +
   1.240 +    uint32_t count = __builtin_popcountll(bits);
   1.241 +    for (uint32_t i = 0; i < count; i++) {
   1.242 +        parcel->writeFloat(values[i]);
   1.243 +    }
   1.244 +    return OK;
   1.245 +}
   1.246 +#endif
   1.247 +
   1.248 +void PointerCoords::tooManyAxes(int axis) {
   1.249 +    ALOGW("Could not set value for axis %d because the PointerCoords structure is full and "
   1.250 +            "cannot contain more than %d axis values.", axis, int(MAX_AXES));
   1.251 +}
   1.252 +
   1.253 +bool PointerCoords::operator==(const PointerCoords& other) const {
   1.254 +    if (bits != other.bits) {
   1.255 +        return false;
   1.256 +    }
   1.257 +    uint32_t count = __builtin_popcountll(bits);
   1.258 +    for (uint32_t i = 0; i < count; i++) {
   1.259 +        if (values[i] != other.values[i]) {
   1.260 +            return false;
   1.261 +        }
   1.262 +    }
   1.263 +    return true;
   1.264 +}
   1.265 +
   1.266 +void PointerCoords::copyFrom(const PointerCoords& other) {
   1.267 +    bits = other.bits;
   1.268 +    uint32_t count = __builtin_popcountll(bits);
   1.269 +    for (uint32_t i = 0; i < count; i++) {
   1.270 +        values[i] = other.values[i];
   1.271 +    }
   1.272 +}
   1.273 +
   1.274 +
   1.275 +// --- PointerProperties ---
   1.276 +
   1.277 +bool PointerProperties::operator==(const PointerProperties& other) const {
   1.278 +    return id == other.id
   1.279 +            && toolType == other.toolType;
   1.280 +}
   1.281 +
   1.282 +void PointerProperties::copyFrom(const PointerProperties& other) {
   1.283 +    id = other.id;
   1.284 +    toolType = other.toolType;
   1.285 +}
   1.286 +
   1.287 +
   1.288 +// --- MotionEvent ---
   1.289 +
   1.290 +void MotionEvent::initialize(
   1.291 +        int32_t deviceId,
   1.292 +        int32_t source,
   1.293 +        int32_t action,
   1.294 +        int32_t flags,
   1.295 +        int32_t edgeFlags,
   1.296 +        int32_t metaState,
   1.297 +        int32_t buttonState,
   1.298 +        float xOffset,
   1.299 +        float yOffset,
   1.300 +        float xPrecision,
   1.301 +        float yPrecision,
   1.302 +        nsecs_t downTime,
   1.303 +        nsecs_t eventTime,
   1.304 +        size_t pointerCount,
   1.305 +        const PointerProperties* pointerProperties,
   1.306 +        const PointerCoords* pointerCoords) {
   1.307 +    InputEvent::initialize(deviceId, source);
   1.308 +    mAction = action;
   1.309 +    mFlags = flags;
   1.310 +    mEdgeFlags = edgeFlags;
   1.311 +    mMetaState = metaState;
   1.312 +    mButtonState = buttonState;
   1.313 +    mXOffset = xOffset;
   1.314 +    mYOffset = yOffset;
   1.315 +    mXPrecision = xPrecision;
   1.316 +    mYPrecision = yPrecision;
   1.317 +    mDownTime = downTime;
   1.318 +    mPointerProperties.clear();
   1.319 +    mPointerProperties.appendArray(pointerProperties, pointerCount);
   1.320 +    mSampleEventTimes.clear();
   1.321 +    mSamplePointerCoords.clear();
   1.322 +    addSample(eventTime, pointerCoords);
   1.323 +}
   1.324 +
   1.325 +void MotionEvent::copyFrom(const MotionEvent* other, bool keepHistory) {
   1.326 +    InputEvent::initialize(other->mDeviceId, other->mSource);
   1.327 +    mAction = other->mAction;
   1.328 +    mFlags = other->mFlags;
   1.329 +    mEdgeFlags = other->mEdgeFlags;
   1.330 +    mMetaState = other->mMetaState;
   1.331 +    mButtonState = other->mButtonState;
   1.332 +    mXOffset = other->mXOffset;
   1.333 +    mYOffset = other->mYOffset;
   1.334 +    mXPrecision = other->mXPrecision;
   1.335 +    mYPrecision = other->mYPrecision;
   1.336 +    mDownTime = other->mDownTime;
   1.337 +    mPointerProperties = other->mPointerProperties;
   1.338 +
   1.339 +    if (keepHistory) {
   1.340 +        mSampleEventTimes = other->mSampleEventTimes;
   1.341 +        mSamplePointerCoords = other->mSamplePointerCoords;
   1.342 +    } else {
   1.343 +        mSampleEventTimes.clear();
   1.344 +        mSampleEventTimes.push(other->getEventTime());
   1.345 +        mSamplePointerCoords.clear();
   1.346 +        size_t pointerCount = other->getPointerCount();
   1.347 +        size_t historySize = other->getHistorySize();
   1.348 +        mSamplePointerCoords.appendArray(other->mSamplePointerCoords.array()
   1.349 +                + (historySize * pointerCount), pointerCount);
   1.350 +    }
   1.351 +}
   1.352 +
   1.353 +void MotionEvent::addSample(
   1.354 +        int64_t eventTime,
   1.355 +        const PointerCoords* pointerCoords) {
   1.356 +    mSampleEventTimes.push(eventTime);
   1.357 +    mSamplePointerCoords.appendArray(pointerCoords, getPointerCount());
   1.358 +}
   1.359 +
   1.360 +const PointerCoords* MotionEvent::getRawPointerCoords(size_t pointerIndex) const {
   1.361 +    return &mSamplePointerCoords[getHistorySize() * getPointerCount() + pointerIndex];
   1.362 +}
   1.363 +
   1.364 +float MotionEvent::getRawAxisValue(int32_t axis, size_t pointerIndex) const {
   1.365 +    return getRawPointerCoords(pointerIndex)->getAxisValue(axis);
   1.366 +}
   1.367 +
   1.368 +float MotionEvent::getAxisValue(int32_t axis, size_t pointerIndex) const {
   1.369 +    float value = getRawPointerCoords(pointerIndex)->getAxisValue(axis);
   1.370 +    switch (axis) {
   1.371 +    case AMOTION_EVENT_AXIS_X:
   1.372 +        return value + mXOffset;
   1.373 +    case AMOTION_EVENT_AXIS_Y:
   1.374 +        return value + mYOffset;
   1.375 +    }
   1.376 +    return value;
   1.377 +}
   1.378 +
   1.379 +const PointerCoords* MotionEvent::getHistoricalRawPointerCoords(
   1.380 +        size_t pointerIndex, size_t historicalIndex) const {
   1.381 +    return &mSamplePointerCoords[historicalIndex * getPointerCount() + pointerIndex];
   1.382 +}
   1.383 +
   1.384 +float MotionEvent::getHistoricalRawAxisValue(int32_t axis, size_t pointerIndex,
   1.385 +        size_t historicalIndex) const {
   1.386 +    return getHistoricalRawPointerCoords(pointerIndex, historicalIndex)->getAxisValue(axis);
   1.387 +}
   1.388 +
   1.389 +float MotionEvent::getHistoricalAxisValue(int32_t axis, size_t pointerIndex,
   1.390 +        size_t historicalIndex) const {
   1.391 +    float value = getHistoricalRawPointerCoords(pointerIndex, historicalIndex)->getAxisValue(axis);
   1.392 +    switch (axis) {
   1.393 +    case AMOTION_EVENT_AXIS_X:
   1.394 +        return value + mXOffset;
   1.395 +    case AMOTION_EVENT_AXIS_Y:
   1.396 +        return value + mYOffset;
   1.397 +    }
   1.398 +    return value;
   1.399 +}
   1.400 +
   1.401 +ssize_t MotionEvent::findPointerIndex(int32_t pointerId) const {
   1.402 +    size_t pointerCount = mPointerProperties.size();
   1.403 +    for (size_t i = 0; i < pointerCount; i++) {
   1.404 +        if (mPointerProperties.itemAt(i).id == pointerId) {
   1.405 +            return i;
   1.406 +        }
   1.407 +    }
   1.408 +    return -1;
   1.409 +}
   1.410 +
   1.411 +void MotionEvent::offsetLocation(float xOffset, float yOffset) {
   1.412 +    mXOffset += xOffset;
   1.413 +    mYOffset += yOffset;
   1.414 +}
   1.415 +
   1.416 +void MotionEvent::scale(float scaleFactor) {
   1.417 +    mXOffset *= scaleFactor;
   1.418 +    mYOffset *= scaleFactor;
   1.419 +    mXPrecision *= scaleFactor;
   1.420 +    mYPrecision *= scaleFactor;
   1.421 +
   1.422 +    size_t numSamples = mSamplePointerCoords.size();
   1.423 +    for (size_t i = 0; i < numSamples; i++) {
   1.424 +        mSamplePointerCoords.editItemAt(i).scale(scaleFactor);
   1.425 +    }
   1.426 +}
   1.427 +
   1.428 +#ifdef HAVE_ANDROID_OS
   1.429 +static inline float transformAngle(const SkMatrix* matrix, float angleRadians) {
   1.430 +    // Construct and transform a vector oriented at the specified clockwise angle from vertical.
   1.431 +    // Coordinate system: down is increasing Y, right is increasing X.
   1.432 +    SkPoint vector;
   1.433 +    vector.fX = SkFloatToScalar(sinf(angleRadians));
   1.434 +    vector.fY = SkFloatToScalar(-cosf(angleRadians));
   1.435 +    matrix->mapVectors(& vector, 1);
   1.436 +
   1.437 +    // Derive the transformed vector's clockwise angle from vertical.
   1.438 +    float result = atan2f(SkScalarToFloat(vector.fX), SkScalarToFloat(-vector.fY));
   1.439 +    if (result < - M_PI_2) {
   1.440 +        result += M_PI;
   1.441 +    } else if (result > M_PI_2) {
   1.442 +        result -= M_PI;
   1.443 +    }
   1.444 +    return result;
   1.445 +}
   1.446 +
   1.447 +void MotionEvent::transform(const SkMatrix* matrix) {
   1.448 +    float oldXOffset = mXOffset;
   1.449 +    float oldYOffset = mYOffset;
   1.450 +
   1.451 +    // The tricky part of this implementation is to preserve the value of
   1.452 +    // rawX and rawY.  So we apply the transformation to the first point
   1.453 +    // then derive an appropriate new X/Y offset that will preserve rawX and rawY.
   1.454 +    SkPoint point;
   1.455 +    float rawX = getRawX(0);
   1.456 +    float rawY = getRawY(0);
   1.457 +    matrix->mapXY(SkFloatToScalar(rawX + oldXOffset), SkFloatToScalar(rawY + oldYOffset),
   1.458 +            & point);
   1.459 +    float newX = SkScalarToFloat(point.fX);
   1.460 +    float newY = SkScalarToFloat(point.fY);
   1.461 +    float newXOffset = newX - rawX;
   1.462 +    float newYOffset = newY - rawY;
   1.463 +
   1.464 +    mXOffset = newXOffset;
   1.465 +    mYOffset = newYOffset;
   1.466 +
   1.467 +    // Apply the transformation to all samples.
   1.468 +    size_t numSamples = mSamplePointerCoords.size();
   1.469 +    for (size_t i = 0; i < numSamples; i++) {
   1.470 +        PointerCoords& c = mSamplePointerCoords.editItemAt(i);
   1.471 +        float x = c.getAxisValue(AMOTION_EVENT_AXIS_X) + oldXOffset;
   1.472 +        float y = c.getAxisValue(AMOTION_EVENT_AXIS_Y) + oldYOffset;
   1.473 +        matrix->mapXY(SkFloatToScalar(x), SkFloatToScalar(y), &point);
   1.474 +        c.setAxisValue(AMOTION_EVENT_AXIS_X, SkScalarToFloat(point.fX) - newXOffset);
   1.475 +        c.setAxisValue(AMOTION_EVENT_AXIS_Y, SkScalarToFloat(point.fY) - newYOffset);
   1.476 +
   1.477 +        float orientation = c.getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION);
   1.478 +        c.setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, transformAngle(matrix, orientation));
   1.479 +    }
   1.480 +}
   1.481 +
   1.482 +status_t MotionEvent::readFromParcel(Parcel* parcel) {
   1.483 +    size_t pointerCount = parcel->readInt32();
   1.484 +    size_t sampleCount = parcel->readInt32();
   1.485 +    if (pointerCount == 0 || pointerCount > MAX_POINTERS || sampleCount == 0) {
   1.486 +        return BAD_VALUE;
   1.487 +    }
   1.488 +
   1.489 +    mDeviceId = parcel->readInt32();
   1.490 +    mSource = parcel->readInt32();
   1.491 +    mAction = parcel->readInt32();
   1.492 +    mFlags = parcel->readInt32();
   1.493 +    mEdgeFlags = parcel->readInt32();
   1.494 +    mMetaState = parcel->readInt32();
   1.495 +    mButtonState = parcel->readInt32();
   1.496 +    mXOffset = parcel->readFloat();
   1.497 +    mYOffset = parcel->readFloat();
   1.498 +    mXPrecision = parcel->readFloat();
   1.499 +    mYPrecision = parcel->readFloat();
   1.500 +    mDownTime = parcel->readInt64();
   1.501 +
   1.502 +    mPointerProperties.clear();
   1.503 +    mPointerProperties.setCapacity(pointerCount);
   1.504 +    mSampleEventTimes.clear();
   1.505 +    mSampleEventTimes.setCapacity(sampleCount);
   1.506 +    mSamplePointerCoords.clear();
   1.507 +    mSamplePointerCoords.setCapacity(sampleCount * pointerCount);
   1.508 +
   1.509 +    for (size_t i = 0; i < pointerCount; i++) {
   1.510 +        mPointerProperties.push();
   1.511 +        PointerProperties& properties = mPointerProperties.editTop();
   1.512 +        properties.id = parcel->readInt32();
   1.513 +        properties.toolType = parcel->readInt32();
   1.514 +    }
   1.515 +
   1.516 +    while (sampleCount-- > 0) {
   1.517 +        mSampleEventTimes.push(parcel->readInt64());
   1.518 +        for (size_t i = 0; i < pointerCount; i++) {
   1.519 +            mSamplePointerCoords.push();
   1.520 +            status_t status = mSamplePointerCoords.editTop().readFromParcel(parcel);
   1.521 +            if (status) {
   1.522 +                return status;
   1.523 +            }
   1.524 +        }
   1.525 +    }
   1.526 +    return OK;
   1.527 +}
   1.528 +
   1.529 +status_t MotionEvent::writeToParcel(Parcel* parcel) const {
   1.530 +    size_t pointerCount = mPointerProperties.size();
   1.531 +    size_t sampleCount = mSampleEventTimes.size();
   1.532 +
   1.533 +    parcel->writeInt32(pointerCount);
   1.534 +    parcel->writeInt32(sampleCount);
   1.535 +
   1.536 +    parcel->writeInt32(mDeviceId);
   1.537 +    parcel->writeInt32(mSource);
   1.538 +    parcel->writeInt32(mAction);
   1.539 +    parcel->writeInt32(mFlags);
   1.540 +    parcel->writeInt32(mEdgeFlags);
   1.541 +    parcel->writeInt32(mMetaState);
   1.542 +    parcel->writeInt32(mButtonState);
   1.543 +    parcel->writeFloat(mXOffset);
   1.544 +    parcel->writeFloat(mYOffset);
   1.545 +    parcel->writeFloat(mXPrecision);
   1.546 +    parcel->writeFloat(mYPrecision);
   1.547 +    parcel->writeInt64(mDownTime);
   1.548 +
   1.549 +    for (size_t i = 0; i < pointerCount; i++) {
   1.550 +        const PointerProperties& properties = mPointerProperties.itemAt(i);
   1.551 +        parcel->writeInt32(properties.id);
   1.552 +        parcel->writeInt32(properties.toolType);
   1.553 +    }
   1.554 +
   1.555 +    const PointerCoords* pc = mSamplePointerCoords.array();
   1.556 +    for (size_t h = 0; h < sampleCount; h++) {
   1.557 +        parcel->writeInt64(mSampleEventTimes.itemAt(h));
   1.558 +        for (size_t i = 0; i < pointerCount; i++) {
   1.559 +            status_t status = (pc++)->writeToParcel(parcel);
   1.560 +            if (status) {
   1.561 +                return status;
   1.562 +            }
   1.563 +        }
   1.564 +    }
   1.565 +    return OK;
   1.566 +}
   1.567 +#endif
   1.568 +
   1.569 +bool MotionEvent::isTouchEvent(int32_t source, int32_t action) {
   1.570 +    if (source & AINPUT_SOURCE_CLASS_POINTER) {
   1.571 +        // Specifically excludes HOVER_MOVE and SCROLL.
   1.572 +        switch (action & AMOTION_EVENT_ACTION_MASK) {
   1.573 +        case AMOTION_EVENT_ACTION_DOWN:
   1.574 +        case AMOTION_EVENT_ACTION_MOVE:
   1.575 +        case AMOTION_EVENT_ACTION_UP:
   1.576 +        case AMOTION_EVENT_ACTION_POINTER_DOWN:
   1.577 +        case AMOTION_EVENT_ACTION_POINTER_UP:
   1.578 +        case AMOTION_EVENT_ACTION_CANCEL:
   1.579 +        case AMOTION_EVENT_ACTION_OUTSIDE:
   1.580 +            return true;
   1.581 +        }
   1.582 +    }
   1.583 +    return false;
   1.584 +}
   1.585 +
   1.586 +
   1.587 +// --- PooledInputEventFactory ---
   1.588 +
   1.589 +PooledInputEventFactory::PooledInputEventFactory(size_t maxPoolSize) :
   1.590 +        mMaxPoolSize(maxPoolSize) {
   1.591 +}
   1.592 +
   1.593 +PooledInputEventFactory::~PooledInputEventFactory() {
   1.594 +    for (size_t i = 0; i < mKeyEventPool.size(); i++) {
   1.595 +        delete mKeyEventPool.itemAt(i);
   1.596 +    }
   1.597 +    for (size_t i = 0; i < mMotionEventPool.size(); i++) {
   1.598 +        delete mMotionEventPool.itemAt(i);
   1.599 +    }
   1.600 +}
   1.601 +
   1.602 +KeyEvent* PooledInputEventFactory::createKeyEvent() {
   1.603 +    if (!mKeyEventPool.isEmpty()) {
   1.604 +        KeyEvent* event = mKeyEventPool.top();
   1.605 +        mKeyEventPool.pop();
   1.606 +        return event;
   1.607 +    }
   1.608 +    return new KeyEvent();
   1.609 +}
   1.610 +
   1.611 +MotionEvent* PooledInputEventFactory::createMotionEvent() {
   1.612 +    if (!mMotionEventPool.isEmpty()) {
   1.613 +        MotionEvent* event = mMotionEventPool.top();
   1.614 +        mMotionEventPool.pop();
   1.615 +        return event;
   1.616 +    }
   1.617 +    return new MotionEvent();
   1.618 +}
   1.619 +
   1.620 +void PooledInputEventFactory::recycle(InputEvent* event) {
   1.621 +    switch (event->getType()) {
   1.622 +    case AINPUT_EVENT_TYPE_KEY:
   1.623 +        if (mKeyEventPool.size() < mMaxPoolSize) {
   1.624 +            mKeyEventPool.push(static_cast<KeyEvent*>(event));
   1.625 +            return;
   1.626 +        }
   1.627 +        break;
   1.628 +    case AINPUT_EVENT_TYPE_MOTION:
   1.629 +        if (mMotionEventPool.size() < mMaxPoolSize) {
   1.630 +            mMotionEventPool.push(static_cast<MotionEvent*>(event));
   1.631 +            return;
   1.632 +        }
   1.633 +        break;
   1.634 +    }
   1.635 +    delete event;
   1.636 +}
   1.637 +
   1.638 +} // namespace android

mercurial