1 // 2 // Copyright 2010 The Android Open Source Project 3 // 4 // Provides a pipe-based transport for native events in the NDK. 5 // 6 #define LOG_TAG "Input" 7 8 //#define LOG_NDEBUG 0 9 10 // Log debug messages about keymap probing. 11 #define DEBUG_PROBE 0 12 13 // Log debug messages about velocity tracking. 14 #define DEBUG_VELOCITY 0 15 16 // Log debug messages about least squares fitting. 17 #define DEBUG_LEAST_SQUARES 0 18 19 // Log debug messages about acceleration. 20 #define DEBUG_ACCELERATION 0 21 22 23 #include <stdlib.h> 24 #include <unistd.h> 25 #include <ctype.h> 26 27 #include <ui/Input.h> 28 29 #include <math.h> 30 #include <limits.h> 31 32 #ifdef HAVE_ANDROID_OS 33 #include <binder/Parcel.h> 34 35 #include "SkPoint.h" 36 #include "SkMatrix.h" 37 #include "SkScalar.h" 38 #endif 39 40 namespace android { 41 42 static const char* CONFIGURATION_FILE_DIR[] = { 43 "idc/", 44 "keylayout/", 45 "keychars/", 46 }; 47 48 static const char* CONFIGURATION_FILE_EXTENSION[] = { 49 ".idc", 50 ".kl", 51 ".kcm", 52 }; 53 54 static bool isValidNameChar(char ch) { 55 return isascii(ch) && (isdigit(ch) || isalpha(ch) || ch == '-' || ch == '_'); 56 } 57 58 static void appendInputDeviceConfigurationFileRelativePath(String8& path, 59 const String8& name, InputDeviceConfigurationFileType type) { 60 path.append(CONFIGURATION_FILE_DIR[type]); 61 for (size_t i = 0; i < name.length(); i++) { 62 char ch = name[i]; 63 if (!isValidNameChar(ch)) { 64 ch = '_'; 65 } 66 path.append(&ch, 1); 67 } 68 path.append(CONFIGURATION_FILE_EXTENSION[type]); 69 } 70 71 String8 getInputDeviceConfigurationFilePathByDeviceIdentifier( 72 const InputDeviceIdentifier& deviceIdentifier, 73 InputDeviceConfigurationFileType type) { 74 if (deviceIdentifier.vendor !=0 && deviceIdentifier.product != 0) { 75 if (deviceIdentifier.version != 0) { 76 // Try vendor product version. 77 String8 versionPath(getInputDeviceConfigurationFilePathByName( 78 String8::format("Vendor_%04x_Product_%04x_Version_%04x", 79 deviceIdentifier.vendor, deviceIdentifier.product, 80 deviceIdentifier.version), 81 type)); 82 if (!versionPath.isEmpty()) { 83 return versionPath; 84 } 85 } 86 87 // Try vendor product. 88 String8 productPath(getInputDeviceConfigurationFilePathByName( 89 String8::format("Vendor_%04x_Product_%04x", 90 deviceIdentifier.vendor, deviceIdentifier.product), 91 type)); 92 if (!productPath.isEmpty()) { 93 return productPath; 94 } 95 } 96 97 // Try device name. 98 return getInputDeviceConfigurationFilePathByName(deviceIdentifier.name, type); 99 } 100 101 String8 getInputDeviceConfigurationFilePathByName( 102 const String8& name, InputDeviceConfigurationFileType type) { 103 // Search system repository. 104 String8 path; 105 path.setTo(getenv("ANDROID_ROOT")); 106 path.append("/usr/"); 107 appendInputDeviceConfigurationFileRelativePath(path, name, type); 108 #if DEBUG_PROBE 109 LOGD("Probing for system provided input device configuration file: path='%s'", path.string()); 110 #endif 111 if (!access(path.string(), R_OK)) { 112 #if DEBUG_PROBE 113 LOGD("Found"); 114 #endif 115 return path; 116 } 117 118 // Search user repository. 119 // TODO Should only look here if not in safe mode. 120 path.setTo(getenv("ANDROID_DATA")); 121 path.append("/system/devices/"); 122 appendInputDeviceConfigurationFileRelativePath(path, name, type); 123 #if DEBUG_PROBE 124 LOGD("Probing for system user input device configuration file: path='%s'", path.string()); 125 #endif 126 if (!access(path.string(), R_OK)) { 127 #if DEBUG_PROBE 128 LOGD("Found"); 129 #endif 130 return path; 131 } 132 133 // Not found. 134 #if DEBUG_PROBE 135 LOGD("Probe failed to find input device configuration file: name='%s', type=%d", 136 name.string(), type); 137 #endif 138 return String8(); 139 } 140 141 142 // --- InputEvent --- 143 144 void InputEvent::initialize(int32_t deviceId, int32_t source) { 145 mDeviceId = deviceId; 146 mSource = source; 147 } 148 149 void InputEvent::initialize(const InputEvent& from) { 150 mDeviceId = from.mDeviceId; 151 mSource = from.mSource; 152 } 153 154 // --- KeyEvent --- 155 156 bool KeyEvent::hasDefaultAction(int32_t keyCode) { 157 switch (keyCode) { 158 case AKEYCODE_HOME: 159 case AKEYCODE_BACK: 160 case AKEYCODE_CALL: 161 case AKEYCODE_ENDCALL: 162 case AKEYCODE_VOLUME_UP: 163 case AKEYCODE_VOLUME_DOWN: 164 case AKEYCODE_VOLUME_MUTE: 165 case AKEYCODE_POWER: 166 case AKEYCODE_CAMERA: 167 case AKEYCODE_HEADSETHOOK: 168 case AKEYCODE_MENU: 169 case AKEYCODE_NOTIFICATION: 170 case AKEYCODE_FOCUS: 171 case AKEYCODE_SEARCH: 172 case AKEYCODE_MEDIA_PLAY: 173 case AKEYCODE_MEDIA_PAUSE: 174 case AKEYCODE_MEDIA_PLAY_PAUSE: 175 case AKEYCODE_MEDIA_STOP: 176 case AKEYCODE_MEDIA_NEXT: 177 case AKEYCODE_MEDIA_PREVIOUS: 178 case AKEYCODE_MEDIA_REWIND: 179 case AKEYCODE_MEDIA_RECORD: 180 case AKEYCODE_MEDIA_FAST_FORWARD: 181 case AKEYCODE_MUTE: 182 return true; 183 } 184 185 return false; 186 } 187 188 bool KeyEvent::hasDefaultAction() const { 189 return hasDefaultAction(getKeyCode()); 190 } 191 192 bool KeyEvent::isSystemKey(int32_t keyCode) { 193 switch (keyCode) { 194 case AKEYCODE_MENU: 195 case AKEYCODE_SOFT_RIGHT: 196 case AKEYCODE_HOME: 197 case AKEYCODE_BACK: 198 case AKEYCODE_CALL: 199 case AKEYCODE_ENDCALL: 200 case AKEYCODE_VOLUME_UP: 201 case AKEYCODE_VOLUME_DOWN: 202 case AKEYCODE_VOLUME_MUTE: 203 case AKEYCODE_MUTE: 204 case AKEYCODE_POWER: 205 case AKEYCODE_HEADSETHOOK: 206 case AKEYCODE_MEDIA_PLAY: 207 case AKEYCODE_MEDIA_PAUSE: 208 case AKEYCODE_MEDIA_PLAY_PAUSE: 209 case AKEYCODE_MEDIA_STOP: 210 case AKEYCODE_MEDIA_NEXT: 211 case AKEYCODE_MEDIA_PREVIOUS: 212 case AKEYCODE_MEDIA_REWIND: 213 case AKEYCODE_MEDIA_RECORD: 214 case AKEYCODE_MEDIA_FAST_FORWARD: 215 case AKEYCODE_CAMERA: 216 case AKEYCODE_FOCUS: 217 case AKEYCODE_SEARCH: 218 return true; 219 } 220 221 return false; 222 } 223 224 bool KeyEvent::isSystemKey() const { 225 return isSystemKey(getKeyCode()); 226 } 227 228 void KeyEvent::initialize( 229 int32_t deviceId, 230 int32_t source, 231 int32_t action, 232 int32_t flags, 233 int32_t keyCode, 234 int32_t scanCode, 235 int32_t metaState, 236 int32_t repeatCount, 237 nsecs_t downTime, 238 nsecs_t eventTime) { 239 InputEvent::initialize(deviceId, source); 240 mAction = action; 241 mFlags = flags; 242 mKeyCode = keyCode; 243 mScanCode = scanCode; 244 mMetaState = metaState; 245 mRepeatCount = repeatCount; 246 mDownTime = downTime; 247 mEventTime = eventTime; 248 } 249 250 void KeyEvent::initialize(const KeyEvent& from) { 251 InputEvent::initialize(from); 252 mAction = from.mAction; 253 mFlags = from.mFlags; 254 mKeyCode = from.mKeyCode; 255 mScanCode = from.mScanCode; 256 mMetaState = from.mMetaState; 257 mRepeatCount = from.mRepeatCount; 258 mDownTime = from.mDownTime; 259 mEventTime = from.mEventTime; 260 } 261 262 263 // --- PointerCoords --- 264 265 float PointerCoords::getAxisValue(int32_t axis) const { 266 if (axis < 0 || axis > 63) { 267 return 0; 268 } 269 270 uint64_t axisBit = 1LL << axis; 271 if (!(bits & axisBit)) { 272 return 0; 273 } 274 uint32_t index = __builtin_popcountll(bits & (axisBit - 1LL)); 275 return values[index]; 276 } 277 278 status_t PointerCoords::setAxisValue(int32_t axis, float value) { 279 if (axis < 0 || axis > 63) { 280 return NAME_NOT_FOUND; 281 } 282 283 uint64_t axisBit = 1LL << axis; 284 uint32_t index = __builtin_popcountll(bits & (axisBit - 1LL)); 285 if (!(bits & axisBit)) { 286 if (value == 0) { 287 return OK; // axes with value 0 do not need to be stored 288 } 289 uint32_t count = __builtin_popcountll(bits); 290 if (count >= MAX_AXES) { 291 tooManyAxes(axis); 292 return NO_MEMORY; 293 } 294 bits |= axisBit; 295 for (uint32_t i = count; i > index; i--) { 296 values[i] = values[i - 1]; 297 } 298 } 299 values[index] = value; 300 return OK; 301 } 302 303 static inline void scaleAxisValue(PointerCoords& c, int axis, float scaleFactor) { 304 float value = c.getAxisValue(axis); 305 if (value != 0) { 306 c.setAxisValue(axis, value * scaleFactor); 307 } 308 } 309 310 void PointerCoords::scale(float scaleFactor) { 311 // No need to scale pressure or size since they are normalized. 312 // No need to scale orientation since it is meaningless to do so. 313 scaleAxisValue(*this, AMOTION_EVENT_AXIS_X, scaleFactor); 314 scaleAxisValue(*this, AMOTION_EVENT_AXIS_Y, scaleFactor); 315 scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOUCH_MAJOR, scaleFactor); 316 scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOUCH_MINOR, scaleFactor); 317 scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOOL_MAJOR, scaleFactor); 318 scaleAxisValue(*this, AMOTION_EVENT_AXIS_TOOL_MINOR, scaleFactor); 319 } 320 321 #ifdef HAVE_ANDROID_OS 322 status_t PointerCoords::readFromParcel(Parcel* parcel) { 323 bits = parcel->readInt64(); 324 325 uint32_t count = __builtin_popcountll(bits); 326 if (count > MAX_AXES) { 327 return BAD_VALUE; 328 } 329 330 for (uint32_t i = 0; i < count; i++) { 331 values[i] = parcel->readInt32(); 332 } 333 return OK; 334 } 335 336 status_t PointerCoords::writeToParcel(Parcel* parcel) const { 337 parcel->writeInt64(bits); 338 339 uint32_t count = __builtin_popcountll(bits); 340 for (uint32_t i = 0; i < count; i++) { 341 parcel->writeInt32(values[i]); 342 } 343 return OK; 344 } 345 #endif 346 347 void PointerCoords::tooManyAxes(int axis) { 348 LOGW("Could not set value for axis %d because the PointerCoords structure is full and " 349 "cannot contain more than %d axis values.", axis, int(MAX_AXES)); 350 } 351 352 bool PointerCoords::operator==(const PointerCoords& other) const { 353 if (bits != other.bits) { 354 return false; 355 } 356 uint32_t count = __builtin_popcountll(bits); 357 for (uint32_t i = 0; i < count; i++) { 358 if (values[i] != other.values[i]) { 359 return false; 360 } 361 } 362 return true; 363 } 364 365 void PointerCoords::copyFrom(const PointerCoords& other) { 366 bits = other.bits; 367 uint32_t count = __builtin_popcountll(bits); 368 for (uint32_t i = 0; i < count; i++) { 369 values[i] = other.values[i]; 370 } 371 } 372 373 374 // --- PointerProperties --- 375 376 bool PointerProperties::operator==(const PointerProperties& other) const { 377 return id == other.id 378 && toolType == other.toolType; 379 } 380 381 void PointerProperties::copyFrom(const PointerProperties& other) { 382 id = other.id; 383 toolType = other.toolType; 384 } 385 386 387 // --- MotionEvent --- 388 389 void MotionEvent::initialize( 390 int32_t deviceId, 391 int32_t source, 392 int32_t action, 393 int32_t flags, 394 int32_t edgeFlags, 395 int32_t metaState, 396 int32_t buttonState, 397 float xOffset, 398 float yOffset, 399 float xPrecision, 400 float yPrecision, 401 nsecs_t downTime, 402 nsecs_t eventTime, 403 size_t pointerCount, 404 const PointerProperties* pointerProperties, 405 const PointerCoords* pointerCoords) { 406 InputEvent::initialize(deviceId, source); 407 mAction = action; 408 mFlags = flags; 409 mEdgeFlags = edgeFlags; 410 mMetaState = metaState; 411 mButtonState = buttonState; 412 mXOffset = xOffset; 413 mYOffset = yOffset; 414 mXPrecision = xPrecision; 415 mYPrecision = yPrecision; 416 mDownTime = downTime; 417 mPointerProperties.clear(); 418 mPointerProperties.appendArray(pointerProperties, pointerCount); 419 mSampleEventTimes.clear(); 420 mSamplePointerCoords.clear(); 421 addSample(eventTime, pointerCoords); 422 } 423 424 void MotionEvent::copyFrom(const MotionEvent* other, bool keepHistory) { 425 InputEvent::initialize(other->mDeviceId, other->mSource); 426 mAction = other->mAction; 427 mFlags = other->mFlags; 428 mEdgeFlags = other->mEdgeFlags; 429 mMetaState = other->mMetaState; 430 mButtonState = other->mButtonState; 431 mXOffset = other->mXOffset; 432 mYOffset = other->mYOffset; 433 mXPrecision = other->mXPrecision; 434 mYPrecision = other->mYPrecision; 435 mDownTime = other->mDownTime; 436 mPointerProperties = other->mPointerProperties; 437 438 if (keepHistory) { 439 mSampleEventTimes = other->mSampleEventTimes; 440 mSamplePointerCoords = other->mSamplePointerCoords; 441 } else { 442 mSampleEventTimes.clear(); 443 mSampleEventTimes.push(other->getEventTime()); 444 mSamplePointerCoords.clear(); 445 size_t pointerCount = other->getPointerCount(); 446 size_t historySize = other->getHistorySize(); 447 mSamplePointerCoords.appendArray(other->mSamplePointerCoords.array() 448 + (historySize * pointerCount), pointerCount); 449 } 450 } 451 452 void MotionEvent::addSample( 453 int64_t eventTime, 454 const PointerCoords* pointerCoords) { 455 mSampleEventTimes.push(eventTime); 456 mSamplePointerCoords.appendArray(pointerCoords, getPointerCount()); 457 } 458 459 const PointerCoords* MotionEvent::getRawPointerCoords(size_t pointerIndex) const { 460 return &mSamplePointerCoords[getHistorySize() * getPointerCount() + pointerIndex]; 461 } 462 463 float MotionEvent::getRawAxisValue(int32_t axis, size_t pointerIndex) const { 464 return getRawPointerCoords(pointerIndex)->getAxisValue(axis); 465 } 466 467 float MotionEvent::getAxisValue(int32_t axis, size_t pointerIndex) const { 468 float value = getRawPointerCoords(pointerIndex)->getAxisValue(axis); 469 switch (axis) { 470 case AMOTION_EVENT_AXIS_X: 471 return value + mXOffset; 472 case AMOTION_EVENT_AXIS_Y: 473 return value + mYOffset; 474 } 475 return value; 476 } 477 478 const PointerCoords* MotionEvent::getHistoricalRawPointerCoords( 479 size_t pointerIndex, size_t historicalIndex) const { 480 return &mSamplePointerCoords[historicalIndex * getPointerCount() + pointerIndex]; 481 } 482 483 float MotionEvent::getHistoricalRawAxisValue(int32_t axis, size_t pointerIndex, 484 size_t historicalIndex) const { 485 return getHistoricalRawPointerCoords(pointerIndex, historicalIndex)->getAxisValue(axis); 486 } 487 488 float MotionEvent::getHistoricalAxisValue(int32_t axis, size_t pointerIndex, 489 size_t historicalIndex) const { 490 float value = getHistoricalRawPointerCoords(pointerIndex, historicalIndex)->getAxisValue(axis); 491 switch (axis) { 492 case AMOTION_EVENT_AXIS_X: 493 return value + mXOffset; 494 case AMOTION_EVENT_AXIS_Y: 495 return value + mYOffset; 496 } 497 return value; 498 } 499 500 ssize_t MotionEvent::findPointerIndex(int32_t pointerId) const { 501 size_t pointerCount = mPointerProperties.size(); 502 for (size_t i = 0; i < pointerCount; i++) { 503 if (mPointerProperties.itemAt(i).id == pointerId) { 504 return i; 505 } 506 } 507 return -1; 508 } 509 510 void MotionEvent::offsetLocation(float xOffset, float yOffset) { 511 mXOffset += xOffset; 512 mYOffset += yOffset; 513 } 514 515 void MotionEvent::scale(float scaleFactor) { 516 mXOffset *= scaleFactor; 517 mYOffset *= scaleFactor; 518 mXPrecision *= scaleFactor; 519 mYPrecision *= scaleFactor; 520 521 size_t numSamples = mSamplePointerCoords.size(); 522 for (size_t i = 0; i < numSamples; i++) { 523 mSamplePointerCoords.editItemAt(i).scale(scaleFactor); 524 } 525 } 526 527 #ifdef HAVE_ANDROID_OS 528 static inline float transformAngle(const SkMatrix* matrix, float angleRadians) { 529 // Construct and transform a vector oriented at the specified clockwise angle from vertical. 530 // Coordinate system: down is increasing Y, right is increasing X. 531 SkPoint vector; 532 vector.fX = SkFloatToScalar(sinf(angleRadians)); 533 vector.fY = SkFloatToScalar(-cosf(angleRadians)); 534 matrix->mapVectors(& vector, 1); 535 536 // Derive the transformed vector's clockwise angle from vertical. 537 float result = atan2f(SkScalarToFloat(vector.fX), SkScalarToFloat(-vector.fY)); 538 if (result < - M_PI_2) { 539 result += M_PI; 540 } else if (result > M_PI_2) { 541 result -= M_PI; 542 } 543 return result; 544 } 545 546 void MotionEvent::transform(const SkMatrix* matrix) { 547 float oldXOffset = mXOffset; 548 float oldYOffset = mYOffset; 549 550 // The tricky part of this implementation is to preserve the value of 551 // rawX and rawY. So we apply the transformation to the first point 552 // then derive an appropriate new X/Y offset that will preserve rawX and rawY. 553 SkPoint point; 554 float rawX = getRawX(0); 555 float rawY = getRawY(0); 556 matrix->mapXY(SkFloatToScalar(rawX + oldXOffset), SkFloatToScalar(rawY + oldYOffset), 557 & point); 558 float newX = SkScalarToFloat(point.fX); 559 float newY = SkScalarToFloat(point.fY); 560 float newXOffset = newX - rawX; 561 float newYOffset = newY - rawY; 562 563 mXOffset = newXOffset; 564 mYOffset = newYOffset; 565 566 // Apply the transformation to all samples. 567 size_t numSamples = mSamplePointerCoords.size(); 568 for (size_t i = 0; i < numSamples; i++) { 569 PointerCoords& c = mSamplePointerCoords.editItemAt(i); 570 float x = c.getAxisValue(AMOTION_EVENT_AXIS_X) + oldXOffset; 571 float y = c.getAxisValue(AMOTION_EVENT_AXIS_Y) + oldYOffset; 572 matrix->mapXY(SkFloatToScalar(x), SkFloatToScalar(y), &point); 573 c.setAxisValue(AMOTION_EVENT_AXIS_X, SkScalarToFloat(point.fX) - newXOffset); 574 c.setAxisValue(AMOTION_EVENT_AXIS_Y, SkScalarToFloat(point.fY) - newYOffset); 575 576 float orientation = c.getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION); 577 c.setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, transformAngle(matrix, orientation)); 578 } 579 } 580 581 status_t MotionEvent::readFromParcel(Parcel* parcel) { 582 size_t pointerCount = parcel->readInt32(); 583 size_t sampleCount = parcel->readInt32(); 584 if (pointerCount == 0 || pointerCount > MAX_POINTERS || sampleCount == 0) { 585 return BAD_VALUE; 586 } 587 588 mDeviceId = parcel->readInt32(); 589 mSource = parcel->readInt32(); 590 mAction = parcel->readInt32(); 591 mFlags = parcel->readInt32(); 592 mEdgeFlags = parcel->readInt32(); 593 mMetaState = parcel->readInt32(); 594 mButtonState = parcel->readInt32(); 595 mXOffset = parcel->readFloat(); 596 mYOffset = parcel->readFloat(); 597 mXPrecision = parcel->readFloat(); 598 mYPrecision = parcel->readFloat(); 599 mDownTime = parcel->readInt64(); 600 601 mPointerProperties.clear(); 602 mPointerProperties.setCapacity(pointerCount); 603 mSampleEventTimes.clear(); 604 mSampleEventTimes.setCapacity(sampleCount); 605 mSamplePointerCoords.clear(); 606 mSamplePointerCoords.setCapacity(sampleCount * pointerCount); 607 608 for (size_t i = 0; i < pointerCount; i++) { 609 mPointerProperties.push(); 610 PointerProperties& properties = mPointerProperties.editTop(); 611 properties.id = parcel->readInt32(); 612 properties.toolType = parcel->readInt32(); 613 } 614 615 while (sampleCount-- > 0) { 616 mSampleEventTimes.push(parcel->readInt64()); 617 for (size_t i = 0; i < pointerCount; i++) { 618 mSamplePointerCoords.push(); 619 status_t status = mSamplePointerCoords.editTop().readFromParcel(parcel); 620 if (status) { 621 return status; 622 } 623 } 624 } 625 return OK; 626 } 627 628 status_t MotionEvent::writeToParcel(Parcel* parcel) const { 629 size_t pointerCount = mPointerProperties.size(); 630 size_t sampleCount = mSampleEventTimes.size(); 631 632 parcel->writeInt32(pointerCount); 633 parcel->writeInt32(sampleCount); 634 635 parcel->writeInt32(mDeviceId); 636 parcel->writeInt32(mSource); 637 parcel->writeInt32(mAction); 638 parcel->writeInt32(mFlags); 639 parcel->writeInt32(mEdgeFlags); 640 parcel->writeInt32(mMetaState); 641 parcel->writeInt32(mButtonState); 642 parcel->writeFloat(mXOffset); 643 parcel->writeFloat(mYOffset); 644 parcel->writeFloat(mXPrecision); 645 parcel->writeFloat(mYPrecision); 646 parcel->writeInt64(mDownTime); 647 648 for (size_t i = 0; i < pointerCount; i++) { 649 const PointerProperties& properties = mPointerProperties.itemAt(i); 650 parcel->writeInt32(properties.id); 651 parcel->writeInt32(properties.toolType); 652 } 653 654 const PointerCoords* pc = mSamplePointerCoords.array(); 655 for (size_t h = 0; h < sampleCount; h++) { 656 parcel->writeInt64(mSampleEventTimes.itemAt(h)); 657 for (size_t i = 0; i < pointerCount; i++) { 658 status_t status = (pc++)->writeToParcel(parcel); 659 if (status) { 660 return status; 661 } 662 } 663 } 664 return OK; 665 } 666 #endif 667 668 bool MotionEvent::isTouchEvent(int32_t source, int32_t action) { 669 if (source & AINPUT_SOURCE_CLASS_POINTER) { 670 // Specifically excludes HOVER_MOVE and SCROLL. 671 switch (action & AMOTION_EVENT_ACTION_MASK) { 672 case AMOTION_EVENT_ACTION_DOWN: 673 case AMOTION_EVENT_ACTION_MOVE: 674 case AMOTION_EVENT_ACTION_UP: 675 case AMOTION_EVENT_ACTION_POINTER_DOWN: 676 case AMOTION_EVENT_ACTION_POINTER_UP: 677 case AMOTION_EVENT_ACTION_CANCEL: 678 case AMOTION_EVENT_ACTION_OUTSIDE: 679 return true; 680 } 681 } 682 return false; 683 } 684 685 686 // --- VelocityTracker --- 687 688 const uint32_t VelocityTracker::DEFAULT_DEGREE; 689 const nsecs_t VelocityTracker::DEFAULT_HORIZON; 690 const uint32_t VelocityTracker::HISTORY_SIZE; 691 692 static inline float vectorDot(const float* a, const float* b, uint32_t m) { 693 float r = 0; 694 while (m--) { 695 r += *(a++) * *(b++); 696 } 697 return r; 698 } 699 700 static inline float vectorNorm(const float* a, uint32_t m) { 701 float r = 0; 702 while (m--) { 703 float t = *(a++); 704 r += t * t; 705 } 706 return sqrtf(r); 707 } 708 709 #if DEBUG_LEAST_SQUARES || DEBUG_VELOCITY 710 static String8 vectorToString(const float* a, uint32_t m) { 711 String8 str; 712 str.append("["); 713 while (m--) { 714 str.appendFormat(" %f", *(a++)); 715 if (m) { 716 str.append(","); 717 } 718 } 719 str.append(" ]"); 720 return str; 721 } 722 723 static String8 matrixToString(const float* a, uint32_t m, uint32_t n, bool rowMajor) { 724 String8 str; 725 str.append("["); 726 for (size_t i = 0; i < m; i++) { 727 if (i) { 728 str.append(","); 729 } 730 str.append(" ["); 731 for (size_t j = 0; j < n; j++) { 732 if (j) { 733 str.append(","); 734 } 735 str.appendFormat(" %f", a[rowMajor ? i * n + j : j * m + i]); 736 } 737 str.append(" ]"); 738 } 739 str.append(" ]"); 740 return str; 741 } 742 #endif 743 744 VelocityTracker::VelocityTracker() { 745 clear(); 746 } 747 748 void VelocityTracker::clear() { 749 mIndex = 0; 750 mMovements[0].idBits.clear(); 751 mActivePointerId = -1; 752 } 753 754 void VelocityTracker::clearPointers(BitSet32 idBits) { 755 BitSet32 remainingIdBits(mMovements[mIndex].idBits.value & ~idBits.value); 756 mMovements[mIndex].idBits = remainingIdBits; 757 758 if (mActivePointerId >= 0 && idBits.hasBit(mActivePointerId)) { 759 mActivePointerId = !remainingIdBits.isEmpty() ? remainingIdBits.firstMarkedBit() : -1; 760 } 761 } 762 763 void VelocityTracker::addMovement(nsecs_t eventTime, BitSet32 idBits, const Position* positions) { 764 if (++mIndex == HISTORY_SIZE) { 765 mIndex = 0; 766 } 767 768 while (idBits.count() > MAX_POINTERS) { 769 idBits.clearLastMarkedBit(); 770 } 771 772 Movement& movement = mMovements[mIndex]; 773 movement.eventTime = eventTime; 774 movement.idBits = idBits; 775 uint32_t count = idBits.count(); 776 for (uint32_t i = 0; i < count; i++) { 777 movement.positions[i] = positions[i]; 778 } 779 780 if (mActivePointerId < 0 || !idBits.hasBit(mActivePointerId)) { 781 mActivePointerId = count != 0 ? idBits.firstMarkedBit() : -1; 782 } 783 784 #if DEBUG_VELOCITY 785 LOGD("VelocityTracker: addMovement eventTime=%lld, idBits=0x%08x, activePointerId=%d", 786 eventTime, idBits.value, mActivePointerId); 787 for (BitSet32 iterBits(idBits); !iterBits.isEmpty(); ) { 788 uint32_t id = iterBits.firstMarkedBit(); 789 uint32_t index = idBits.getIndexOfBit(id); 790 iterBits.clearBit(id); 791 Estimator estimator; 792 getEstimator(id, DEFAULT_DEGREE, DEFAULT_HORIZON, &estimator); 793 LOGD(" %d: position (%0.3f, %0.3f), " 794 "estimator (degree=%d, xCoeff=%s, yCoeff=%s, confidence=%f)", 795 id, positions[index].x, positions[index].y, 796 int(estimator.degree), 797 vectorToString(estimator.xCoeff, estimator.degree).string(), 798 vectorToString(estimator.yCoeff, estimator.degree).string(), 799 estimator.confidence); 800 } 801 #endif 802 } 803 804 void VelocityTracker::addMovement(const MotionEvent* event) { 805 int32_t actionMasked = event->getActionMasked(); 806 807 switch (actionMasked) { 808 case AMOTION_EVENT_ACTION_DOWN: 809 case AMOTION_EVENT_ACTION_HOVER_ENTER: 810 // Clear all pointers on down before adding the new movement. 811 clear(); 812 break; 813 case AMOTION_EVENT_ACTION_POINTER_DOWN: { 814 // Start a new movement trace for a pointer that just went down. 815 // We do this on down instead of on up because the client may want to query the 816 // final velocity for a pointer that just went up. 817 BitSet32 downIdBits; 818 downIdBits.markBit(event->getPointerId(event->getActionIndex())); 819 clearPointers(downIdBits); 820 break; 821 } 822 case AMOTION_EVENT_ACTION_MOVE: 823 case AMOTION_EVENT_ACTION_HOVER_MOVE: 824 break; 825 default: 826 // Ignore all other actions because they do not convey any new information about 827 // pointer movement. We also want to preserve the last known velocity of the pointers. 828 // Note that ACTION_UP and ACTION_POINTER_UP always report the last known position 829 // of the pointers that went up. ACTION_POINTER_UP does include the new position of 830 // pointers that remained down but we will also receive an ACTION_MOVE with this 831 // information if any of them actually moved. Since we don't know how many pointers 832 // will be going up at once it makes sense to just wait for the following ACTION_MOVE 833 // before adding the movement. 834 return; 835 } 836 837 size_t pointerCount = event->getPointerCount(); 838 if (pointerCount > MAX_POINTERS) { 839 pointerCount = MAX_POINTERS; 840 } 841 842 BitSet32 idBits; 843 for (size_t i = 0; i < pointerCount; i++) { 844 idBits.markBit(event->getPointerId(i)); 845 } 846 847 nsecs_t eventTime; 848 Position positions[pointerCount]; 849 850 size_t historySize = event->getHistorySize(); 851 for (size_t h = 0; h < historySize; h++) { 852 eventTime = event->getHistoricalEventTime(h); 853 for (size_t i = 0; i < pointerCount; i++) { 854 positions[i].x = event->getHistoricalX(i, h); 855 positions[i].y = event->getHistoricalY(i, h); 856 } 857 addMovement(eventTime, idBits, positions); 858 } 859 860 eventTime = event->getEventTime(); 861 for (size_t i = 0; i < pointerCount; i++) { 862 positions[i].x = event->getX(i); 863 positions[i].y = event->getY(i); 864 } 865 addMovement(eventTime, idBits, positions); 866 } 867 868 /** 869 * Solves a linear least squares problem to obtain a N degree polynomial that fits 870 * the specified input data as nearly as possible. 871 * 872 * Returns true if a solution is found, false otherwise. 873 * 874 * The input consists of two vectors of data points X and Y with indices 0..m-1. 875 * The output is a vector B with indices 0..n-1 that describes a polynomial 876 * that fits the data, such the sum of abs(Y[i] - (B[0] + B[1] X[i] + B[2] X[i]^2 ... B[n] X[i]^n)) 877 * for all i between 0 and m-1 is minimized. 878 * 879 * That is to say, the function that generated the input data can be approximated 880 * by y(x) ~= B[0] + B[1] x + B[2] x^2 + ... + B[n] x^n. 881 * 882 * The coefficient of determination (R^2) is also returned to describe the goodness 883 * of fit of the model for the given data. It is a value between 0 and 1, where 1 884 * indicates perfect correspondence. 885 * 886 * This function first expands the X vector to a m by n matrix A such that 887 * A[i][0] = 1, A[i][1] = X[i], A[i][2] = X[i]^2, ..., A[i][n] = X[i]^n. 888 * 889 * Then it calculates the QR decomposition of A yielding an m by m orthonormal matrix Q 890 * and an m by n upper triangular matrix R. Because R is upper triangular (lower 891 * part is all zeroes), we can simplify the decomposition into an m by n matrix 892 * Q1 and a n by n matrix R1 such that A = Q1 R1. 893 * 894 * Finally we solve the system of linear equations given by R1 B = (Qtranspose Y) 895 * to find B. 896 * 897 * For efficiency, we lay out A and Q column-wise in memory because we frequently 898 * operate on the column vectors. Conversely, we lay out R row-wise. 899 * 900 * http://en.wikipedia.org/wiki/Numerical_methods_for_linear_least_squares 901 * http://en.wikipedia.org/wiki/Gram-Schmidt 902 */ 903 static bool solveLeastSquares(const float* x, const float* y, uint32_t m, uint32_t n, 904 float* outB, float* outDet) { 905 #if DEBUG_LEAST_SQUARES 906 LOGD("solveLeastSquares: m=%d, n=%d, x=%s, y=%s", int(m), int(n), 907 vectorToString(x, m).string(), vectorToString(y, m).string()); 908 #endif 909 910 // Expand the X vector to a matrix A. 911 float a[n][m]; // column-major order 912 for (uint32_t h = 0; h < m; h++) { 913 a[0][h] = 1; 914 for (uint32_t i = 1; i < n; i++) { 915 a[i][h] = a[i - 1][h] * x[h]; 916 } 917 } 918 #if DEBUG_LEAST_SQUARES 919 LOGD(" - a=%s", matrixToString(&a[0][0], m, n, false /*rowMajor*/).string()); 920 #endif 921 922 // Apply the Gram-Schmidt process to A to obtain its QR decomposition. 923 float q[n][m]; // orthonormal basis, column-major order 924 float r[n][n]; // upper triangular matrix, row-major order 925 for (uint32_t j = 0; j < n; j++) { 926 for (uint32_t h = 0; h < m; h++) { 927 q[j][h] = a[j][h]; 928 } 929 for (uint32_t i = 0; i < j; i++) { 930 float dot = vectorDot(&q[j][0], &q[i][0], m); 931 for (uint32_t h = 0; h < m; h++) { 932 q[j][h] -= dot * q[i][h]; 933 } 934 } 935 936 float norm = vectorNorm(&q[j][0], m); 937 if (norm < 0.000001f) { 938 // vectors are linearly dependent or zero so no solution 939 #if DEBUG_LEAST_SQUARES 940 LOGD(" - no solution, norm=%f", norm); 941 #endif 942 return false; 943 } 944 945 float invNorm = 1.0f / norm; 946 for (uint32_t h = 0; h < m; h++) { 947 q[j][h] *= invNorm; 948 } 949 for (uint32_t i = 0; i < n; i++) { 950 r[j][i] = i < j ? 0 : vectorDot(&q[j][0], &a[i][0], m); 951 } 952 } 953 #if DEBUG_LEAST_SQUARES 954 LOGD(" - q=%s", matrixToString(&q[0][0], m, n, false /*rowMajor*/).string()); 955 LOGD(" - r=%s", matrixToString(&r[0][0], n, n, true /*rowMajor*/).string()); 956 957 // calculate QR, if we factored A correctly then QR should equal A 958 float qr[n][m]; 959 for (uint32_t h = 0; h < m; h++) { 960 for (uint32_t i = 0; i < n; i++) { 961 qr[i][h] = 0; 962 for (uint32_t j = 0; j < n; j++) { 963 qr[i][h] += q[j][h] * r[j][i]; 964 } 965 } 966 } 967 LOGD(" - qr=%s", matrixToString(&qr[0][0], m, n, false /*rowMajor*/).string()); 968 #endif 969 970 // Solve R B = Qt Y to find B. This is easy because R is upper triangular. 971 // We just work from bottom-right to top-left calculating B's coefficients. 972 for (uint32_t i = n; i-- != 0; ) { 973 outB[i] = vectorDot(&q[i][0], y, m); 974 for (uint32_t j = n - 1; j > i; j--) { 975 outB[i] -= r[i][j] * outB[j]; 976 } 977 outB[i] /= r[i][i]; 978 } 979 #if DEBUG_LEAST_SQUARES 980 LOGD(" - b=%s", vectorToString(outB, n).string()); 981 #endif 982 983 // Calculate the coefficient of determination as 1 - (SSerr / SStot) where 984 // SSerr is the residual sum of squares (squared variance of the error), 985 // and SStot is the total sum of squares (squared variance of the data). 986 float ymean = 0; 987 for (uint32_t h = 0; h < m; h++) { 988 ymean += y[h]; 989 } 990 ymean /= m; 991 992 float sserr = 0; 993 float sstot = 0; 994 for (uint32_t h = 0; h < m; h++) { 995 float err = y[h] - outB[0]; 996 float term = 1; 997 for (uint32_t i = 1; i < n; i++) { 998 term *= x[h]; 999 err -= term * outB[i]; 1000 } 1001 sserr += err * err; 1002 float var = y[h] - ymean; 1003 sstot += var * var; 1004 } 1005 *outDet = sstot > 0.000001f ? 1.0f - (sserr / sstot) : 1; 1006 #if DEBUG_LEAST_SQUARES 1007 LOGD(" - sserr=%f", sserr); 1008 LOGD(" - sstot=%f", sstot); 1009 LOGD(" - det=%f", *outDet); 1010 #endif 1011 return true; 1012 } 1013 1014 bool VelocityTracker::getVelocity(uint32_t id, float* outVx, float* outVy) const { 1015 Estimator estimator; 1016 if (getEstimator(id, DEFAULT_DEGREE, DEFAULT_HORIZON, &estimator)) { 1017 if (estimator.degree >= 1) { 1018 *outVx = estimator.xCoeff[1]; 1019 *outVy = estimator.yCoeff[1]; 1020 return true; 1021 } 1022 } 1023 *outVx = 0; 1024 *outVy = 0; 1025 return false; 1026 } 1027 1028 bool VelocityTracker::getEstimator(uint32_t id, uint32_t degree, nsecs_t horizon, 1029 Estimator* outEstimator) const { 1030 outEstimator->clear(); 1031 1032 // Iterate over movement samples in reverse time order and collect samples. 1033 float x[HISTORY_SIZE]; 1034 float y[HISTORY_SIZE]; 1035 float time[HISTORY_SIZE]; 1036 uint32_t m = 0; 1037 uint32_t index = mIndex; 1038 const Movement& newestMovement = mMovements[mIndex]; 1039 do { 1040 const Movement& movement = mMovements[index]; 1041 if (!movement.idBits.hasBit(id)) { 1042 break; 1043 } 1044 1045 nsecs_t age = newestMovement.eventTime - movement.eventTime; 1046 if (age > horizon) { 1047 break; 1048 } 1049 1050 const Position& position = movement.getPosition(id); 1051 x[m] = position.x; 1052 y[m] = position.y; 1053 time[m] = -age * 0.000000001f; 1054 index = (index == 0 ? HISTORY_SIZE : index) - 1; 1055 } while (++m < HISTORY_SIZE); 1056 1057 if (m == 0) { 1058 return false; // no data 1059 } 1060 1061 // Calculate a least squares polynomial fit. 1062 if (degree > Estimator::MAX_DEGREE) { 1063 degree = Estimator::MAX_DEGREE; 1064 } 1065 if (degree > m - 1) { 1066 degree = m - 1; 1067 } 1068 if (degree >= 1) { 1069 float xdet, ydet; 1070 uint32_t n = degree + 1; 1071 if (solveLeastSquares(time, x, m, n, outEstimator->xCoeff, &xdet) 1072 && solveLeastSquares(time, y, m, n, outEstimator->yCoeff, &ydet)) { 1073 outEstimator->degree = degree; 1074 outEstimator->confidence = xdet * ydet; 1075 #if DEBUG_LEAST_SQUARES 1076 LOGD("estimate: degree=%d, xCoeff=%s, yCoeff=%s, confidence=%f", 1077 int(outEstimator->degree), 1078 vectorToString(outEstimator->xCoeff, n).string(), 1079 vectorToString(outEstimator->yCoeff, n).string(), 1080 outEstimator->confidence); 1081 #endif 1082 return true; 1083 } 1084 } 1085 1086 // No velocity data available for this pointer, but we do have its current position. 1087 outEstimator->xCoeff[0] = x[0]; 1088 outEstimator->yCoeff[0] = y[0]; 1089 outEstimator->degree = 0; 1090 outEstimator->confidence = 1; 1091 return true; 1092 } 1093 1094 1095 // --- VelocityControl --- 1096 1097 const nsecs_t VelocityControl::STOP_TIME; 1098 1099 VelocityControl::VelocityControl() { 1100 reset(); 1101 } 1102 1103 void VelocityControl::setParameters(const VelocityControlParameters& parameters) { 1104 mParameters = parameters; 1105 reset(); 1106 } 1107 1108 void VelocityControl::reset() { 1109 mLastMovementTime = LLONG_MIN; 1110 mRawPosition.x = 0; 1111 mRawPosition.y = 0; 1112 mVelocityTracker.clear(); 1113 } 1114 1115 void VelocityControl::move(nsecs_t eventTime, float* deltaX, float* deltaY) { 1116 if ((deltaX && *deltaX) || (deltaY && *deltaY)) { 1117 if (eventTime >= mLastMovementTime + STOP_TIME) { 1118 #if DEBUG_ACCELERATION 1119 LOGD("VelocityControl: stopped, last movement was %0.3fms ago", 1120 (eventTime - mLastMovementTime) * 0.000001f); 1121 #endif 1122 reset(); 1123 } 1124 1125 mLastMovementTime = eventTime; 1126 if (deltaX) { 1127 mRawPosition.x += *deltaX; 1128 } 1129 if (deltaY) { 1130 mRawPosition.y += *deltaY; 1131 } 1132 mVelocityTracker.addMovement(eventTime, BitSet32(BitSet32::valueForBit(0)), &mRawPosition); 1133 1134 float vx, vy; 1135 float scale = mParameters.scale; 1136 if (mVelocityTracker.getVelocity(0, &vx, &vy)) { 1137 float speed = hypotf(vx, vy) * scale; 1138 if (speed >= mParameters.highThreshold) { 1139 // Apply full acceleration above the high speed threshold. 1140 scale *= mParameters.acceleration; 1141 } else if (speed > mParameters.lowThreshold) { 1142 // Linearly interpolate the acceleration to apply between the low and high 1143 // speed thresholds. 1144 scale *= 1 + (speed - mParameters.lowThreshold) 1145 / (mParameters.highThreshold - mParameters.lowThreshold) 1146 * (mParameters.acceleration - 1); 1147 } 1148 1149 #if DEBUG_ACCELERATION 1150 LOGD("VelocityControl(%0.3f, %0.3f, %0.3f, %0.3f): " 1151 "vx=%0.3f, vy=%0.3f, speed=%0.3f, accel=%0.3f", 1152 mParameters.scale, mParameters.lowThreshold, mParameters.highThreshold, 1153 mParameters.acceleration, 1154 vx, vy, speed, scale / mParameters.scale); 1155 #endif 1156 } else { 1157 #if DEBUG_ACCELERATION 1158 LOGD("VelocityControl(%0.3f, %0.3f, %0.3f, %0.3f): unknown velocity", 1159 mParameters.scale, mParameters.lowThreshold, mParameters.highThreshold, 1160 mParameters.acceleration); 1161 #endif 1162 } 1163 1164 if (deltaX) { 1165 *deltaX *= scale; 1166 } 1167 if (deltaY) { 1168 *deltaY *= scale; 1169 } 1170 } 1171 } 1172 1173 1174 // --- InputDeviceInfo --- 1175 1176 InputDeviceInfo::InputDeviceInfo() { 1177 initialize(-1, String8("uninitialized device info")); 1178 } 1179 1180 InputDeviceInfo::InputDeviceInfo(const InputDeviceInfo& other) : 1181 mId(other.mId), mName(other.mName), mSources(other.mSources), 1182 mKeyboardType(other.mKeyboardType), 1183 mMotionRanges(other.mMotionRanges) { 1184 } 1185 1186 InputDeviceInfo::~InputDeviceInfo() { 1187 } 1188 1189 void InputDeviceInfo::initialize(int32_t id, const String8& name) { 1190 mId = id; 1191 mName = name; 1192 mSources = 0; 1193 mKeyboardType = AINPUT_KEYBOARD_TYPE_NONE; 1194 mMotionRanges.clear(); 1195 } 1196 1197 const InputDeviceInfo::MotionRange* InputDeviceInfo::getMotionRange( 1198 int32_t axis, uint32_t source) const { 1199 size_t numRanges = mMotionRanges.size(); 1200 for (size_t i = 0; i < numRanges; i++) { 1201 const MotionRange& range = mMotionRanges.itemAt(i); 1202 if (range.axis == axis && range.source == source) { 1203 return ⦥ 1204 } 1205 } 1206 return NULL; 1207 } 1208 1209 void InputDeviceInfo::addSource(uint32_t source) { 1210 mSources |= source; 1211 } 1212 1213 void InputDeviceInfo::addMotionRange(int32_t axis, uint32_t source, float min, float max, 1214 float flat, float fuzz) { 1215 MotionRange range = { axis, source, min, max, flat, fuzz }; 1216 mMotionRanges.add(range); 1217 } 1218 1219 void InputDeviceInfo::addMotionRange(const MotionRange& range) { 1220 mMotionRanges.add(range); 1221 } 1222 1223 } // namespace android 1224