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 #include <android-base/parseint.h>
30 #include <android-base/stringprintf.h>
31 #include <android/os/IInputConstants.h>
32 #include <android_runtime/AndroidRuntime.h>
33 #include <android_runtime/Log.h>
34 #include <limits.h>
35 #include <atomic>
36 #include <cinttypes>
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 <batteryservice/include/batteryservice/BatteryServiceConstants.h>
50 #include <inputflinger/InputManager.h>
51 
52 #include <android_os_MessageQueue.h>
53 #include <android_view_InputChannel.h>
54 #include <android_view_InputDevice.h>
55 #include <android_view_KeyEvent.h>
56 #include <android_view_MotionEvent.h>
57 #include <android_view_PointerIcon.h>
58 #include <android_view_VerifiedKeyEvent.h>
59 #include <android_view_VerifiedMotionEvent.h>
60 
61 #include <nativehelper/ScopedLocalFrame.h>
62 #include <nativehelper/ScopedLocalRef.h>
63 #include <nativehelper/ScopedPrimitiveArray.h>
64 #include <nativehelper/ScopedUtfChars.h>
65 
66 #include "android_hardware_display_DisplayViewport.h"
67 #include "android_hardware_input_InputApplicationHandle.h"
68 #include "android_hardware_input_InputWindowHandle.h"
69 #include "android_util_Binder.h"
70 #include "com_android_server_power_PowerManagerService.h"
71 
72 #include <vector>
73 
74 #define INDENT "  "
75 
76 using android::base::ParseUint;
77 using android::base::StringPrintf;
78 using android::os::BlockUntrustedTouchesMode;
79 using android::os::InputEventInjectionResult;
80 using android::os::InputEventInjectionSync;
81 
82 // Maximum allowable delay value in a vibration pattern before
83 // which the delay will be truncated.
84 static constexpr std::chrono::duration MAX_VIBRATE_PATTERN_DELAY = 100s;
85 static constexpr std::chrono::milliseconds MAX_VIBRATE_PATTERN_DELAY_MILLIS =
86         std::chrono::duration_cast<std::chrono::milliseconds>(MAX_VIBRATE_PATTERN_DELAY);
87 
88 namespace android {
89 
90 // The exponent used to calculate the pointer speed scaling factor.
91 // The scaling factor is calculated as 2 ^ (speed * exponent),
92 // where the speed ranges from -7 to + 7 and is supplied by the user.
93 static const float POINTER_SPEED_EXPONENT = 1.0f / 4;
94 
95 static struct {
96     jclass clazz;
97     jmethodID notifyConfigurationChanged;
98     jmethodID notifyInputDevicesChanged;
99     jmethodID notifySwitch;
100     jmethodID notifyInputChannelBroken;
101     jmethodID notifyNoFocusedWindowAnr;
102     jmethodID notifyWindowUnresponsive;
103     jmethodID notifyWindowResponsive;
104     jmethodID notifyMonitorUnresponsive;
105     jmethodID notifyMonitorResponsive;
106     jmethodID notifyFocusChanged;
107     jmethodID notifySensorEvent;
108     jmethodID notifySensorAccuracy;
109     jmethodID notifyVibratorState;
110     jmethodID notifyUntrustedTouch;
111     jmethodID filterInputEvent;
112     jmethodID interceptKeyBeforeQueueing;
113     jmethodID interceptMotionBeforeQueueingNonInteractive;
114     jmethodID interceptKeyBeforeDispatching;
115     jmethodID dispatchUnhandledKey;
116     jmethodID checkInjectEventsPermission;
117     jmethodID onPointerDownOutsideFocus;
118     jmethodID getVirtualKeyQuietTimeMillis;
119     jmethodID getExcludedDeviceNames;
120     jmethodID getInputPortAssociations;
121     jmethodID getInputUniqueIdAssociations;
122     jmethodID getKeyRepeatTimeout;
123     jmethodID getKeyRepeatDelay;
124     jmethodID getHoverTapTimeout;
125     jmethodID getHoverTapSlop;
126     jmethodID getDoubleTapTimeout;
127     jmethodID getLongPressTimeout;
128     jmethodID getPointerLayer;
129     jmethodID getPointerIcon;
130     jmethodID getPointerDisplayId;
131     jmethodID getKeyboardLayoutOverlay;
132     jmethodID getDeviceAlias;
133     jmethodID getTouchCalibrationForInputDevice;
134     jmethodID getContextForDisplay;
135     jmethodID notifyDropWindow;
136 } gServiceClassInfo;
137 
138 static struct {
139     jclass clazz;
140 } gInputDeviceClassInfo;
141 
142 static struct {
143     jclass clazz;
144 } gKeyEventClassInfo;
145 
146 static struct {
147     jclass clazz;
148 } gMotionEventClassInfo;
149 
150 static struct {
151     jclass clazz;
152     jmethodID constructor;
153 } gInputDeviceIdentifierInfo;
154 
155 static struct {
156     jclass clazz;
157     jmethodID getAffineTransform;
158 } gTouchCalibrationClassInfo;
159 
160 static struct {
161     jclass clazz;
162     jmethodID constructor;
163     jfieldID lightTypeInput;
164     jfieldID lightTypePlayerId;
165     jfieldID lightCapabilityBrightness;
166     jfieldID lightCapabilityRgb;
167 } gLightClassInfo;
168 
169 static struct {
170     jclass clazz;
171     jmethodID constructor;
172     jmethodID add;
173 } gArrayListClassInfo;
174 
175 static struct {
176     jclass clazz;
177     jmethodID constructor;
178     jmethodID keyAt;
179     jmethodID valueAt;
180     jmethodID size;
181 } gSparseArrayClassInfo;
182 
183 static struct InputSensorInfoOffsets {
184     jclass clazz;
185     // fields
186     jfieldID name;
187     jfieldID vendor;
188     jfieldID version;
189     jfieldID handle;
190     jfieldID maxRange;
191     jfieldID resolution;
192     jfieldID power;
193     jfieldID minDelay;
194     jfieldID fifoReservedEventCount;
195     jfieldID fifoMaxEventCount;
196     jfieldID stringType;
197     jfieldID requiredPermission;
198     jfieldID maxDelay;
199     jfieldID flags;
200     jfieldID type;
201     jfieldID id;
202     // methods
203     jmethodID init;
204 } gInputSensorInfo;
205 
206 // --- Global functions ---
207 
208 template<typename T>
min(const T & a,const T & b)209 inline static T min(const T& a, const T& b) {
210     return a < b ? a : b;
211 }
212 
213 template<typename T>
max(const T & a,const T & b)214 inline static T max(const T& a, const T& b) {
215     return a > b ? a : b;
216 }
217 
toString(bool value)218 static inline const char* toString(bool value) {
219     return value ? "true" : "false";
220 }
221 
loadSystemIconAsSpriteWithPointerIcon(JNIEnv * env,jobject contextObj,int32_t style,PointerIcon * outPointerIcon,SpriteIcon * outSpriteIcon)222 static void loadSystemIconAsSpriteWithPointerIcon(JNIEnv* env, jobject contextObj, int32_t style,
223         PointerIcon* outPointerIcon, SpriteIcon* outSpriteIcon) {
224     status_t status = android_view_PointerIcon_loadSystemIcon(env,
225             contextObj, style, outPointerIcon);
226     if (!status) {
227         outSpriteIcon->bitmap = outPointerIcon->bitmap.copy(ANDROID_BITMAP_FORMAT_RGBA_8888);
228         outSpriteIcon->style = outPointerIcon->style;
229         outSpriteIcon->hotSpotX = outPointerIcon->hotSpotX;
230         outSpriteIcon->hotSpotY = outPointerIcon->hotSpotY;
231     }
232 }
233 
loadSystemIconAsSprite(JNIEnv * env,jobject contextObj,int32_t style,SpriteIcon * outSpriteIcon)234 static void loadSystemIconAsSprite(JNIEnv* env, jobject contextObj, int32_t style,
235                                    SpriteIcon* outSpriteIcon) {
236     PointerIcon pointerIcon;
237     loadSystemIconAsSpriteWithPointerIcon(env, contextObj, style, &pointerIcon, outSpriteIcon);
238 }
239 
240 enum {
241     WM_ACTION_PASS_TO_USER = 1,
242 };
243 
getStringElementFromJavaArray(JNIEnv * env,jobjectArray array,jsize index)244 static std::string getStringElementFromJavaArray(JNIEnv* env, jobjectArray array, jsize index) {
245     jstring item = jstring(env->GetObjectArrayElement(array, index));
246     ScopedUtfChars chars(env, item);
247     std::string result(chars.c_str());
248     return result;
249 }
250 
251 // --- NativeInputManager ---
252 
253 class NativeInputManager : public virtual RefBase,
254     public virtual InputReaderPolicyInterface,
255     public virtual InputDispatcherPolicyInterface,
256     public virtual PointerControllerPolicyInterface {
257 protected:
258     virtual ~NativeInputManager();
259 
260 public:
261     NativeInputManager(jobject contextObj, jobject serviceObj, const sp<Looper>& looper);
262 
getInputManager() const263     inline sp<InputManagerInterface> getInputManager() const { return mInputManager; }
264 
265     void dump(std::string& dump);
266 
267     void setDisplayViewports(JNIEnv* env, jobjectArray viewportObjArray);
268 
269     base::Result<std::unique_ptr<InputChannel>> createInputChannel(JNIEnv* env,
270                                                                    const std::string& name);
271     base::Result<std::unique_ptr<InputChannel>> createInputMonitor(JNIEnv* env, int32_t displayId,
272                                                                    bool isGestureMonitor,
273                                                                    const std::string& name,
274                                                                    int32_t pid);
275     status_t removeInputChannel(JNIEnv* env, const sp<IBinder>& connectionToken);
276     status_t pilferPointers(const sp<IBinder>& token);
277 
278     void displayRemoved(JNIEnv* env, int32_t displayId);
279     void setFocusedApplication(JNIEnv* env, int32_t displayId, jobject applicationHandleObj);
280     void setFocusedDisplay(JNIEnv* env, int32_t displayId);
281     void setInputDispatchMode(bool enabled, bool frozen);
282     void setSystemUiLightsOut(bool lightsOut);
283     void setPointerSpeed(int32_t speed);
284     void setInputDeviceEnabled(uint32_t deviceId, bool enabled);
285     void setShowTouches(bool enabled);
286     void setInteractive(bool interactive);
287     void reloadCalibration();
288     void setPointerIconType(int32_t iconId);
289     void reloadPointerIcons();
290     void requestPointerCapture(const sp<IBinder>& windowToken, bool enabled);
291     void setCustomPointerIcon(const SpriteIcon& icon);
292     void setMotionClassifierEnabled(bool enabled);
293 
294     /* --- InputReaderPolicyInterface implementation --- */
295 
296     void getReaderConfiguration(InputReaderConfiguration* outConfig) override;
297     std::shared_ptr<PointerControllerInterface> obtainPointerController(int32_t deviceId) override;
298     void notifyInputDevicesChanged(const std::vector<InputDeviceInfo>& inputDevices) override;
299     std::shared_ptr<KeyCharacterMap> getKeyboardLayoutOverlay(
300             const InputDeviceIdentifier& identifier) override;
301     std::string getDeviceAlias(const InputDeviceIdentifier& identifier) override;
302     TouchAffineTransformation getTouchAffineTransformation(const std::string& inputDeviceDescriptor,
303                                                            int32_t surfaceRotation) override;
304 
305     TouchAffineTransformation getTouchAffineTransformation(JNIEnv* env, jfloatArray matrixArr);
306 
307     /* --- InputDispatcherPolicyInterface implementation --- */
308 
309     void notifySwitch(nsecs_t when, uint32_t switchValues, uint32_t switchMask,
310                       uint32_t policyFlags) override;
311     void notifyConfigurationChanged(nsecs_t when) override;
312     // ANR-related callbacks -- start
313     void notifyNoFocusedWindowAnr(const std::shared_ptr<InputApplicationHandle>& handle) override;
314     void notifyWindowUnresponsive(const sp<IBinder>& token, const std::string& reason) override;
315     void notifyWindowResponsive(const sp<IBinder>& token) override;
316     void notifyMonitorUnresponsive(int32_t pid, const std::string& reason) override;
317     void notifyMonitorResponsive(int32_t pid) override;
318     // ANR-related callbacks -- end
319     void notifyInputChannelBroken(const sp<IBinder>& token) override;
320     void notifyFocusChanged(const sp<IBinder>& oldToken, const sp<IBinder>& newToken) override;
321     void notifySensorEvent(int32_t deviceId, InputDeviceSensorType sensorType,
322                            InputDeviceSensorAccuracy accuracy, nsecs_t timestamp,
323                            const std::vector<float>& values) override;
324     void notifySensorAccuracy(int32_t deviceId, InputDeviceSensorType sensorType,
325                               InputDeviceSensorAccuracy accuracy) override;
326     void notifyVibratorState(int32_t deviceId, bool isOn) override;
327     void notifyUntrustedTouch(const std::string& obscuringPackage) override;
328     bool filterInputEvent(const InputEvent* inputEvent, uint32_t policyFlags) override;
329     void getDispatcherConfiguration(InputDispatcherConfiguration* outConfig) override;
330     void interceptKeyBeforeQueueing(const KeyEvent* keyEvent, uint32_t& policyFlags) override;
331     void interceptMotionBeforeQueueing(const int32_t displayId, nsecs_t when,
332                                        uint32_t& policyFlags) override;
333     nsecs_t interceptKeyBeforeDispatching(const sp<IBinder>& token, const KeyEvent* keyEvent,
334                                           uint32_t policyFlags) override;
335     bool dispatchUnhandledKey(const sp<IBinder>& token, const KeyEvent* keyEvent,
336                               uint32_t policyFlags, KeyEvent* outFallbackKeyEvent) override;
337     void pokeUserActivity(nsecs_t eventTime, int32_t eventType, int32_t displayId) override;
338     bool checkInjectEventsPermissionNonReentrant(int32_t injectorPid, int32_t injectorUid) override;
339     void onPointerDownOutsideFocus(const sp<IBinder>& touchedToken) override;
340     void setPointerCapture(const PointerCaptureRequest& request) override;
341     void notifyDropWindow(const sp<IBinder>& token, float x, float y) override;
342 
343     /* --- PointerControllerPolicyInterface implementation --- */
344 
345     virtual void loadPointerIcon(SpriteIcon* icon, int32_t displayId);
346     virtual void loadPointerResources(PointerResources* outResources, int32_t displayId);
347     virtual void loadAdditionalMouseResources(std::map<int32_t, SpriteIcon>* outResources,
348             std::map<int32_t, PointerAnimation>* outAnimationResources, int32_t displayId);
349     virtual int32_t getDefaultPointerIconId();
350     virtual int32_t getCustomPointerIconId();
351 
352 private:
353     sp<InputManagerInterface> mInputManager;
354 
355     jobject mServiceObj;
356     sp<Looper> mLooper;
357 
358     Mutex mLock;
359     struct Locked {
360         // Display size information.
361         std::vector<DisplayViewport> viewports;
362 
363         // True if System UI is less noticeable.
364         bool systemUiLightsOut;
365 
366         // Pointer speed.
367         int32_t pointerSpeed;
368 
369         // True if pointer gestures are enabled.
370         bool pointerGesturesEnabled;
371 
372         // Show touches feature enable/disable.
373         bool showTouches;
374 
375         // The latest request to enable or disable Pointer Capture.
376         PointerCaptureRequest pointerCaptureRequest;
377 
378         // Sprite controller singleton, created on first use.
379         sp<SpriteController> spriteController;
380 
381         // Pointer controller singleton, created and destroyed as needed.
382         std::weak_ptr<PointerController> pointerController;
383 
384         // Input devices to be disabled
385         std::set<int32_t> disabledInputDevices;
386 
387         // Associated Pointer controller display.
388         int32_t pointerDisplayId;
389     } mLocked GUARDED_BY(mLock);
390 
391     std::atomic<bool> mInteractive;
392 
393     void updateInactivityTimeoutLocked();
394     void handleInterceptActions(jint wmActions, nsecs_t when, uint32_t& policyFlags);
395     void ensureSpriteControllerLocked();
396     int32_t getPointerDisplayId();
397     void updatePointerDisplayLocked();
398     static bool checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName);
399 
jniEnv()400     static inline JNIEnv* jniEnv() {
401         return AndroidRuntime::getJNIEnv();
402     }
403 };
404 
405 
406 
NativeInputManager(jobject contextObj,jobject serviceObj,const sp<Looper> & looper)407 NativeInputManager::NativeInputManager(jobject contextObj,
408         jobject serviceObj, const sp<Looper>& looper) :
409         mLooper(looper), mInteractive(true) {
410     JNIEnv* env = jniEnv();
411 
412     mServiceObj = env->NewGlobalRef(serviceObj);
413 
414     {
415         AutoMutex _l(mLock);
416         mLocked.systemUiLightsOut = false;
417         mLocked.pointerSpeed = 0;
418         mLocked.pointerGesturesEnabled = true;
419         mLocked.showTouches = false;
420         mLocked.pointerDisplayId = ADISPLAY_ID_DEFAULT;
421     }
422     mInteractive = true;
423 
424     InputManager* im = new InputManager(this, this);
425     mInputManager = im;
426     defaultServiceManager()->addService(String16("inputflinger"), im);
427 }
428 
~NativeInputManager()429 NativeInputManager::~NativeInputManager() {
430     JNIEnv* env = jniEnv();
431 
432     env->DeleteGlobalRef(mServiceObj);
433 }
434 
dump(std::string & dump)435 void NativeInputManager::dump(std::string& dump) {
436     dump += "Input Manager State:\n";
437     {
438         dump += StringPrintf(INDENT "Interactive: %s\n", toString(mInteractive.load()));
439     }
440     {
441         AutoMutex _l(mLock);
442         dump += StringPrintf(INDENT "System UI Lights Out: %s\n",
443                              toString(mLocked.systemUiLightsOut));
444         dump += StringPrintf(INDENT "Pointer Speed: %" PRId32 "\n", mLocked.pointerSpeed);
445         dump += StringPrintf(INDENT "Pointer Gestures Enabled: %s\n",
446                 toString(mLocked.pointerGesturesEnabled));
447         dump += StringPrintf(INDENT "Show Touches: %s\n", toString(mLocked.showTouches));
448         dump += StringPrintf(INDENT "Pointer Capture: %s, seq=%" PRIu32 "\n",
449                              mLocked.pointerCaptureRequest.enable ? "Enabled" : "Disabled",
450                              mLocked.pointerCaptureRequest.seq);
451     }
452     dump += "\n";
453 
454     mInputManager->getReader()->dump(dump);
455     dump += "\n";
456 
457     mInputManager->getClassifier()->dump(dump);
458     dump += "\n";
459 
460     mInputManager->getDispatcher()->dump(dump);
461     dump += "\n";
462 }
463 
checkAndClearExceptionFromCallback(JNIEnv * env,const char * methodName)464 bool NativeInputManager::checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName) {
465     if (env->ExceptionCheck()) {
466         ALOGE("An exception was thrown by callback '%s'.", methodName);
467         LOGE_EX(env);
468         env->ExceptionClear();
469         return true;
470     }
471     return false;
472 }
473 
setDisplayViewports(JNIEnv * env,jobjectArray viewportObjArray)474 void NativeInputManager::setDisplayViewports(JNIEnv* env, jobjectArray viewportObjArray) {
475     std::vector<DisplayViewport> viewports;
476 
477     if (viewportObjArray) {
478         jsize length = env->GetArrayLength(viewportObjArray);
479         for (jsize i = 0; i < length; i++) {
480             jobject viewportObj = env->GetObjectArrayElement(viewportObjArray, i);
481             if (! viewportObj) {
482                 break; // found null element indicating end of used portion of the array
483             }
484 
485             DisplayViewport viewport;
486             android_hardware_display_DisplayViewport_toNative(env, viewportObj, &viewport);
487             ALOGI("Viewport [%d] to add: %s, isActive: %s", (int)i, viewport.uniqueId.c_str(),
488                   toString(viewport.isActive));
489             viewports.push_back(viewport);
490 
491             env->DeleteLocalRef(viewportObj);
492         }
493     }
494 
495     // Get the preferred pointer controller displayId.
496     int32_t pointerDisplayId = getPointerDisplayId();
497 
498     { // acquire lock
499         AutoMutex _l(mLock);
500         mLocked.viewports = viewports;
501         mLocked.pointerDisplayId = pointerDisplayId;
502         std::shared_ptr<PointerController> controller = mLocked.pointerController.lock();
503         if (controller != nullptr) {
504             controller->onDisplayViewportsUpdated(mLocked.viewports);
505         }
506     } // release lock
507 
508     mInputManager->getReader()->requestRefreshConfiguration(
509             InputReaderConfiguration::CHANGE_DISPLAY_INFO);
510 }
511 
createInputChannel(JNIEnv *,const std::string & name)512 base::Result<std::unique_ptr<InputChannel>> NativeInputManager::createInputChannel(
513         JNIEnv* /* env */, const std::string& name) {
514     ATRACE_CALL();
515     return mInputManager->getDispatcher()->createInputChannel(name);
516 }
517 
createInputMonitor(JNIEnv *,int32_t displayId,bool isGestureMonitor,const std::string & name,int32_t pid)518 base::Result<std::unique_ptr<InputChannel>> NativeInputManager::createInputMonitor(
519         JNIEnv* /* env */, int32_t displayId, bool isGestureMonitor, const std::string& name,
520         int32_t pid) {
521     ATRACE_CALL();
522     return mInputManager->getDispatcher()->createInputMonitor(displayId, isGestureMonitor, name,
523                                                               pid);
524 }
525 
removeInputChannel(JNIEnv *,const sp<IBinder> & connectionToken)526 status_t NativeInputManager::removeInputChannel(JNIEnv* /* env */,
527                                                 const sp<IBinder>& connectionToken) {
528     ATRACE_CALL();
529     return mInputManager->getDispatcher()->removeInputChannel(connectionToken);
530 }
531 
pilferPointers(const sp<IBinder> & token)532 status_t NativeInputManager::pilferPointers(const sp<IBinder>& token) {
533     ATRACE_CALL();
534     return mInputManager->getDispatcher()->pilferPointers(token);
535 }
536 
getReaderConfiguration(InputReaderConfiguration * outConfig)537 void NativeInputManager::getReaderConfiguration(InputReaderConfiguration* outConfig) {
538     ATRACE_CALL();
539     JNIEnv* env = jniEnv();
540 
541     jint virtualKeyQuietTime = env->CallIntMethod(mServiceObj,
542             gServiceClassInfo.getVirtualKeyQuietTimeMillis);
543     if (!checkAndClearExceptionFromCallback(env, "getVirtualKeyQuietTimeMillis")) {
544         outConfig->virtualKeyQuietTime = milliseconds_to_nanoseconds(virtualKeyQuietTime);
545     }
546 
547     outConfig->excludedDeviceNames.clear();
548     jobjectArray excludedDeviceNames = jobjectArray(env->CallStaticObjectMethod(
549             gServiceClassInfo.clazz, gServiceClassInfo.getExcludedDeviceNames));
550     if (!checkAndClearExceptionFromCallback(env, "getExcludedDeviceNames") && excludedDeviceNames) {
551         jsize length = env->GetArrayLength(excludedDeviceNames);
552         for (jsize i = 0; i < length; i++) {
553             std::string deviceName = getStringElementFromJavaArray(env, excludedDeviceNames, i);
554             outConfig->excludedDeviceNames.push_back(deviceName);
555         }
556         env->DeleteLocalRef(excludedDeviceNames);
557     }
558 
559     // Associations between input ports and display ports
560     // The java method packs the information in the following manner:
561     // Original data: [{'inputPort1': '1'}, {'inputPort2': '2'}]
562     // Received data: ['inputPort1', '1', 'inputPort2', '2']
563     // So we unpack accordingly here.
564     outConfig->portAssociations.clear();
565     jobjectArray portAssociations = jobjectArray(env->CallObjectMethod(mServiceObj,
566             gServiceClassInfo.getInputPortAssociations));
567     if (!checkAndClearExceptionFromCallback(env, "getInputPortAssociations") && portAssociations) {
568         jsize length = env->GetArrayLength(portAssociations);
569         for (jsize i = 0; i < length / 2; i++) {
570             std::string inputPort = getStringElementFromJavaArray(env, portAssociations, 2 * i);
571             std::string displayPortStr =
572                     getStringElementFromJavaArray(env, portAssociations, 2 * i + 1);
573             uint8_t displayPort;
574             // Should already have been validated earlier, but do it here for safety.
575             bool success = ParseUint(displayPortStr, &displayPort);
576             if (!success) {
577                 ALOGE("Could not parse entry in port configuration file, received: %s",
578                     displayPortStr.c_str());
579                 continue;
580             }
581             outConfig->portAssociations.insert({inputPort, displayPort});
582         }
583         env->DeleteLocalRef(portAssociations);
584     }
585     outConfig->uniqueIdAssociations.clear();
586     jobjectArray uniqueIdAssociations = jobjectArray(
587             env->CallObjectMethod(mServiceObj, gServiceClassInfo.getInputUniqueIdAssociations));
588     if (!checkAndClearExceptionFromCallback(env, "getInputUniqueIdAssociations") &&
589         uniqueIdAssociations) {
590         jsize length = env->GetArrayLength(uniqueIdAssociations);
591         for (jsize i = 0; i < length / 2; i++) {
592             std::string inputDeviceUniqueId =
593                     getStringElementFromJavaArray(env, uniqueIdAssociations, 2 * i);
594             std::string displayUniqueId =
595                     getStringElementFromJavaArray(env, uniqueIdAssociations, 2 * i + 1);
596             outConfig->uniqueIdAssociations.insert({inputDeviceUniqueId, displayUniqueId});
597         }
598         env->DeleteLocalRef(uniqueIdAssociations);
599     }
600 
601     jint hoverTapTimeout = env->CallIntMethod(mServiceObj,
602             gServiceClassInfo.getHoverTapTimeout);
603     if (!checkAndClearExceptionFromCallback(env, "getHoverTapTimeout")) {
604         jint doubleTapTimeout = env->CallIntMethod(mServiceObj,
605                 gServiceClassInfo.getDoubleTapTimeout);
606         if (!checkAndClearExceptionFromCallback(env, "getDoubleTapTimeout")) {
607             jint longPressTimeout = env->CallIntMethod(mServiceObj,
608                     gServiceClassInfo.getLongPressTimeout);
609             if (!checkAndClearExceptionFromCallback(env, "getLongPressTimeout")) {
610                 outConfig->pointerGestureTapInterval = milliseconds_to_nanoseconds(hoverTapTimeout);
611 
612                 // We must ensure that the tap-drag interval is significantly shorter than
613                 // the long-press timeout because the tap is held down for the entire duration
614                 // of the double-tap timeout.
615                 jint tapDragInterval = max(min(longPressTimeout - 100,
616                         doubleTapTimeout), hoverTapTimeout);
617                 outConfig->pointerGestureTapDragInterval =
618                         milliseconds_to_nanoseconds(tapDragInterval);
619             }
620         }
621     }
622 
623     jint hoverTapSlop = env->CallIntMethod(mServiceObj,
624             gServiceClassInfo.getHoverTapSlop);
625     if (!checkAndClearExceptionFromCallback(env, "getHoverTapSlop")) {
626         outConfig->pointerGestureTapSlop = hoverTapSlop;
627     }
628 
629     { // acquire lock
630         AutoMutex _l(mLock);
631 
632         outConfig->pointerVelocityControlParameters.scale = exp2f(mLocked.pointerSpeed
633                 * POINTER_SPEED_EXPONENT);
634         outConfig->pointerGesturesEnabled = mLocked.pointerGesturesEnabled;
635 
636         outConfig->showTouches = mLocked.showTouches;
637 
638         outConfig->pointerCaptureRequest = mLocked.pointerCaptureRequest;
639 
640         outConfig->setDisplayViewports(mLocked.viewports);
641 
642         outConfig->defaultPointerDisplayId = mLocked.pointerDisplayId;
643 
644         outConfig->disabledDevices = mLocked.disabledInputDevices;
645     } // release lock
646 }
647 
obtainPointerController(int32_t)648 std::shared_ptr<PointerControllerInterface> NativeInputManager::obtainPointerController(
649         int32_t /* deviceId */) {
650     ATRACE_CALL();
651     AutoMutex _l(mLock);
652 
653     std::shared_ptr<PointerController> controller = mLocked.pointerController.lock();
654     if (controller == nullptr) {
655         ensureSpriteControllerLocked();
656 
657         controller = PointerController::create(this, mLooper, mLocked.spriteController);
658         mLocked.pointerController = controller;
659         updateInactivityTimeoutLocked();
660     }
661 
662     return controller;
663 }
664 
getPointerDisplayId()665 int32_t NativeInputManager::getPointerDisplayId() {
666     JNIEnv* env = jniEnv();
667     jint pointerDisplayId = env->CallIntMethod(mServiceObj,
668             gServiceClassInfo.getPointerDisplayId);
669     if (checkAndClearExceptionFromCallback(env, "getPointerDisplayId")) {
670         pointerDisplayId = ADISPLAY_ID_DEFAULT;
671     }
672 
673     return pointerDisplayId;
674 }
675 
ensureSpriteControllerLocked()676 void NativeInputManager::ensureSpriteControllerLocked() REQUIRES(mLock) {
677     if (mLocked.spriteController == nullptr) {
678         JNIEnv* env = jniEnv();
679         jint layer = env->CallIntMethod(mServiceObj, gServiceClassInfo.getPointerLayer);
680         if (checkAndClearExceptionFromCallback(env, "getPointerLayer")) {
681             layer = -1;
682         }
683         mLocked.spriteController = new SpriteController(mLooper, layer);
684     }
685 }
686 
notifyInputDevicesChanged(const std::vector<InputDeviceInfo> & inputDevices)687 void NativeInputManager::notifyInputDevicesChanged(const std::vector<InputDeviceInfo>& inputDevices) {
688     ATRACE_CALL();
689     JNIEnv* env = jniEnv();
690 
691     size_t count = inputDevices.size();
692     jobjectArray inputDevicesObjArray = env->NewObjectArray(
693             count, gInputDeviceClassInfo.clazz, nullptr);
694     if (inputDevicesObjArray) {
695         bool error = false;
696         for (size_t i = 0; i < count; i++) {
697             jobject inputDeviceObj = android_view_InputDevice_create(env, inputDevices[i]);
698             if (!inputDeviceObj) {
699                 error = true;
700                 break;
701             }
702 
703             env->SetObjectArrayElement(inputDevicesObjArray, i, inputDeviceObj);
704             env->DeleteLocalRef(inputDeviceObj);
705         }
706 
707         if (!error) {
708             env->CallVoidMethod(mServiceObj, gServiceClassInfo.notifyInputDevicesChanged,
709                     inputDevicesObjArray);
710         }
711 
712         env->DeleteLocalRef(inputDevicesObjArray);
713     }
714 
715     checkAndClearExceptionFromCallback(env, "notifyInputDevicesChanged");
716 }
717 
getKeyboardLayoutOverlay(const InputDeviceIdentifier & identifier)718 std::shared_ptr<KeyCharacterMap> NativeInputManager::getKeyboardLayoutOverlay(
719         const InputDeviceIdentifier& identifier) {
720     ATRACE_CALL();
721     JNIEnv* env = jniEnv();
722 
723     std::shared_ptr<KeyCharacterMap> result;
724     ScopedLocalRef<jstring> descriptor(env, env->NewStringUTF(identifier.descriptor.c_str()));
725     ScopedLocalRef<jobject> identifierObj(env, env->NewObject(gInputDeviceIdentifierInfo.clazz,
726             gInputDeviceIdentifierInfo.constructor, descriptor.get(),
727             identifier.vendor, identifier.product));
728     ScopedLocalRef<jobjectArray> arrayObj(env, jobjectArray(env->CallObjectMethod(mServiceObj,
729                 gServiceClassInfo.getKeyboardLayoutOverlay, identifierObj.get())));
730     if (arrayObj.get()) {
731         ScopedLocalRef<jstring> filenameObj(env,
732                 jstring(env->GetObjectArrayElement(arrayObj.get(), 0)));
733         ScopedLocalRef<jstring> contentsObj(env,
734                 jstring(env->GetObjectArrayElement(arrayObj.get(), 1)));
735         ScopedUtfChars filenameChars(env, filenameObj.get());
736         ScopedUtfChars contentsChars(env, contentsObj.get());
737 
738         base::Result<std::shared_ptr<KeyCharacterMap>> ret =
739                 KeyCharacterMap::loadContents(filenameChars.c_str(), contentsChars.c_str(),
740                                               KeyCharacterMap::Format::OVERLAY);
741         if (ret.ok()) {
742             result = *ret;
743         }
744     }
745     checkAndClearExceptionFromCallback(env, "getKeyboardLayoutOverlay");
746     return result;
747 }
748 
getDeviceAlias(const InputDeviceIdentifier & identifier)749 std::string NativeInputManager::getDeviceAlias(const InputDeviceIdentifier& identifier) {
750     ATRACE_CALL();
751     JNIEnv* env = jniEnv();
752 
753     ScopedLocalRef<jstring> uniqueIdObj(env, env->NewStringUTF(identifier.uniqueId.c_str()));
754     ScopedLocalRef<jstring> aliasObj(env, jstring(env->CallObjectMethod(mServiceObj,
755             gServiceClassInfo.getDeviceAlias, uniqueIdObj.get())));
756     std::string result;
757     if (aliasObj.get()) {
758         ScopedUtfChars aliasChars(env, aliasObj.get());
759         result = aliasChars.c_str();
760     }
761     checkAndClearExceptionFromCallback(env, "getDeviceAlias");
762     return result;
763 }
764 
notifySwitch(nsecs_t when,uint32_t switchValues,uint32_t switchMask,uint32_t)765 void NativeInputManager::notifySwitch(nsecs_t when,
766         uint32_t switchValues, uint32_t switchMask, uint32_t /* policyFlags */) {
767 #if DEBUG_INPUT_DISPATCHER_POLICY
768     ALOGD("notifySwitch - when=%lld, switchValues=0x%08x, switchMask=0x%08x, policyFlags=0x%x",
769             when, switchValues, switchMask, policyFlags);
770 #endif
771     ATRACE_CALL();
772 
773     JNIEnv* env = jniEnv();
774 
775     env->CallVoidMethod(mServiceObj, gServiceClassInfo.notifySwitch,
776             when, switchValues, switchMask);
777     checkAndClearExceptionFromCallback(env, "notifySwitch");
778 }
779 
notifyConfigurationChanged(nsecs_t when)780 void NativeInputManager::notifyConfigurationChanged(nsecs_t when) {
781 #if DEBUG_INPUT_DISPATCHER_POLICY
782     ALOGD("notifyConfigurationChanged - when=%lld", when);
783 #endif
784     ATRACE_CALL();
785 
786     JNIEnv* env = jniEnv();
787 
788     env->CallVoidMethod(mServiceObj, gServiceClassInfo.notifyConfigurationChanged, when);
789     checkAndClearExceptionFromCallback(env, "notifyConfigurationChanged");
790 }
791 
getInputApplicationHandleObjLocalRef(JNIEnv * env,const std::shared_ptr<InputApplicationHandle> & inputApplicationHandle)792 static jobject getInputApplicationHandleObjLocalRef(
793         JNIEnv* env, const std::shared_ptr<InputApplicationHandle>& inputApplicationHandle) {
794     if (inputApplicationHandle == nullptr) {
795         return nullptr;
796     }
797     NativeInputApplicationHandle* handle =
798             static_cast<NativeInputApplicationHandle*>(inputApplicationHandle.get());
799 
800     return handle->getInputApplicationHandleObjLocalRef(env);
801 }
802 
notifyNoFocusedWindowAnr(const std::shared_ptr<InputApplicationHandle> & inputApplicationHandle)803 void NativeInputManager::notifyNoFocusedWindowAnr(
804         const std::shared_ptr<InputApplicationHandle>& inputApplicationHandle) {
805 #if DEBUG_INPUT_DISPATCHER_POLICY
806     ALOGD("notifyNoFocusedWindowAnr");
807 #endif
808     ATRACE_CALL();
809 
810     JNIEnv* env = jniEnv();
811     ScopedLocalFrame localFrame(env);
812 
813     jobject inputApplicationHandleObj =
814             getInputApplicationHandleObjLocalRef(env, inputApplicationHandle);
815 
816     env->CallVoidMethod(mServiceObj, gServiceClassInfo.notifyNoFocusedWindowAnr,
817                         inputApplicationHandleObj);
818     checkAndClearExceptionFromCallback(env, "notifyNoFocusedWindowAnr");
819 }
820 
notifyWindowUnresponsive(const sp<IBinder> & token,const std::string & reason)821 void NativeInputManager::notifyWindowUnresponsive(const sp<IBinder>& token,
822                                                   const std::string& reason) {
823 #if DEBUG_INPUT_DISPATCHER_POLICY
824     ALOGD("notifyWindowUnresponsive");
825 #endif
826     ATRACE_CALL();
827 
828     JNIEnv* env = jniEnv();
829     ScopedLocalFrame localFrame(env);
830 
831     jobject tokenObj = javaObjectForIBinder(env, token);
832     ScopedLocalRef<jstring> reasonObj(env, env->NewStringUTF(reason.c_str()));
833 
834     env->CallVoidMethod(mServiceObj, gServiceClassInfo.notifyWindowUnresponsive, tokenObj,
835                         reasonObj.get());
836     checkAndClearExceptionFromCallback(env, "notifyWindowUnresponsive");
837 }
838 
notifyWindowResponsive(const sp<IBinder> & token)839 void NativeInputManager::notifyWindowResponsive(const sp<IBinder>& token) {
840 #if DEBUG_INPUT_DISPATCHER_POLICY
841     ALOGD("notifyWindowResponsive");
842 #endif
843     ATRACE_CALL();
844 
845     JNIEnv* env = jniEnv();
846     ScopedLocalFrame localFrame(env);
847 
848     jobject tokenObj = javaObjectForIBinder(env, token);
849 
850     env->CallVoidMethod(mServiceObj, gServiceClassInfo.notifyWindowResponsive, tokenObj);
851     checkAndClearExceptionFromCallback(env, "notifyWindowResponsive");
852 }
853 
notifyMonitorUnresponsive(int32_t pid,const std::string & reason)854 void NativeInputManager::notifyMonitorUnresponsive(int32_t pid, const std::string& reason) {
855 #if DEBUG_INPUT_DISPATCHER_POLICY
856     ALOGD("notifyMonitorUnresponsive");
857 #endif
858     ATRACE_CALL();
859 
860     JNIEnv* env = jniEnv();
861     ScopedLocalFrame localFrame(env);
862 
863     ScopedLocalRef<jstring> reasonObj(env, env->NewStringUTF(reason.c_str()));
864 
865     env->CallVoidMethod(mServiceObj, gServiceClassInfo.notifyMonitorUnresponsive, pid,
866                         reasonObj.get());
867     checkAndClearExceptionFromCallback(env, "notifyMonitorUnresponsive");
868 }
869 
notifyMonitorResponsive(int32_t pid)870 void NativeInputManager::notifyMonitorResponsive(int32_t pid) {
871 #if DEBUG_INPUT_DISPATCHER_POLICY
872     ALOGD("notifyMonitorResponsive");
873 #endif
874     ATRACE_CALL();
875 
876     JNIEnv* env = jniEnv();
877     ScopedLocalFrame localFrame(env);
878 
879     env->CallVoidMethod(mServiceObj, gServiceClassInfo.notifyMonitorResponsive, pid);
880     checkAndClearExceptionFromCallback(env, "notifyMonitorResponsive");
881 }
882 
notifyInputChannelBroken(const sp<IBinder> & token)883 void NativeInputManager::notifyInputChannelBroken(const sp<IBinder>& token) {
884 #if DEBUG_INPUT_DISPATCHER_POLICY
885     ALOGD("notifyInputChannelBroken");
886 #endif
887     ATRACE_CALL();
888 
889     JNIEnv* env = jniEnv();
890     ScopedLocalFrame localFrame(env);
891 
892     jobject tokenObj = javaObjectForIBinder(env, token);
893     if (tokenObj) {
894         env->CallVoidMethod(mServiceObj, gServiceClassInfo.notifyInputChannelBroken,
895                 tokenObj);
896         checkAndClearExceptionFromCallback(env, "notifyInputChannelBroken");
897     }
898 }
899 
notifyUntrustedTouch(const std::string & obscuringPackage)900 void NativeInputManager::notifyUntrustedTouch(const std::string& obscuringPackage) {
901 #if DEBUG_INPUT_DISPATCHER_POLICY
902     ALOGD("notifyUntrustedTouch - obscuringPackage=%s", obscuringPackage.c_str());
903 #endif
904     ATRACE_CALL();
905     JNIEnv* env = jniEnv();
906     jstring jPackage = env->NewStringUTF(obscuringPackage.c_str());
907     env->CallVoidMethod(mServiceObj, gServiceClassInfo.notifyUntrustedTouch, jPackage);
908     checkAndClearExceptionFromCallback(env, "notifyUntrustedTouch");
909 }
910 
notifyFocusChanged(const sp<IBinder> & oldToken,const sp<IBinder> & newToken)911 void NativeInputManager::notifyFocusChanged(const sp<IBinder>& oldToken,
912         const sp<IBinder>& newToken) {
913 #if DEBUG_INPUT_DISPATCHER_POLICY
914     ALOGD("notifyFocusChanged");
915 #endif
916     ATRACE_CALL();
917 
918     JNIEnv* env = jniEnv();
919     ScopedLocalFrame localFrame(env);
920 
921     jobject oldTokenObj = javaObjectForIBinder(env, oldToken);
922     jobject newTokenObj = javaObjectForIBinder(env, newToken);
923     env->CallVoidMethod(mServiceObj, gServiceClassInfo.notifyFocusChanged,
924             oldTokenObj, newTokenObj);
925     checkAndClearExceptionFromCallback(env, "notifyFocusChanged");
926 }
927 
notifyDropWindow(const sp<IBinder> & token,float x,float y)928 void NativeInputManager::notifyDropWindow(const sp<IBinder>& token, float x, float y) {
929 #if DEBUG_INPUT_DISPATCHER_POLICY
930     ALOGD("notifyDropWindow");
931 #endif
932     ATRACE_CALL();
933 
934     JNIEnv* env = jniEnv();
935     ScopedLocalFrame localFrame(env);
936 
937     jobject tokenObj = javaObjectForIBinder(env, token);
938     env->CallVoidMethod(mServiceObj, gServiceClassInfo.notifyDropWindow, tokenObj, x, y);
939     checkAndClearExceptionFromCallback(env, "notifyDropWindow");
940 }
941 
notifySensorEvent(int32_t deviceId,InputDeviceSensorType sensorType,InputDeviceSensorAccuracy accuracy,nsecs_t timestamp,const std::vector<float> & values)942 void NativeInputManager::notifySensorEvent(int32_t deviceId, InputDeviceSensorType sensorType,
943                                            InputDeviceSensorAccuracy accuracy, nsecs_t timestamp,
944                                            const std::vector<float>& values) {
945 #if DEBUG_INPUT_DISPATCHER_POLICY
946     ALOGD("notifySensorEvent");
947 #endif
948     ATRACE_CALL();
949     JNIEnv* env = jniEnv();
950     ScopedLocalFrame localFrame(env);
951     jfloatArray arr = env->NewFloatArray(values.size());
952     env->SetFloatArrayRegion(arr, 0, values.size(), values.data());
953     env->CallVoidMethod(mServiceObj, gServiceClassInfo.notifySensorEvent, deviceId,
954                         static_cast<jint>(sensorType), accuracy, timestamp, arr);
955     checkAndClearExceptionFromCallback(env, "notifySensorEvent");
956 }
957 
notifySensorAccuracy(int32_t deviceId,InputDeviceSensorType sensorType,InputDeviceSensorAccuracy accuracy)958 void NativeInputManager::notifySensorAccuracy(int32_t deviceId, InputDeviceSensorType sensorType,
959                                               InputDeviceSensorAccuracy accuracy) {
960 #if DEBUG_INPUT_DISPATCHER_POLICY
961     ALOGD("notifySensorAccuracy");
962 #endif
963     ATRACE_CALL();
964     JNIEnv* env = jniEnv();
965     ScopedLocalFrame localFrame(env);
966     env->CallVoidMethod(mServiceObj, gServiceClassInfo.notifySensorAccuracy, deviceId,
967                         static_cast<jint>(sensorType), accuracy);
968     checkAndClearExceptionFromCallback(env, "notifySensorAccuracy");
969 }
970 
notifyVibratorState(int32_t deviceId,bool isOn)971 void NativeInputManager::notifyVibratorState(int32_t deviceId, bool isOn) {
972 #if DEBUG_INPUT_DISPATCHER_POLICY
973     ALOGD("notifyVibratorState isOn:%d", isOn);
974 #endif
975     ATRACE_CALL();
976     JNIEnv* env = jniEnv();
977     ScopedLocalFrame localFrame(env);
978     env->CallVoidMethod(mServiceObj, gServiceClassInfo.notifyVibratorState,
979                         static_cast<jint>(deviceId), static_cast<jboolean>(isOn));
980     checkAndClearExceptionFromCallback(env, "notifyVibratorState");
981 }
982 
getDispatcherConfiguration(InputDispatcherConfiguration * outConfig)983 void NativeInputManager::getDispatcherConfiguration(InputDispatcherConfiguration* outConfig) {
984     ATRACE_CALL();
985     JNIEnv* env = jniEnv();
986 
987     jint keyRepeatTimeout = env->CallIntMethod(mServiceObj,
988             gServiceClassInfo.getKeyRepeatTimeout);
989     if (!checkAndClearExceptionFromCallback(env, "getKeyRepeatTimeout")) {
990         outConfig->keyRepeatTimeout = milliseconds_to_nanoseconds(keyRepeatTimeout);
991     }
992 
993     jint keyRepeatDelay = env->CallIntMethod(mServiceObj,
994             gServiceClassInfo.getKeyRepeatDelay);
995     if (!checkAndClearExceptionFromCallback(env, "getKeyRepeatDelay")) {
996         outConfig->keyRepeatDelay = milliseconds_to_nanoseconds(keyRepeatDelay);
997     }
998 }
999 
displayRemoved(JNIEnv * env,int32_t displayId)1000 void NativeInputManager::displayRemoved(JNIEnv* env, int32_t displayId) {
1001     mInputManager->getDispatcher()->displayRemoved(displayId);
1002 }
1003 
setFocusedApplication(JNIEnv * env,int32_t displayId,jobject applicationHandleObj)1004 void NativeInputManager::setFocusedApplication(JNIEnv* env, int32_t displayId,
1005         jobject applicationHandleObj) {
1006     if (!applicationHandleObj) {
1007         return;
1008     }
1009     std::shared_ptr<InputApplicationHandle> applicationHandle =
1010             android_view_InputApplicationHandle_getHandle(env, applicationHandleObj);
1011     applicationHandle->updateInfo();
1012     mInputManager->getDispatcher()->setFocusedApplication(displayId, applicationHandle);
1013 }
1014 
setFocusedDisplay(JNIEnv * env,int32_t displayId)1015 void NativeInputManager::setFocusedDisplay(JNIEnv* env, int32_t displayId) {
1016     mInputManager->getDispatcher()->setFocusedDisplay(displayId);
1017 }
1018 
setInputDispatchMode(bool enabled,bool frozen)1019 void NativeInputManager::setInputDispatchMode(bool enabled, bool frozen) {
1020     mInputManager->getDispatcher()->setInputDispatchMode(enabled, frozen);
1021 }
1022 
setSystemUiLightsOut(bool lightsOut)1023 void NativeInputManager::setSystemUiLightsOut(bool lightsOut) {
1024     AutoMutex _l(mLock);
1025 
1026     if (mLocked.systemUiLightsOut != lightsOut) {
1027         mLocked.systemUiLightsOut = lightsOut;
1028         updateInactivityTimeoutLocked();
1029     }
1030 }
1031 
updateInactivityTimeoutLocked()1032 void NativeInputManager::updateInactivityTimeoutLocked() REQUIRES(mLock) {
1033     std::shared_ptr<PointerController> controller = mLocked.pointerController.lock();
1034     if (controller == nullptr) {
1035         return;
1036     }
1037 
1038     controller->setInactivityTimeout(mLocked.systemUiLightsOut ? InactivityTimeout::SHORT
1039                                                                : InactivityTimeout::NORMAL);
1040 }
1041 
setPointerSpeed(int32_t speed)1042 void NativeInputManager::setPointerSpeed(int32_t speed) {
1043     { // acquire lock
1044         AutoMutex _l(mLock);
1045 
1046         if (mLocked.pointerSpeed == speed) {
1047             return;
1048         }
1049 
1050         ALOGI("Setting pointer speed to %d.", speed);
1051         mLocked.pointerSpeed = speed;
1052     } // release lock
1053 
1054     mInputManager->getReader()->requestRefreshConfiguration(
1055             InputReaderConfiguration::CHANGE_POINTER_SPEED);
1056 }
1057 
setInputDeviceEnabled(uint32_t deviceId,bool enabled)1058 void NativeInputManager::setInputDeviceEnabled(uint32_t deviceId, bool enabled) {
1059     { // acquire lock
1060         AutoMutex _l(mLock);
1061 
1062         auto it = mLocked.disabledInputDevices.find(deviceId);
1063         bool currentlyEnabled = it == mLocked.disabledInputDevices.end();
1064         if (!enabled && currentlyEnabled) {
1065             mLocked.disabledInputDevices.insert(deviceId);
1066         }
1067         if (enabled && !currentlyEnabled) {
1068             mLocked.disabledInputDevices.erase(deviceId);
1069         }
1070     } // release lock
1071 
1072     mInputManager->getReader()->requestRefreshConfiguration(
1073             InputReaderConfiguration::CHANGE_ENABLED_STATE);
1074 }
1075 
setShowTouches(bool enabled)1076 void NativeInputManager::setShowTouches(bool enabled) {
1077     { // acquire lock
1078         AutoMutex _l(mLock);
1079 
1080         if (mLocked.showTouches == enabled) {
1081             return;
1082         }
1083 
1084         ALOGI("Setting show touches feature to %s.", enabled ? "enabled" : "disabled");
1085         mLocked.showTouches = enabled;
1086     } // release lock
1087 
1088     mInputManager->getReader()->requestRefreshConfiguration(
1089             InputReaderConfiguration::CHANGE_SHOW_TOUCHES);
1090 }
1091 
requestPointerCapture(const sp<IBinder> & windowToken,bool enabled)1092 void NativeInputManager::requestPointerCapture(const sp<IBinder>& windowToken, bool enabled) {
1093     mInputManager->getDispatcher()->requestPointerCapture(windowToken, enabled);
1094 }
1095 
setInteractive(bool interactive)1096 void NativeInputManager::setInteractive(bool interactive) {
1097     mInteractive = interactive;
1098 }
1099 
reloadCalibration()1100 void NativeInputManager::reloadCalibration() {
1101     mInputManager->getReader()->requestRefreshConfiguration(
1102             InputReaderConfiguration::CHANGE_TOUCH_AFFINE_TRANSFORMATION);
1103 }
1104 
setPointerIconType(int32_t iconId)1105 void NativeInputManager::setPointerIconType(int32_t iconId) {
1106     AutoMutex _l(mLock);
1107     std::shared_ptr<PointerController> controller = mLocked.pointerController.lock();
1108     if (controller != nullptr) {
1109         controller->updatePointerIcon(iconId);
1110     }
1111 }
1112 
reloadPointerIcons()1113 void NativeInputManager::reloadPointerIcons() {
1114     AutoMutex _l(mLock);
1115     std::shared_ptr<PointerController> controller = mLocked.pointerController.lock();
1116     if (controller != nullptr) {
1117         controller->reloadPointerResources();
1118     }
1119 }
1120 
setCustomPointerIcon(const SpriteIcon & icon)1121 void NativeInputManager::setCustomPointerIcon(const SpriteIcon& icon) {
1122     AutoMutex _l(mLock);
1123     std::shared_ptr<PointerController> controller = mLocked.pointerController.lock();
1124     if (controller != nullptr) {
1125         controller->setCustomPointerIcon(icon);
1126     }
1127 }
1128 
getTouchAffineTransformation(JNIEnv * env,jfloatArray matrixArr)1129 TouchAffineTransformation NativeInputManager::getTouchAffineTransformation(
1130         JNIEnv *env, jfloatArray matrixArr) {
1131     ATRACE_CALL();
1132     ScopedFloatArrayRO matrix(env, matrixArr);
1133     assert(matrix.size() == 6);
1134 
1135     TouchAffineTransformation transform;
1136     transform.x_scale  = matrix[0];
1137     transform.x_ymix   = matrix[1];
1138     transform.x_offset = matrix[2];
1139     transform.y_xmix   = matrix[3];
1140     transform.y_scale  = matrix[4];
1141     transform.y_offset = matrix[5];
1142 
1143     return transform;
1144 }
1145 
getTouchAffineTransformation(const std::string & inputDeviceDescriptor,int32_t surfaceRotation)1146 TouchAffineTransformation NativeInputManager::getTouchAffineTransformation(
1147         const std::string& inputDeviceDescriptor, int32_t surfaceRotation) {
1148     JNIEnv* env = jniEnv();
1149 
1150     ScopedLocalRef<jstring> descriptorObj(env, env->NewStringUTF(inputDeviceDescriptor.c_str()));
1151 
1152     jobject cal = env->CallObjectMethod(mServiceObj,
1153             gServiceClassInfo.getTouchCalibrationForInputDevice, descriptorObj.get(),
1154             surfaceRotation);
1155 
1156     jfloatArray matrixArr = jfloatArray(env->CallObjectMethod(cal,
1157             gTouchCalibrationClassInfo.getAffineTransform));
1158 
1159     TouchAffineTransformation transform = getTouchAffineTransformation(env, matrixArr);
1160 
1161     env->DeleteLocalRef(matrixArr);
1162     env->DeleteLocalRef(cal);
1163 
1164     return transform;
1165 }
1166 
filterInputEvent(const InputEvent * inputEvent,uint32_t policyFlags)1167 bool NativeInputManager::filterInputEvent(const InputEvent* inputEvent, uint32_t policyFlags) {
1168     ATRACE_CALL();
1169     jobject inputEventObj;
1170 
1171     JNIEnv* env = jniEnv();
1172     switch (inputEvent->getType()) {
1173     case AINPUT_EVENT_TYPE_KEY:
1174         inputEventObj = android_view_KeyEvent_fromNative(env,
1175                 static_cast<const KeyEvent*>(inputEvent));
1176         break;
1177     case AINPUT_EVENT_TYPE_MOTION:
1178         inputEventObj = android_view_MotionEvent_obtainAsCopy(env,
1179                 static_cast<const MotionEvent*>(inputEvent));
1180         break;
1181     default:
1182         return true; // dispatch the event normally
1183     }
1184 
1185     if (!inputEventObj) {
1186         ALOGE("Failed to obtain input event object for filterInputEvent.");
1187         return true; // dispatch the event normally
1188     }
1189 
1190     // The callee is responsible for recycling the event.
1191     jboolean pass = env->CallBooleanMethod(mServiceObj, gServiceClassInfo.filterInputEvent,
1192             inputEventObj, policyFlags);
1193     if (checkAndClearExceptionFromCallback(env, "filterInputEvent")) {
1194         pass = true;
1195     }
1196     env->DeleteLocalRef(inputEventObj);
1197     return pass;
1198 }
1199 
interceptKeyBeforeQueueing(const KeyEvent * keyEvent,uint32_t & policyFlags)1200 void NativeInputManager::interceptKeyBeforeQueueing(const KeyEvent* keyEvent,
1201         uint32_t& policyFlags) {
1202     ATRACE_CALL();
1203     // Policy:
1204     // - Ignore untrusted events and pass them along.
1205     // - Ask the window manager what to do with normal events and trusted injected events.
1206     // - For normal events wake and brighten the screen if currently off or dim.
1207     bool interactive = mInteractive.load();
1208     if (interactive) {
1209         policyFlags |= POLICY_FLAG_INTERACTIVE;
1210     }
1211     if ((policyFlags & POLICY_FLAG_TRUSTED)) {
1212         nsecs_t when = keyEvent->getEventTime();
1213         JNIEnv* env = jniEnv();
1214         jobject keyEventObj = android_view_KeyEvent_fromNative(env, keyEvent);
1215         jint wmActions;
1216         if (keyEventObj) {
1217             wmActions = env->CallIntMethod(mServiceObj,
1218                     gServiceClassInfo.interceptKeyBeforeQueueing,
1219                     keyEventObj, policyFlags);
1220             if (checkAndClearExceptionFromCallback(env, "interceptKeyBeforeQueueing")) {
1221                 wmActions = 0;
1222             }
1223             android_view_KeyEvent_recycle(env, keyEventObj);
1224             env->DeleteLocalRef(keyEventObj);
1225         } else {
1226             ALOGE("Failed to obtain key event object for interceptKeyBeforeQueueing.");
1227             wmActions = 0;
1228         }
1229 
1230         handleInterceptActions(wmActions, when, /*byref*/ policyFlags);
1231     } else {
1232         if (interactive) {
1233             policyFlags |= POLICY_FLAG_PASS_TO_USER;
1234         }
1235     }
1236 }
1237 
interceptMotionBeforeQueueing(const int32_t displayId,nsecs_t when,uint32_t & policyFlags)1238 void NativeInputManager::interceptMotionBeforeQueueing(const int32_t displayId, nsecs_t when,
1239         uint32_t& policyFlags) {
1240     ATRACE_CALL();
1241     // Policy:
1242     // - Ignore untrusted events and pass them along.
1243     // - No special filtering for injected events required at this time.
1244     // - Filter normal events based on screen state.
1245     // - For normal events brighten (but do not wake) the screen if currently dim.
1246     bool interactive = mInteractive.load();
1247     if (interactive) {
1248         policyFlags |= POLICY_FLAG_INTERACTIVE;
1249     }
1250     if ((policyFlags & POLICY_FLAG_TRUSTED) && !(policyFlags & POLICY_FLAG_INJECTED)) {
1251         if (policyFlags & POLICY_FLAG_INTERACTIVE) {
1252             policyFlags |= POLICY_FLAG_PASS_TO_USER;
1253         } else {
1254             JNIEnv* env = jniEnv();
1255             jint wmActions = env->CallIntMethod(mServiceObj,
1256                         gServiceClassInfo.interceptMotionBeforeQueueingNonInteractive,
1257                         displayId, when, policyFlags);
1258             if (checkAndClearExceptionFromCallback(env,
1259                     "interceptMotionBeforeQueueingNonInteractive")) {
1260                 wmActions = 0;
1261             }
1262 
1263             handleInterceptActions(wmActions, when, /*byref*/ policyFlags);
1264         }
1265     } else {
1266         if (interactive) {
1267             policyFlags |= POLICY_FLAG_PASS_TO_USER;
1268         }
1269     }
1270 }
1271 
handleInterceptActions(jint wmActions,nsecs_t when,uint32_t & policyFlags)1272 void NativeInputManager::handleInterceptActions(jint wmActions, nsecs_t when,
1273         uint32_t& policyFlags) {
1274     if (wmActions & WM_ACTION_PASS_TO_USER) {
1275         policyFlags |= POLICY_FLAG_PASS_TO_USER;
1276     } else {
1277 #if DEBUG_INPUT_DISPATCHER_POLICY
1278         ALOGD("handleInterceptActions: Not passing key to user.");
1279 #endif
1280     }
1281 }
1282 
interceptKeyBeforeDispatching(const sp<IBinder> & token,const KeyEvent * keyEvent,uint32_t policyFlags)1283 nsecs_t NativeInputManager::interceptKeyBeforeDispatching(
1284         const sp<IBinder>& token,
1285         const KeyEvent* keyEvent, uint32_t policyFlags) {
1286     ATRACE_CALL();
1287     // Policy:
1288     // - Ignore untrusted events and pass them along.
1289     // - Filter normal events and trusted injected events through the window manager policy to
1290     //   handle the HOME key and the like.
1291     nsecs_t result = 0;
1292     if (policyFlags & POLICY_FLAG_TRUSTED) {
1293         JNIEnv* env = jniEnv();
1294         ScopedLocalFrame localFrame(env);
1295 
1296         // Token may be null
1297         jobject tokenObj = javaObjectForIBinder(env, token);
1298 
1299         jobject keyEventObj = android_view_KeyEvent_fromNative(env, keyEvent);
1300         if (keyEventObj) {
1301             jlong delayMillis = env->CallLongMethod(mServiceObj,
1302                     gServiceClassInfo.interceptKeyBeforeDispatching,
1303                     tokenObj, keyEventObj, policyFlags);
1304             bool error = checkAndClearExceptionFromCallback(env, "interceptKeyBeforeDispatching");
1305             android_view_KeyEvent_recycle(env, keyEventObj);
1306             env->DeleteLocalRef(keyEventObj);
1307             if (!error) {
1308                 if (delayMillis < 0) {
1309                     result = -1;
1310                 } else if (delayMillis > 0) {
1311                     result = milliseconds_to_nanoseconds(delayMillis);
1312                 }
1313             }
1314         } else {
1315             ALOGE("Failed to obtain key event object for interceptKeyBeforeDispatching.");
1316         }
1317     }
1318     return result;
1319 }
1320 
dispatchUnhandledKey(const sp<IBinder> & token,const KeyEvent * keyEvent,uint32_t policyFlags,KeyEvent * outFallbackKeyEvent)1321 bool NativeInputManager::dispatchUnhandledKey(const sp<IBinder>& token,
1322         const KeyEvent* keyEvent, uint32_t policyFlags, KeyEvent* outFallbackKeyEvent) {
1323     ATRACE_CALL();
1324     // Policy:
1325     // - Ignore untrusted events and do not perform default handling.
1326     bool result = false;
1327     if (policyFlags & POLICY_FLAG_TRUSTED) {
1328         JNIEnv* env = jniEnv();
1329         ScopedLocalFrame localFrame(env);
1330 
1331         // Note: tokenObj may be null.
1332         jobject tokenObj = javaObjectForIBinder(env, token);
1333         jobject keyEventObj = android_view_KeyEvent_fromNative(env, keyEvent);
1334         if (keyEventObj) {
1335             jobject fallbackKeyEventObj = env->CallObjectMethod(mServiceObj,
1336                     gServiceClassInfo.dispatchUnhandledKey,
1337                     tokenObj, keyEventObj, policyFlags);
1338             if (checkAndClearExceptionFromCallback(env, "dispatchUnhandledKey")) {
1339                 fallbackKeyEventObj = nullptr;
1340             }
1341             android_view_KeyEvent_recycle(env, keyEventObj);
1342             env->DeleteLocalRef(keyEventObj);
1343 
1344             if (fallbackKeyEventObj) {
1345                 // Note: outFallbackKeyEvent may be the same object as keyEvent.
1346                 if (!android_view_KeyEvent_toNative(env, fallbackKeyEventObj,
1347                         outFallbackKeyEvent)) {
1348                     result = true;
1349                 }
1350                 android_view_KeyEvent_recycle(env, fallbackKeyEventObj);
1351                 env->DeleteLocalRef(fallbackKeyEventObj);
1352             }
1353         } else {
1354             ALOGE("Failed to obtain key event object for dispatchUnhandledKey.");
1355         }
1356     }
1357     return result;
1358 }
1359 
pokeUserActivity(nsecs_t eventTime,int32_t eventType,int32_t displayId)1360 void NativeInputManager::pokeUserActivity(nsecs_t eventTime, int32_t eventType, int32_t displayId) {
1361     ATRACE_CALL();
1362     android_server_PowerManagerService_userActivity(eventTime, eventType, displayId);
1363 }
1364 
checkInjectEventsPermissionNonReentrant(int32_t injectorPid,int32_t injectorUid)1365 bool NativeInputManager::checkInjectEventsPermissionNonReentrant(
1366         int32_t injectorPid, int32_t injectorUid) {
1367     ATRACE_CALL();
1368     JNIEnv* env = jniEnv();
1369     jboolean result = env->CallBooleanMethod(mServiceObj,
1370             gServiceClassInfo.checkInjectEventsPermission, injectorPid, injectorUid);
1371     if (checkAndClearExceptionFromCallback(env, "checkInjectEventsPermission")) {
1372         result = false;
1373     }
1374     return result;
1375 }
1376 
onPointerDownOutsideFocus(const sp<IBinder> & touchedToken)1377 void NativeInputManager::onPointerDownOutsideFocus(const sp<IBinder>& touchedToken) {
1378     ATRACE_CALL();
1379     JNIEnv* env = jniEnv();
1380     ScopedLocalFrame localFrame(env);
1381 
1382     jobject touchedTokenObj = javaObjectForIBinder(env, touchedToken);
1383     env->CallVoidMethod(mServiceObj, gServiceClassInfo.onPointerDownOutsideFocus, touchedTokenObj);
1384     checkAndClearExceptionFromCallback(env, "onPointerDownOutsideFocus");
1385 }
1386 
setPointerCapture(const PointerCaptureRequest & request)1387 void NativeInputManager::setPointerCapture(const PointerCaptureRequest& request) {
1388     { // acquire lock
1389         AutoMutex _l(mLock);
1390 
1391         if (mLocked.pointerCaptureRequest == request) {
1392             return;
1393         }
1394 
1395         ALOGV("%s pointer capture.", request.enable ? "Enabling" : "Disabling");
1396         mLocked.pointerCaptureRequest = request;
1397     } // release lock
1398 
1399     mInputManager->getReader()->requestRefreshConfiguration(
1400             InputReaderConfiguration::CHANGE_POINTER_CAPTURE);
1401 }
1402 
loadPointerIcon(SpriteIcon * icon,int32_t displayId)1403 void NativeInputManager::loadPointerIcon(SpriteIcon* icon, int32_t displayId) {
1404     ATRACE_CALL();
1405     JNIEnv* env = jniEnv();
1406 
1407     ScopedLocalRef<jobject> pointerIconObj(env, env->CallObjectMethod(
1408             mServiceObj, gServiceClassInfo.getPointerIcon, displayId));
1409     if (checkAndClearExceptionFromCallback(env, "getPointerIcon")) {
1410         return;
1411     }
1412 
1413     ScopedLocalRef<jobject> displayContext(env, env->CallObjectMethod(
1414             mServiceObj, gServiceClassInfo.getContextForDisplay, displayId));
1415 
1416     PointerIcon pointerIcon;
1417     status_t status = android_view_PointerIcon_load(env, pointerIconObj.get(),
1418             displayContext.get(), &pointerIcon);
1419     if (!status && !pointerIcon.isNullIcon()) {
1420         *icon = SpriteIcon(
1421                 pointerIcon.bitmap, pointerIcon.style, pointerIcon.hotSpotX, pointerIcon.hotSpotY);
1422     } else {
1423         *icon = SpriteIcon();
1424     }
1425 }
1426 
loadPointerResources(PointerResources * outResources,int32_t displayId)1427 void NativeInputManager::loadPointerResources(PointerResources* outResources, int32_t displayId) {
1428     ATRACE_CALL();
1429     JNIEnv* env = jniEnv();
1430 
1431     ScopedLocalRef<jobject> displayContext(env, env->CallObjectMethod(
1432             mServiceObj, gServiceClassInfo.getContextForDisplay, displayId));
1433 
1434     loadSystemIconAsSprite(env, displayContext.get(), POINTER_ICON_STYLE_SPOT_HOVER,
1435             &outResources->spotHover);
1436     loadSystemIconAsSprite(env, displayContext.get(), POINTER_ICON_STYLE_SPOT_TOUCH,
1437             &outResources->spotTouch);
1438     loadSystemIconAsSprite(env, displayContext.get(), POINTER_ICON_STYLE_SPOT_ANCHOR,
1439             &outResources->spotAnchor);
1440 }
1441 
loadAdditionalMouseResources(std::map<int32_t,SpriteIcon> * outResources,std::map<int32_t,PointerAnimation> * outAnimationResources,int32_t displayId)1442 void NativeInputManager::loadAdditionalMouseResources(std::map<int32_t, SpriteIcon>* outResources,
1443         std::map<int32_t, PointerAnimation>* outAnimationResources, int32_t displayId) {
1444     ATRACE_CALL();
1445     JNIEnv* env = jniEnv();
1446 
1447     ScopedLocalRef<jobject> displayContext(env, env->CallObjectMethod(
1448             mServiceObj, gServiceClassInfo.getContextForDisplay, displayId));
1449 
1450     for (int iconId = POINTER_ICON_STYLE_CONTEXT_MENU; iconId <= POINTER_ICON_STYLE_GRABBING;
1451              ++iconId) {
1452         PointerIcon pointerIcon;
1453         loadSystemIconAsSpriteWithPointerIcon(
1454                 env, displayContext.get(), iconId, &pointerIcon, &((*outResources)[iconId]));
1455         if (!pointerIcon.bitmapFrames.empty()) {
1456             PointerAnimation& animationData = (*outAnimationResources)[iconId];
1457             size_t numFrames = pointerIcon.bitmapFrames.size() + 1;
1458             animationData.durationPerFrame =
1459                     milliseconds_to_nanoseconds(pointerIcon.durationPerFrame);
1460             animationData.animationFrames.reserve(numFrames);
1461             animationData.animationFrames.push_back(SpriteIcon(
1462                     pointerIcon.bitmap, pointerIcon.style,
1463                     pointerIcon.hotSpotX, pointerIcon.hotSpotY));
1464             for (size_t i = 0; i < numFrames - 1; ++i) {
1465               animationData.animationFrames.push_back(SpriteIcon(
1466                       pointerIcon.bitmapFrames[i], pointerIcon.style,
1467                       pointerIcon.hotSpotX, pointerIcon.hotSpotY));
1468             }
1469         }
1470     }
1471     loadSystemIconAsSprite(env, displayContext.get(), POINTER_ICON_STYLE_NULL,
1472             &((*outResources)[POINTER_ICON_STYLE_NULL]));
1473 }
1474 
getDefaultPointerIconId()1475 int32_t NativeInputManager::getDefaultPointerIconId() {
1476     return POINTER_ICON_STYLE_ARROW;
1477 }
1478 
getCustomPointerIconId()1479 int32_t NativeInputManager::getCustomPointerIconId() {
1480     return POINTER_ICON_STYLE_CUSTOM;
1481 }
1482 
setMotionClassifierEnabled(bool enabled)1483 void NativeInputManager::setMotionClassifierEnabled(bool enabled) {
1484     mInputManager->getClassifier()->setMotionClassifierEnabled(enabled);
1485 }
1486 
1487 // ----------------------------------------------------------------------------
1488 
nativeInit(JNIEnv * env,jclass,jobject serviceObj,jobject contextObj,jobject messageQueueObj)1489 static jlong nativeInit(JNIEnv* env, jclass /* clazz */,
1490         jobject serviceObj, jobject contextObj, jobject messageQueueObj) {
1491     sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueObj);
1492     if (messageQueue == nullptr) {
1493         jniThrowRuntimeException(env, "MessageQueue is not initialized.");
1494         return 0;
1495     }
1496 
1497     NativeInputManager* im = new NativeInputManager(contextObj, serviceObj,
1498             messageQueue->getLooper());
1499     im->incStrong(0);
1500     return reinterpret_cast<jlong>(im);
1501 }
1502 
nativeStart(JNIEnv * env,jclass,jlong ptr)1503 static void nativeStart(JNIEnv* env, jclass /* clazz */, jlong ptr) {
1504     NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
1505 
1506     status_t result = im->getInputManager()->start();
1507     if (result) {
1508         jniThrowRuntimeException(env, "Input manager could not be started.");
1509     }
1510 }
1511 
nativeSetDisplayViewports(JNIEnv * env,jclass,jlong ptr,jobjectArray viewportObjArray)1512 static void nativeSetDisplayViewports(JNIEnv* env, jclass /* clazz */, jlong ptr,
1513         jobjectArray viewportObjArray) {
1514     NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
1515     im->setDisplayViewports(env, viewportObjArray);
1516 }
1517 
nativeGetScanCodeState(JNIEnv *,jclass,jlong ptr,jint deviceId,jint sourceMask,jint scanCode)1518 static jint nativeGetScanCodeState(JNIEnv* /* env */, jclass /* clazz */,
1519         jlong ptr, jint deviceId, jint sourceMask, jint scanCode) {
1520     NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
1521 
1522     return (jint) im->getInputManager()->getReader()->getScanCodeState(
1523             deviceId, uint32_t(sourceMask), scanCode);
1524 }
1525 
nativeGetKeyCodeState(JNIEnv *,jclass,jlong ptr,jint deviceId,jint sourceMask,jint keyCode)1526 static jint nativeGetKeyCodeState(JNIEnv* /* env */, jclass /* clazz */,
1527         jlong ptr, jint deviceId, jint sourceMask, jint keyCode) {
1528     NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
1529 
1530     return (jint) im->getInputManager()->getReader()->getKeyCodeState(
1531             deviceId, uint32_t(sourceMask), keyCode);
1532 }
1533 
nativeGetSwitchState(JNIEnv *,jclass,jlong ptr,jint deviceId,jint sourceMask,jint sw)1534 static jint nativeGetSwitchState(JNIEnv* /* env */, jclass /* clazz */,
1535         jlong ptr, jint deviceId, jint sourceMask, jint sw) {
1536     NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
1537 
1538     return (jint) im->getInputManager()->getReader()->getSwitchState(
1539             deviceId, uint32_t(sourceMask), sw);
1540 }
1541 
nativeHasKeys(JNIEnv * env,jclass,jlong ptr,jint deviceId,jint sourceMask,jintArray keyCodes,jbooleanArray outFlags)1542 static jboolean nativeHasKeys(JNIEnv* env, jclass /* clazz */,
1543         jlong ptr, jint deviceId, jint sourceMask, jintArray keyCodes, jbooleanArray outFlags) {
1544     NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
1545 
1546     int32_t* codes = env->GetIntArrayElements(keyCodes, nullptr);
1547     uint8_t* flags = env->GetBooleanArrayElements(outFlags, nullptr);
1548     jsize numCodes = env->GetArrayLength(keyCodes);
1549     jboolean result;
1550     if (numCodes == env->GetArrayLength(keyCodes)) {
1551         if (im->getInputManager()->getReader()->hasKeys(
1552                 deviceId, uint32_t(sourceMask), numCodes, codes, flags)) {
1553             result = JNI_TRUE;
1554         } else {
1555             result = JNI_FALSE;
1556         }
1557     } else {
1558         result = JNI_FALSE;
1559     }
1560 
1561     env->ReleaseBooleanArrayElements(outFlags, flags, 0);
1562     env->ReleaseIntArrayElements(keyCodes, codes, 0);
1563     return result;
1564 }
1565 
handleInputChannelDisposed(JNIEnv * env,jobject,const std::shared_ptr<InputChannel> & inputChannel,void * data)1566 static void handleInputChannelDisposed(JNIEnv* env, jobject /* inputChannelObj */,
1567                                        const std::shared_ptr<InputChannel>& inputChannel,
1568                                        void* data) {
1569     NativeInputManager* im = static_cast<NativeInputManager*>(data);
1570 
1571     ALOGW("Input channel object '%s' was disposed without first being removed with "
1572           "the input manager!",
1573           inputChannel->getName().c_str());
1574     im->removeInputChannel(env, inputChannel->getConnectionToken());
1575 }
1576 
nativeCreateInputChannel(JNIEnv * env,jclass,jlong ptr,jstring nameObj)1577 static jobject nativeCreateInputChannel(JNIEnv* env, jclass /* clazz */, jlong ptr,
1578                                         jstring nameObj) {
1579     NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
1580 
1581     ScopedUtfChars nameChars(env, nameObj);
1582     std::string name = nameChars.c_str();
1583 
1584     base::Result<std::unique_ptr<InputChannel>> inputChannel = im->createInputChannel(env, name);
1585 
1586     if (!inputChannel.ok()) {
1587         std::string message = inputChannel.error().message();
1588         message += StringPrintf(" Status=%d", inputChannel.error().code());
1589         jniThrowRuntimeException(env, message.c_str());
1590         return nullptr;
1591     }
1592 
1593     jobject inputChannelObj =
1594             android_view_InputChannel_createJavaObject(env, std::move(*inputChannel));
1595     if (!inputChannelObj) {
1596         return nullptr;
1597     }
1598 
1599     android_view_InputChannel_setDisposeCallback(env, inputChannelObj,
1600             handleInputChannelDisposed, im);
1601     return inputChannelObj;
1602 }
1603 
nativeCreateInputMonitor(JNIEnv * env,jclass,jlong ptr,jint displayId,jboolean isGestureMonitor,jstring nameObj,jint pid)1604 static jobject nativeCreateInputMonitor(JNIEnv* env, jclass /* clazz */, jlong ptr, jint displayId,
1605                                         jboolean isGestureMonitor, jstring nameObj, jint pid) {
1606     NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
1607 
1608     if (displayId == ADISPLAY_ID_NONE) {
1609         std::string message = "InputChannel used as a monitor must be associated with a display";
1610         jniThrowRuntimeException(env, message.c_str());
1611         return nullptr;
1612     }
1613 
1614     ScopedUtfChars nameChars(env, nameObj);
1615     std::string name = nameChars.c_str();
1616 
1617     base::Result<std::unique_ptr<InputChannel>> inputChannel =
1618             im->createInputMonitor(env, displayId, isGestureMonitor, name, pid);
1619 
1620     if (!inputChannel.ok()) {
1621         std::string message = inputChannel.error().message();
1622         message += StringPrintf(" Status=%d", inputChannel.error().code());
1623         jniThrowRuntimeException(env, message.c_str());
1624         return nullptr;
1625     }
1626 
1627     jobject inputChannelObj =
1628             android_view_InputChannel_createJavaObject(env, std::move(*inputChannel));
1629     if (!inputChannelObj) {
1630         return nullptr;
1631     }
1632     return inputChannelObj;
1633 }
1634 
nativeRemoveInputChannel(JNIEnv * env,jclass,jlong ptr,jobject tokenObj)1635 static void nativeRemoveInputChannel(JNIEnv* env, jclass /* clazz */, jlong ptr, jobject tokenObj) {
1636     NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
1637     sp<IBinder> token = ibinderForJavaObject(env, tokenObj);
1638 
1639     status_t status = im->removeInputChannel(env, token);
1640     if (status && status != BAD_VALUE) { // ignore already removed channel
1641         std::string message;
1642         message += StringPrintf("Failed to remove input channel.  status=%d", status);
1643         jniThrowRuntimeException(env, message.c_str());
1644     }
1645 }
1646 
nativePilferPointers(JNIEnv * env,jclass,jlong ptr,jobject tokenObj)1647 static void nativePilferPointers(JNIEnv* env, jclass /* clazz */, jlong ptr, jobject tokenObj) {
1648     NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
1649     sp<IBinder> token = ibinderForJavaObject(env, tokenObj);
1650     im->pilferPointers(token);
1651 }
1652 
1653 
nativeSetInputFilterEnabled(JNIEnv *,jclass,jlong ptr,jboolean enabled)1654 static void nativeSetInputFilterEnabled(JNIEnv* /* env */, jclass /* clazz */,
1655         jlong ptr, jboolean enabled) {
1656     NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
1657 
1658     im->getInputManager()->getDispatcher()->setInputFilterEnabled(enabled);
1659 }
1660 
nativeSetInTouchMode(JNIEnv *,jclass,jlong ptr,jboolean inTouchMode)1661 static void nativeSetInTouchMode(JNIEnv* /* env */, jclass /* clazz */,
1662         jlong ptr, jboolean inTouchMode) {
1663     NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
1664 
1665     im->getInputManager()->getDispatcher()->setInTouchMode(inTouchMode);
1666 }
1667 
nativeSetMaximumObscuringOpacityForTouch(JNIEnv *,jclass,jlong ptr,jfloat opacity)1668 static void nativeSetMaximumObscuringOpacityForTouch(JNIEnv* /* env */, jclass /* clazz */,
1669                                                      jlong ptr, jfloat opacity) {
1670     NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
1671 
1672     im->getInputManager()->getDispatcher()->setMaximumObscuringOpacityForTouch(opacity);
1673 }
1674 
nativeSetBlockUntrustedTouchesMode(JNIEnv * env,jclass,jlong ptr,jint mode)1675 static void nativeSetBlockUntrustedTouchesMode(JNIEnv* env, jclass /* clazz */, jlong ptr,
1676                                                jint mode) {
1677     NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
1678 
1679     im->getInputManager()->getDispatcher()->setBlockUntrustedTouchesMode(
1680             static_cast<BlockUntrustedTouchesMode>(mode));
1681 }
1682 
nativeInjectInputEvent(JNIEnv * env,jclass,jlong ptr,jobject inputEventObj,jint injectorPid,jint injectorUid,jint syncMode,jint timeoutMillis,jint policyFlags)1683 static jint nativeInjectInputEvent(JNIEnv* env, jclass /* clazz */,
1684         jlong ptr, jobject inputEventObj, jint injectorPid, jint injectorUid,
1685         jint syncMode, jint timeoutMillis, jint policyFlags) {
1686     NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
1687 
1688     // static_cast is safe because the value was already checked at the Java layer
1689     InputEventInjectionSync mode = static_cast<InputEventInjectionSync>(syncMode);
1690 
1691     if (env->IsInstanceOf(inputEventObj, gKeyEventClassInfo.clazz)) {
1692         KeyEvent keyEvent;
1693         status_t status = android_view_KeyEvent_toNative(env, inputEventObj, & keyEvent);
1694         if (status) {
1695             jniThrowRuntimeException(env, "Could not read contents of KeyEvent object.");
1696             return static_cast<jint>(InputEventInjectionResult::FAILED);
1697         }
1698 
1699         const InputEventInjectionResult result =
1700                 im->getInputManager()->getDispatcher()->injectInputEvent(&keyEvent, injectorPid,
1701                                                                          injectorUid, mode,
1702                                                                          std::chrono::milliseconds(
1703                                                                                  timeoutMillis),
1704                                                                          uint32_t(policyFlags));
1705         return static_cast<jint>(result);
1706     } else if (env->IsInstanceOf(inputEventObj, gMotionEventClassInfo.clazz)) {
1707         const MotionEvent* motionEvent = android_view_MotionEvent_getNativePtr(env, inputEventObj);
1708         if (!motionEvent) {
1709             jniThrowRuntimeException(env, "Could not read contents of MotionEvent object.");
1710             return static_cast<jint>(InputEventInjectionResult::FAILED);
1711         }
1712 
1713         const InputEventInjectionResult result =
1714                 im->getInputManager()->getDispatcher()->injectInputEvent(motionEvent, injectorPid,
1715                                                                          injectorUid, mode,
1716                                                                          std::chrono::milliseconds(
1717                                                                                  timeoutMillis),
1718                                                                          uint32_t(policyFlags));
1719         return static_cast<jint>(result);
1720     } else {
1721         jniThrowRuntimeException(env, "Invalid input event type.");
1722         return static_cast<jint>(InputEventInjectionResult::FAILED);
1723     }
1724 }
1725 
nativeVerifyInputEvent(JNIEnv * env,jclass,jlong ptr,jobject inputEventObj)1726 static jobject nativeVerifyInputEvent(JNIEnv* env, jclass /* clazz */, jlong ptr,
1727                                       jobject inputEventObj) {
1728     NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
1729 
1730     if (env->IsInstanceOf(inputEventObj, gKeyEventClassInfo.clazz)) {
1731         KeyEvent keyEvent;
1732         status_t status = android_view_KeyEvent_toNative(env, inputEventObj, &keyEvent);
1733         if (status) {
1734             jniThrowRuntimeException(env, "Could not read contents of KeyEvent object.");
1735             return nullptr;
1736         }
1737 
1738         std::unique_ptr<VerifiedInputEvent> verifiedEvent =
1739                 im->getInputManager()->getDispatcher()->verifyInputEvent(keyEvent);
1740         if (verifiedEvent == nullptr) {
1741             return nullptr;
1742         }
1743 
1744         return android_view_VerifiedKeyEvent(env,
1745                                              static_cast<const VerifiedKeyEvent&>(*verifiedEvent));
1746     } else if (env->IsInstanceOf(inputEventObj, gMotionEventClassInfo.clazz)) {
1747         const MotionEvent* motionEvent = android_view_MotionEvent_getNativePtr(env, inputEventObj);
1748         if (!motionEvent) {
1749             jniThrowRuntimeException(env, "Could not read contents of MotionEvent object.");
1750             return nullptr;
1751         }
1752 
1753         std::unique_ptr<VerifiedInputEvent> verifiedEvent =
1754                 im->getInputManager()->getDispatcher()->verifyInputEvent(*motionEvent);
1755 
1756         if (verifiedEvent == nullptr) {
1757             return nullptr;
1758         }
1759 
1760         return android_view_VerifiedMotionEvent(env,
1761                                                 static_cast<const VerifiedMotionEvent&>(
1762                                                         *verifiedEvent));
1763     } else {
1764         jniThrowRuntimeException(env, "Invalid input event type.");
1765         return nullptr;
1766     }
1767 }
1768 
nativeToggleCapsLock(JNIEnv * env,jclass,jlong ptr,jint deviceId)1769 static void nativeToggleCapsLock(JNIEnv* env, jclass /* clazz */,
1770          jlong ptr, jint deviceId) {
1771     NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
1772 
1773     im->getInputManager()->getReader()->toggleCapsLockState(deviceId);
1774 }
1775 
nativeDisplayRemoved(JNIEnv * env,jclass,jlong ptr,jint displayId)1776 static void nativeDisplayRemoved(JNIEnv* env, jclass /* clazz */, jlong ptr, jint displayId) {
1777     NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
1778 
1779     im->displayRemoved(env, displayId);
1780 }
1781 
nativeSetFocusedApplication(JNIEnv * env,jclass,jlong ptr,jint displayId,jobject applicationHandleObj)1782 static void nativeSetFocusedApplication(JNIEnv* env, jclass /* clazz */,
1783         jlong ptr, jint displayId, jobject applicationHandleObj) {
1784     NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
1785 
1786     im->setFocusedApplication(env, displayId, applicationHandleObj);
1787 }
1788 
nativeSetFocusedDisplay(JNIEnv * env,jclass,jlong ptr,jint displayId)1789 static void nativeSetFocusedDisplay(JNIEnv* env, jclass /* clazz */,
1790         jlong ptr, jint displayId) {
1791     NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
1792 
1793     im->setFocusedDisplay(env, displayId);
1794 }
1795 
nativeRequestPointerCapture(JNIEnv * env,jclass,jlong ptr,jobject tokenObj,jboolean enabled)1796 static void nativeRequestPointerCapture(JNIEnv* env, jclass /* clazz */, jlong ptr,
1797                                         jobject tokenObj, jboolean enabled) {
1798     NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
1799     sp<IBinder> windowToken = ibinderForJavaObject(env, tokenObj);
1800 
1801     im->requestPointerCapture(windowToken, enabled);
1802 }
1803 
nativeSetInputDispatchMode(JNIEnv *,jclass,jlong ptr,jboolean enabled,jboolean frozen)1804 static void nativeSetInputDispatchMode(JNIEnv* /* env */,
1805         jclass /* clazz */, jlong ptr, jboolean enabled, jboolean frozen) {
1806     NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
1807 
1808     im->setInputDispatchMode(enabled, frozen);
1809 }
1810 
nativeSetSystemUiLightsOut(JNIEnv *,jclass,jlong ptr,jboolean lightsOut)1811 static void nativeSetSystemUiLightsOut(JNIEnv* /* env */, jclass /* clazz */, jlong ptr,
1812                                        jboolean lightsOut) {
1813     NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
1814 
1815     im->setSystemUiLightsOut(lightsOut);
1816 }
1817 
nativeTransferTouchFocus(JNIEnv * env,jclass,jlong ptr,jobject fromChannelTokenObj,jobject toChannelTokenObj,jboolean isDragDrop)1818 static jboolean nativeTransferTouchFocus(JNIEnv* env, jclass /* clazz */, jlong ptr,
1819                                          jobject fromChannelTokenObj, jobject toChannelTokenObj,
1820                                          jboolean isDragDrop) {
1821     if (fromChannelTokenObj == nullptr || toChannelTokenObj == nullptr) {
1822         return JNI_FALSE;
1823     }
1824 
1825     sp<IBinder> fromChannelToken = ibinderForJavaObject(env, fromChannelTokenObj);
1826     sp<IBinder> toChannelToken = ibinderForJavaObject(env, toChannelTokenObj);
1827 
1828     NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
1829     if (im->getInputManager()->getDispatcher()->transferTouchFocus(fromChannelToken, toChannelToken,
1830                                                                    isDragDrop)) {
1831         return JNI_TRUE;
1832     } else {
1833         return JNI_FALSE;
1834     }
1835 }
1836 
nativeTransferTouch(JNIEnv * env,jclass,jlong ptr,jobject destChannelTokenObj)1837 static jboolean nativeTransferTouch(JNIEnv* env, jclass /* clazz */, jlong ptr,
1838                                     jobject destChannelTokenObj) {
1839     sp<IBinder> destChannelToken = ibinderForJavaObject(env, destChannelTokenObj);
1840 
1841     NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
1842     if (im->getInputManager()->getDispatcher()->transferTouch(destChannelToken)) {
1843         return JNI_TRUE;
1844     } else {
1845         return JNI_FALSE;
1846     }
1847 }
1848 
nativeSetPointerSpeed(JNIEnv *,jclass,jlong ptr,jint speed)1849 static void nativeSetPointerSpeed(JNIEnv* /* env */, jclass /* clazz */, jlong ptr, jint speed) {
1850     NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
1851 
1852     im->setPointerSpeed(speed);
1853 }
1854 
nativeSetShowTouches(JNIEnv *,jclass,jlong ptr,jboolean enabled)1855 static void nativeSetShowTouches(JNIEnv* /* env */,
1856         jclass /* clazz */, jlong ptr, jboolean enabled) {
1857     NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
1858 
1859     im->setShowTouches(enabled);
1860 }
1861 
nativeSetInteractive(JNIEnv * env,jclass clazz,jlong ptr,jboolean interactive)1862 static void nativeSetInteractive(JNIEnv* env,
1863         jclass clazz, jlong ptr, jboolean interactive) {
1864     NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
1865 
1866     im->setInteractive(interactive);
1867 }
1868 
nativeReloadCalibration(JNIEnv * env,jclass clazz,jlong ptr)1869 static void nativeReloadCalibration(JNIEnv* env, jclass clazz, jlong ptr) {
1870     NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
1871 
1872     im->reloadCalibration();
1873 }
1874 
nativeVibrate(JNIEnv * env,jclass,jlong ptr,jint deviceId,jlongArray patternObj,jintArray amplitudesObj,jint repeat,jint token)1875 static void nativeVibrate(JNIEnv* env, jclass /* clazz */, jlong ptr, jint deviceId,
1876                           jlongArray patternObj, jintArray amplitudesObj, jint repeat, jint token) {
1877     NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
1878 
1879     size_t patternSize = env->GetArrayLength(patternObj);
1880     if (patternSize > MAX_VIBRATE_PATTERN_SIZE) {
1881         ALOGI("Skipped requested vibration because the pattern size is %zu "
1882                 "which is more than the maximum supported size of %d.",
1883                 patternSize, MAX_VIBRATE_PATTERN_SIZE);
1884         return; // limit to reasonable size
1885     }
1886 
1887     jlong* patternMillis = static_cast<jlong*>(env->GetPrimitiveArrayCritical(
1888             patternObj, nullptr));
1889     jint* amplitudes = static_cast<jint*>(env->GetPrimitiveArrayCritical(amplitudesObj, nullptr));
1890 
1891     VibrationSequence sequence(patternSize);
1892     std::vector<int32_t> vibrators = im->getInputManager()->getReader()->getVibratorIds(deviceId);
1893     for (size_t i = 0; i < patternSize; i++) {
1894         // VibrationEffect.validate guarantees duration > 0.
1895         std::chrono::milliseconds duration(patternMillis[i]);
1896         VibrationElement element(CHANNEL_SIZE);
1897         element.duration = std::min(duration, MAX_VIBRATE_PATTERN_DELAY_MILLIS);
1898         // Vibrate on both channels
1899         for (int32_t channel = 0; channel < vibrators.size(); channel++) {
1900             element.addChannel(vibrators[channel], static_cast<uint8_t>(amplitudes[i]));
1901         }
1902         sequence.addElement(element);
1903     }
1904     env->ReleasePrimitiveArrayCritical(patternObj, patternMillis, JNI_ABORT);
1905     env->ReleasePrimitiveArrayCritical(amplitudesObj, amplitudes, JNI_ABORT);
1906 
1907     im->getInputManager()->getReader()->vibrate(deviceId, sequence, repeat, token);
1908 }
1909 
nativeVibrateCombined(JNIEnv * env,jclass,jlong ptr,jint deviceId,jlongArray patternObj,jobject amplitudesObj,jint repeat,jint token)1910 static void nativeVibrateCombined(JNIEnv* env, jclass /* clazz */, jlong ptr, jint deviceId,
1911                                   jlongArray patternObj, jobject amplitudesObj, jint repeat,
1912                                   jint token) {
1913     NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
1914 
1915     size_t patternSize = env->GetArrayLength(patternObj);
1916 
1917     if (patternSize > MAX_VIBRATE_PATTERN_SIZE) {
1918         ALOGI("Skipped requested vibration because the pattern size is %zu "
1919               "which is more than the maximum supported size of %d.",
1920               patternSize, MAX_VIBRATE_PATTERN_SIZE);
1921         return; // limit to reasonable size
1922     }
1923     const jlong* patternMillis = env->GetLongArrayElements(patternObj, nullptr);
1924 
1925     std::array<jint*, CHANNEL_SIZE> amplitudesArray;
1926     std::array<jint, CHANNEL_SIZE> vibratorIdArray;
1927     jint amplSize = env->CallIntMethod(amplitudesObj, gSparseArrayClassInfo.size);
1928     if (amplSize > CHANNEL_SIZE) {
1929         ALOGE("Can not fit into input device vibration element.");
1930         return;
1931     }
1932 
1933     for (int i = 0; i < amplSize; i++) {
1934         vibratorIdArray[i] = env->CallIntMethod(amplitudesObj, gSparseArrayClassInfo.keyAt, i);
1935         jintArray arr = static_cast<jintArray>(
1936                 env->CallObjectMethod(amplitudesObj, gSparseArrayClassInfo.valueAt, i));
1937         amplitudesArray[i] = env->GetIntArrayElements(arr, nullptr);
1938         if (env->GetArrayLength(arr) != patternSize) {
1939             ALOGE("Amplitude length not equal to pattern length!");
1940             return;
1941         }
1942     }
1943 
1944     VibrationSequence sequence(patternSize);
1945     for (size_t i = 0; i < patternSize; i++) {
1946         VibrationElement element(CHANNEL_SIZE);
1947         // VibrationEffect.validate guarantees duration > 0.
1948         std::chrono::milliseconds duration(patternMillis[i]);
1949         element.duration = std::min(duration, MAX_VIBRATE_PATTERN_DELAY_MILLIS);
1950         for (int32_t channel = 0; channel < amplSize; channel++) {
1951             element.addChannel(vibratorIdArray[channel],
1952                                static_cast<uint8_t>(amplitudesArray[channel][i]));
1953         }
1954         sequence.addElement(element);
1955     }
1956 
1957     im->getInputManager()->getReader()->vibrate(deviceId, sequence, repeat, token);
1958 }
1959 
nativeCancelVibrate(JNIEnv *,jclass,jlong ptr,jint deviceId,jint token)1960 static void nativeCancelVibrate(JNIEnv* /* env */,
1961         jclass /* clazz */, jlong ptr, jint deviceId, jint token) {
1962     NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
1963 
1964     im->getInputManager()->getReader()->cancelVibrate(deviceId, token);
1965 }
1966 
nativeIsVibrating(JNIEnv *,jclass,jlong ptr,jint deviceId)1967 static bool nativeIsVibrating(JNIEnv* /* env */, jclass /* clazz */, jlong ptr, jint deviceId) {
1968     NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
1969 
1970     return im->getInputManager()->getReader()->isVibrating(deviceId);
1971 }
1972 
nativeGetVibratorIds(JNIEnv * env,jclass clazz,jlong ptr,jint deviceId)1973 static jintArray nativeGetVibratorIds(JNIEnv* env, jclass clazz, jlong ptr, jint deviceId) {
1974     NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
1975     std::vector<int32_t> vibrators = im->getInputManager()->getReader()->getVibratorIds(deviceId);
1976 
1977     jintArray vibIdArray = env->NewIntArray(vibrators.size());
1978     if (vibIdArray != nullptr) {
1979         env->SetIntArrayRegion(vibIdArray, 0, vibrators.size(), vibrators.data());
1980     }
1981     return vibIdArray;
1982 }
1983 
nativeGetLights(JNIEnv * env,jclass clazz,jlong ptr,jint deviceId)1984 static jobject nativeGetLights(JNIEnv* env, jclass clazz, jlong ptr, jint deviceId) {
1985     NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
1986     jobject jLights = env->NewObject(gArrayListClassInfo.clazz, gArrayListClassInfo.constructor);
1987 
1988     std::vector<InputDeviceLightInfo> lights =
1989             im->getInputManager()->getReader()->getLights(deviceId);
1990 
1991     for (size_t i = 0; i < lights.size(); i++) {
1992         const InputDeviceLightInfo& lightInfo = lights[i];
1993 
1994         jint jTypeId =
1995                 env->GetStaticIntField(gLightClassInfo.clazz, gLightClassInfo.lightTypeInput);
1996         jint jCapability = 0;
1997 
1998         if (lightInfo.type == InputDeviceLightType::MONO) {
1999             jCapability = env->GetStaticIntField(gLightClassInfo.clazz,
2000                                                  gLightClassInfo.lightCapabilityBrightness);
2001         } else if (lightInfo.type == InputDeviceLightType::RGB ||
2002                    lightInfo.type == InputDeviceLightType::MULTI_COLOR) {
2003             jCapability =
2004                 env->GetStaticIntField(gLightClassInfo.clazz,
2005                                                  gLightClassInfo.lightCapabilityBrightness) |
2006                 env->GetStaticIntField(gLightClassInfo.clazz,
2007                                                  gLightClassInfo.lightCapabilityRgb);
2008         } else if (lightInfo.type == InputDeviceLightType::PLAYER_ID) {
2009             jTypeId = env->GetStaticIntField(gLightClassInfo.clazz,
2010                                                  gLightClassInfo.lightTypePlayerId);
2011         } else {
2012             ALOGW("Unknown light type %d", lightInfo.type);
2013             continue;
2014         }
2015         ScopedLocalRef<jobject> lightObj(env,
2016                                          env->NewObject(gLightClassInfo.clazz,
2017                                                         gLightClassInfo.constructor,
2018                                                         static_cast<jint>(lightInfo.id),
2019                                                         env->NewStringUTF(lightInfo.name.c_str()),
2020                                                         static_cast<jint>(lightInfo.ordinal),
2021                                                         jTypeId, jCapability));
2022         // Add light object to list
2023         env->CallBooleanMethod(jLights, gArrayListClassInfo.add, lightObj.get());
2024     }
2025 
2026     return jLights;
2027 }
2028 
nativeGetLightPlayerId(JNIEnv * env,jclass,jlong ptr,jint deviceId,jint lightId)2029 static jint nativeGetLightPlayerId(JNIEnv* env, jclass /* clazz */, jlong ptr, jint deviceId,
2030                                    jint lightId) {
2031     NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
2032 
2033     std::optional<int32_t> ret =
2034             im->getInputManager()->getReader()->getLightPlayerId(deviceId, lightId);
2035 
2036     return static_cast<jint>(ret.value_or(0));
2037 }
2038 
nativeGetLightColor(JNIEnv * env,jclass,jlong ptr,jint deviceId,jint lightId)2039 static jint nativeGetLightColor(JNIEnv* env, jclass /* clazz */, jlong ptr, jint deviceId,
2040                                 jint lightId) {
2041     NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
2042 
2043     std::optional<int32_t> ret =
2044             im->getInputManager()->getReader()->getLightColor(deviceId, lightId);
2045     return static_cast<jint>(ret.value_or(0));
2046 }
2047 
nativeSetLightPlayerId(JNIEnv * env,jclass,jlong ptr,jint deviceId,jint lightId,jint playerId)2048 static void nativeSetLightPlayerId(JNIEnv* env, jclass /* clazz */, jlong ptr, jint deviceId,
2049                                    jint lightId, jint playerId) {
2050     NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
2051 
2052     im->getInputManager()->getReader()->setLightPlayerId(deviceId, lightId, playerId);
2053 }
2054 
nativeSetLightColor(JNIEnv * env,jclass,jlong ptr,jint deviceId,jint lightId,jint color)2055 static void nativeSetLightColor(JNIEnv* env, jclass /* clazz */, jlong ptr, jint deviceId,
2056                                 jint lightId, jint color) {
2057     NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
2058 
2059     im->getInputManager()->getReader()->setLightColor(deviceId, lightId, color);
2060 }
2061 
nativeGetBatteryCapacity(JNIEnv * env,jclass,jlong ptr,jint deviceId)2062 static jint nativeGetBatteryCapacity(JNIEnv* env, jclass /* clazz */, jlong ptr, jint deviceId) {
2063     NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
2064 
2065     std::optional<int32_t> ret = im->getInputManager()->getReader()->getBatteryCapacity(deviceId);
2066     return static_cast<jint>(ret.value_or(android::os::IInputConstants::INVALID_BATTERY_CAPACITY));
2067 }
2068 
nativeGetBatteryStatus(JNIEnv * env,jclass,jlong ptr,jint deviceId)2069 static jint nativeGetBatteryStatus(JNIEnv* env, jclass /* clazz */, jlong ptr, jint deviceId) {
2070     NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
2071 
2072     std::optional<int32_t> ret = im->getInputManager()->getReader()->getBatteryStatus(deviceId);
2073     return static_cast<jint>(ret.value_or(BATTERY_STATUS_UNKNOWN));
2074 }
2075 
nativeReloadKeyboardLayouts(JNIEnv *,jclass,jlong ptr)2076 static void nativeReloadKeyboardLayouts(JNIEnv* /* env */,
2077         jclass /* clazz */, jlong ptr) {
2078     NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
2079 
2080     im->getInputManager()->getReader()->requestRefreshConfiguration(
2081             InputReaderConfiguration::CHANGE_KEYBOARD_LAYOUTS);
2082 }
2083 
nativeReloadDeviceAliases(JNIEnv *,jclass,jlong ptr)2084 static void nativeReloadDeviceAliases(JNIEnv* /* env */,
2085         jclass /* clazz */, jlong ptr) {
2086     NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
2087 
2088     im->getInputManager()->getReader()->requestRefreshConfiguration(
2089             InputReaderConfiguration::CHANGE_DEVICE_ALIAS);
2090 }
2091 
nativeDump(JNIEnv * env,jclass,jlong ptr)2092 static jstring nativeDump(JNIEnv* env, jclass /* clazz */, jlong ptr) {
2093     NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
2094 
2095     std::string dump;
2096     im->dump(dump);
2097     return env->NewStringUTF(dump.c_str());
2098 }
2099 
nativeMonitor(JNIEnv *,jclass,jlong ptr)2100 static void nativeMonitor(JNIEnv* /* env */, jclass /* clazz */, jlong ptr) {
2101     NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
2102 
2103     im->getInputManager()->getReader()->monitor();
2104     im->getInputManager()->getDispatcher()->monitor();
2105 }
2106 
nativeIsInputDeviceEnabled(JNIEnv * env,jclass,jlong ptr,jint deviceId)2107 static jboolean nativeIsInputDeviceEnabled(JNIEnv* env /* env */,
2108         jclass /* clazz */, jlong ptr, jint deviceId) {
2109     NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
2110 
2111     return im->getInputManager()->getReader()->isInputDeviceEnabled(deviceId);
2112 }
2113 
nativeEnableInputDevice(JNIEnv *,jclass,jlong ptr,jint deviceId)2114 static void nativeEnableInputDevice(JNIEnv* /* env */,
2115         jclass /* clazz */, jlong ptr, jint deviceId) {
2116     NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
2117 
2118     im->setInputDeviceEnabled(deviceId, true);
2119 }
2120 
nativeDisableInputDevice(JNIEnv *,jclass,jlong ptr,jint deviceId)2121 static void nativeDisableInputDevice(JNIEnv* /* env */,
2122         jclass /* clazz */, jlong ptr, jint deviceId) {
2123     NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
2124 
2125     im->setInputDeviceEnabled(deviceId, false);
2126 }
2127 
nativeSetPointerIconType(JNIEnv *,jclass,jlong ptr,jint iconId)2128 static void nativeSetPointerIconType(JNIEnv* /* env */, jclass /* clazz */, jlong ptr, jint iconId) {
2129     NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
2130 
2131     im->setPointerIconType(iconId);
2132 }
2133 
nativeReloadPointerIcons(JNIEnv *,jclass,jlong ptr)2134 static void nativeReloadPointerIcons(JNIEnv* /* env */, jclass /* clazz */, jlong ptr) {
2135     NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
2136 
2137     im->reloadPointerIcons();
2138 }
2139 
nativeSetCustomPointerIcon(JNIEnv * env,jclass,jlong ptr,jobject iconObj)2140 static void nativeSetCustomPointerIcon(JNIEnv* env, jclass /* clazz */,
2141                                        jlong ptr, jobject iconObj) {
2142     NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
2143 
2144     PointerIcon pointerIcon;
2145     status_t result = android_view_PointerIcon_getLoadedIcon(env, iconObj, &pointerIcon);
2146     if (result) {
2147         jniThrowRuntimeException(env, "Failed to load custom pointer icon.");
2148         return;
2149     }
2150 
2151     SpriteIcon spriteIcon(pointerIcon.bitmap.copy(ANDROID_BITMAP_FORMAT_RGBA_8888),
2152                           pointerIcon.style, pointerIcon.hotSpotX, pointerIcon.hotSpotY);
2153     im->setCustomPointerIcon(spriteIcon);
2154 }
2155 
nativeCanDispatchToDisplay(JNIEnv * env,jclass,jlong ptr,jint deviceId,jint displayId)2156 static jboolean nativeCanDispatchToDisplay(JNIEnv* env, jclass /* clazz */, jlong ptr,
2157         jint deviceId, jint displayId) {
2158 
2159     NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
2160     return im->getInputManager()->getReader()->canDispatchToDisplay(deviceId, displayId);
2161 }
2162 
nativeNotifyPortAssociationsChanged(JNIEnv * env,jclass,jlong ptr)2163 static void nativeNotifyPortAssociationsChanged(JNIEnv* env, jclass /* clazz */, jlong ptr) {
2164     NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
2165     im->getInputManager()->getReader()->requestRefreshConfiguration(
2166             InputReaderConfiguration::CHANGE_DISPLAY_INFO);
2167 }
2168 
nativeChangeUniqueIdAssociation(JNIEnv * env,jclass,jlong ptr)2169 static void nativeChangeUniqueIdAssociation(JNIEnv* env, jclass /* clazz */, jlong ptr) {
2170     NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
2171     im->getInputManager()->getReader()->requestRefreshConfiguration(
2172             InputReaderConfiguration::CHANGE_DISPLAY_INFO);
2173 }
2174 
nativeSetMotionClassifierEnabled(JNIEnv *,jclass,jlong ptr,jboolean enabled)2175 static void nativeSetMotionClassifierEnabled(JNIEnv* /* env */, jclass /* clazz */, jlong ptr,
2176                                              jboolean enabled) {
2177     NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
2178 
2179     im->setMotionClassifierEnabled(enabled);
2180 }
2181 
createInputSensorInfo(JNIEnv * env,jstring name,jstring vendor,jint version,jint handle,jint type,jfloat maxRange,jfloat resolution,jfloat power,jfloat minDelay,jint fifoReservedEventCount,jint fifoMaxEventCount,jstring stringType,jstring requiredPermission,jint maxDelay,jint flags,jint id)2182 static jobject createInputSensorInfo(JNIEnv* env, jstring name, jstring vendor, jint version,
2183                                      jint handle, jint type, jfloat maxRange, jfloat resolution,
2184                                      jfloat power, jfloat minDelay, jint fifoReservedEventCount,
2185                                      jint fifoMaxEventCount, jstring stringType,
2186                                      jstring requiredPermission, jint maxDelay, jint flags,
2187                                      jint id) {
2188     // SensorInfo sensorInfo = new Sensor();
2189     jobject sensorInfo = env->NewObject(gInputSensorInfo.clazz, gInputSensorInfo.init, "");
2190 
2191     if (sensorInfo != NULL) {
2192         env->SetObjectField(sensorInfo, gInputSensorInfo.name, name);
2193         env->SetObjectField(sensorInfo, gInputSensorInfo.vendor, vendor);
2194         env->SetIntField(sensorInfo, gInputSensorInfo.version, version);
2195         env->SetIntField(sensorInfo, gInputSensorInfo.handle, handle);
2196         env->SetFloatField(sensorInfo, gInputSensorInfo.maxRange, maxRange);
2197         env->SetFloatField(sensorInfo, gInputSensorInfo.resolution, resolution);
2198         env->SetFloatField(sensorInfo, gInputSensorInfo.power, power);
2199         env->SetIntField(sensorInfo, gInputSensorInfo.minDelay, minDelay);
2200         env->SetIntField(sensorInfo, gInputSensorInfo.fifoReservedEventCount,
2201                          fifoReservedEventCount);
2202         env->SetIntField(sensorInfo, gInputSensorInfo.fifoMaxEventCount, fifoMaxEventCount);
2203         env->SetObjectField(sensorInfo, gInputSensorInfo.requiredPermission, requiredPermission);
2204         env->SetIntField(sensorInfo, gInputSensorInfo.maxDelay, maxDelay);
2205         env->SetIntField(sensorInfo, gInputSensorInfo.flags, flags);
2206         env->SetObjectField(sensorInfo, gInputSensorInfo.stringType, stringType);
2207         env->SetIntField(sensorInfo, gInputSensorInfo.type, type);
2208         env->SetIntField(sensorInfo, gInputSensorInfo.id, id);
2209     }
2210     return sensorInfo;
2211 }
2212 
nativeGetSensorList(JNIEnv * env,jclass,jlong ptr,jint deviceId)2213 static jobjectArray nativeGetSensorList(JNIEnv* env, jclass /* clazz */, jlong ptr, jint deviceId) {
2214     NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
2215     std::vector<InputDeviceSensorInfo> sensors =
2216             im->getInputManager()->getReader()->getSensors(deviceId);
2217 
2218     jobjectArray arr = env->NewObjectArray(sensors.size(), gInputSensorInfo.clazz, nullptr);
2219     for (int i = 0; i < sensors.size(); i++) {
2220         const InputDeviceSensorInfo& sensorInfo = sensors[i];
2221 
2222         jobject info = createInputSensorInfo(env, env->NewStringUTF(sensorInfo.name.c_str()),
2223                                              env->NewStringUTF(sensorInfo.vendor.c_str()),
2224                                              static_cast<jint>(sensorInfo.version), 0 /* handle */,
2225                                              static_cast<jint>(sensorInfo.type),
2226                                              static_cast<jfloat>(sensorInfo.maxRange),
2227                                              static_cast<jfloat>(sensorInfo.resolution),
2228                                              static_cast<jfloat>(sensorInfo.power),
2229                                              static_cast<jfloat>(sensorInfo.minDelay),
2230                                              static_cast<jint>(sensorInfo.fifoReservedEventCount),
2231                                              static_cast<jint>(sensorInfo.fifoMaxEventCount),
2232                                              env->NewStringUTF(sensorInfo.stringType.c_str()),
2233                                              env->NewStringUTF("") /* requiredPermission */,
2234                                              static_cast<jint>(sensorInfo.maxDelay),
2235                                              static_cast<jint>(sensorInfo.flags),
2236                                              static_cast<jint>(sensorInfo.id));
2237         env->SetObjectArrayElement(arr, i, info);
2238         env->DeleteLocalRef(info);
2239     }
2240     return arr;
2241 }
2242 
nativeEnableSensor(JNIEnv * env,jclass,jlong ptr,jint deviceId,jint sensorType,jint samplingPeriodUs,jint maxBatchReportLatencyUs)2243 static jboolean nativeEnableSensor(JNIEnv* env, jclass /* clazz */, jlong ptr, jint deviceId,
2244                                    jint sensorType, jint samplingPeriodUs,
2245                                    jint maxBatchReportLatencyUs) {
2246     NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
2247 
2248     return im->getInputManager()
2249             ->getReader()
2250             ->enableSensor(deviceId, static_cast<InputDeviceSensorType>(sensorType),
2251                            std::chrono::microseconds(samplingPeriodUs),
2252                            std::chrono::microseconds(maxBatchReportLatencyUs));
2253 }
2254 
nativeDisableSensor(JNIEnv * env,jclass,jlong ptr,jint deviceId,jint sensorType)2255 static void nativeDisableSensor(JNIEnv* env, jclass /* clazz */, jlong ptr, jint deviceId,
2256                                 jint sensorType) {
2257     NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
2258 
2259     im->getInputManager()->getReader()->disableSensor(deviceId,
2260                                                       static_cast<InputDeviceSensorType>(
2261                                                               sensorType));
2262 }
2263 
nativeFlushSensor(JNIEnv * env,jclass,jlong ptr,jint deviceId,jint sensorType)2264 static jboolean nativeFlushSensor(JNIEnv* env, jclass /* clazz */, jlong ptr, jint deviceId,
2265                                   jint sensorType) {
2266     NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
2267 
2268     im->getInputManager()->getReader()->flushSensor(deviceId,
2269                                                     static_cast<InputDeviceSensorType>(sensorType));
2270     return im->getInputManager()->getDispatcher()->flushSensor(deviceId,
2271                                                                static_cast<InputDeviceSensorType>(
2272                                                                        sensorType));
2273 }
2274 
2275 // ----------------------------------------------------------------------------
2276 
2277 static const JNINativeMethod gInputManagerMethods[] = {
2278         /* name, signature, funcPtr */
2279         {"nativeInit",
2280          "(Lcom/android/server/input/InputManagerService;Landroid/content/Context;Landroid/os/"
2281          "MessageQueue;)J",
2282          (void*)nativeInit},
2283         {"nativeStart", "(J)V", (void*)nativeStart},
2284         {"nativeSetDisplayViewports", "(J[Landroid/hardware/display/DisplayViewport;)V",
2285          (void*)nativeSetDisplayViewports},
2286         {"nativeGetScanCodeState", "(JIII)I", (void*)nativeGetScanCodeState},
2287         {"nativeGetKeyCodeState", "(JIII)I", (void*)nativeGetKeyCodeState},
2288         {"nativeGetSwitchState", "(JIII)I", (void*)nativeGetSwitchState},
2289         {"nativeHasKeys", "(JII[I[Z)Z", (void*)nativeHasKeys},
2290         {"nativeCreateInputChannel", "(JLjava/lang/String;)Landroid/view/InputChannel;",
2291          (void*)nativeCreateInputChannel},
2292         {"nativeCreateInputMonitor", "(JIZLjava/lang/String;I)Landroid/view/InputChannel;",
2293          (void*)nativeCreateInputMonitor},
2294         {"nativeRemoveInputChannel", "(JLandroid/os/IBinder;)V", (void*)nativeRemoveInputChannel},
2295         {"nativePilferPointers", "(JLandroid/os/IBinder;)V", (void*)nativePilferPointers},
2296         {"nativeSetInputFilterEnabled", "(JZ)V", (void*)nativeSetInputFilterEnabled},
2297         {"nativeSetInTouchMode", "(JZ)V", (void*)nativeSetInTouchMode},
2298         {"nativeSetMaximumObscuringOpacityForTouch", "(JF)V",
2299          (void*)nativeSetMaximumObscuringOpacityForTouch},
2300         {"nativeSetBlockUntrustedTouchesMode", "(JI)V", (void*)nativeSetBlockUntrustedTouchesMode},
2301         {"nativeInjectInputEvent", "(JLandroid/view/InputEvent;IIIII)I",
2302          (void*)nativeInjectInputEvent},
2303         {"nativeVerifyInputEvent", "(JLandroid/view/InputEvent;)Landroid/view/VerifiedInputEvent;",
2304          (void*)nativeVerifyInputEvent},
2305         {"nativeToggleCapsLock", "(JI)V", (void*)nativeToggleCapsLock},
2306         {"nativeDisplayRemoved", "(JI)V", (void*)nativeDisplayRemoved},
2307         {"nativeSetFocusedApplication", "(JILandroid/view/InputApplicationHandle;)V",
2308          (void*)nativeSetFocusedApplication},
2309         {"nativeSetFocusedDisplay", "(JI)V", (void*)nativeSetFocusedDisplay},
2310         {"nativeRequestPointerCapture", "(JLandroid/os/IBinder;Z)V",
2311          (void*)nativeRequestPointerCapture},
2312         {"nativeSetInputDispatchMode", "(JZZ)V", (void*)nativeSetInputDispatchMode},
2313         {"nativeSetSystemUiLightsOut", "(JZ)V", (void*)nativeSetSystemUiLightsOut},
2314         {"nativeTransferTouchFocus", "(JLandroid/os/IBinder;Landroid/os/IBinder;Z)Z",
2315          (void*)nativeTransferTouchFocus},
2316         {"nativeTransferTouch", "(JLandroid/os/IBinder;)Z", (void*)nativeTransferTouch},
2317         {"nativeSetPointerSpeed", "(JI)V", (void*)nativeSetPointerSpeed},
2318         {"nativeSetShowTouches", "(JZ)V", (void*)nativeSetShowTouches},
2319         {"nativeSetInteractive", "(JZ)V", (void*)nativeSetInteractive},
2320         {"nativeReloadCalibration", "(J)V", (void*)nativeReloadCalibration},
2321         {"nativeVibrate", "(JI[J[III)V", (void*)nativeVibrate},
2322         {"nativeVibrateCombined", "(JI[JLandroid/util/SparseArray;II)V",
2323          (void*)nativeVibrateCombined},
2324         {"nativeCancelVibrate", "(JII)V", (void*)nativeCancelVibrate},
2325         {"nativeIsVibrating", "(JI)Z", (void*)nativeIsVibrating},
2326         {"nativeGetVibratorIds", "(JI)[I", (void*)nativeGetVibratorIds},
2327         {"nativeGetLights", "(JI)Ljava/util/List;", (void*)nativeGetLights},
2328         {"nativeGetLightPlayerId", "(JII)I", (void*)nativeGetLightPlayerId},
2329         {"nativeGetLightColor", "(JII)I", (void*)nativeGetLightColor},
2330         {"nativeSetLightPlayerId", "(JIII)V", (void*)nativeSetLightPlayerId},
2331         {"nativeSetLightColor", "(JIII)V", (void*)nativeSetLightColor},
2332         {"nativeGetBatteryCapacity", "(JI)I", (void*)nativeGetBatteryCapacity},
2333         {"nativeGetBatteryStatus", "(JI)I", (void*)nativeGetBatteryStatus},
2334         {"nativeReloadKeyboardLayouts", "(J)V", (void*)nativeReloadKeyboardLayouts},
2335         {"nativeReloadDeviceAliases", "(J)V", (void*)nativeReloadDeviceAliases},
2336         {"nativeDump", "(J)Ljava/lang/String;", (void*)nativeDump},
2337         {"nativeMonitor", "(J)V", (void*)nativeMonitor},
2338         {"nativeIsInputDeviceEnabled", "(JI)Z", (void*)nativeIsInputDeviceEnabled},
2339         {"nativeEnableInputDevice", "(JI)V", (void*)nativeEnableInputDevice},
2340         {"nativeDisableInputDevice", "(JI)V", (void*)nativeDisableInputDevice},
2341         {"nativeSetPointerIconType", "(JI)V", (void*)nativeSetPointerIconType},
2342         {"nativeReloadPointerIcons", "(J)V", (void*)nativeReloadPointerIcons},
2343         {"nativeSetCustomPointerIcon", "(JLandroid/view/PointerIcon;)V",
2344          (void*)nativeSetCustomPointerIcon},
2345         {"nativeCanDispatchToDisplay", "(JII)Z", (void*)nativeCanDispatchToDisplay},
2346         {"nativeNotifyPortAssociationsChanged", "(J)V", (void*)nativeNotifyPortAssociationsChanged},
2347         {"nativeChangeUniqueIdAssociation", "(J)V", (void*)nativeChangeUniqueIdAssociation},
2348         {"nativeSetMotionClassifierEnabled", "(JZ)V", (void*)nativeSetMotionClassifierEnabled},
2349         {"nativeGetSensorList", "(JI)[Landroid/hardware/input/InputSensorInfo;",
2350          (void*)nativeGetSensorList},
2351         {"nativeEnableSensor", "(JIIII)Z", (void*)nativeEnableSensor},
2352         {"nativeDisableSensor", "(JII)V", (void*)nativeDisableSensor},
2353         {"nativeFlushSensor", "(JII)Z", (void*)nativeFlushSensor},
2354 };
2355 
2356 #define FIND_CLASS(var, className) \
2357         var = env->FindClass(className); \
2358         LOG_FATAL_IF(! (var), "Unable to find class " className);
2359 
2360 #define GET_METHOD_ID(var, clazz, methodName, methodDescriptor) \
2361         var = env->GetMethodID(clazz, methodName, methodDescriptor); \
2362         LOG_FATAL_IF(! (var), "Unable to find method " methodName);
2363 
2364 #define GET_STATIC_METHOD_ID(var, clazz, methodName, methodDescriptor) \
2365         var = env->GetStaticMethodID(clazz, methodName, methodDescriptor); \
2366         LOG_FATAL_IF(! (var), "Unable to find static method " methodName);
2367 
2368 #define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \
2369         var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \
2370         LOG_FATAL_IF(! (var), "Unable to find field " fieldName);
2371 
register_android_server_InputManager(JNIEnv * env)2372 int register_android_server_InputManager(JNIEnv* env) {
2373     int res = jniRegisterNativeMethods(env, "com/android/server/input/InputManagerService",
2374             gInputManagerMethods, NELEM(gInputManagerMethods));
2375     (void) res;  // Faked use when LOG_NDEBUG.
2376     LOG_FATAL_IF(res < 0, "Unable to register native methods.");
2377 
2378     // Callbacks
2379 
2380     jclass clazz;
2381     FIND_CLASS(clazz, "com/android/server/input/InputManagerService");
2382     gServiceClassInfo.clazz = reinterpret_cast<jclass>(env->NewGlobalRef(clazz));
2383 
2384     GET_METHOD_ID(gServiceClassInfo.notifyConfigurationChanged, clazz,
2385             "notifyConfigurationChanged", "(J)V");
2386 
2387     GET_METHOD_ID(gServiceClassInfo.notifyInputDevicesChanged, clazz,
2388             "notifyInputDevicesChanged", "([Landroid/view/InputDevice;)V");
2389 
2390     GET_METHOD_ID(gServiceClassInfo.notifySwitch, clazz,
2391             "notifySwitch", "(JII)V");
2392 
2393     GET_METHOD_ID(gServiceClassInfo.notifyInputChannelBroken, clazz,
2394             "notifyInputChannelBroken", "(Landroid/os/IBinder;)V");
2395 
2396     GET_METHOD_ID(gServiceClassInfo.notifyFocusChanged, clazz,
2397             "notifyFocusChanged", "(Landroid/os/IBinder;Landroid/os/IBinder;)V");
2398     GET_METHOD_ID(gServiceClassInfo.notifyDropWindow, clazz, "notifyDropWindow",
2399                   "(Landroid/os/IBinder;FF)V");
2400 
2401     GET_METHOD_ID(gServiceClassInfo.notifySensorEvent, clazz, "notifySensorEvent", "(IIIJ[F)V");
2402 
2403     GET_METHOD_ID(gServiceClassInfo.notifySensorAccuracy, clazz, "notifySensorAccuracy", "(III)V");
2404 
2405     GET_METHOD_ID(gServiceClassInfo.notifyVibratorState, clazz, "notifyVibratorState", "(IZ)V");
2406 
2407     GET_METHOD_ID(gServiceClassInfo.notifyUntrustedTouch, clazz, "notifyUntrustedTouch",
2408                   "(Ljava/lang/String;)V");
2409 
2410     GET_METHOD_ID(gServiceClassInfo.notifyNoFocusedWindowAnr, clazz, "notifyNoFocusedWindowAnr",
2411                   "(Landroid/view/InputApplicationHandle;)V");
2412 
2413     GET_METHOD_ID(gServiceClassInfo.notifyWindowUnresponsive, clazz, "notifyWindowUnresponsive",
2414                   "(Landroid/os/IBinder;Ljava/lang/String;)V");
2415 
2416     GET_METHOD_ID(gServiceClassInfo.notifyMonitorUnresponsive, clazz, "notifyMonitorUnresponsive",
2417                   "(ILjava/lang/String;)V");
2418 
2419     GET_METHOD_ID(gServiceClassInfo.notifyWindowResponsive, clazz, "notifyWindowResponsive",
2420                   "(Landroid/os/IBinder;)V");
2421 
2422     GET_METHOD_ID(gServiceClassInfo.notifyMonitorResponsive, clazz, "notifyMonitorResponsive",
2423                   "(I)V");
2424 
2425     GET_METHOD_ID(gServiceClassInfo.filterInputEvent, clazz,
2426             "filterInputEvent", "(Landroid/view/InputEvent;I)Z");
2427 
2428     GET_METHOD_ID(gServiceClassInfo.interceptKeyBeforeQueueing, clazz,
2429             "interceptKeyBeforeQueueing", "(Landroid/view/KeyEvent;I)I");
2430 
2431     GET_METHOD_ID(gServiceClassInfo.interceptMotionBeforeQueueingNonInteractive, clazz,
2432             "interceptMotionBeforeQueueingNonInteractive", "(IJI)I");
2433 
2434     GET_METHOD_ID(gServiceClassInfo.interceptKeyBeforeDispatching, clazz,
2435             "interceptKeyBeforeDispatching",
2436             "(Landroid/os/IBinder;Landroid/view/KeyEvent;I)J");
2437 
2438     GET_METHOD_ID(gServiceClassInfo.dispatchUnhandledKey, clazz,
2439             "dispatchUnhandledKey",
2440             "(Landroid/os/IBinder;Landroid/view/KeyEvent;I)Landroid/view/KeyEvent;");
2441 
2442     GET_METHOD_ID(gServiceClassInfo.checkInjectEventsPermission, clazz,
2443             "checkInjectEventsPermission", "(II)Z");
2444 
2445     GET_METHOD_ID(gServiceClassInfo.onPointerDownOutsideFocus, clazz,
2446             "onPointerDownOutsideFocus", "(Landroid/os/IBinder;)V");
2447 
2448     GET_METHOD_ID(gServiceClassInfo.getVirtualKeyQuietTimeMillis, clazz,
2449             "getVirtualKeyQuietTimeMillis", "()I");
2450 
2451     GET_STATIC_METHOD_ID(gServiceClassInfo.getExcludedDeviceNames, clazz,
2452             "getExcludedDeviceNames", "()[Ljava/lang/String;");
2453 
2454     GET_METHOD_ID(gServiceClassInfo.getInputPortAssociations, clazz,
2455             "getInputPortAssociations", "()[Ljava/lang/String;");
2456 
2457     GET_METHOD_ID(gServiceClassInfo.getInputUniqueIdAssociations, clazz,
2458                   "getInputUniqueIdAssociations", "()[Ljava/lang/String;");
2459 
2460     GET_METHOD_ID(gServiceClassInfo.getKeyRepeatTimeout, clazz,
2461             "getKeyRepeatTimeout", "()I");
2462 
2463     GET_METHOD_ID(gServiceClassInfo.getKeyRepeatDelay, clazz,
2464             "getKeyRepeatDelay", "()I");
2465 
2466     GET_METHOD_ID(gServiceClassInfo.getHoverTapTimeout, clazz,
2467             "getHoverTapTimeout", "()I");
2468 
2469     GET_METHOD_ID(gServiceClassInfo.getHoverTapSlop, clazz,
2470             "getHoverTapSlop", "()I");
2471 
2472     GET_METHOD_ID(gServiceClassInfo.getDoubleTapTimeout, clazz,
2473             "getDoubleTapTimeout", "()I");
2474 
2475     GET_METHOD_ID(gServiceClassInfo.getLongPressTimeout, clazz,
2476             "getLongPressTimeout", "()I");
2477 
2478     GET_METHOD_ID(gServiceClassInfo.getPointerLayer, clazz,
2479             "getPointerLayer", "()I");
2480 
2481     GET_METHOD_ID(gServiceClassInfo.getPointerIcon, clazz,
2482             "getPointerIcon", "(I)Landroid/view/PointerIcon;");
2483 
2484     GET_METHOD_ID(gServiceClassInfo.getPointerDisplayId, clazz,
2485             "getPointerDisplayId", "()I");
2486 
2487     GET_METHOD_ID(gServiceClassInfo.getKeyboardLayoutOverlay, clazz,
2488             "getKeyboardLayoutOverlay",
2489             "(Landroid/hardware/input/InputDeviceIdentifier;)[Ljava/lang/String;");
2490 
2491     GET_METHOD_ID(gServiceClassInfo.getDeviceAlias, clazz,
2492             "getDeviceAlias", "(Ljava/lang/String;)Ljava/lang/String;");
2493 
2494     GET_METHOD_ID(gServiceClassInfo.getTouchCalibrationForInputDevice, clazz,
2495             "getTouchCalibrationForInputDevice",
2496             "(Ljava/lang/String;I)Landroid/hardware/input/TouchCalibration;");
2497 
2498     GET_METHOD_ID(gServiceClassInfo.getContextForDisplay, clazz,
2499             "getContextForDisplay",
2500             "(I)Landroid/content/Context;")
2501 
2502     // InputDevice
2503 
2504     FIND_CLASS(gInputDeviceClassInfo.clazz, "android/view/InputDevice");
2505     gInputDeviceClassInfo.clazz = jclass(env->NewGlobalRef(gInputDeviceClassInfo.clazz));
2506 
2507     // KeyEvent
2508 
2509     FIND_CLASS(gKeyEventClassInfo.clazz, "android/view/KeyEvent");
2510     gKeyEventClassInfo.clazz = jclass(env->NewGlobalRef(gKeyEventClassInfo.clazz));
2511 
2512     // MotionEvent
2513 
2514     FIND_CLASS(gMotionEventClassInfo.clazz, "android/view/MotionEvent");
2515     gMotionEventClassInfo.clazz = jclass(env->NewGlobalRef(gMotionEventClassInfo.clazz));
2516 
2517     // InputDeviceIdentifier
2518 
2519     FIND_CLASS(gInputDeviceIdentifierInfo.clazz, "android/hardware/input/InputDeviceIdentifier");
2520     gInputDeviceIdentifierInfo.clazz = jclass(env->NewGlobalRef(gInputDeviceIdentifierInfo.clazz));
2521     GET_METHOD_ID(gInputDeviceIdentifierInfo.constructor, gInputDeviceIdentifierInfo.clazz,
2522             "<init>", "(Ljava/lang/String;II)V");
2523 
2524     // TouchCalibration
2525 
2526     FIND_CLASS(gTouchCalibrationClassInfo.clazz, "android/hardware/input/TouchCalibration");
2527     gTouchCalibrationClassInfo.clazz = jclass(env->NewGlobalRef(gTouchCalibrationClassInfo.clazz));
2528 
2529     GET_METHOD_ID(gTouchCalibrationClassInfo.getAffineTransform, gTouchCalibrationClassInfo.clazz,
2530             "getAffineTransform", "()[F");
2531 
2532     // Light
2533     FIND_CLASS(gLightClassInfo.clazz, "android/hardware/lights/Light");
2534     gLightClassInfo.clazz = jclass(env->NewGlobalRef(gLightClassInfo.clazz));
2535     GET_METHOD_ID(gLightClassInfo.constructor, gLightClassInfo.clazz, "<init>",
2536                   "(ILjava/lang/String;III)V");
2537 
2538     gLightClassInfo.clazz = jclass(env->NewGlobalRef(gLightClassInfo.clazz));
2539     gLightClassInfo.lightTypeInput =
2540             env->GetStaticFieldID(gLightClassInfo.clazz, "LIGHT_TYPE_INPUT", "I");
2541     gLightClassInfo.lightTypePlayerId =
2542             env->GetStaticFieldID(gLightClassInfo.clazz, "LIGHT_TYPE_PLAYER_ID", "I");
2543     gLightClassInfo.lightCapabilityBrightness =
2544             env->GetStaticFieldID(gLightClassInfo.clazz, "LIGHT_CAPABILITY_BRIGHTNESS", "I");
2545     gLightClassInfo.lightCapabilityRgb =
2546             env->GetStaticFieldID(gLightClassInfo.clazz, "LIGHT_CAPABILITY_RGB", "I");
2547 
2548     // ArrayList
2549     FIND_CLASS(gArrayListClassInfo.clazz, "java/util/ArrayList");
2550     gArrayListClassInfo.clazz = jclass(env->NewGlobalRef(gArrayListClassInfo.clazz));
2551     GET_METHOD_ID(gArrayListClassInfo.constructor, gArrayListClassInfo.clazz, "<init>", "()V");
2552     GET_METHOD_ID(gArrayListClassInfo.add, gArrayListClassInfo.clazz, "add",
2553                   "(Ljava/lang/Object;)Z");
2554 
2555     // SparseArray
2556     FIND_CLASS(gSparseArrayClassInfo.clazz, "android/util/SparseArray");
2557     gSparseArrayClassInfo.clazz = jclass(env->NewGlobalRef(gSparseArrayClassInfo.clazz));
2558     GET_METHOD_ID(gSparseArrayClassInfo.constructor, gSparseArrayClassInfo.clazz, "<init>", "()V");
2559     GET_METHOD_ID(gSparseArrayClassInfo.keyAt, gSparseArrayClassInfo.clazz, "keyAt", "(I)I");
2560     GET_METHOD_ID(gSparseArrayClassInfo.valueAt, gSparseArrayClassInfo.clazz, "valueAt",
2561                   "(I)Ljava/lang/Object;");
2562     GET_METHOD_ID(gSparseArrayClassInfo.size, gSparseArrayClassInfo.clazz, "size", "()I");
2563     // InputSensorInfo
2564     // android.hardware.input.InputDeviceSensorInfo
2565     FIND_CLASS(clazz, "android/hardware/input/InputSensorInfo");
2566     gInputSensorInfo.clazz = reinterpret_cast<jclass>(env->NewGlobalRef(clazz));
2567 
2568     GET_FIELD_ID(gInputSensorInfo.name, gInputSensorInfo.clazz, "mName", "Ljava/lang/String;");
2569     GET_FIELD_ID(gInputSensorInfo.vendor, gInputSensorInfo.clazz, "mVendor", "Ljava/lang/String;");
2570     GET_FIELD_ID(gInputSensorInfo.version, gInputSensorInfo.clazz, "mVersion", "I");
2571     GET_FIELD_ID(gInputSensorInfo.handle, gInputSensorInfo.clazz, "mHandle", "I");
2572     GET_FIELD_ID(gInputSensorInfo.maxRange, gInputSensorInfo.clazz, "mMaxRange", "F");
2573     GET_FIELD_ID(gInputSensorInfo.resolution, gInputSensorInfo.clazz, "mResolution", "F");
2574     GET_FIELD_ID(gInputSensorInfo.power, gInputSensorInfo.clazz, "mPower", "F");
2575     GET_FIELD_ID(gInputSensorInfo.minDelay, gInputSensorInfo.clazz, "mMinDelay", "I");
2576     GET_FIELD_ID(gInputSensorInfo.fifoReservedEventCount, gInputSensorInfo.clazz,
2577                  "mFifoReservedEventCount", "I");
2578     GET_FIELD_ID(gInputSensorInfo.fifoMaxEventCount, gInputSensorInfo.clazz, "mFifoMaxEventCount",
2579                  "I");
2580     GET_FIELD_ID(gInputSensorInfo.stringType, gInputSensorInfo.clazz, "mStringType",
2581                  "Ljava/lang/String;");
2582     GET_FIELD_ID(gInputSensorInfo.requiredPermission, gInputSensorInfo.clazz, "mRequiredPermission",
2583                  "Ljava/lang/String;");
2584     GET_FIELD_ID(gInputSensorInfo.maxDelay, gInputSensorInfo.clazz, "mMaxDelay", "I");
2585     GET_FIELD_ID(gInputSensorInfo.flags, gInputSensorInfo.clazz, "mFlags", "I");
2586     GET_FIELD_ID(gInputSensorInfo.type, gInputSensorInfo.clazz, "mType", "I");
2587     GET_FIELD_ID(gInputSensorInfo.id, gInputSensorInfo.clazz, "mId", "I");
2588 
2589     GET_METHOD_ID(gInputSensorInfo.init, gInputSensorInfo.clazz, "<init>", "()V");
2590 
2591     return 0;
2592 }
2593 
2594 } /* namespace android */
2595