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