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