1/* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#define LOG_TAG "Input" 18//#define LOG_NDEBUG 0 19 20#include <math.h> 21#include <limits.h> 22 23#include <input/Input.h> 24#include <input/InputEventLabels.h> 25 26#ifdef __ANDROID__ 27#include <binder/Parcel.h> 28#endif 29 30namespace android { 31 32// --- InputEvent --- 33 34void InputEvent::initialize(int32_t deviceId, int32_t source) { 35 mDeviceId = deviceId; 36 mSource = source; 37} 38 39void InputEvent::initialize(const InputEvent& from) { 40 mDeviceId = from.mDeviceId; 41 mSource = from.mSource; 42} 43 44// --- KeyEvent --- 45 46const char* KeyEvent::getLabel(int32_t keyCode) { 47 return getLabelByKeyCode(keyCode); 48} 49 50int32_t KeyEvent::getKeyCodeFromLabel(const char* label) { 51 return getKeyCodeByLabel(label); 52} 53 54void KeyEvent::initialize( 55 int32_t deviceId, 56 int32_t source, 57 int32_t action, 58 int32_t flags, 59 int32_t keyCode, 60 int32_t scanCode, 61 int32_t metaState, 62 int32_t repeatCount, 63 nsecs_t downTime, 64 nsecs_t eventTime) { 65 InputEvent::initialize(deviceId, source); 66 mAction = action; 67 mFlags = flags; 68 mKeyCode = keyCode; 69 mScanCode = scanCode; 70 mMetaState = metaState; 71 mRepeatCount = repeatCount; 72 mDownTime = downTime; 73 mEventTime = eventTime; 74} 75 76void KeyEvent::initialize(const KeyEvent& from) { 77 InputEvent::initialize(from); 78 mAction = from.mAction; 79 mFlags = from.mFlags; 80 mKeyCode = from.mKeyCode; 81 mScanCode = from.mScanCode; 82 mMetaState = from.mMetaState; 83 mRepeatCount = from.mRepeatCount; 84 mDownTime = from.mDownTime; 85 mEventTime = from.mEventTime; 86} 87 88 89// --- PointerCoords --- 90 91float PointerCoords::getAxisValue(int32_t axis) const { 92 if (axis < 0 || axis > 63 || !BitSet64::hasBit(bits, axis)){ 93 return 0; 94 } 95 return values[BitSet64::getIndexOfBit(bits, axis)]; 96} 97 98status_t PointerCoords::setAxisValue(int32_t axis, float value) { 99 if (axis < 0 || axis > 63) { 100 return NAME_NOT_FOUND; 101 } 102 103 uint32_t index = BitSet64::getIndexOfBit(bits, axis); 104 if (!BitSet64::hasBit(bits, axis)) { 105 if (value == 0) { 106 return OK; // axes with value 0 do not need to be stored 107 } 108 109 uint32_t count = BitSet64::count(bits); 110 if (count >= MAX_AXES) { 111 tooManyAxes(axis); 112 return NO_MEMORY; 113 } 114 BitSet64::markBit(bits, axis); 115 for (uint32_t i = count; i > index; i--) { 116 values[i] = values[i - 1]; 117 } 118 } 119 120 values[index] = value; 121 return OK; 122} 123 124static inline void scaleAxisValue(PointerCoords& c, int axis, float scaleFactor) { 125 float value = c.getAxisValue(axis); 126 if (value != 0) { 127 c.setAxisValue(axis, value * scaleFactor); 128 } 129} 130 131void PointerCoords::scale(float scaleFactor) { 132 // No need to scale pressure or size since they are normalized. 133 // No need to scale orientation since it is meaningless to do so. 134 scaleAxisValue(*this, AMOTION_EVENT_AXIS_X, scaleFactor); 135 scaleAxisValue(*this, AMOTION_EVENT_AXIS_Y, scaleFactor); 136 scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOUCH_MAJOR, scaleFactor); 137 scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOUCH_MINOR, scaleFactor); 138 scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOOL_MAJOR, scaleFactor); 139 scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOOL_MINOR, scaleFactor); 140} 141 142void PointerCoords::applyOffset(float xOffset, float yOffset) { 143 setAxisValue(AMOTION_EVENT_AXIS_X, getX() + xOffset); 144 setAxisValue(AMOTION_EVENT_AXIS_Y, getY() + yOffset); 145} 146 147#ifdef __ANDROID__ 148status_t PointerCoords::readFromParcel(Parcel* parcel) { 149 bits = parcel->readInt64(); 150 151 uint32_t count = BitSet64::count(bits); 152 if (count > MAX_AXES) { 153 return BAD_VALUE; 154 } 155 156 for (uint32_t i = 0; i < count; i++) { 157 values[i] = parcel->readFloat(); 158 } 159 return OK; 160} 161 162status_t PointerCoords::writeToParcel(Parcel* parcel) const { 163 parcel->writeInt64(bits); 164 165 uint32_t count = BitSet64::count(bits); 166 for (uint32_t i = 0; i < count; i++) { 167 parcel->writeFloat(values[i]); 168 } 169 return OK; 170} 171#endif 172 173void PointerCoords::tooManyAxes(int axis) { 174 ALOGW("Could not set value for axis %d because the PointerCoords structure is full and " 175 "cannot contain more than %d axis values.", axis, int(MAX_AXES)); 176} 177 178bool PointerCoords::operator==(const PointerCoords& other) const { 179 if (bits != other.bits) { 180 return false; 181 } 182 uint32_t count = BitSet64::count(bits); 183 for (uint32_t i = 0; i < count; i++) { 184 if (values[i] != other.values[i]) { 185 return false; 186 } 187 } 188 return true; 189} 190 191void PointerCoords::copyFrom(const PointerCoords& other) { 192 bits = other.bits; 193 uint32_t count = BitSet64::count(bits); 194 for (uint32_t i = 0; i < count; i++) { 195 values[i] = other.values[i]; 196 } 197} 198 199 200// --- PointerProperties --- 201 202bool PointerProperties::operator==(const PointerProperties& other) const { 203 return id == other.id 204 && toolType == other.toolType; 205} 206 207void PointerProperties::copyFrom(const PointerProperties& other) { 208 id = other.id; 209 toolType = other.toolType; 210} 211 212 213// --- MotionEvent --- 214 215void MotionEvent::initialize( 216 int32_t deviceId, 217 int32_t source, 218 int32_t action, 219 int32_t actionButton, 220 int32_t flags, 221 int32_t edgeFlags, 222 int32_t metaState, 223 int32_t buttonState, 224 float xOffset, 225 float yOffset, 226 float xPrecision, 227 float yPrecision, 228 nsecs_t downTime, 229 nsecs_t eventTime, 230 size_t pointerCount, 231 const PointerProperties* pointerProperties, 232 const PointerCoords* pointerCoords) { 233 InputEvent::initialize(deviceId, source); 234 mAction = action; 235 mActionButton = actionButton; 236 mFlags = flags; 237 mEdgeFlags = edgeFlags; 238 mMetaState = metaState; 239 mButtonState = buttonState; 240 mXOffset = xOffset; 241 mYOffset = yOffset; 242 mXPrecision = xPrecision; 243 mYPrecision = yPrecision; 244 mDownTime = downTime; 245 mPointerProperties.clear(); 246 mPointerProperties.appendArray(pointerProperties, pointerCount); 247 mSampleEventTimes.clear(); 248 mSamplePointerCoords.clear(); 249 addSample(eventTime, pointerCoords); 250} 251 252void MotionEvent::copyFrom(const MotionEvent* other, bool keepHistory) { 253 InputEvent::initialize(other->mDeviceId, other->mSource); 254 mAction = other->mAction; 255 mActionButton = other->mActionButton; 256 mFlags = other->mFlags; 257 mEdgeFlags = other->mEdgeFlags; 258 mMetaState = other->mMetaState; 259 mButtonState = other->mButtonState; 260 mXOffset = other->mXOffset; 261 mYOffset = other->mYOffset; 262 mXPrecision = other->mXPrecision; 263 mYPrecision = other->mYPrecision; 264 mDownTime = other->mDownTime; 265 mPointerProperties = other->mPointerProperties; 266 267 if (keepHistory) { 268 mSampleEventTimes = other->mSampleEventTimes; 269 mSamplePointerCoords = other->mSamplePointerCoords; 270 } else { 271 mSampleEventTimes.clear(); 272 mSampleEventTimes.push(other->getEventTime()); 273 mSamplePointerCoords.clear(); 274 size_t pointerCount = other->getPointerCount(); 275 size_t historySize = other->getHistorySize(); 276 mSamplePointerCoords.appendArray(other->mSamplePointerCoords.array() 277 + (historySize * pointerCount), pointerCount); 278 } 279} 280 281void MotionEvent::addSample( 282 int64_t eventTime, 283 const PointerCoords* pointerCoords) { 284 mSampleEventTimes.push(eventTime); 285 mSamplePointerCoords.appendArray(pointerCoords, getPointerCount()); 286} 287 288const PointerCoords* MotionEvent::getRawPointerCoords(size_t pointerIndex) const { 289 return &mSamplePointerCoords[getHistorySize() * getPointerCount() + pointerIndex]; 290} 291 292float MotionEvent::getRawAxisValue(int32_t axis, size_t pointerIndex) const { 293 return getRawPointerCoords(pointerIndex)->getAxisValue(axis); 294} 295 296float MotionEvent::getAxisValue(int32_t axis, size_t pointerIndex) const { 297 float value = getRawPointerCoords(pointerIndex)->getAxisValue(axis); 298 switch (axis) { 299 case AMOTION_EVENT_AXIS_X: 300 return value + mXOffset; 301 case AMOTION_EVENT_AXIS_Y: 302 return value + mYOffset; 303 } 304 return value; 305} 306 307const PointerCoords* MotionEvent::getHistoricalRawPointerCoords( 308 size_t pointerIndex, size_t historicalIndex) const { 309 return &mSamplePointerCoords[historicalIndex * getPointerCount() + pointerIndex]; 310} 311 312float MotionEvent::getHistoricalRawAxisValue(int32_t axis, size_t pointerIndex, 313 size_t historicalIndex) const { 314 return getHistoricalRawPointerCoords(pointerIndex, historicalIndex)->getAxisValue(axis); 315} 316 317float MotionEvent::getHistoricalAxisValue(int32_t axis, size_t pointerIndex, 318 size_t historicalIndex) const { 319 float value = getHistoricalRawPointerCoords(pointerIndex, historicalIndex)->getAxisValue(axis); 320 switch (axis) { 321 case AMOTION_EVENT_AXIS_X: 322 return value + mXOffset; 323 case AMOTION_EVENT_AXIS_Y: 324 return value + mYOffset; 325 } 326 return value; 327} 328 329ssize_t MotionEvent::findPointerIndex(int32_t pointerId) const { 330 size_t pointerCount = mPointerProperties.size(); 331 for (size_t i = 0; i < pointerCount; i++) { 332 if (mPointerProperties.itemAt(i).id == pointerId) { 333 return i; 334 } 335 } 336 return -1; 337} 338 339void MotionEvent::offsetLocation(float xOffset, float yOffset) { 340 mXOffset += xOffset; 341 mYOffset += yOffset; 342} 343 344void MotionEvent::scale(float scaleFactor) { 345 mXOffset *= scaleFactor; 346 mYOffset *= scaleFactor; 347 mXPrecision *= scaleFactor; 348 mYPrecision *= scaleFactor; 349 350 size_t numSamples = mSamplePointerCoords.size(); 351 for (size_t i = 0; i < numSamples; i++) { 352 mSamplePointerCoords.editItemAt(i).scale(scaleFactor); 353 } 354} 355 356static void transformPoint(const float matrix[9], float x, float y, float *outX, float *outY) { 357 // Apply perspective transform like Skia. 358 float newX = matrix[0] * x + matrix[1] * y + matrix[2]; 359 float newY = matrix[3] * x + matrix[4] * y + matrix[5]; 360 float newZ = matrix[6] * x + matrix[7] * y + matrix[8]; 361 if (newZ) { 362 newZ = 1.0f / newZ; 363 } 364 *outX = newX * newZ; 365 *outY = newY * newZ; 366} 367 368static float transformAngle(const float matrix[9], float angleRadians, 369 float originX, float originY) { 370 // Construct and transform a vector oriented at the specified clockwise angle from vertical. 371 // Coordinate system: down is increasing Y, right is increasing X. 372 float x = sinf(angleRadians); 373 float y = -cosf(angleRadians); 374 transformPoint(matrix, x, y, &x, &y); 375 x -= originX; 376 y -= originY; 377 378 // Derive the transformed vector's clockwise angle from vertical. 379 float result = atan2f(x, -y); 380 if (result < - M_PI_2) { 381 result += M_PI; 382 } else if (result > M_PI_2) { 383 result -= M_PI; 384 } 385 return result; 386} 387 388void MotionEvent::transform(const float matrix[9]) { 389 // The tricky part of this implementation is to preserve the value of 390 // rawX and rawY. So we apply the transformation to the first point 391 // then derive an appropriate new X/Y offset that will preserve rawX 392 // and rawY for that point. 393 float oldXOffset = mXOffset; 394 float oldYOffset = mYOffset; 395 float newX, newY; 396 float rawX = getRawX(0); 397 float rawY = getRawY(0); 398 transformPoint(matrix, rawX + oldXOffset, rawY + oldYOffset, &newX, &newY); 399 mXOffset = newX - rawX; 400 mYOffset = newY - rawY; 401 402 // Determine how the origin is transformed by the matrix so that we 403 // can transform orientation vectors. 404 float originX, originY; 405 transformPoint(matrix, 0, 0, &originX, &originY); 406 407 // Apply the transformation to all samples. 408 size_t numSamples = mSamplePointerCoords.size(); 409 for (size_t i = 0; i < numSamples; i++) { 410 PointerCoords& c = mSamplePointerCoords.editItemAt(i); 411 float x = c.getAxisValue(AMOTION_EVENT_AXIS_X) + oldXOffset; 412 float y = c.getAxisValue(AMOTION_EVENT_AXIS_Y) + oldYOffset; 413 transformPoint(matrix, x, y, &x, &y); 414 c.setAxisValue(AMOTION_EVENT_AXIS_X, x - mXOffset); 415 c.setAxisValue(AMOTION_EVENT_AXIS_Y, y - mYOffset); 416 417 float orientation = c.getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION); 418 c.setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, 419 transformAngle(matrix, orientation, originX, originY)); 420 } 421} 422 423#ifdef __ANDROID__ 424status_t MotionEvent::readFromParcel(Parcel* parcel) { 425 size_t pointerCount = parcel->readInt32(); 426 size_t sampleCount = parcel->readInt32(); 427 if (pointerCount == 0 || pointerCount > MAX_POINTERS || 428 sampleCount == 0 || sampleCount > MAX_SAMPLES) { 429 return BAD_VALUE; 430 } 431 432 mDeviceId = parcel->readInt32(); 433 mSource = parcel->readInt32(); 434 mAction = parcel->readInt32(); 435 mActionButton = parcel->readInt32(); 436 mFlags = parcel->readInt32(); 437 mEdgeFlags = parcel->readInt32(); 438 mMetaState = parcel->readInt32(); 439 mButtonState = parcel->readInt32(); 440 mXOffset = parcel->readFloat(); 441 mYOffset = parcel->readFloat(); 442 mXPrecision = parcel->readFloat(); 443 mYPrecision = parcel->readFloat(); 444 mDownTime = parcel->readInt64(); 445 446 mPointerProperties.clear(); 447 mPointerProperties.setCapacity(pointerCount); 448 mSampleEventTimes.clear(); 449 mSampleEventTimes.setCapacity(sampleCount); 450 mSamplePointerCoords.clear(); 451 mSamplePointerCoords.setCapacity(sampleCount * pointerCount); 452 453 for (size_t i = 0; i < pointerCount; i++) { 454 mPointerProperties.push(); 455 PointerProperties& properties = mPointerProperties.editTop(); 456 properties.id = parcel->readInt32(); 457 properties.toolType = parcel->readInt32(); 458 } 459 460 while (sampleCount > 0) { 461 sampleCount--; 462 mSampleEventTimes.push(parcel->readInt64()); 463 for (size_t i = 0; i < pointerCount; i++) { 464 mSamplePointerCoords.push(); 465 status_t status = mSamplePointerCoords.editTop().readFromParcel(parcel); 466 if (status) { 467 return status; 468 } 469 } 470 } 471 return OK; 472} 473 474status_t MotionEvent::writeToParcel(Parcel* parcel) const { 475 size_t pointerCount = mPointerProperties.size(); 476 size_t sampleCount = mSampleEventTimes.size(); 477 478 parcel->writeInt32(pointerCount); 479 parcel->writeInt32(sampleCount); 480 481 parcel->writeInt32(mDeviceId); 482 parcel->writeInt32(mSource); 483 parcel->writeInt32(mAction); 484 parcel->writeInt32(mActionButton); 485 parcel->writeInt32(mFlags); 486 parcel->writeInt32(mEdgeFlags); 487 parcel->writeInt32(mMetaState); 488 parcel->writeInt32(mButtonState); 489 parcel->writeFloat(mXOffset); 490 parcel->writeFloat(mYOffset); 491 parcel->writeFloat(mXPrecision); 492 parcel->writeFloat(mYPrecision); 493 parcel->writeInt64(mDownTime); 494 495 for (size_t i = 0; i < pointerCount; i++) { 496 const PointerProperties& properties = mPointerProperties.itemAt(i); 497 parcel->writeInt32(properties.id); 498 parcel->writeInt32(properties.toolType); 499 } 500 501 const PointerCoords* pc = mSamplePointerCoords.array(); 502 for (size_t h = 0; h < sampleCount; h++) { 503 parcel->writeInt64(mSampleEventTimes.itemAt(h)); 504 for (size_t i = 0; i < pointerCount; i++) { 505 status_t status = (pc++)->writeToParcel(parcel); 506 if (status) { 507 return status; 508 } 509 } 510 } 511 return OK; 512} 513#endif 514 515bool MotionEvent::isTouchEvent(int32_t source, int32_t action) { 516 if (source & AINPUT_SOURCE_CLASS_POINTER) { 517 // Specifically excludes HOVER_MOVE and SCROLL. 518 switch (action & AMOTION_EVENT_ACTION_MASK) { 519 case AMOTION_EVENT_ACTION_DOWN: 520 case AMOTION_EVENT_ACTION_MOVE: 521 case AMOTION_EVENT_ACTION_UP: 522 case AMOTION_EVENT_ACTION_POINTER_DOWN: 523 case AMOTION_EVENT_ACTION_POINTER_UP: 524 case AMOTION_EVENT_ACTION_CANCEL: 525 case AMOTION_EVENT_ACTION_OUTSIDE: 526 return true; 527 } 528 } 529 return false; 530} 531 532const char* MotionEvent::getLabel(int32_t axis) { 533 return getAxisLabel(axis); 534} 535 536int32_t MotionEvent::getAxisFromLabel(const char* label) { 537 return getAxisByLabel(label); 538} 539 540 541// --- PooledInputEventFactory --- 542 543PooledInputEventFactory::PooledInputEventFactory(size_t maxPoolSize) : 544 mMaxPoolSize(maxPoolSize) { 545} 546 547PooledInputEventFactory::~PooledInputEventFactory() { 548 for (size_t i = 0; i < mKeyEventPool.size(); i++) { 549 delete mKeyEventPool.itemAt(i); 550 } 551 for (size_t i = 0; i < mMotionEventPool.size(); i++) { 552 delete mMotionEventPool.itemAt(i); 553 } 554} 555 556KeyEvent* PooledInputEventFactory::createKeyEvent() { 557 if (!mKeyEventPool.isEmpty()) { 558 KeyEvent* event = mKeyEventPool.top(); 559 mKeyEventPool.pop(); 560 return event; 561 } 562 return new KeyEvent(); 563} 564 565MotionEvent* PooledInputEventFactory::createMotionEvent() { 566 if (!mMotionEventPool.isEmpty()) { 567 MotionEvent* event = mMotionEventPool.top(); 568 mMotionEventPool.pop(); 569 return event; 570 } 571 return new MotionEvent(); 572} 573 574void PooledInputEventFactory::recycle(InputEvent* event) { 575 switch (event->getType()) { 576 case AINPUT_EVENT_TYPE_KEY: 577 if (mKeyEventPool.size() < mMaxPoolSize) { 578 mKeyEventPool.push(static_cast<KeyEvent*>(event)); 579 return; 580 } 581 break; 582 case AINPUT_EVENT_TYPE_MOTION: 583 if (mMotionEventPool.size() < mMaxPoolSize) { 584 mMotionEventPool.push(static_cast<MotionEvent*>(event)); 585 return; 586 } 587 break; 588 } 589 delete event; 590} 591 592} // namespace android 593