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