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