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