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