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