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