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