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