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