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