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