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 "InputManager-JNI" 18 19 //#define LOG_NDEBUG 0 20 21 // Log debug messages about InputReaderPolicy 22 #define DEBUG_INPUT_READER_POLICY 0 23 24 // Log debug messages about InputDispatcherPolicy 25 #define DEBUG_INPUT_DISPATCHER_POLICY 0 26 27 28 #include "JNIHelp.h" 29 #include "jni.h" 30 #include <atomic> 31 #include <cinttypes> 32 #include <limits.h> 33 #include <android_runtime/AndroidRuntime.h> 34 #include <android_runtime/Log.h> 35 36 #include <utils/Log.h> 37 #include <utils/Looper.h> 38 #include <utils/threads.h> 39 40 #include <input/PointerController.h> 41 #include <input/SpriteController.h> 42 43 #include <inputflinger/InputManager.h> 44 45 #include <android_os_MessageQueue.h> 46 #include <android_view_InputDevice.h> 47 #include <android_view_KeyEvent.h> 48 #include <android_view_MotionEvent.h> 49 #include <android_view_InputChannel.h> 50 #include <android_view_PointerIcon.h> 51 #include <android/graphics/GraphicsJNI.h> 52 53 #include <ScopedLocalRef.h> 54 #include <ScopedPrimitiveArray.h> 55 #include <ScopedUtfChars.h> 56 57 #include "com_android_server_power_PowerManagerService.h" 58 #include "com_android_server_input_InputApplicationHandle.h" 59 #include "com_android_server_input_InputWindowHandle.h" 60 61 #define INDENT " " 62 63 namespace android { 64 65 // The exponent used to calculate the pointer speed scaling factor. 66 // The scaling factor is calculated as 2 ^ (speed * exponent), 67 // where the speed ranges from -7 to + 7 and is supplied by the user. 68 static const float POINTER_SPEED_EXPONENT = 1.0f / 4; 69 70 static struct { 71 jmethodID notifyConfigurationChanged; 72 jmethodID notifyInputDevicesChanged; 73 jmethodID notifySwitch; 74 jmethodID notifyInputChannelBroken; 75 jmethodID notifyANR; 76 jmethodID filterInputEvent; 77 jmethodID interceptKeyBeforeQueueing; 78 jmethodID interceptMotionBeforeQueueingNonInteractive; 79 jmethodID interceptKeyBeforeDispatching; 80 jmethodID dispatchUnhandledKey; 81 jmethodID checkInjectEventsPermission; 82 jmethodID getVirtualKeyQuietTimeMillis; 83 jmethodID getExcludedDeviceNames; 84 jmethodID getKeyRepeatTimeout; 85 jmethodID getKeyRepeatDelay; 86 jmethodID getHoverTapTimeout; 87 jmethodID getHoverTapSlop; 88 jmethodID getDoubleTapTimeout; 89 jmethodID getLongPressTimeout; 90 jmethodID getPointerLayer; 91 jmethodID getPointerIcon; 92 jmethodID getKeyboardLayoutOverlay; 93 jmethodID getDeviceAlias; 94 jmethodID getTouchCalibrationForInputDevice; 95 } gServiceClassInfo; 96 97 static struct { 98 jclass clazz; 99 } gInputDeviceClassInfo; 100 101 static struct { 102 jclass clazz; 103 } gKeyEventClassInfo; 104 105 static struct { 106 jclass clazz; 107 } gMotionEventClassInfo; 108 109 static struct { 110 jclass clazz; 111 jmethodID constructor; 112 } gInputDeviceIdentifierInfo; 113 114 static struct { 115 jclass clazz; 116 jmethodID getAffineTransform; 117 } gTouchCalibrationClassInfo; 118 119 120 121 // --- Global functions --- 122 123 template<typename T> 124 inline static T min(const T& a, const T& b) { 125 return a < b ? a : b; 126 } 127 128 template<typename T> 129 inline static T max(const T& a, const T& b) { 130 return a > b ? a : b; 131 } 132 133 static inline const char* toString(bool value) { 134 return value ? "true" : "false"; 135 } 136 137 static jobject getInputApplicationHandleObjLocalRef(JNIEnv* env, 138 const sp<InputApplicationHandle>& inputApplicationHandle) { 139 if (inputApplicationHandle == NULL) { 140 return NULL; 141 } 142 return static_cast<NativeInputApplicationHandle*>(inputApplicationHandle.get())-> 143 getInputApplicationHandleObjLocalRef(env); 144 } 145 146 static jobject getInputWindowHandleObjLocalRef(JNIEnv* env, 147 const sp<InputWindowHandle>& inputWindowHandle) { 148 if (inputWindowHandle == NULL) { 149 return NULL; 150 } 151 return static_cast<NativeInputWindowHandle*>(inputWindowHandle.get())-> 152 getInputWindowHandleObjLocalRef(env); 153 } 154 155 static void loadSystemIconAsSpriteWithPointerIcon(JNIEnv* env, jobject contextObj, int32_t style, 156 PointerIcon* outPointerIcon, SpriteIcon* outSpriteIcon) { 157 status_t status = android_view_PointerIcon_loadSystemIcon(env, 158 contextObj, style, outPointerIcon); 159 if (!status) { 160 outPointerIcon->bitmap.copyTo(&outSpriteIcon->bitmap, kN32_SkColorType); 161 outSpriteIcon->hotSpotX = outPointerIcon->hotSpotX; 162 outSpriteIcon->hotSpotY = outPointerIcon->hotSpotY; 163 } 164 } 165 166 static void loadSystemIconAsSprite(JNIEnv* env, jobject contextObj, int32_t style, 167 SpriteIcon* outSpriteIcon) { 168 PointerIcon pointerIcon; 169 loadSystemIconAsSpriteWithPointerIcon(env, contextObj, style, &pointerIcon, outSpriteIcon); 170 } 171 172 enum { 173 WM_ACTION_PASS_TO_USER = 1, 174 }; 175 176 177 // --- NativeInputManager --- 178 179 class NativeInputManager : public virtual RefBase, 180 public virtual InputReaderPolicyInterface, 181 public virtual InputDispatcherPolicyInterface, 182 public virtual PointerControllerPolicyInterface { 183 protected: 184 virtual ~NativeInputManager(); 185 186 public: 187 NativeInputManager(jobject contextObj, jobject serviceObj, const sp<Looper>& looper); 188 189 inline sp<InputManager> getInputManager() const { return mInputManager; } 190 191 void dump(String8& dump); 192 193 void setDisplayViewport(bool external, const DisplayViewport& viewport); 194 195 status_t registerInputChannel(JNIEnv* env, const sp<InputChannel>& inputChannel, 196 const sp<InputWindowHandle>& inputWindowHandle, bool monitor); 197 status_t unregisterInputChannel(JNIEnv* env, const sp<InputChannel>& inputChannel); 198 199 void setInputWindows(JNIEnv* env, jobjectArray windowHandleObjArray); 200 void setFocusedApplication(JNIEnv* env, jobject applicationHandleObj); 201 void setInputDispatchMode(bool enabled, bool frozen); 202 void setSystemUiVisibility(int32_t visibility); 203 void setPointerSpeed(int32_t speed); 204 void setShowTouches(bool enabled); 205 void setInteractive(bool interactive); 206 void reloadCalibration(); 207 void setPointerIconType(int32_t iconId); 208 void reloadPointerIcons(); 209 void setCustomPointerIcon(const SpriteIcon& icon); 210 211 /* --- InputReaderPolicyInterface implementation --- */ 212 213 virtual void getReaderConfiguration(InputReaderConfiguration* outConfig); 214 virtual sp<PointerControllerInterface> obtainPointerController(int32_t deviceId); 215 virtual void notifyInputDevicesChanged(const Vector<InputDeviceInfo>& inputDevices); 216 virtual sp<KeyCharacterMap> getKeyboardLayoutOverlay(const InputDeviceIdentifier& identifier); 217 virtual String8 getDeviceAlias(const InputDeviceIdentifier& identifier); 218 virtual TouchAffineTransformation getTouchAffineTransformation(JNIEnv *env, 219 jfloatArray matrixArr); 220 virtual TouchAffineTransformation getTouchAffineTransformation( 221 const String8& inputDeviceDescriptor, int32_t surfaceRotation); 222 223 /* --- InputDispatcherPolicyInterface implementation --- */ 224 225 virtual void notifySwitch(nsecs_t when, uint32_t switchValues, uint32_t switchMask, 226 uint32_t policyFlags); 227 virtual void notifyConfigurationChanged(nsecs_t when); 228 virtual nsecs_t notifyANR(const sp<InputApplicationHandle>& inputApplicationHandle, 229 const sp<InputWindowHandle>& inputWindowHandle, 230 const String8& reason); 231 virtual void notifyInputChannelBroken(const sp<InputWindowHandle>& inputWindowHandle); 232 virtual bool filterInputEvent(const InputEvent* inputEvent, uint32_t policyFlags); 233 virtual void getDispatcherConfiguration(InputDispatcherConfiguration* outConfig); 234 virtual void interceptKeyBeforeQueueing(const KeyEvent* keyEvent, uint32_t& policyFlags); 235 virtual void interceptMotionBeforeQueueing(nsecs_t when, uint32_t& policyFlags); 236 virtual nsecs_t interceptKeyBeforeDispatching( 237 const sp<InputWindowHandle>& inputWindowHandle, 238 const KeyEvent* keyEvent, uint32_t policyFlags); 239 virtual bool dispatchUnhandledKey(const sp<InputWindowHandle>& inputWindowHandle, 240 const KeyEvent* keyEvent, uint32_t policyFlags, KeyEvent* outFallbackKeyEvent); 241 virtual void pokeUserActivity(nsecs_t eventTime, int32_t eventType); 242 virtual bool checkInjectEventsPermissionNonReentrant( 243 int32_t injectorPid, int32_t injectorUid); 244 245 /* --- PointerControllerPolicyInterface implementation --- */ 246 247 virtual void loadPointerIcon(SpriteIcon* icon); 248 virtual void loadPointerResources(PointerResources* outResources); 249 virtual void loadAdditionalMouseResources(std::map<int32_t, SpriteIcon>* outResources, 250 std::map<int32_t, PointerAnimation>* outAnimationResources); 251 virtual int32_t getDefaultPointerIconId(); 252 virtual int32_t getCustomPointerIconId(); 253 254 private: 255 sp<InputManager> mInputManager; 256 257 jobject mContextObj; 258 jobject mServiceObj; 259 sp<Looper> mLooper; 260 261 Mutex mLock; 262 struct Locked { 263 // Display size information. 264 DisplayViewport internalViewport; 265 DisplayViewport externalViewport; 266 267 // System UI visibility. 268 int32_t systemUiVisibility; 269 270 // Pointer speed. 271 int32_t pointerSpeed; 272 273 // True if pointer gestures are enabled. 274 bool pointerGesturesEnabled; 275 276 // Show touches feature enable/disable. 277 bool showTouches; 278 279 // Sprite controller singleton, created on first use. 280 sp<SpriteController> spriteController; 281 282 // Pointer controller singleton, created and destroyed as needed. 283 wp<PointerController> pointerController; 284 } mLocked; 285 286 std::atomic<bool> mInteractive; 287 288 void updateInactivityTimeoutLocked(const sp<PointerController>& controller); 289 void handleInterceptActions(jint wmActions, nsecs_t when, uint32_t& policyFlags); 290 void ensureSpriteControllerLocked(); 291 292 static bool checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName); 293 294 static inline JNIEnv* jniEnv() { 295 return AndroidRuntime::getJNIEnv(); 296 } 297 }; 298 299 300 301 NativeInputManager::NativeInputManager(jobject contextObj, 302 jobject serviceObj, const sp<Looper>& looper) : 303 mLooper(looper), mInteractive(true) { 304 JNIEnv* env = jniEnv(); 305 306 mContextObj = env->NewGlobalRef(contextObj); 307 mServiceObj = env->NewGlobalRef(serviceObj); 308 309 { 310 AutoMutex _l(mLock); 311 mLocked.systemUiVisibility = ASYSTEM_UI_VISIBILITY_STATUS_BAR_VISIBLE; 312 mLocked.pointerSpeed = 0; 313 mLocked.pointerGesturesEnabled = true; 314 mLocked.showTouches = false; 315 } 316 mInteractive = true; 317 318 sp<EventHub> eventHub = new EventHub(); 319 mInputManager = new InputManager(eventHub, this, this); 320 } 321 322 NativeInputManager::~NativeInputManager() { 323 JNIEnv* env = jniEnv(); 324 325 env->DeleteGlobalRef(mContextObj); 326 env->DeleteGlobalRef(mServiceObj); 327 } 328 329 void NativeInputManager::dump(String8& dump) { 330 dump.append("Input Manager State:\n"); 331 { 332 dump.appendFormat(INDENT "Interactive: %s\n", toString(mInteractive.load())); 333 } 334 { 335 AutoMutex _l(mLock); 336 dump.appendFormat(INDENT "System UI Visibility: 0x%0" PRIx32 "\n", 337 mLocked.systemUiVisibility); 338 dump.appendFormat(INDENT "Pointer Speed: %" PRId32 "\n", mLocked.pointerSpeed); 339 dump.appendFormat(INDENT "Pointer Gestures Enabled: %s\n", 340 toString(mLocked.pointerGesturesEnabled)); 341 dump.appendFormat(INDENT "Show Touches: %s\n", toString(mLocked.showTouches)); 342 } 343 dump.append("\n"); 344 345 mInputManager->getReader()->dump(dump); 346 dump.append("\n"); 347 348 mInputManager->getDispatcher()->dump(dump); 349 dump.append("\n"); 350 } 351 352 bool NativeInputManager::checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName) { 353 if (env->ExceptionCheck()) { 354 ALOGE("An exception was thrown by callback '%s'.", methodName); 355 LOGE_EX(env); 356 env->ExceptionClear(); 357 return true; 358 } 359 return false; 360 } 361 362 void NativeInputManager::setDisplayViewport(bool external, const DisplayViewport& viewport) { 363 bool changed = false; 364 { 365 AutoMutex _l(mLock); 366 367 DisplayViewport& v = external ? mLocked.externalViewport : mLocked.internalViewport; 368 if (v != viewport) { 369 changed = true; 370 v = viewport; 371 372 if (!external) { 373 sp<PointerController> controller = mLocked.pointerController.promote(); 374 if (controller != NULL) { 375 controller->setDisplayViewport( 376 viewport.logicalRight - viewport.logicalLeft, 377 viewport.logicalBottom - viewport.logicalTop, 378 viewport.orientation); 379 } 380 } 381 } 382 } 383 384 if (changed) { 385 mInputManager->getReader()->requestRefreshConfiguration( 386 InputReaderConfiguration::CHANGE_DISPLAY_INFO); 387 } 388 } 389 390 status_t NativeInputManager::registerInputChannel(JNIEnv* /* env */, 391 const sp<InputChannel>& inputChannel, 392 const sp<InputWindowHandle>& inputWindowHandle, bool monitor) { 393 return mInputManager->getDispatcher()->registerInputChannel( 394 inputChannel, inputWindowHandle, monitor); 395 } 396 397 status_t NativeInputManager::unregisterInputChannel(JNIEnv* /* env */, 398 const sp<InputChannel>& inputChannel) { 399 return mInputManager->getDispatcher()->unregisterInputChannel(inputChannel); 400 } 401 402 void NativeInputManager::getReaderConfiguration(InputReaderConfiguration* outConfig) { 403 JNIEnv* env = jniEnv(); 404 405 jint virtualKeyQuietTime = env->CallIntMethod(mServiceObj, 406 gServiceClassInfo.getVirtualKeyQuietTimeMillis); 407 if (!checkAndClearExceptionFromCallback(env, "getVirtualKeyQuietTimeMillis")) { 408 outConfig->virtualKeyQuietTime = milliseconds_to_nanoseconds(virtualKeyQuietTime); 409 } 410 411 outConfig->excludedDeviceNames.clear(); 412 jobjectArray excludedDeviceNames = jobjectArray(env->CallObjectMethod(mServiceObj, 413 gServiceClassInfo.getExcludedDeviceNames)); 414 if (!checkAndClearExceptionFromCallback(env, "getExcludedDeviceNames") && excludedDeviceNames) { 415 jsize length = env->GetArrayLength(excludedDeviceNames); 416 for (jsize i = 0; i < length; i++) { 417 jstring item = jstring(env->GetObjectArrayElement(excludedDeviceNames, i)); 418 const char* deviceNameChars = env->GetStringUTFChars(item, NULL); 419 outConfig->excludedDeviceNames.add(String8(deviceNameChars)); 420 env->ReleaseStringUTFChars(item, deviceNameChars); 421 env->DeleteLocalRef(item); 422 } 423 env->DeleteLocalRef(excludedDeviceNames); 424 } 425 426 jint hoverTapTimeout = env->CallIntMethod(mServiceObj, 427 gServiceClassInfo.getHoverTapTimeout); 428 if (!checkAndClearExceptionFromCallback(env, "getHoverTapTimeout")) { 429 jint doubleTapTimeout = env->CallIntMethod(mServiceObj, 430 gServiceClassInfo.getDoubleTapTimeout); 431 if (!checkAndClearExceptionFromCallback(env, "getDoubleTapTimeout")) { 432 jint longPressTimeout = env->CallIntMethod(mServiceObj, 433 gServiceClassInfo.getLongPressTimeout); 434 if (!checkAndClearExceptionFromCallback(env, "getLongPressTimeout")) { 435 outConfig->pointerGestureTapInterval = milliseconds_to_nanoseconds(hoverTapTimeout); 436 437 // We must ensure that the tap-drag interval is significantly shorter than 438 // the long-press timeout because the tap is held down for the entire duration 439 // of the double-tap timeout. 440 jint tapDragInterval = max(min(longPressTimeout - 100, 441 doubleTapTimeout), hoverTapTimeout); 442 outConfig->pointerGestureTapDragInterval = 443 milliseconds_to_nanoseconds(tapDragInterval); 444 } 445 } 446 } 447 448 jint hoverTapSlop = env->CallIntMethod(mServiceObj, 449 gServiceClassInfo.getHoverTapSlop); 450 if (!checkAndClearExceptionFromCallback(env, "getHoverTapSlop")) { 451 outConfig->pointerGestureTapSlop = hoverTapSlop; 452 } 453 454 { // acquire lock 455 AutoMutex _l(mLock); 456 457 outConfig->pointerVelocityControlParameters.scale = exp2f(mLocked.pointerSpeed 458 * POINTER_SPEED_EXPONENT); 459 outConfig->pointerGesturesEnabled = mLocked.pointerGesturesEnabled; 460 461 outConfig->showTouches = mLocked.showTouches; 462 463 outConfig->setDisplayInfo(false /*external*/, mLocked.internalViewport); 464 outConfig->setDisplayInfo(true /*external*/, mLocked.externalViewport); 465 } // release lock 466 } 467 468 sp<PointerControllerInterface> NativeInputManager::obtainPointerController(int32_t /* deviceId */) { 469 AutoMutex _l(mLock); 470 471 sp<PointerController> controller = mLocked.pointerController.promote(); 472 if (controller == NULL) { 473 ensureSpriteControllerLocked(); 474 475 controller = new PointerController(this, mLooper, mLocked.spriteController); 476 mLocked.pointerController = controller; 477 478 DisplayViewport& v = mLocked.internalViewport; 479 controller->setDisplayViewport( 480 v.logicalRight - v.logicalLeft, 481 v.logicalBottom - v.logicalTop, 482 v.orientation); 483 484 updateInactivityTimeoutLocked(controller); 485 } 486 return controller; 487 } 488 489 void NativeInputManager::ensureSpriteControllerLocked() { 490 if (mLocked.spriteController == NULL) { 491 JNIEnv* env = jniEnv(); 492 jint layer = env->CallIntMethod(mServiceObj, gServiceClassInfo.getPointerLayer); 493 if (checkAndClearExceptionFromCallback(env, "getPointerLayer")) { 494 layer = -1; 495 } 496 mLocked.spriteController = new SpriteController(mLooper, layer); 497 } 498 } 499 500 void NativeInputManager::notifyInputDevicesChanged(const Vector<InputDeviceInfo>& inputDevices) { 501 JNIEnv* env = jniEnv(); 502 503 size_t count = inputDevices.size(); 504 jobjectArray inputDevicesObjArray = env->NewObjectArray( 505 count, gInputDeviceClassInfo.clazz, NULL); 506 if (inputDevicesObjArray) { 507 bool error = false; 508 for (size_t i = 0; i < count; i++) { 509 jobject inputDeviceObj = android_view_InputDevice_create(env, inputDevices.itemAt(i)); 510 if (!inputDeviceObj) { 511 error = true; 512 break; 513 } 514 515 env->SetObjectArrayElement(inputDevicesObjArray, i, inputDeviceObj); 516 env->DeleteLocalRef(inputDeviceObj); 517 } 518 519 if (!error) { 520 env->CallVoidMethod(mServiceObj, gServiceClassInfo.notifyInputDevicesChanged, 521 inputDevicesObjArray); 522 } 523 524 env->DeleteLocalRef(inputDevicesObjArray); 525 } 526 527 checkAndClearExceptionFromCallback(env, "notifyInputDevicesChanged"); 528 } 529 530 sp<KeyCharacterMap> NativeInputManager::getKeyboardLayoutOverlay( 531 const InputDeviceIdentifier& identifier) { 532 JNIEnv* env = jniEnv(); 533 534 sp<KeyCharacterMap> result; 535 ScopedLocalRef<jstring> descriptor(env, env->NewStringUTF(identifier.descriptor.string())); 536 ScopedLocalRef<jobject> identifierObj(env, env->NewObject(gInputDeviceIdentifierInfo.clazz, 537 gInputDeviceIdentifierInfo.constructor, descriptor.get(), 538 identifier.vendor, identifier.product)); 539 ScopedLocalRef<jobjectArray> arrayObj(env, jobjectArray(env->CallObjectMethod(mServiceObj, 540 gServiceClassInfo.getKeyboardLayoutOverlay, identifierObj.get()))); 541 if (arrayObj.get()) { 542 ScopedLocalRef<jstring> filenameObj(env, 543 jstring(env->GetObjectArrayElement(arrayObj.get(), 0))); 544 ScopedLocalRef<jstring> contentsObj(env, 545 jstring(env->GetObjectArrayElement(arrayObj.get(), 1))); 546 ScopedUtfChars filenameChars(env, filenameObj.get()); 547 ScopedUtfChars contentsChars(env, contentsObj.get()); 548 549 KeyCharacterMap::loadContents(String8(filenameChars.c_str()), 550 String8(contentsChars.c_str()), KeyCharacterMap::FORMAT_OVERLAY, &result); 551 } 552 checkAndClearExceptionFromCallback(env, "getKeyboardLayoutOverlay"); 553 return result; 554 } 555 556 String8 NativeInputManager::getDeviceAlias(const InputDeviceIdentifier& identifier) { 557 JNIEnv* env = jniEnv(); 558 559 ScopedLocalRef<jstring> uniqueIdObj(env, env->NewStringUTF(identifier.uniqueId.string())); 560 ScopedLocalRef<jstring> aliasObj(env, jstring(env->CallObjectMethod(mServiceObj, 561 gServiceClassInfo.getDeviceAlias, uniqueIdObj.get()))); 562 String8 result; 563 if (aliasObj.get()) { 564 ScopedUtfChars aliasChars(env, aliasObj.get()); 565 result.setTo(aliasChars.c_str()); 566 } 567 checkAndClearExceptionFromCallback(env, "getDeviceAlias"); 568 return result; 569 } 570 571 void NativeInputManager::notifySwitch(nsecs_t when, 572 uint32_t switchValues, uint32_t switchMask, uint32_t /* policyFlags */) { 573 #if DEBUG_INPUT_DISPATCHER_POLICY 574 ALOGD("notifySwitch - when=%lld, switchValues=0x%08x, switchMask=0x%08x, policyFlags=0x%x", 575 when, switchValues, switchMask, policyFlags); 576 #endif 577 578 JNIEnv* env = jniEnv(); 579 580 env->CallVoidMethod(mServiceObj, gServiceClassInfo.notifySwitch, 581 when, switchValues, switchMask); 582 checkAndClearExceptionFromCallback(env, "notifySwitch"); 583 } 584 585 void NativeInputManager::notifyConfigurationChanged(nsecs_t when) { 586 #if DEBUG_INPUT_DISPATCHER_POLICY 587 ALOGD("notifyConfigurationChanged - when=%lld", when); 588 #endif 589 590 JNIEnv* env = jniEnv(); 591 592 env->CallVoidMethod(mServiceObj, gServiceClassInfo.notifyConfigurationChanged, when); 593 checkAndClearExceptionFromCallback(env, "notifyConfigurationChanged"); 594 } 595 596 nsecs_t NativeInputManager::notifyANR(const sp<InputApplicationHandle>& inputApplicationHandle, 597 const sp<InputWindowHandle>& inputWindowHandle, const String8& reason) { 598 #if DEBUG_INPUT_DISPATCHER_POLICY 599 ALOGD("notifyANR"); 600 #endif 601 602 JNIEnv* env = jniEnv(); 603 604 jobject inputApplicationHandleObj = 605 getInputApplicationHandleObjLocalRef(env, inputApplicationHandle); 606 jobject inputWindowHandleObj = 607 getInputWindowHandleObjLocalRef(env, inputWindowHandle); 608 jstring reasonObj = env->NewStringUTF(reason.string()); 609 610 jlong newTimeout = env->CallLongMethod(mServiceObj, 611 gServiceClassInfo.notifyANR, inputApplicationHandleObj, inputWindowHandleObj, 612 reasonObj); 613 if (checkAndClearExceptionFromCallback(env, "notifyANR")) { 614 newTimeout = 0; // abort dispatch 615 } else { 616 assert(newTimeout >= 0); 617 } 618 619 env->DeleteLocalRef(reasonObj); 620 env->DeleteLocalRef(inputWindowHandleObj); 621 env->DeleteLocalRef(inputApplicationHandleObj); 622 return newTimeout; 623 } 624 625 void NativeInputManager::notifyInputChannelBroken(const sp<InputWindowHandle>& inputWindowHandle) { 626 #if DEBUG_INPUT_DISPATCHER_POLICY 627 ALOGD("notifyInputChannelBroken"); 628 #endif 629 630 JNIEnv* env = jniEnv(); 631 632 jobject inputWindowHandleObj = 633 getInputWindowHandleObjLocalRef(env, inputWindowHandle); 634 if (inputWindowHandleObj) { 635 env->CallVoidMethod(mServiceObj, gServiceClassInfo.notifyInputChannelBroken, 636 inputWindowHandleObj); 637 checkAndClearExceptionFromCallback(env, "notifyInputChannelBroken"); 638 639 env->DeleteLocalRef(inputWindowHandleObj); 640 } 641 } 642 643 void NativeInputManager::getDispatcherConfiguration(InputDispatcherConfiguration* outConfig) { 644 JNIEnv* env = jniEnv(); 645 646 jint keyRepeatTimeout = env->CallIntMethod(mServiceObj, 647 gServiceClassInfo.getKeyRepeatTimeout); 648 if (!checkAndClearExceptionFromCallback(env, "getKeyRepeatTimeout")) { 649 outConfig->keyRepeatTimeout = milliseconds_to_nanoseconds(keyRepeatTimeout); 650 } 651 652 jint keyRepeatDelay = env->CallIntMethod(mServiceObj, 653 gServiceClassInfo.getKeyRepeatDelay); 654 if (!checkAndClearExceptionFromCallback(env, "getKeyRepeatDelay")) { 655 outConfig->keyRepeatDelay = milliseconds_to_nanoseconds(keyRepeatDelay); 656 } 657 } 658 659 void NativeInputManager::setInputWindows(JNIEnv* env, jobjectArray windowHandleObjArray) { 660 Vector<sp<InputWindowHandle> > windowHandles; 661 662 if (windowHandleObjArray) { 663 jsize length = env->GetArrayLength(windowHandleObjArray); 664 for (jsize i = 0; i < length; i++) { 665 jobject windowHandleObj = env->GetObjectArrayElement(windowHandleObjArray, i); 666 if (! windowHandleObj) { 667 break; // found null element indicating end of used portion of the array 668 } 669 670 sp<InputWindowHandle> windowHandle = 671 android_server_InputWindowHandle_getHandle(env, windowHandleObj); 672 if (windowHandle != NULL) { 673 windowHandles.push(windowHandle); 674 } 675 env->DeleteLocalRef(windowHandleObj); 676 } 677 } 678 679 mInputManager->getDispatcher()->setInputWindows(windowHandles); 680 681 // Do this after the dispatcher has updated the window handle state. 682 bool newPointerGesturesEnabled = true; 683 size_t numWindows = windowHandles.size(); 684 for (size_t i = 0; i < numWindows; i++) { 685 const sp<InputWindowHandle>& windowHandle = windowHandles.itemAt(i); 686 const InputWindowInfo* windowInfo = windowHandle->getInfo(); 687 if (windowInfo && windowInfo->hasFocus && (windowInfo->inputFeatures 688 & InputWindowInfo::INPUT_FEATURE_DISABLE_TOUCH_PAD_GESTURES)) { 689 newPointerGesturesEnabled = false; 690 } 691 } 692 693 uint32_t changes = 0; 694 { // acquire lock 695 AutoMutex _l(mLock); 696 697 if (mLocked.pointerGesturesEnabled != newPointerGesturesEnabled) { 698 mLocked.pointerGesturesEnabled = newPointerGesturesEnabled; 699 changes |= InputReaderConfiguration::CHANGE_POINTER_GESTURE_ENABLEMENT; 700 } 701 } // release lock 702 703 if (changes) { 704 mInputManager->getReader()->requestRefreshConfiguration(changes); 705 } 706 } 707 708 void NativeInputManager::setFocusedApplication(JNIEnv* env, jobject applicationHandleObj) { 709 sp<InputApplicationHandle> applicationHandle = 710 android_server_InputApplicationHandle_getHandle(env, applicationHandleObj); 711 mInputManager->getDispatcher()->setFocusedApplication(applicationHandle); 712 } 713 714 void NativeInputManager::setInputDispatchMode(bool enabled, bool frozen) { 715 mInputManager->getDispatcher()->setInputDispatchMode(enabled, frozen); 716 } 717 718 void NativeInputManager::setSystemUiVisibility(int32_t visibility) { 719 AutoMutex _l(mLock); 720 721 if (mLocked.systemUiVisibility != visibility) { 722 mLocked.systemUiVisibility = visibility; 723 724 sp<PointerController> controller = mLocked.pointerController.promote(); 725 if (controller != NULL) { 726 updateInactivityTimeoutLocked(controller); 727 } 728 } 729 } 730 731 void NativeInputManager::updateInactivityTimeoutLocked(const sp<PointerController>& controller) { 732 bool lightsOut = mLocked.systemUiVisibility & ASYSTEM_UI_VISIBILITY_STATUS_BAR_HIDDEN; 733 controller->setInactivityTimeout(lightsOut 734 ? PointerController::INACTIVITY_TIMEOUT_SHORT 735 : PointerController::INACTIVITY_TIMEOUT_NORMAL); 736 } 737 738 void NativeInputManager::setPointerSpeed(int32_t speed) { 739 { // acquire lock 740 AutoMutex _l(mLock); 741 742 if (mLocked.pointerSpeed == speed) { 743 return; 744 } 745 746 ALOGI("Setting pointer speed to %d.", speed); 747 mLocked.pointerSpeed = speed; 748 } // release lock 749 750 mInputManager->getReader()->requestRefreshConfiguration( 751 InputReaderConfiguration::CHANGE_POINTER_SPEED); 752 } 753 754 void NativeInputManager::setShowTouches(bool enabled) { 755 { // acquire lock 756 AutoMutex _l(mLock); 757 758 if (mLocked.showTouches == enabled) { 759 return; 760 } 761 762 ALOGI("Setting show touches feature to %s.", enabled ? "enabled" : "disabled"); 763 mLocked.showTouches = enabled; 764 } // release lock 765 766 mInputManager->getReader()->requestRefreshConfiguration( 767 InputReaderConfiguration::CHANGE_SHOW_TOUCHES); 768 } 769 770 void NativeInputManager::setInteractive(bool interactive) { 771 mInteractive = interactive; 772 } 773 774 void NativeInputManager::reloadCalibration() { 775 mInputManager->getReader()->requestRefreshConfiguration( 776 InputReaderConfiguration::CHANGE_TOUCH_AFFINE_TRANSFORMATION); 777 } 778 779 void NativeInputManager::setPointerIconType(int32_t iconId) { 780 AutoMutex _l(mLock); 781 sp<PointerController> controller = mLocked.pointerController.promote(); 782 if (controller != NULL) { 783 controller->updatePointerIcon(iconId); 784 } 785 } 786 787 void NativeInputManager::reloadPointerIcons() { 788 AutoMutex _l(mLock); 789 sp<PointerController> controller = mLocked.pointerController.promote(); 790 if (controller != NULL) { 791 controller->reloadPointerResources(); 792 } 793 } 794 795 void NativeInputManager::setCustomPointerIcon(const SpriteIcon& icon) { 796 AutoMutex _l(mLock); 797 sp<PointerController> controller = mLocked.pointerController.promote(); 798 if (controller != NULL) { 799 controller->setCustomPointerIcon(icon); 800 } 801 } 802 803 TouchAffineTransformation NativeInputManager::getTouchAffineTransformation( 804 JNIEnv *env, jfloatArray matrixArr) { 805 ScopedFloatArrayRO matrix(env, matrixArr); 806 assert(matrix.size() == 6); 807 808 TouchAffineTransformation transform; 809 transform.x_scale = matrix[0]; 810 transform.x_ymix = matrix[1]; 811 transform.x_offset = matrix[2]; 812 transform.y_xmix = matrix[3]; 813 transform.y_scale = matrix[4]; 814 transform.y_offset = matrix[5]; 815 816 return transform; 817 } 818 819 TouchAffineTransformation NativeInputManager::getTouchAffineTransformation( 820 const String8& inputDeviceDescriptor, int32_t surfaceRotation) { 821 JNIEnv* env = jniEnv(); 822 823 ScopedLocalRef<jstring> descriptorObj(env, env->NewStringUTF(inputDeviceDescriptor.string())); 824 825 jobject cal = env->CallObjectMethod(mServiceObj, 826 gServiceClassInfo.getTouchCalibrationForInputDevice, descriptorObj.get(), 827 surfaceRotation); 828 829 jfloatArray matrixArr = jfloatArray(env->CallObjectMethod(cal, 830 gTouchCalibrationClassInfo.getAffineTransform)); 831 832 TouchAffineTransformation transform = getTouchAffineTransformation(env, matrixArr); 833 834 env->DeleteLocalRef(matrixArr); 835 env->DeleteLocalRef(cal); 836 837 return transform; 838 } 839 840 bool NativeInputManager::filterInputEvent(const InputEvent* inputEvent, uint32_t policyFlags) { 841 jobject inputEventObj; 842 843 JNIEnv* env = jniEnv(); 844 switch (inputEvent->getType()) { 845 case AINPUT_EVENT_TYPE_KEY: 846 inputEventObj = android_view_KeyEvent_fromNative(env, 847 static_cast<const KeyEvent*>(inputEvent)); 848 break; 849 case AINPUT_EVENT_TYPE_MOTION: 850 inputEventObj = android_view_MotionEvent_obtainAsCopy(env, 851 static_cast<const MotionEvent*>(inputEvent)); 852 break; 853 default: 854 return true; // dispatch the event normally 855 } 856 857 if (!inputEventObj) { 858 ALOGE("Failed to obtain input event object for filterInputEvent."); 859 return true; // dispatch the event normally 860 } 861 862 // The callee is responsible for recycling the event. 863 jboolean pass = env->CallBooleanMethod(mServiceObj, gServiceClassInfo.filterInputEvent, 864 inputEventObj, policyFlags); 865 if (checkAndClearExceptionFromCallback(env, "filterInputEvent")) { 866 pass = true; 867 } 868 env->DeleteLocalRef(inputEventObj); 869 return pass; 870 } 871 872 void NativeInputManager::interceptKeyBeforeQueueing(const KeyEvent* keyEvent, 873 uint32_t& policyFlags) { 874 // Policy: 875 // - Ignore untrusted events and pass them along. 876 // - Ask the window manager what to do with normal events and trusted injected events. 877 // - For normal events wake and brighten the screen if currently off or dim. 878 bool interactive = mInteractive.load(); 879 if (interactive) { 880 policyFlags |= POLICY_FLAG_INTERACTIVE; 881 } 882 if ((policyFlags & POLICY_FLAG_TRUSTED)) { 883 nsecs_t when = keyEvent->getEventTime(); 884 JNIEnv* env = jniEnv(); 885 jobject keyEventObj = android_view_KeyEvent_fromNative(env, keyEvent); 886 jint wmActions; 887 if (keyEventObj) { 888 wmActions = env->CallIntMethod(mServiceObj, 889 gServiceClassInfo.interceptKeyBeforeQueueing, 890 keyEventObj, policyFlags); 891 if (checkAndClearExceptionFromCallback(env, "interceptKeyBeforeQueueing")) { 892 wmActions = 0; 893 } 894 android_view_KeyEvent_recycle(env, keyEventObj); 895 env->DeleteLocalRef(keyEventObj); 896 } else { 897 ALOGE("Failed to obtain key event object for interceptKeyBeforeQueueing."); 898 wmActions = 0; 899 } 900 901 handleInterceptActions(wmActions, when, /*byref*/ policyFlags); 902 } else { 903 if (interactive) { 904 policyFlags |= POLICY_FLAG_PASS_TO_USER; 905 } 906 } 907 } 908 909 void NativeInputManager::interceptMotionBeforeQueueing(nsecs_t when, uint32_t& policyFlags) { 910 // Policy: 911 // - Ignore untrusted events and pass them along. 912 // - No special filtering for injected events required at this time. 913 // - Filter normal events based on screen state. 914 // - For normal events brighten (but do not wake) the screen if currently dim. 915 bool interactive = mInteractive.load(); 916 if (interactive) { 917 policyFlags |= POLICY_FLAG_INTERACTIVE; 918 } 919 if ((policyFlags & POLICY_FLAG_TRUSTED) && !(policyFlags & POLICY_FLAG_INJECTED)) { 920 if (policyFlags & POLICY_FLAG_INTERACTIVE) { 921 policyFlags |= POLICY_FLAG_PASS_TO_USER; 922 } else { 923 JNIEnv* env = jniEnv(); 924 jint wmActions = env->CallIntMethod(mServiceObj, 925 gServiceClassInfo.interceptMotionBeforeQueueingNonInteractive, 926 when, policyFlags); 927 if (checkAndClearExceptionFromCallback(env, 928 "interceptMotionBeforeQueueingNonInteractive")) { 929 wmActions = 0; 930 } 931 932 handleInterceptActions(wmActions, when, /*byref*/ policyFlags); 933 } 934 } else { 935 if (interactive) { 936 policyFlags |= POLICY_FLAG_PASS_TO_USER; 937 } 938 } 939 } 940 941 void NativeInputManager::handleInterceptActions(jint wmActions, nsecs_t when, 942 uint32_t& policyFlags) { 943 if (wmActions & WM_ACTION_PASS_TO_USER) { 944 policyFlags |= POLICY_FLAG_PASS_TO_USER; 945 } else { 946 #if DEBUG_INPUT_DISPATCHER_POLICY 947 ALOGD("handleInterceptActions: Not passing key to user."); 948 #endif 949 } 950 } 951 952 nsecs_t NativeInputManager::interceptKeyBeforeDispatching( 953 const sp<InputWindowHandle>& inputWindowHandle, 954 const KeyEvent* keyEvent, uint32_t policyFlags) { 955 // Policy: 956 // - Ignore untrusted events and pass them along. 957 // - Filter normal events and trusted injected events through the window manager policy to 958 // handle the HOME key and the like. 959 nsecs_t result = 0; 960 if (policyFlags & POLICY_FLAG_TRUSTED) { 961 JNIEnv* env = jniEnv(); 962 963 // Note: inputWindowHandle may be null. 964 jobject inputWindowHandleObj = getInputWindowHandleObjLocalRef(env, inputWindowHandle); 965 jobject keyEventObj = android_view_KeyEvent_fromNative(env, keyEvent); 966 if (keyEventObj) { 967 jlong delayMillis = env->CallLongMethod(mServiceObj, 968 gServiceClassInfo.interceptKeyBeforeDispatching, 969 inputWindowHandleObj, keyEventObj, policyFlags); 970 bool error = checkAndClearExceptionFromCallback(env, "interceptKeyBeforeDispatching"); 971 android_view_KeyEvent_recycle(env, keyEventObj); 972 env->DeleteLocalRef(keyEventObj); 973 if (!error) { 974 if (delayMillis < 0) { 975 result = -1; 976 } else if (delayMillis > 0) { 977 result = milliseconds_to_nanoseconds(delayMillis); 978 } 979 } 980 } else { 981 ALOGE("Failed to obtain key event object for interceptKeyBeforeDispatching."); 982 } 983 env->DeleteLocalRef(inputWindowHandleObj); 984 } 985 return result; 986 } 987 988 bool NativeInputManager::dispatchUnhandledKey(const sp<InputWindowHandle>& inputWindowHandle, 989 const KeyEvent* keyEvent, uint32_t policyFlags, KeyEvent* outFallbackKeyEvent) { 990 // Policy: 991 // - Ignore untrusted events and do not perform default handling. 992 bool result = false; 993 if (policyFlags & POLICY_FLAG_TRUSTED) { 994 JNIEnv* env = jniEnv(); 995 996 // Note: inputWindowHandle may be null. 997 jobject inputWindowHandleObj = getInputWindowHandleObjLocalRef(env, inputWindowHandle); 998 jobject keyEventObj = android_view_KeyEvent_fromNative(env, keyEvent); 999 if (keyEventObj) { 1000 jobject fallbackKeyEventObj = env->CallObjectMethod(mServiceObj, 1001 gServiceClassInfo.dispatchUnhandledKey, 1002 inputWindowHandleObj, keyEventObj, policyFlags); 1003 if (checkAndClearExceptionFromCallback(env, "dispatchUnhandledKey")) { 1004 fallbackKeyEventObj = NULL; 1005 } 1006 android_view_KeyEvent_recycle(env, keyEventObj); 1007 env->DeleteLocalRef(keyEventObj); 1008 1009 if (fallbackKeyEventObj) { 1010 // Note: outFallbackKeyEvent may be the same object as keyEvent. 1011 if (!android_view_KeyEvent_toNative(env, fallbackKeyEventObj, 1012 outFallbackKeyEvent)) { 1013 result = true; 1014 } 1015 android_view_KeyEvent_recycle(env, fallbackKeyEventObj); 1016 env->DeleteLocalRef(fallbackKeyEventObj); 1017 } 1018 } else { 1019 ALOGE("Failed to obtain key event object for dispatchUnhandledKey."); 1020 } 1021 env->DeleteLocalRef(inputWindowHandleObj); 1022 } 1023 return result; 1024 } 1025 1026 void NativeInputManager::pokeUserActivity(nsecs_t eventTime, int32_t eventType) { 1027 android_server_PowerManagerService_userActivity(eventTime, eventType); 1028 } 1029 1030 1031 bool NativeInputManager::checkInjectEventsPermissionNonReentrant( 1032 int32_t injectorPid, int32_t injectorUid) { 1033 JNIEnv* env = jniEnv(); 1034 jboolean result = env->CallBooleanMethod(mServiceObj, 1035 gServiceClassInfo.checkInjectEventsPermission, injectorPid, injectorUid); 1036 if (checkAndClearExceptionFromCallback(env, "checkInjectEventsPermission")) { 1037 result = false; 1038 } 1039 return result; 1040 } 1041 1042 void NativeInputManager::loadPointerIcon(SpriteIcon* icon) { 1043 JNIEnv* env = jniEnv(); 1044 1045 ScopedLocalRef<jobject> pointerIconObj(env, env->CallObjectMethod( 1046 mServiceObj, gServiceClassInfo.getPointerIcon)); 1047 if (checkAndClearExceptionFromCallback(env, "getPointerIcon")) { 1048 return; 1049 } 1050 1051 PointerIcon pointerIcon; 1052 status_t status = android_view_PointerIcon_load(env, pointerIconObj.get(), 1053 mContextObj, &pointerIcon); 1054 if (!status && !pointerIcon.isNullIcon()) { 1055 *icon = SpriteIcon(pointerIcon.bitmap, pointerIcon.hotSpotX, pointerIcon.hotSpotY); 1056 } else { 1057 *icon = SpriteIcon(); 1058 } 1059 } 1060 1061 void NativeInputManager::loadPointerResources(PointerResources* outResources) { 1062 JNIEnv* env = jniEnv(); 1063 1064 loadSystemIconAsSprite(env, mContextObj, POINTER_ICON_STYLE_SPOT_HOVER, 1065 &outResources->spotHover); 1066 loadSystemIconAsSprite(env, mContextObj, POINTER_ICON_STYLE_SPOT_TOUCH, 1067 &outResources->spotTouch); 1068 loadSystemIconAsSprite(env, mContextObj, POINTER_ICON_STYLE_SPOT_ANCHOR, 1069 &outResources->spotAnchor); 1070 } 1071 1072 void NativeInputManager::loadAdditionalMouseResources(std::map<int32_t, SpriteIcon>* outResources, 1073 std::map<int32_t, PointerAnimation>* outAnimationResources) { 1074 JNIEnv* env = jniEnv(); 1075 1076 for (int iconId = POINTER_ICON_STYLE_CONTEXT_MENU; iconId <= POINTER_ICON_STYLE_GRABBING; 1077 ++iconId) { 1078 PointerIcon pointerIcon; 1079 loadSystemIconAsSpriteWithPointerIcon( 1080 env, mContextObj, iconId, &pointerIcon, &((*outResources)[iconId])); 1081 if (!pointerIcon.bitmapFrames.empty()) { 1082 PointerAnimation& animationData = (*outAnimationResources)[iconId]; 1083 size_t numFrames = pointerIcon.bitmapFrames.size() + 1; 1084 animationData.durationPerFrame = 1085 milliseconds_to_nanoseconds(pointerIcon.durationPerFrame); 1086 animationData.animationFrames.reserve(numFrames); 1087 animationData.animationFrames.push_back(SpriteIcon( 1088 pointerIcon.bitmap, pointerIcon.hotSpotX, pointerIcon.hotSpotY)); 1089 for (size_t i = 0; i < numFrames - 1; ++i) { 1090 animationData.animationFrames.push_back(SpriteIcon( 1091 pointerIcon.bitmapFrames[i], pointerIcon.hotSpotX, pointerIcon.hotSpotY)); 1092 } 1093 } 1094 } 1095 loadSystemIconAsSprite(env, mContextObj, POINTER_ICON_STYLE_NULL, 1096 &((*outResources)[POINTER_ICON_STYLE_NULL])); 1097 } 1098 1099 int32_t NativeInputManager::getDefaultPointerIconId() { 1100 return POINTER_ICON_STYLE_ARROW; 1101 } 1102 1103 int32_t NativeInputManager::getCustomPointerIconId() { 1104 return POINTER_ICON_STYLE_CUSTOM; 1105 } 1106 1107 // ---------------------------------------------------------------------------- 1108 1109 static jlong nativeInit(JNIEnv* env, jclass /* clazz */, 1110 jobject serviceObj, jobject contextObj, jobject messageQueueObj) { 1111 sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueObj); 1112 if (messageQueue == NULL) { 1113 jniThrowRuntimeException(env, "MessageQueue is not initialized."); 1114 return 0; 1115 } 1116 1117 NativeInputManager* im = new NativeInputManager(contextObj, serviceObj, 1118 messageQueue->getLooper()); 1119 im->incStrong(0); 1120 return reinterpret_cast<jlong>(im); 1121 } 1122 1123 static void nativeStart(JNIEnv* env, jclass /* clazz */, jlong ptr) { 1124 NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); 1125 1126 status_t result = im->getInputManager()->start(); 1127 if (result) { 1128 jniThrowRuntimeException(env, "Input manager could not be started."); 1129 } 1130 } 1131 1132 static void nativeSetDisplayViewport(JNIEnv* /* env */, jclass /* clazz */, jlong ptr, 1133 jboolean external, jint displayId, jint orientation, 1134 jint logicalLeft, jint logicalTop, jint logicalRight, jint logicalBottom, 1135 jint physicalLeft, jint physicalTop, jint physicalRight, jint physicalBottom, 1136 jint deviceWidth, jint deviceHeight) { 1137 NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); 1138 1139 DisplayViewport v; 1140 v.displayId = displayId; 1141 v.orientation = orientation; 1142 v.logicalLeft = logicalLeft; 1143 v.logicalTop = logicalTop; 1144 v.logicalRight = logicalRight; 1145 v.logicalBottom = logicalBottom; 1146 v.physicalLeft = physicalLeft; 1147 v.physicalTop = physicalTop; 1148 v.physicalRight = physicalRight; 1149 v.physicalBottom = physicalBottom; 1150 v.deviceWidth = deviceWidth; 1151 v.deviceHeight = deviceHeight; 1152 im->setDisplayViewport(external, v); 1153 } 1154 1155 static jint nativeGetScanCodeState(JNIEnv* /* env */, jclass /* clazz */, 1156 jlong ptr, jint deviceId, jint sourceMask, jint scanCode) { 1157 NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); 1158 1159 return (jint) im->getInputManager()->getReader()->getScanCodeState( 1160 deviceId, uint32_t(sourceMask), scanCode); 1161 } 1162 1163 static jint nativeGetKeyCodeState(JNIEnv* /* env */, jclass /* clazz */, 1164 jlong ptr, jint deviceId, jint sourceMask, jint keyCode) { 1165 NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); 1166 1167 return (jint) im->getInputManager()->getReader()->getKeyCodeState( 1168 deviceId, uint32_t(sourceMask), keyCode); 1169 } 1170 1171 static jint nativeGetSwitchState(JNIEnv* /* env */, jclass /* clazz */, 1172 jlong ptr, jint deviceId, jint sourceMask, jint sw) { 1173 NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); 1174 1175 return (jint) im->getInputManager()->getReader()->getSwitchState( 1176 deviceId, uint32_t(sourceMask), sw); 1177 } 1178 1179 static jboolean nativeHasKeys(JNIEnv* env, jclass /* clazz */, 1180 jlong ptr, jint deviceId, jint sourceMask, jintArray keyCodes, jbooleanArray outFlags) { 1181 NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); 1182 1183 int32_t* codes = env->GetIntArrayElements(keyCodes, NULL); 1184 uint8_t* flags = env->GetBooleanArrayElements(outFlags, NULL); 1185 jsize numCodes = env->GetArrayLength(keyCodes); 1186 jboolean result; 1187 if (numCodes == env->GetArrayLength(keyCodes)) { 1188 if (im->getInputManager()->getReader()->hasKeys( 1189 deviceId, uint32_t(sourceMask), numCodes, codes, flags)) { 1190 result = JNI_TRUE; 1191 } else { 1192 result = JNI_FALSE; 1193 } 1194 } else { 1195 result = JNI_FALSE; 1196 } 1197 1198 env->ReleaseBooleanArrayElements(outFlags, flags, 0); 1199 env->ReleaseIntArrayElements(keyCodes, codes, 0); 1200 return result; 1201 } 1202 1203 static void throwInputChannelNotInitialized(JNIEnv* env) { 1204 jniThrowException(env, "java/lang/IllegalStateException", 1205 "inputChannel is not initialized"); 1206 } 1207 1208 static void handleInputChannelDisposed(JNIEnv* env, 1209 jobject /* inputChannelObj */, const sp<InputChannel>& inputChannel, void* data) { 1210 NativeInputManager* im = static_cast<NativeInputManager*>(data); 1211 1212 ALOGW("Input channel object '%s' was disposed without first being unregistered with " 1213 "the input manager!", inputChannel->getName().string()); 1214 im->unregisterInputChannel(env, inputChannel); 1215 } 1216 1217 static void nativeRegisterInputChannel(JNIEnv* env, jclass /* clazz */, 1218 jlong ptr, jobject inputChannelObj, jobject inputWindowHandleObj, jboolean monitor) { 1219 NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); 1220 1221 sp<InputChannel> inputChannel = android_view_InputChannel_getInputChannel(env, 1222 inputChannelObj); 1223 if (inputChannel == NULL) { 1224 throwInputChannelNotInitialized(env); 1225 return; 1226 } 1227 1228 sp<InputWindowHandle> inputWindowHandle = 1229 android_server_InputWindowHandle_getHandle(env, inputWindowHandleObj); 1230 1231 status_t status = im->registerInputChannel( 1232 env, inputChannel, inputWindowHandle, monitor); 1233 if (status) { 1234 String8 message; 1235 message.appendFormat("Failed to register input channel. status=%d", status); 1236 jniThrowRuntimeException(env, message.string()); 1237 return; 1238 } 1239 1240 if (! monitor) { 1241 android_view_InputChannel_setDisposeCallback(env, inputChannelObj, 1242 handleInputChannelDisposed, im); 1243 } 1244 } 1245 1246 static void nativeUnregisterInputChannel(JNIEnv* env, jclass /* clazz */, 1247 jlong ptr, jobject inputChannelObj) { 1248 NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); 1249 1250 sp<InputChannel> inputChannel = android_view_InputChannel_getInputChannel(env, 1251 inputChannelObj); 1252 if (inputChannel == NULL) { 1253 throwInputChannelNotInitialized(env); 1254 return; 1255 } 1256 1257 android_view_InputChannel_setDisposeCallback(env, inputChannelObj, NULL, NULL); 1258 1259 status_t status = im->unregisterInputChannel(env, inputChannel); 1260 if (status && status != BAD_VALUE) { // ignore already unregistered channel 1261 String8 message; 1262 message.appendFormat("Failed to unregister input channel. status=%d", status); 1263 jniThrowRuntimeException(env, message.string()); 1264 } 1265 } 1266 1267 static void nativeSetInputFilterEnabled(JNIEnv* /* env */, jclass /* clazz */, 1268 jlong ptr, jboolean enabled) { 1269 NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); 1270 1271 im->getInputManager()->getDispatcher()->setInputFilterEnabled(enabled); 1272 } 1273 1274 static jint nativeInjectInputEvent(JNIEnv* env, jclass /* clazz */, 1275 jlong ptr, jobject inputEventObj, jint displayId, jint injectorPid, jint injectorUid, 1276 jint syncMode, jint timeoutMillis, jint policyFlags) { 1277 NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); 1278 1279 if (env->IsInstanceOf(inputEventObj, gKeyEventClassInfo.clazz)) { 1280 KeyEvent keyEvent; 1281 status_t status = android_view_KeyEvent_toNative(env, inputEventObj, & keyEvent); 1282 if (status) { 1283 jniThrowRuntimeException(env, "Could not read contents of KeyEvent object."); 1284 return INPUT_EVENT_INJECTION_FAILED; 1285 } 1286 1287 return (jint) im->getInputManager()->getDispatcher()->injectInputEvent( 1288 & keyEvent, displayId, injectorPid, injectorUid, syncMode, timeoutMillis, 1289 uint32_t(policyFlags)); 1290 } else if (env->IsInstanceOf(inputEventObj, gMotionEventClassInfo.clazz)) { 1291 const MotionEvent* motionEvent = android_view_MotionEvent_getNativePtr(env, inputEventObj); 1292 if (!motionEvent) { 1293 jniThrowRuntimeException(env, "Could not read contents of MotionEvent object."); 1294 return INPUT_EVENT_INJECTION_FAILED; 1295 } 1296 1297 return (jint) im->getInputManager()->getDispatcher()->injectInputEvent( 1298 motionEvent, displayId, injectorPid, injectorUid, syncMode, timeoutMillis, 1299 uint32_t(policyFlags)); 1300 } else { 1301 jniThrowRuntimeException(env, "Invalid input event type."); 1302 return INPUT_EVENT_INJECTION_FAILED; 1303 } 1304 } 1305 1306 static void nativeToggleCapsLock(JNIEnv* env, jclass /* clazz */, 1307 jlong ptr, jint deviceId) { 1308 NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); 1309 im->getInputManager()->getReader()->toggleCapsLockState(deviceId); 1310 } 1311 1312 static void nativeSetInputWindows(JNIEnv* env, jclass /* clazz */, 1313 jlong ptr, jobjectArray windowHandleObjArray) { 1314 NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); 1315 1316 im->setInputWindows(env, windowHandleObjArray); 1317 } 1318 1319 static void nativeSetFocusedApplication(JNIEnv* env, jclass /* clazz */, 1320 jlong ptr, jobject applicationHandleObj) { 1321 NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); 1322 1323 im->setFocusedApplication(env, applicationHandleObj); 1324 } 1325 1326 static void nativeSetInputDispatchMode(JNIEnv* /* env */, 1327 jclass /* clazz */, jlong ptr, jboolean enabled, jboolean frozen) { 1328 NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); 1329 1330 im->setInputDispatchMode(enabled, frozen); 1331 } 1332 1333 static void nativeSetSystemUiVisibility(JNIEnv* /* env */, 1334 jclass /* clazz */, jlong ptr, jint visibility) { 1335 NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); 1336 1337 im->setSystemUiVisibility(visibility); 1338 } 1339 1340 static jboolean nativeTransferTouchFocus(JNIEnv* env, 1341 jclass /* clazz */, jlong ptr, jobject fromChannelObj, jobject toChannelObj) { 1342 NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); 1343 1344 sp<InputChannel> fromChannel = 1345 android_view_InputChannel_getInputChannel(env, fromChannelObj); 1346 sp<InputChannel> toChannel = 1347 android_view_InputChannel_getInputChannel(env, toChannelObj); 1348 1349 if (fromChannel == NULL || toChannel == NULL) { 1350 return JNI_FALSE; 1351 } 1352 1353 if (im->getInputManager()->getDispatcher()-> 1354 transferTouchFocus(fromChannel, toChannel)) { 1355 return JNI_TRUE; 1356 } else { 1357 return JNI_FALSE; 1358 } 1359 } 1360 1361 static void nativeSetPointerSpeed(JNIEnv* /* env */, 1362 jclass /* clazz */, jlong ptr, jint speed) { 1363 NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); 1364 1365 im->setPointerSpeed(speed); 1366 } 1367 1368 static void nativeSetShowTouches(JNIEnv* /* env */, 1369 jclass /* clazz */, jlong ptr, jboolean enabled) { 1370 NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); 1371 1372 im->setShowTouches(enabled); 1373 } 1374 1375 static void nativeSetInteractive(JNIEnv* env, 1376 jclass clazz, jlong ptr, jboolean interactive) { 1377 NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); 1378 1379 im->setInteractive(interactive); 1380 } 1381 1382 static void nativeReloadCalibration(JNIEnv* env, jclass clazz, jlong ptr) { 1383 NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); 1384 im->reloadCalibration(); 1385 } 1386 1387 static void nativeVibrate(JNIEnv* env, 1388 jclass /* clazz */, jlong ptr, jint deviceId, jlongArray patternObj, 1389 jint repeat, jint token) { 1390 NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); 1391 1392 size_t patternSize = env->GetArrayLength(patternObj); 1393 if (patternSize > MAX_VIBRATE_PATTERN_SIZE) { 1394 ALOGI("Skipped requested vibration because the pattern size is %zu " 1395 "which is more than the maximum supported size of %d.", 1396 patternSize, MAX_VIBRATE_PATTERN_SIZE); 1397 return; // limit to reasonable size 1398 } 1399 1400 jlong* patternMillis = static_cast<jlong*>(env->GetPrimitiveArrayCritical( 1401 patternObj, NULL)); 1402 nsecs_t pattern[patternSize]; 1403 for (size_t i = 0; i < patternSize; i++) { 1404 pattern[i] = max(jlong(0), min(patternMillis[i], 1405 (jlong)(MAX_VIBRATE_PATTERN_DELAY_NSECS / 1000000LL))) * 1000000LL; 1406 } 1407 env->ReleasePrimitiveArrayCritical(patternObj, patternMillis, JNI_ABORT); 1408 1409 im->getInputManager()->getReader()->vibrate(deviceId, pattern, patternSize, repeat, token); 1410 } 1411 1412 static void nativeCancelVibrate(JNIEnv* /* env */, 1413 jclass /* clazz */, jlong ptr, jint deviceId, jint token) { 1414 NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); 1415 1416 im->getInputManager()->getReader()->cancelVibrate(deviceId, token); 1417 } 1418 1419 static void nativeReloadKeyboardLayouts(JNIEnv* /* env */, 1420 jclass /* clazz */, jlong ptr) { 1421 NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); 1422 1423 im->getInputManager()->getReader()->requestRefreshConfiguration( 1424 InputReaderConfiguration::CHANGE_KEYBOARD_LAYOUTS); 1425 } 1426 1427 static void nativeReloadDeviceAliases(JNIEnv* /* env */, 1428 jclass /* clazz */, jlong ptr) { 1429 NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); 1430 1431 im->getInputManager()->getReader()->requestRefreshConfiguration( 1432 InputReaderConfiguration::CHANGE_DEVICE_ALIAS); 1433 } 1434 1435 static jstring nativeDump(JNIEnv* env, jclass /* clazz */, jlong ptr) { 1436 NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); 1437 1438 String8 dump; 1439 im->dump(dump); 1440 return env->NewStringUTF(dump.string()); 1441 } 1442 1443 static void nativeMonitor(JNIEnv* /* env */, jclass /* clazz */, jlong ptr) { 1444 NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); 1445 1446 im->getInputManager()->getReader()->monitor(); 1447 im->getInputManager()->getDispatcher()->monitor(); 1448 } 1449 1450 static void nativeSetPointerIconType(JNIEnv* /* env */, jclass /* clazz */, jlong ptr, jint iconId) { 1451 NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); 1452 im->setPointerIconType(iconId); 1453 } 1454 1455 static void nativeReloadPointerIcons(JNIEnv* /* env */, jclass /* clazz */, jlong ptr) { 1456 NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); 1457 im->reloadPointerIcons(); 1458 } 1459 1460 static void nativeSetCustomPointerIcon(JNIEnv* env, jclass /* clazz */, 1461 jlong ptr, jobject iconObj) { 1462 NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); 1463 1464 PointerIcon pointerIcon; 1465 android_view_PointerIcon_getLoadedIcon(env, iconObj, &pointerIcon); 1466 1467 SpriteIcon spriteIcon; 1468 pointerIcon.bitmap.copyTo(&spriteIcon.bitmap, kN32_SkColorType); 1469 spriteIcon.hotSpotX = pointerIcon.hotSpotX; 1470 spriteIcon.hotSpotY = pointerIcon.hotSpotY; 1471 im->setCustomPointerIcon(spriteIcon); 1472 } 1473 1474 // ---------------------------------------------------------------------------- 1475 1476 static const JNINativeMethod gInputManagerMethods[] = { 1477 /* name, signature, funcPtr */ 1478 { "nativeInit", 1479 "(Lcom/android/server/input/InputManagerService;Landroid/content/Context;Landroid/os/MessageQueue;)J", 1480 (void*) nativeInit }, 1481 { "nativeStart", "(J)V", 1482 (void*) nativeStart }, 1483 { "nativeSetDisplayViewport", "(JZIIIIIIIIIIII)V", 1484 (void*) nativeSetDisplayViewport }, 1485 { "nativeGetScanCodeState", "(JIII)I", 1486 (void*) nativeGetScanCodeState }, 1487 { "nativeGetKeyCodeState", "(JIII)I", 1488 (void*) nativeGetKeyCodeState }, 1489 { "nativeGetSwitchState", "(JIII)I", 1490 (void*) nativeGetSwitchState }, 1491 { "nativeHasKeys", "(JII[I[Z)Z", 1492 (void*) nativeHasKeys }, 1493 { "nativeRegisterInputChannel", 1494 "(JLandroid/view/InputChannel;Lcom/android/server/input/InputWindowHandle;Z)V", 1495 (void*) nativeRegisterInputChannel }, 1496 { "nativeUnregisterInputChannel", "(JLandroid/view/InputChannel;)V", 1497 (void*) nativeUnregisterInputChannel }, 1498 { "nativeSetInputFilterEnabled", "(JZ)V", 1499 (void*) nativeSetInputFilterEnabled }, 1500 { "nativeInjectInputEvent", "(JLandroid/view/InputEvent;IIIIII)I", 1501 (void*) nativeInjectInputEvent }, 1502 { "nativeToggleCapsLock", "(JI)V", 1503 (void*) nativeToggleCapsLock }, 1504 { "nativeSetInputWindows", "(J[Lcom/android/server/input/InputWindowHandle;)V", 1505 (void*) nativeSetInputWindows }, 1506 { "nativeSetFocusedApplication", "(JLcom/android/server/input/InputApplicationHandle;)V", 1507 (void*) nativeSetFocusedApplication }, 1508 { "nativeSetInputDispatchMode", "(JZZ)V", 1509 (void*) nativeSetInputDispatchMode }, 1510 { "nativeSetSystemUiVisibility", "(JI)V", 1511 (void*) nativeSetSystemUiVisibility }, 1512 { "nativeTransferTouchFocus", "(JLandroid/view/InputChannel;Landroid/view/InputChannel;)Z", 1513 (void*) nativeTransferTouchFocus }, 1514 { "nativeSetPointerSpeed", "(JI)V", 1515 (void*) nativeSetPointerSpeed }, 1516 { "nativeSetShowTouches", "(JZ)V", 1517 (void*) nativeSetShowTouches }, 1518 { "nativeSetInteractive", "(JZ)V", 1519 (void*) nativeSetInteractive }, 1520 { "nativeReloadCalibration", "(J)V", 1521 (void*) nativeReloadCalibration }, 1522 { "nativeVibrate", "(JI[JII)V", 1523 (void*) nativeVibrate }, 1524 { "nativeCancelVibrate", "(JII)V", 1525 (void*) nativeCancelVibrate }, 1526 { "nativeReloadKeyboardLayouts", "(J)V", 1527 (void*) nativeReloadKeyboardLayouts }, 1528 { "nativeReloadDeviceAliases", "(J)V", 1529 (void*) nativeReloadDeviceAliases }, 1530 { "nativeDump", "(J)Ljava/lang/String;", 1531 (void*) nativeDump }, 1532 { "nativeMonitor", "(J)V", 1533 (void*) nativeMonitor }, 1534 { "nativeSetPointerIconType", "(JI)V", 1535 (void*) nativeSetPointerIconType }, 1536 { "nativeReloadPointerIcons", "(J)V", 1537 (void*) nativeReloadPointerIcons }, 1538 { "nativeSetCustomPointerIcon", "(JLandroid/view/PointerIcon;)V", 1539 (void*) nativeSetCustomPointerIcon }, 1540 }; 1541 1542 #define FIND_CLASS(var, className) \ 1543 var = env->FindClass(className); \ 1544 LOG_FATAL_IF(! var, "Unable to find class " className); 1545 1546 #define GET_METHOD_ID(var, clazz, methodName, methodDescriptor) \ 1547 var = env->GetMethodID(clazz, methodName, methodDescriptor); \ 1548 LOG_FATAL_IF(! var, "Unable to find method " methodName); 1549 1550 #define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \ 1551 var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \ 1552 LOG_FATAL_IF(! var, "Unable to find field " fieldName); 1553 1554 int register_android_server_InputManager(JNIEnv* env) { 1555 int res = jniRegisterNativeMethods(env, "com/android/server/input/InputManagerService", 1556 gInputManagerMethods, NELEM(gInputManagerMethods)); 1557 (void) res; // Faked use when LOG_NDEBUG. 1558 LOG_FATAL_IF(res < 0, "Unable to register native methods."); 1559 1560 // Callbacks 1561 1562 jclass clazz; 1563 FIND_CLASS(clazz, "com/android/server/input/InputManagerService"); 1564 1565 GET_METHOD_ID(gServiceClassInfo.notifyConfigurationChanged, clazz, 1566 "notifyConfigurationChanged", "(J)V"); 1567 1568 GET_METHOD_ID(gServiceClassInfo.notifyInputDevicesChanged, clazz, 1569 "notifyInputDevicesChanged", "([Landroid/view/InputDevice;)V"); 1570 1571 GET_METHOD_ID(gServiceClassInfo.notifySwitch, clazz, 1572 "notifySwitch", "(JII)V"); 1573 1574 GET_METHOD_ID(gServiceClassInfo.notifyInputChannelBroken, clazz, 1575 "notifyInputChannelBroken", "(Lcom/android/server/input/InputWindowHandle;)V"); 1576 1577 GET_METHOD_ID(gServiceClassInfo.notifyANR, clazz, 1578 "notifyANR", 1579 "(Lcom/android/server/input/InputApplicationHandle;Lcom/android/server/input/InputWindowHandle;Ljava/lang/String;)J"); 1580 1581 GET_METHOD_ID(gServiceClassInfo.filterInputEvent, clazz, 1582 "filterInputEvent", "(Landroid/view/InputEvent;I)Z"); 1583 1584 GET_METHOD_ID(gServiceClassInfo.interceptKeyBeforeQueueing, clazz, 1585 "interceptKeyBeforeQueueing", "(Landroid/view/KeyEvent;I)I"); 1586 1587 GET_METHOD_ID(gServiceClassInfo.interceptMotionBeforeQueueingNonInteractive, clazz, 1588 "interceptMotionBeforeQueueingNonInteractive", "(JI)I"); 1589 1590 GET_METHOD_ID(gServiceClassInfo.interceptKeyBeforeDispatching, clazz, 1591 "interceptKeyBeforeDispatching", 1592 "(Lcom/android/server/input/InputWindowHandle;Landroid/view/KeyEvent;I)J"); 1593 1594 GET_METHOD_ID(gServiceClassInfo.dispatchUnhandledKey, clazz, 1595 "dispatchUnhandledKey", 1596 "(Lcom/android/server/input/InputWindowHandle;Landroid/view/KeyEvent;I)Landroid/view/KeyEvent;"); 1597 1598 GET_METHOD_ID(gServiceClassInfo.checkInjectEventsPermission, clazz, 1599 "checkInjectEventsPermission", "(II)Z"); 1600 1601 GET_METHOD_ID(gServiceClassInfo.getVirtualKeyQuietTimeMillis, clazz, 1602 "getVirtualKeyQuietTimeMillis", "()I"); 1603 1604 GET_METHOD_ID(gServiceClassInfo.getExcludedDeviceNames, clazz, 1605 "getExcludedDeviceNames", "()[Ljava/lang/String;"); 1606 1607 GET_METHOD_ID(gServiceClassInfo.getKeyRepeatTimeout, clazz, 1608 "getKeyRepeatTimeout", "()I"); 1609 1610 GET_METHOD_ID(gServiceClassInfo.getKeyRepeatDelay, clazz, 1611 "getKeyRepeatDelay", "()I"); 1612 1613 GET_METHOD_ID(gServiceClassInfo.getHoverTapTimeout, clazz, 1614 "getHoverTapTimeout", "()I"); 1615 1616 GET_METHOD_ID(gServiceClassInfo.getHoverTapSlop, clazz, 1617 "getHoverTapSlop", "()I"); 1618 1619 GET_METHOD_ID(gServiceClassInfo.getDoubleTapTimeout, clazz, 1620 "getDoubleTapTimeout", "()I"); 1621 1622 GET_METHOD_ID(gServiceClassInfo.getLongPressTimeout, clazz, 1623 "getLongPressTimeout", "()I"); 1624 1625 GET_METHOD_ID(gServiceClassInfo.getPointerLayer, clazz, 1626 "getPointerLayer", "()I"); 1627 1628 GET_METHOD_ID(gServiceClassInfo.getPointerIcon, clazz, 1629 "getPointerIcon", "()Landroid/view/PointerIcon;"); 1630 1631 GET_METHOD_ID(gServiceClassInfo.getKeyboardLayoutOverlay, clazz, 1632 "getKeyboardLayoutOverlay", 1633 "(Landroid/hardware/input/InputDeviceIdentifier;)[Ljava/lang/String;"); 1634 1635 GET_METHOD_ID(gServiceClassInfo.getDeviceAlias, clazz, 1636 "getDeviceAlias", "(Ljava/lang/String;)Ljava/lang/String;"); 1637 1638 GET_METHOD_ID(gServiceClassInfo.getTouchCalibrationForInputDevice, clazz, 1639 "getTouchCalibrationForInputDevice", 1640 "(Ljava/lang/String;I)Landroid/hardware/input/TouchCalibration;"); 1641 1642 // InputDevice 1643 1644 FIND_CLASS(gInputDeviceClassInfo.clazz, "android/view/InputDevice"); 1645 gInputDeviceClassInfo.clazz = jclass(env->NewGlobalRef(gInputDeviceClassInfo.clazz)); 1646 1647 // KeyEvent 1648 1649 FIND_CLASS(gKeyEventClassInfo.clazz, "android/view/KeyEvent"); 1650 gKeyEventClassInfo.clazz = jclass(env->NewGlobalRef(gKeyEventClassInfo.clazz)); 1651 1652 // MotionEvent 1653 1654 FIND_CLASS(gMotionEventClassInfo.clazz, "android/view/MotionEvent"); 1655 gMotionEventClassInfo.clazz = jclass(env->NewGlobalRef(gMotionEventClassInfo.clazz)); 1656 1657 // InputDeviceIdentifier 1658 1659 FIND_CLASS(gInputDeviceIdentifierInfo.clazz, "android/hardware/input/InputDeviceIdentifier"); 1660 gInputDeviceIdentifierInfo.clazz = jclass(env->NewGlobalRef(gInputDeviceIdentifierInfo.clazz)); 1661 GET_METHOD_ID(gInputDeviceIdentifierInfo.constructor, gInputDeviceIdentifierInfo.clazz, 1662 "<init>", "(Ljava/lang/String;II)V"); 1663 1664 // TouchCalibration 1665 1666 FIND_CLASS(gTouchCalibrationClassInfo.clazz, "android/hardware/input/TouchCalibration"); 1667 gTouchCalibrationClassInfo.clazz = jclass(env->NewGlobalRef(gTouchCalibrationClassInfo.clazz)); 1668 1669 GET_METHOD_ID(gTouchCalibrationClassInfo.getAffineTransform, gTouchCalibrationClassInfo.clazz, 1670 "getAffineTransform", "()[F"); 1671 1672 return 0; 1673 } 1674 1675 } /* namespace android */ 1676