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