xref: /aosp_15_r20/frameworks/base/services/core/jni/com_android_server_input_InputManagerService.cpp (revision d57664e9bc4670b3ecf6748a746a57c557b6bc9e)
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/logging.h>
30 #include <android-base/parseint.h>
31 #include <android-base/stringprintf.h>
32 #include <android/os/IInputConstants.h>
33 #include <android/sysprop/InputProperties.sysprop.h>
34 #include <android_os_MessageQueue.h>
35 #include <android_runtime/AndroidRuntime.h>
36 #include <android_runtime/Log.h>
37 #include <android_view_InputChannel.h>
38 #include <android_view_InputDevice.h>
39 #include <android_view_KeyEvent.h>
40 #include <android_view_MotionEvent.h>
41 #include <android_view_PointerIcon.h>
42 #include <android_view_VerifiedKeyEvent.h>
43 #include <android_view_VerifiedMotionEvent.h>
44 #include <batteryservice/include/batteryservice/BatteryServiceConstants.h>
45 #include <binder/IServiceManager.h>
46 #include <com_android_input_flags.h>
47 #include <include/gestures.h>
48 #include <input/Input.h>
49 #include <input/PointerController.h>
50 #include <input/PrintTools.h>
51 #include <input/SpriteController.h>
52 #include <inputflinger/InputManager.h>
53 #include <limits.h>
54 #include <nativehelper/ScopedLocalFrame.h>
55 #include <nativehelper/ScopedLocalRef.h>
56 #include <nativehelper/ScopedPrimitiveArray.h>
57 #include <nativehelper/ScopedUtfChars.h>
58 #include <server_configurable_flags/get_flags.h>
59 #include <ui/LogicalDisplayId.h>
60 #include <ui/Region.h>
61 #include <utils/Log.h>
62 #include <utils/Looper.h>
63 #include <utils/Trace.h>
64 #include <utils/threads.h>
65 
66 #include <atomic>
67 #include <cinttypes>
68 #include <map>
69 #include <vector>
70 
71 #include "android_hardware_display_DisplayTopology.h"
72 #include "android_hardware_display_DisplayViewport.h"
73 #include "android_hardware_input_InputApplicationHandle.h"
74 #include "android_hardware_input_InputWindowHandle.h"
75 #include "android_util_Binder.h"
76 #include "com_android_server_power_PowerManagerService.h"
77 
78 #define INDENT "  "
79 
80 using android::base::ParseUint;
81 using android::base::StringPrintf;
82 using android::os::InputEventInjectionResult;
83 using android::os::InputEventInjectionSync;
84 
85 // Maximum allowable delay value in a vibration pattern before
86 // which the delay will be truncated.
87 static constexpr std::chrono::duration MAX_VIBRATE_PATTERN_DELAY = 100s;
88 static constexpr std::chrono::milliseconds MAX_VIBRATE_PATTERN_DELAY_MILLIS =
89         std::chrono::duration_cast<std::chrono::milliseconds>(MAX_VIBRATE_PATTERN_DELAY);
90 
91 namespace input_flags = com::android::input::flags;
92 
93 namespace android {
94 
95 static const bool ENABLE_INPUT_FILTER_RUST = input_flags::enable_input_filter_rust_impl();
96 
97 // The exponent used to calculate the pointer speed scaling factor.
98 // The scaling factor is calculated as 2 ^ (speed * exponent),
99 // where the speed ranges from -7 to + 7 and is supplied by the user.
100 static const float POINTER_SPEED_EXPONENT = 1.0f / 4;
101 
102 // Category (=namespace) name for the input settings that are applied at boot time
103 static const char* INPUT_NATIVE_BOOT = "input_native_boot";
104 /**
105  * Feature flag name. This flag determines which VelocityTracker strategy is used by default.
106  */
107 static const char* VELOCITYTRACKER_STRATEGY = "velocitytracker_strategy";
108 
109 static struct {
110     jclass clazz;
111     jmethodID notifyInputDevicesChanged;
112     jmethodID notifyTouchpadHardwareState;
113     jmethodID notifyTouchpadGestureInfo;
114     jmethodID notifyTouchpadThreeFingerTap;
115     jmethodID notifySwitch;
116     jmethodID notifyInputChannelBroken;
117     jmethodID notifyNoFocusedWindowAnr;
118     jmethodID notifyWindowUnresponsive;
119     jmethodID notifyWindowResponsive;
120     jmethodID notifyFocusChanged;
121     jmethodID notifySensorEvent;
122     jmethodID notifySensorAccuracy;
123     jmethodID notifyStickyModifierStateChanged;
124     jmethodID notifyStylusGestureStarted;
125     jmethodID notifyVibratorState;
126     jmethodID filterInputEvent;
127     jmethodID interceptKeyBeforeQueueing;
128     jmethodID interceptMotionBeforeQueueingNonInteractive;
129     jmethodID interceptKeyBeforeDispatching;
130     jmethodID dispatchUnhandledKey;
131     jmethodID onPointerDownOutsideFocus;
132     jmethodID getVirtualKeyQuietTimeMillis;
133     jmethodID getExcludedDeviceNames;
134     jmethodID getInputPortAssociations;
135     jmethodID getInputUniqueIdAssociationsByPort;
136     jmethodID getInputUniqueIdAssociationsByDescriptor;
137     jmethodID getDeviceTypeAssociations;
138     jmethodID getKeyboardLayoutAssociations;
139     jmethodID getHoverTapTimeout;
140     jmethodID getHoverTapSlop;
141     jmethodID getDoubleTapTimeout;
142     jmethodID getLongPressTimeout;
143     jmethodID getPointerLayer;
144     jmethodID getLoadedPointerIcon;
145     jmethodID getKeyboardLayoutOverlay;
146     jmethodID getDeviceAlias;
147     jmethodID getTouchCalibrationForInputDevice;
148     jmethodID notifyDropWindow;
149     jmethodID getParentSurfaceForPointers;
150 } gServiceClassInfo;
151 
152 static struct {
153     jclass clazz;
154     // fields
155     jfieldID timestamp;
156     jfieldID buttonsDown;
157     jfieldID fingerCount;
158     jfieldID touchCount;
159     jfieldID fingerStates;
160     // methods
161     jmethodID init;
162 } gTouchpadHardwareStateClassInfo;
163 
164 static struct {
165     jclass clazz;
166     // fields
167     jfieldID touchMajor;
168     jfieldID touchMinor;
169     jfieldID widthMajor;
170     jfieldID widthMinor;
171     jfieldID pressure;
172     jfieldID orientation;
173     jfieldID positionX;
174     jfieldID positionY;
175     jfieldID trackingId;
176     // methods
177     jmethodID init;
178 } gTouchpadFingerStateClassInfo;
179 
180 static struct {
181     jclass clazz;
182     jfieldID mPtr;
183 } gNativeInputManagerServiceImpl;
184 
185 static struct {
186     jclass clazz;
187 } gInputDeviceClassInfo;
188 
189 static struct {
190     jclass clazz;
191 } gKeyEventClassInfo;
192 
193 static struct {
194     jclass clazz;
195 } gMotionEventClassInfo;
196 
197 static struct {
198     jclass clazz;
199     jmethodID constructor;
200 } gInputDeviceIdentifierInfo;
201 
202 static struct {
203     jclass clazz;
204     jmethodID getAffineTransform;
205 } gTouchCalibrationClassInfo;
206 
207 static struct {
208     jclass clazz;
209     jmethodID constructor;
210     jfieldID lightTypeInput;
211     jfieldID lightTypePlayerId;
212     jfieldID lightTypeKeyboardBacklight;
213     jfieldID lightTypeKeyboardMicMute;
214     jfieldID lightTypeKeyboardVolumeMute;
215     jfieldID lightCapabilityBrightness;
216     jfieldID lightCapabilityColorRgb;
217 } gLightClassInfo;
218 
219 static struct {
220     jclass clazz;
221     jmethodID constructor;
222     jmethodID add;
223 } gArrayListClassInfo;
224 
225 static struct {
226     jclass clazz;
227     jmethodID constructor;
228     jmethodID keyAt;
229     jmethodID valueAt;
230     jmethodID size;
231 } gSparseArrayClassInfo;
232 
233 static struct InputSensorInfoOffsets {
234     jclass clazz;
235     // fields
236     jfieldID name;
237     jfieldID vendor;
238     jfieldID version;
239     jfieldID handle;
240     jfieldID maxRange;
241     jfieldID resolution;
242     jfieldID power;
243     jfieldID minDelay;
244     jfieldID fifoReservedEventCount;
245     jfieldID fifoMaxEventCount;
246     jfieldID stringType;
247     jfieldID requiredPermission;
248     jfieldID maxDelay;
249     jfieldID flags;
250     jfieldID type;
251     jfieldID id;
252     // methods
253     jmethodID init;
254 } gInputSensorInfo;
255 
256 static struct TouchpadHardwarePropertiesOffsets {
257     jclass clazz;
258     jmethodID constructor;
259     jfieldID left;
260     jfieldID top;
261     jfieldID right;
262     jfieldID bottom;
263     jfieldID resX;
264     jfieldID resY;
265     jfieldID orientationMinimum;
266     jfieldID orientationMaximum;
267     jfieldID maxFingerCount;
268     jfieldID isButtonPad;
269     jfieldID isHapticPad;
270     jfieldID reportsPressure;
271 } gTouchpadHardwarePropertiesOffsets;
272 
273 // --- Global functions ---
274 
275 template<typename T>
min(const T & a,const T & b)276 inline static T min(const T& a, const T& b) {
277     return a < b ? a : b;
278 }
279 
280 template<typename T>
max(const T & a,const T & b)281 inline static T max(const T& a, const T& b) {
282     return a > b ? a : b;
283 }
284 
toSpriteIcon(PointerIcon pointerIcon)285 static SpriteIcon toSpriteIcon(PointerIcon pointerIcon) {
286     // As a minor optimization, do not make a copy of the PointerIcon bitmap here. The loaded
287     // PointerIcons are only cached by InputManagerService in java, so we can safely assume they
288     // will not be modified. This is safe because the native bitmap object holds a strong reference
289     // to the underlying bitmap, so even if the java object is released, we will still have access
290     // to it.
291     return SpriteIcon(pointerIcon.bitmap, pointerIcon.style, pointerIcon.hotSpotX,
292                       pointerIcon.hotSpotY, pointerIcon.drawNativeDropShadow);
293 }
294 
295 enum {
296     WM_ACTION_PASS_TO_USER = 1,
297 };
298 
getStringElementFromJavaArray(JNIEnv * env,jobjectArray array,jsize index)299 static std::string getStringElementFromJavaArray(JNIEnv* env, jobjectArray array, jsize index) {
300     jstring item = jstring(env->GetObjectArrayElement(array, index));
301     ScopedUtfChars chars(env, item);
302     std::string result(chars.c_str());
303     return result;
304 }
305 
306 // --- NativeInputManager ---
307 
308 class NativeInputManager : public virtual InputReaderPolicyInterface,
309                            public virtual InputDispatcherPolicyInterface,
310                            public virtual PointerControllerPolicyInterface,
311                            public virtual PointerChoreographerPolicyInterface,
312                            public virtual InputFilterPolicyInterface {
313 protected:
314     virtual ~NativeInputManager();
315 
316 public:
317     NativeInputManager(jobject serviceObj, const sp<Looper>& looper);
318 
getInputManager() const319     inline sp<InputManagerInterface> getInputManager() const { return mInputManager; }
320 
321     void dump(std::string& dump);
322 
323     void setDisplayViewports(JNIEnv* env, jobjectArray viewportObjArray);
324 
325     void setDisplayTopology(JNIEnv* env, jobject topologyGraph);
326 
327     base::Result<std::unique_ptr<InputChannel>> createInputChannel(const std::string& name);
328     base::Result<std::unique_ptr<InputChannel>> createInputMonitor(ui::LogicalDisplayId displayId,
329                                                                    const std::string& name,
330                                                                    gui::Pid pid);
331     status_t removeInputChannel(const sp<IBinder>& connectionToken);
332     status_t pilferPointers(const sp<IBinder>& token);
333 
334     void displayRemoved(JNIEnv* env, ui::LogicalDisplayId displayId);
335     void setFocusedApplication(JNIEnv* env, ui::LogicalDisplayId displayId,
336                                jobject applicationHandleObj);
337     void setFocusedDisplay(ui::LogicalDisplayId displayId);
338     void setMinTimeBetweenUserActivityPokes(int64_t intervalMillis);
339     void setInputDispatchMode(bool enabled, bool frozen);
340     void setSystemUiLightsOut(bool lightsOut);
341     void setPointerDisplayId(ui::LogicalDisplayId displayId);
342     int32_t getMousePointerSpeed();
343     void setPointerSpeed(int32_t speed);
344     void setMousePointerAccelerationEnabled(ui::LogicalDisplayId displayId, bool enabled);
345     void setMouseReverseVerticalScrollingEnabled(bool enabled);
346     void setMouseSwapPrimaryButtonEnabled(bool enabled);
347     void setTouchpadPointerSpeed(int32_t speed);
348     void setTouchpadNaturalScrollingEnabled(bool enabled);
349     void setTouchpadTapToClickEnabled(bool enabled);
350     void setTouchpadTapDraggingEnabled(bool enabled);
351     void setShouldNotifyTouchpadHardwareState(bool enabled);
352     void setTouchpadRightClickZoneEnabled(bool enabled);
353     void setTouchpadThreeFingerTapShortcutEnabled(bool enabled);
354     void setTouchpadSystemGesturesEnabled(bool enabled);
355     void setInputDeviceEnabled(uint32_t deviceId, bool enabled);
356     void setShowTouches(bool enabled);
357     void setNonInteractiveDisplays(const std::set<ui::LogicalDisplayId>& displayIds);
358     void reloadCalibration();
359     void reloadPointerIcons();
360     void requestPointerCapture(const sp<IBinder>& windowToken, bool enabled);
361     bool setPointerIcon(std::variant<std::unique_ptr<SpriteIcon>, PointerIconStyle> icon,
362                         ui::LogicalDisplayId displayId, DeviceId deviceId, int32_t pointerId,
363                         const sp<IBinder>& inputToken);
364     void setPointerIconVisibility(ui::LogicalDisplayId displayId, bool visible);
365     void setMotionClassifierEnabled(bool enabled);
366     std::optional<std::string> getBluetoothAddress(int32_t deviceId);
367     void setStylusButtonMotionEventsEnabled(bool enabled);
368     vec2 getMouseCursorPosition(ui::LogicalDisplayId displayId);
369     void setStylusPointerIconEnabled(bool enabled);
370     void setInputMethodConnectionIsActive(bool isActive);
371     void setKeyRemapping(const std::map<int32_t, int32_t>& keyRemapping);
372 
373     /* --- InputReaderPolicyInterface implementation --- */
374 
375     void getReaderConfiguration(InputReaderConfiguration* outConfig) override;
376     void notifyInputDevicesChanged(const std::vector<InputDeviceInfo>& inputDevices) override;
377     void notifyTouchpadHardwareState(const SelfContainedHardwareState& schs,
378                                      int32_t deviceId) override;
379     void notifyTouchpadGestureInfo(enum GestureType type, int32_t deviceId) override;
380     void notifyTouchpadThreeFingerTap() override;
381     std::shared_ptr<KeyCharacterMap> getKeyboardLayoutOverlay(
382             const InputDeviceIdentifier& identifier,
383             const std::optional<KeyboardLayoutInfo> keyboardLayoutInfo) override;
384     std::string getDeviceAlias(const InputDeviceIdentifier& identifier) override;
385     TouchAffineTransformation getTouchAffineTransformation(const std::string& inputDeviceDescriptor,
386                                                            ui::Rotation surfaceRotation) override;
387 
388     TouchAffineTransformation getTouchAffineTransformation(JNIEnv* env, jfloatArray matrixArr);
389     void notifyStylusGestureStarted(int32_t deviceId, nsecs_t eventTime) override;
390     bool isInputMethodConnectionActive() override;
391     std::optional<DisplayViewport> getPointerViewportForAssociatedDisplay(
392             ui::LogicalDisplayId associatedDisplayId) override;
393 
394     /* --- InputDispatcherPolicyInterface implementation --- */
395 
396     void notifySwitch(nsecs_t when, uint32_t switchValues, uint32_t switchMask,
397                       uint32_t policyFlags) override;
398     // ANR-related callbacks -- start
399     void notifyNoFocusedWindowAnr(const std::shared_ptr<InputApplicationHandle>& handle) override;
400     void notifyWindowUnresponsive(const sp<IBinder>& token, std::optional<gui::Pid> pid,
401                                   const std::string& reason) override;
402     void notifyWindowResponsive(const sp<IBinder>& token, std::optional<gui::Pid> pid) override;
403     // ANR-related callbacks -- end
404     void notifyInputChannelBroken(const sp<IBinder>& token) override;
405     void notifyFocusChanged(const sp<IBinder>& oldToken, const sp<IBinder>& newToken) override;
406     void notifySensorEvent(int32_t deviceId, InputDeviceSensorType sensorType,
407                            InputDeviceSensorAccuracy accuracy, nsecs_t timestamp,
408                            const std::vector<float>& values) override;
409     void notifySensorAccuracy(int32_t deviceId, InputDeviceSensorType sensorType,
410                               InputDeviceSensorAccuracy accuracy) override;
411     void notifyVibratorState(int32_t deviceId, bool isOn) override;
412     bool filterInputEvent(const InputEvent& inputEvent, uint32_t policyFlags) override;
413     void interceptKeyBeforeQueueing(const KeyEvent& keyEvent, uint32_t& policyFlags) override;
414     void interceptMotionBeforeQueueing(ui::LogicalDisplayId displayId, uint32_t source,
415                                        int32_t action, nsecs_t when,
416                                        uint32_t& policyFlags) override;
417     nsecs_t interceptKeyBeforeDispatching(const sp<IBinder>& token, const KeyEvent& keyEvent,
418                                           uint32_t policyFlags) override;
419     std::optional<KeyEvent> dispatchUnhandledKey(const sp<IBinder>& token, const KeyEvent& keyEvent,
420                                                  uint32_t policyFlags) override;
421     void pokeUserActivity(nsecs_t eventTime, int32_t eventType,
422                           ui::LogicalDisplayId displayId) override;
423     void onPointerDownOutsideFocus(const sp<IBinder>& touchedToken) override;
424     void setPointerCapture(const PointerCaptureRequest& request) override;
425     void notifyDropWindow(const sp<IBinder>& token, float x, float y) override;
426     void notifyDeviceInteraction(int32_t deviceId, nsecs_t timestamp,
427                                  const std::set<gui::Uid>& uids) override;
428     void notifyFocusedDisplayChanged(ui::LogicalDisplayId displayId) override;
429 
430     /* --- PointerControllerPolicyInterface implementation --- */
431 
432     virtual void loadPointerIcon(SpriteIcon* icon, ui::LogicalDisplayId displayId);
433     virtual void loadPointerResources(PointerResources* outResources,
434                                       ui::LogicalDisplayId displayId);
435     virtual void loadAdditionalMouseResources(
436             std::map<PointerIconStyle, SpriteIcon>* outResources,
437             std::map<PointerIconStyle, PointerAnimation>* outAnimationResources,
438             ui::LogicalDisplayId displayId);
439     virtual PointerIconStyle getDefaultPointerIconId();
440     virtual PointerIconStyle getDefaultStylusIconId();
441     virtual PointerIconStyle getCustomPointerIconId();
442 
443     /* --- PointerChoreographerPolicyInterface implementation --- */
444     std::shared_ptr<PointerControllerInterface> createPointerController(
445             PointerControllerInterface::ControllerType type) override;
446     void notifyPointerDisplayIdChanged(ui::LogicalDisplayId displayId,
447                                        const vec2& position) override;
448     void notifyMouseCursorFadedOnTyping() override;
449 
450     /* --- InputFilterPolicyInterface implementation --- */
451     void notifyStickyModifierStateChanged(uint32_t modifierState,
452                                           uint32_t lockedModifierState) override;
453 
454 private:
455     sp<InputManagerInterface> mInputManager;
456 
457     jobject mServiceObj;
458     sp<Looper> mLooper;
459 
460     std::mutex mLock;
461     struct Locked {
462         // Display size information.
463         std::vector<DisplayViewport> viewports{};
464 
465         // True if System UI is less noticeable.
466         bool systemUiLightsOut{false};
467 
468         // Pointer speed.
469         int32_t pointerSpeed{0};
470 
471         // Displays on which its associated mice will have pointer acceleration disabled.
472         std::set<ui::LogicalDisplayId> displaysWithMousePointerAccelerationDisabled{};
473 
474         // True if pointer gestures are enabled.
475         bool pointerGesturesEnabled{true};
476 
477         // The latest request to enable or disable Pointer Capture.
478         PointerCaptureRequest pointerCaptureRequest{};
479 
480         // Sprite controller singleton, created on first use.
481         std::shared_ptr<SpriteController> spriteController{};
482 
483         // The list of PointerControllers created and managed by the PointerChoreographer.
484         std::list<std::weak_ptr<PointerController>> pointerControllers{};
485 
486         // Input devices to be disabled
487         std::set<int32_t> disabledInputDevices{};
488 
489         // Associated Pointer controller display.
490         ui::LogicalDisplayId pointerDisplayId{ui::LogicalDisplayId::DEFAULT};
491 
492         // True if stylus button reporting through motion events is enabled.
493         bool stylusButtonMotionEventsEnabled{true};
494 
495         // True if mouse vertical scrolling is reversed.
496         bool mouseReverseVerticalScrollingEnabled{false};
497 
498         // True if the mouse primary button is swapped (left/right buttons).
499         bool mouseSwapPrimaryButtonEnabled{false};
500 
501         // The touchpad pointer speed, as a number from -7 (slowest) to 7 (fastest).
502         int32_t touchpadPointerSpeed{0};
503 
504         // True to invert the touchpad scrolling direction, so that moving two fingers downwards on
505         // the touchpad scrolls the content upwards.
506         bool touchpadNaturalScrollingEnabled{true};
507 
508         // True to enable tap-to-click on touchpads.
509         bool touchpadTapToClickEnabled{true};
510 
511         // True to enable tap dragging on touchpads.
512         bool touchpadTapDraggingEnabled{false};
513 
514         // True if hardware state update notifications should be sent to the policy.
515         bool shouldNotifyTouchpadHardwareState{false};
516 
517         // True to enable a zone on the right-hand side of touchpads where clicks will be turned
518         // into context (a.k.a. "right") clicks.
519         bool touchpadRightClickZoneEnabled{false};
520 
521         // True to use three-finger tap as a customizable shortcut; false to use it as a
522         // middle-click.
523         bool touchpadThreeFingerTapShortcutEnabled{false};
524 
525         // True to enable system gestures (three- and four-finger swipes) on touchpads.
526         bool touchpadSystemGesturesEnabled{true};
527 
528         // True if a pointer icon should be shown for stylus pointers.
529         bool stylusPointerIconEnabled{false};
530 
531         // True if there is an active input method connection.
532         bool isInputMethodConnectionActive{false};
533 
534         // Keycodes to be remapped.
535         std::map<int32_t /* fromKeyCode */, int32_t /* toKeyCode */> keyRemapping{};
536 
537         // Displays which are non-interactive.
538         std::set<ui::LogicalDisplayId> nonInteractiveDisplays;
539     } mLocked GUARDED_BY(mLock);
540 
541     void updateInactivityTimeoutLocked();
542     void handleInterceptActions(jint wmActions, nsecs_t when, uint32_t& policyFlags);
543     void ensureSpriteControllerLocked();
544     sp<SurfaceControl> getParentSurfaceForPointers(ui::LogicalDisplayId displayId);
545     static bool checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName);
546     template <typename T>
547     std::unordered_map<std::string, T> readMapFromInterleavedJavaArray(
548             jmethodID method, const char* methodName,
__anon42c2477a0e02(auto&& v) 549             std::function<T(std::string)> opOnValue = [](auto&& v) { return std::move(v); });
550 
551     void forEachPointerControllerLocked(std::function<void(PointerController&)> apply)
552             REQUIRES(mLock);
553     PointerIcon loadPointerIcon(JNIEnv* env, ui::LogicalDisplayId displayId, PointerIconStyle type);
554     bool isDisplayInteractive(ui::LogicalDisplayId displayId);
555 
jniEnv()556     static inline JNIEnv* jniEnv() { return AndroidRuntime::getJNIEnv(); }
557 };
558 
NativeInputManager(jobject serviceObj,const sp<Looper> & looper)559 NativeInputManager::NativeInputManager(jobject serviceObj, const sp<Looper>& looper)
560       : mLooper(looper) {
561     JNIEnv* env = jniEnv();
562 
563     mServiceObj = env->NewGlobalRef(serviceObj);
564 
565     InputManager* im = new InputManager(this, *this, *this, *this);
566     mInputManager = im;
567     defaultServiceManager()->addService(String16("inputflinger"), im);
568 }
569 
~NativeInputManager()570 NativeInputManager::~NativeInputManager() {
571     JNIEnv* env = jniEnv();
572 
573     env->DeleteGlobalRef(mServiceObj);
574 }
575 
dump(std::string & dump)576 void NativeInputManager::dump(std::string& dump) {
577     dump += "Input Manager State:\n";
578     { // acquire lock
579         std::scoped_lock _l(mLock);
580         auto logicalDisplayIdToString = [](const ui::LogicalDisplayId& displayId) {
581             return std::to_string(displayId.val());
582         };
583         dump += StringPrintf(INDENT "Display not interactive: %s\n",
584                              dumpSet(mLocked.nonInteractiveDisplays, streamableToString).c_str());
585         dump += StringPrintf(INDENT "System UI Lights Out: %s\n",
586                              toString(mLocked.systemUiLightsOut));
587         dump += StringPrintf(INDENT "Pointer Speed: %" PRId32 "\n", mLocked.pointerSpeed);
588         dump += StringPrintf(INDENT "Display with Mouse Pointer Acceleration Disabled: %s\n",
589                              dumpSet(mLocked.displaysWithMousePointerAccelerationDisabled,
590                                      streamableToString)
591                                      .c_str());
592         dump += StringPrintf(INDENT "Pointer Gestures Enabled: %s\n",
593                              toString(mLocked.pointerGesturesEnabled));
594         dump += StringPrintf(INDENT "Pointer Capture: %s, seq=%" PRIu32 "\n",
595                              mLocked.pointerCaptureRequest.isEnable() ? "Enabled" : "Disabled",
596                              mLocked.pointerCaptureRequest.seq);
597     } // release lock
598     dump += "\n";
599 
600     mInputManager->dump(dump);
601 }
602 
checkAndClearExceptionFromCallback(JNIEnv * env,const char * methodName)603 bool NativeInputManager::checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName) {
604     if (env->ExceptionCheck()) {
605         ALOGE("An exception was thrown by callback '%s'.", methodName);
606         LOGE_EX(env);
607         env->ExceptionClear();
608         return true;
609     }
610     return false;
611 }
612 
setDisplayViewports(JNIEnv * env,jobjectArray viewportObjArray)613 void NativeInputManager::setDisplayViewports(JNIEnv* env, jobjectArray viewportObjArray) {
614     std::vector<DisplayViewport> viewports;
615 
616     if (viewportObjArray) {
617         jsize length = env->GetArrayLength(viewportObjArray);
618         for (jsize i = 0; i < length; i++) {
619             jobject viewportObj = env->GetObjectArrayElement(viewportObjArray, i);
620             if (! viewportObj) {
621                 break; // found null element indicating end of used portion of the array
622             }
623 
624             DisplayViewport viewport;
625             android_hardware_display_DisplayViewport_toNative(env, viewportObj, &viewport);
626             ALOGI("Viewport [%d] to add: %s, isActive: %s", (int)i, viewport.uniqueId.c_str(),
627                   toString(viewport.isActive));
628             viewports.push_back(viewport);
629 
630             env->DeleteLocalRef(viewportObj);
631         }
632     }
633 
634     { // acquire lock
635         std::scoped_lock _l(mLock);
636         mLocked.viewports = viewports;
637         forEachPointerControllerLocked(
638                 [&viewports](PointerController& pc) { pc.onDisplayViewportsUpdated(viewports); });
639     } // release lock
640 
641     mInputManager->getChoreographer().setDisplayViewports(viewports);
642     mInputManager->getReader().requestRefreshConfiguration(
643             InputReaderConfiguration::Change::DISPLAY_INFO);
644 }
645 
setDisplayTopology(JNIEnv * env,jobject topologyGraph)646 void NativeInputManager::setDisplayTopology(JNIEnv* env, jobject topologyGraph) {
647     android_hardware_display_DisplayTopologyGraph_toNative(env, topologyGraph);
648     // TODO(b/367661489): Use the topology
649 }
650 
createInputChannel(const std::string & name)651 base::Result<std::unique_ptr<InputChannel>> NativeInputManager::createInputChannel(
652         const std::string& name) {
653     ATRACE_CALL();
654     return mInputManager->getDispatcher().createInputChannel(name);
655 }
656 
createInputMonitor(ui::LogicalDisplayId displayId,const std::string & name,gui::Pid pid)657 base::Result<std::unique_ptr<InputChannel>> NativeInputManager::createInputMonitor(
658         ui::LogicalDisplayId displayId, const std::string& name, gui::Pid pid) {
659     ATRACE_CALL();
660     return mInputManager->getDispatcher().createInputMonitor(displayId, name, pid);
661 }
662 
removeInputChannel(const sp<IBinder> & connectionToken)663 status_t NativeInputManager::removeInputChannel(const sp<IBinder>& connectionToken) {
664     ATRACE_CALL();
665     return mInputManager->getDispatcher().removeInputChannel(connectionToken);
666 }
667 
pilferPointers(const sp<IBinder> & token)668 status_t NativeInputManager::pilferPointers(const sp<IBinder>& token) {
669     ATRACE_CALL();
670     return mInputManager->getDispatcher().pilferPointers(token);
671 }
672 
getReaderConfiguration(InputReaderConfiguration * outConfig)673 void NativeInputManager::getReaderConfiguration(InputReaderConfiguration* outConfig) {
674     ATRACE_CALL();
675     JNIEnv* env = jniEnv();
676 
677     jint virtualKeyQuietTime = env->CallIntMethod(mServiceObj,
678             gServiceClassInfo.getVirtualKeyQuietTimeMillis);
679     if (!checkAndClearExceptionFromCallback(env, "getVirtualKeyQuietTimeMillis")) {
680         outConfig->virtualKeyQuietTime = milliseconds_to_nanoseconds(virtualKeyQuietTime);
681     }
682 
683     outConfig->excludedDeviceNames.clear();
684     jobjectArray excludedDeviceNames = jobjectArray(env->CallStaticObjectMethod(
685             gServiceClassInfo.clazz, gServiceClassInfo.getExcludedDeviceNames));
686     if (!checkAndClearExceptionFromCallback(env, "getExcludedDeviceNames") && excludedDeviceNames) {
687         jsize length = env->GetArrayLength(excludedDeviceNames);
688         for (jsize i = 0; i < length; i++) {
689             std::string deviceName = getStringElementFromJavaArray(env, excludedDeviceNames, i);
690             outConfig->excludedDeviceNames.push_back(deviceName);
691         }
692         env->DeleteLocalRef(excludedDeviceNames);
693     }
694 
695     // Associations between input ports and display ports
696     // The java method packs the information in the following manner:
697     // Original data: [{'inputPort1': '1'}, {'inputPort2': '2'}]
698     // Received data: ['inputPort1', '1', 'inputPort2', '2']
699     // So we unpack accordingly here.
700     outConfig->inputPortToDisplayPortAssociations.clear();
701     jobjectArray portAssociations = jobjectArray(env->CallObjectMethod(mServiceObj,
702             gServiceClassInfo.getInputPortAssociations));
703     if (!checkAndClearExceptionFromCallback(env, "getInputPortAssociations") && portAssociations) {
704         jsize length = env->GetArrayLength(portAssociations);
705         for (jsize i = 0; i < length / 2; i++) {
706             std::string inputPort = getStringElementFromJavaArray(env, portAssociations, 2 * i);
707             std::string displayPortStr =
708                     getStringElementFromJavaArray(env, portAssociations, 2 * i + 1);
709             uint8_t displayPort;
710             // Should already have been validated earlier, but do it here for safety.
711             bool success = ParseUint(displayPortStr, &displayPort);
712             if (!success) {
713                 ALOGE("Could not parse entry in port configuration file, received: %s",
714                     displayPortStr.c_str());
715                 continue;
716             }
717             outConfig->inputPortToDisplayPortAssociations.insert({inputPort, displayPort});
718         }
719         env->DeleteLocalRef(portAssociations);
720     }
721 
722     outConfig->inputPortToDisplayUniqueIdAssociations = readMapFromInterleavedJavaArray<
723             std::string>(gServiceClassInfo.getInputUniqueIdAssociationsByPort,
724                          "getInputUniqueIdAssociationsByPort");
725 
726     outConfig->inputDeviceDescriptorToDisplayUniqueIdAssociations = readMapFromInterleavedJavaArray<
727             std::string>(gServiceClassInfo.getInputUniqueIdAssociationsByDescriptor,
728                          "getInputUniqueIdAssociationsByDescriptor");
729 
730     outConfig->deviceTypeAssociations =
731             readMapFromInterleavedJavaArray<std::string>(gServiceClassInfo
732                                                                  .getDeviceTypeAssociations,
733                                                          "getDeviceTypeAssociations");
734     outConfig->keyboardLayoutAssociations = readMapFromInterleavedJavaArray<
735             KeyboardLayoutInfo>(gServiceClassInfo.getKeyboardLayoutAssociations,
736                                 "getKeyboardLayoutAssociations", [](auto&& layoutIdentifier) {
737                                     size_t commaPos = layoutIdentifier.find(',');
738                                     std::string languageTag = layoutIdentifier.substr(0, commaPos);
739                                     std::string layoutType = layoutIdentifier.substr(commaPos + 1);
740                                     return KeyboardLayoutInfo(std::move(languageTag),
741                                                               std::move(layoutType));
742                                 });
743 
744     jint hoverTapTimeout = env->CallIntMethod(mServiceObj,
745             gServiceClassInfo.getHoverTapTimeout);
746     if (!checkAndClearExceptionFromCallback(env, "getHoverTapTimeout")) {
747         jint doubleTapTimeout = env->CallIntMethod(mServiceObj,
748                 gServiceClassInfo.getDoubleTapTimeout);
749         if (!checkAndClearExceptionFromCallback(env, "getDoubleTapTimeout")) {
750             jint longPressTimeout = env->CallIntMethod(mServiceObj,
751                     gServiceClassInfo.getLongPressTimeout);
752             if (!checkAndClearExceptionFromCallback(env, "getLongPressTimeout")) {
753                 outConfig->pointerGestureTapInterval = milliseconds_to_nanoseconds(hoverTapTimeout);
754 
755                 // We must ensure that the tap-drag interval is significantly shorter than
756                 // the long-press timeout because the tap is held down for the entire duration
757                 // of the double-tap timeout.
758                 jint tapDragInterval = max(min(longPressTimeout - 100,
759                         doubleTapTimeout), hoverTapTimeout);
760                 outConfig->pointerGestureTapDragInterval =
761                         milliseconds_to_nanoseconds(tapDragInterval);
762             }
763         }
764     }
765 
766     jint hoverTapSlop = env->CallIntMethod(mServiceObj,
767             gServiceClassInfo.getHoverTapSlop);
768     if (!checkAndClearExceptionFromCallback(env, "getHoverTapSlop")) {
769         outConfig->pointerGestureTapSlop = hoverTapSlop;
770     }
771 
772     { // acquire lock
773         std::scoped_lock _l(mLock);
774 
775         outConfig->mousePointerSpeed = mLocked.pointerSpeed;
776         outConfig->displaysWithMousePointerAccelerationDisabled =
777                 mLocked.displaysWithMousePointerAccelerationDisabled;
778         outConfig->pointerVelocityControlParameters.scale =
779                 exp2f(mLocked.pointerSpeed * POINTER_SPEED_EXPONENT);
780         outConfig->pointerVelocityControlParameters.acceleration =
781                 mLocked.displaysWithMousePointerAccelerationDisabled.count(
782                         mLocked.pointerDisplayId) == 0
783                 ? android::os::IInputConstants::DEFAULT_POINTER_ACCELERATION
784                 : 1;
785         outConfig->pointerGesturesEnabled = mLocked.pointerGesturesEnabled;
786 
787         outConfig->pointerCaptureRequest = mLocked.pointerCaptureRequest;
788 
789         outConfig->setDisplayViewports(mLocked.viewports);
790 
791         outConfig->defaultPointerDisplayId = mLocked.pointerDisplayId;
792 
793         outConfig->mouseReverseVerticalScrollingEnabled =
794                 mLocked.mouseReverseVerticalScrollingEnabled;
795         outConfig->mouseSwapPrimaryButtonEnabled = mLocked.mouseSwapPrimaryButtonEnabled;
796 
797         outConfig->touchpadPointerSpeed = mLocked.touchpadPointerSpeed;
798         outConfig->touchpadNaturalScrollingEnabled = mLocked.touchpadNaturalScrollingEnabled;
799         outConfig->touchpadTapToClickEnabled = mLocked.touchpadTapToClickEnabled;
800         outConfig->touchpadTapDraggingEnabled = mLocked.touchpadTapDraggingEnabled;
801         outConfig->shouldNotifyTouchpadHardwareState = mLocked.shouldNotifyTouchpadHardwareState;
802         outConfig->touchpadRightClickZoneEnabled = mLocked.touchpadRightClickZoneEnabled;
803         outConfig->touchpadThreeFingerTapShortcutEnabled =
804                 mLocked.touchpadThreeFingerTapShortcutEnabled;
805         outConfig->touchpadSystemGesturesEnabled = mLocked.touchpadSystemGesturesEnabled;
806 
807         outConfig->disabledDevices = mLocked.disabledInputDevices;
808 
809         outConfig->stylusButtonMotionEventsEnabled = mLocked.stylusButtonMotionEventsEnabled;
810 
811         outConfig->stylusPointerIconEnabled = mLocked.stylusPointerIconEnabled;
812 
813         outConfig->keyRemapping = mLocked.keyRemapping;
814     } // release lock
815 }
816 
817 template <typename T>
readMapFromInterleavedJavaArray(jmethodID method,const char * methodName,std::function<T (std::string)> opOnValue)818 std::unordered_map<std::string, T> NativeInputManager::readMapFromInterleavedJavaArray(
819         jmethodID method, const char* methodName, std::function<T(std::string)> opOnValue) {
820     JNIEnv* env = jniEnv();
821     jobjectArray javaArray = jobjectArray(env->CallObjectMethod(mServiceObj, method));
822     std::unordered_map<std::string, T> map;
823     if (!checkAndClearExceptionFromCallback(env, methodName) && javaArray) {
824         jsize length = env->GetArrayLength(javaArray);
825         for (jsize i = 0; i < length / 2; i++) {
826             std::string key = getStringElementFromJavaArray(env, javaArray, 2 * i);
827             T value =
828                     opOnValue(std::move(getStringElementFromJavaArray(env, javaArray, 2 * i + 1)));
829             map.insert({key, value});
830         }
831     }
832     env->DeleteLocalRef(javaArray);
833     return map;
834 }
835 
forEachPointerControllerLocked(std::function<void (PointerController &)> apply)836 void NativeInputManager::forEachPointerControllerLocked(
837         std::function<void(PointerController&)> apply) {
838     auto it = mLocked.pointerControllers.begin();
839     while (it != mLocked.pointerControllers.end()) {
840         auto pc = it->lock();
841         if (!pc) {
842             it = mLocked.pointerControllers.erase(it);
843             continue;
844         }
845         apply(*pc);
846         it++;
847     }
848 }
849 
loadPointerIcon(JNIEnv * env,ui::LogicalDisplayId displayId,PointerIconStyle type)850 PointerIcon NativeInputManager::loadPointerIcon(JNIEnv* env, ui::LogicalDisplayId displayId,
851                                                 PointerIconStyle type) {
852     if (type == PointerIconStyle::TYPE_CUSTOM) {
853         LOG(FATAL) << __func__ << ": Cannot load non-system icon type";
854     }
855     if (type == PointerIconStyle::TYPE_NULL) {
856         return PointerIcon();
857     }
858 
859     ScopedLocalRef<jobject> pointerIconObj(env,
860                                            env->CallObjectMethod(mServiceObj,
861                                                                  gServiceClassInfo
862                                                                          .getLoadedPointerIcon,
863                                                                  displayId, type));
864     if (checkAndClearExceptionFromCallback(env, "getLoadedPointerIcon")) {
865         LOG(FATAL) << __func__ << ": Failed to load pointer icon";
866     }
867 
868     return android_view_PointerIcon_toNative(env, pointerIconObj.get());
869 }
870 
createPointerController(PointerControllerInterface::ControllerType type)871 std::shared_ptr<PointerControllerInterface> NativeInputManager::createPointerController(
872         PointerControllerInterface::ControllerType type) {
873     std::scoped_lock _l(mLock);
874     ensureSpriteControllerLocked();
875     std::shared_ptr<PointerController> pc =
876             PointerController::create(this, mLooper, *mLocked.spriteController, type);
877     mLocked.pointerControllers.emplace_back(pc);
878     return pc;
879 }
880 
notifyPointerDisplayIdChanged(ui::LogicalDisplayId pointerDisplayId,const vec2 & position)881 void NativeInputManager::notifyPointerDisplayIdChanged(ui::LogicalDisplayId pointerDisplayId,
882                                                        const vec2& position) {
883     // Notify the Reader so that devices can be reconfigured.
884     { // acquire lock
885         std::scoped_lock _l(mLock);
886         if (mLocked.pointerDisplayId == pointerDisplayId) {
887             return;
888         }
889         mLocked.pointerDisplayId = pointerDisplayId;
890         ALOGI("%s: pointer displayId set to: %s", __func__, pointerDisplayId.toString().c_str());
891     } // release lock
892     mInputManager->getReader().requestRefreshConfiguration(
893             InputReaderConfiguration::Change::DISPLAY_INFO);
894 }
895 
notifyMouseCursorFadedOnTyping()896 void NativeInputManager::notifyMouseCursorFadedOnTyping() {
897     mInputManager->getReader().notifyMouseCursorFadedOnTyping();
898 }
899 
notifyStickyModifierStateChanged(uint32_t modifierState,uint32_t lockedModifierState)900 void NativeInputManager::notifyStickyModifierStateChanged(uint32_t modifierState,
901                                                           uint32_t lockedModifierState) {
902     JNIEnv* env = jniEnv();
903     env->CallVoidMethod(mServiceObj, gServiceClassInfo.notifyStickyModifierStateChanged,
904                         modifierState, lockedModifierState);
905     checkAndClearExceptionFromCallback(env, "notifyStickyModifierStateChanged");
906 }
907 
getParentSurfaceForPointers(ui::LogicalDisplayId displayId)908 sp<SurfaceControl> NativeInputManager::getParentSurfaceForPointers(ui::LogicalDisplayId displayId) {
909     JNIEnv* env = jniEnv();
910     jlong nativeSurfaceControlPtr =
911             env->CallLongMethod(mServiceObj, gServiceClassInfo.getParentSurfaceForPointers,
912                                 displayId);
913     if (checkAndClearExceptionFromCallback(env, "getParentSurfaceForPointers")) {
914         return nullptr;
915     }
916 
917     return reinterpret_cast<SurfaceControl*>(nativeSurfaceControlPtr);
918 }
919 
ensureSpriteControllerLocked()920 void NativeInputManager::ensureSpriteControllerLocked() REQUIRES(mLock) {
921     if (mLocked.spriteController) {
922         return;
923     }
924     JNIEnv* env = jniEnv();
925     jint layer = env->CallIntMethod(mServiceObj, gServiceClassInfo.getPointerLayer);
926     if (checkAndClearExceptionFromCallback(env, "getPointerLayer")) {
927         layer = -1;
928     }
929     mLocked.spriteController =
930             std::make_shared<SpriteController>(mLooper, layer,
931                                                [this](ui::LogicalDisplayId displayId) {
932                                                    return getParentSurfaceForPointers(displayId);
933                                                });
934     // The SpriteController needs to be shared pointer because the handler callback needs to hold
935     // a weak reference so that we can avoid racy conditions when the controller is being destroyed.
936     mLocked.spriteController->setHandlerController(mLocked.spriteController);
937 }
938 
notifyInputDevicesChanged(const std::vector<InputDeviceInfo> & inputDevices)939 void NativeInputManager::notifyInputDevicesChanged(const std::vector<InputDeviceInfo>& inputDevices) {
940     ATRACE_CALL();
941     JNIEnv* env = jniEnv();
942 
943     size_t count = inputDevices.size();
944     jobjectArray inputDevicesObjArray = env->NewObjectArray(
945             count, gInputDeviceClassInfo.clazz, nullptr);
946     if (inputDevicesObjArray) {
947         bool error = false;
948         for (size_t i = 0; i < count; i++) {
949             jobject inputDeviceObj = android_view_InputDevice_create(env, inputDevices[i]);
950             if (!inputDeviceObj) {
951                 error = true;
952                 break;
953             }
954 
955             env->SetObjectArrayElement(inputDevicesObjArray, i, inputDeviceObj);
956             env->DeleteLocalRef(inputDeviceObj);
957         }
958 
959         if (!error) {
960             env->CallVoidMethod(mServiceObj, gServiceClassInfo.notifyInputDevicesChanged,
961                     inputDevicesObjArray);
962         }
963 
964         env->DeleteLocalRef(inputDevicesObjArray);
965     }
966 
967     checkAndClearExceptionFromCallback(env, "notifyInputDevicesChanged");
968 }
969 
createTouchpadHardwareStateObj(JNIEnv * env,const SelfContainedHardwareState & schs)970 static ScopedLocalRef<jobject> createTouchpadHardwareStateObj(
971         JNIEnv* env, const SelfContainedHardwareState& schs) {
972     ScopedLocalRef<jobject>
973             touchpadHardwareStateObj(env,
974                                      env->NewObject(gTouchpadHardwareStateClassInfo.clazz,
975                                                     gTouchpadHardwareStateClassInfo.init, ""));
976 
977     if (!touchpadHardwareStateObj.get()) {
978         return ScopedLocalRef<jobject>(env);
979     }
980 
981     env->SetFloatField(touchpadHardwareStateObj.get(), gTouchpadHardwareStateClassInfo.timestamp,
982                        static_cast<jfloat>(schs.state.timestamp));
983     env->SetIntField(touchpadHardwareStateObj.get(), gTouchpadHardwareStateClassInfo.buttonsDown,
984                      static_cast<jint>(schs.state.buttons_down));
985     env->SetIntField(touchpadHardwareStateObj.get(), gTouchpadHardwareStateClassInfo.fingerCount,
986                      static_cast<jint>(schs.state.finger_cnt));
987     env->SetIntField(touchpadHardwareStateObj.get(), gTouchpadHardwareStateClassInfo.touchCount,
988                      static_cast<jint>(schs.state.touch_cnt));
989 
990     size_t count = schs.fingers.size();
991     ScopedLocalRef<jobjectArray>
992             fingerStateObjArray(env,
993                                 env->NewObjectArray(count, gTouchpadFingerStateClassInfo.clazz,
994                                                     nullptr));
995 
996     if (!fingerStateObjArray.get()) {
997         return ScopedLocalRef<jobject>(env);
998     }
999 
1000     for (size_t i = 0; i < count; i++) {
1001         ScopedLocalRef<jobject> fingerStateObj(env,
1002                                                env->NewObject(gTouchpadFingerStateClassInfo.clazz,
1003                                                               gTouchpadFingerStateClassInfo.init,
1004                                                               ""));
1005         if (!fingerStateObj.get()) {
1006             return ScopedLocalRef<jobject>(env);
1007         }
1008         env->SetFloatField(fingerStateObj.get(), gTouchpadFingerStateClassInfo.touchMajor,
1009                            static_cast<jfloat>(schs.fingers[i].touch_major));
1010         env->SetFloatField(fingerStateObj.get(), gTouchpadFingerStateClassInfo.touchMinor,
1011                            static_cast<jfloat>(schs.fingers[i].touch_minor));
1012         env->SetFloatField(fingerStateObj.get(), gTouchpadFingerStateClassInfo.widthMajor,
1013                            static_cast<jfloat>(schs.fingers[i].width_major));
1014         env->SetFloatField(fingerStateObj.get(), gTouchpadFingerStateClassInfo.widthMinor,
1015                            static_cast<jfloat>(schs.fingers[i].width_minor));
1016         env->SetFloatField(fingerStateObj.get(), gTouchpadFingerStateClassInfo.pressure,
1017                            static_cast<jfloat>(schs.fingers[i].pressure));
1018         env->SetFloatField(fingerStateObj.get(), gTouchpadFingerStateClassInfo.orientation,
1019                            static_cast<jfloat>(schs.fingers[i].orientation));
1020         env->SetFloatField(fingerStateObj.get(), gTouchpadFingerStateClassInfo.positionX,
1021                            static_cast<jfloat>(schs.fingers[i].position_x));
1022         env->SetFloatField(fingerStateObj.get(), gTouchpadFingerStateClassInfo.positionY,
1023                            static_cast<jfloat>(schs.fingers[i].position_y));
1024         env->SetIntField(fingerStateObj.get(), gTouchpadFingerStateClassInfo.trackingId,
1025                          static_cast<jint>(schs.fingers[i].tracking_id));
1026 
1027         env->SetObjectArrayElement(fingerStateObjArray.get(), i, fingerStateObj.get());
1028     }
1029 
1030     env->SetObjectField(touchpadHardwareStateObj.get(),
1031                         gTouchpadHardwareStateClassInfo.fingerStates, fingerStateObjArray.get());
1032 
1033     return touchpadHardwareStateObj;
1034 }
1035 
notifyTouchpadHardwareState(const SelfContainedHardwareState & schs,int32_t deviceId)1036 void NativeInputManager::notifyTouchpadHardwareState(const SelfContainedHardwareState& schs,
1037                                                      int32_t deviceId) {
1038     ATRACE_CALL();
1039     JNIEnv* env = jniEnv();
1040 
1041     ScopedLocalRef<jobject> hardwareStateObj = createTouchpadHardwareStateObj(env, schs);
1042 
1043     if (hardwareStateObj.get()) {
1044         env->CallVoidMethod(mServiceObj, gServiceClassInfo.notifyTouchpadHardwareState,
1045                             hardwareStateObj.get(), deviceId);
1046     }
1047 
1048     checkAndClearExceptionFromCallback(env, "notifyTouchpadHardwareState");
1049 }
1050 
notifyTouchpadGestureInfo(enum GestureType type,int32_t deviceId)1051 void NativeInputManager::notifyTouchpadGestureInfo(enum GestureType type, int32_t deviceId) {
1052     ATRACE_CALL();
1053     JNIEnv* env = jniEnv();
1054 
1055     env->CallVoidMethod(mServiceObj, gServiceClassInfo.notifyTouchpadGestureInfo, type, deviceId);
1056 
1057     checkAndClearExceptionFromCallback(env, "notifyTouchpadGestureInfo");
1058 }
1059 
notifyTouchpadThreeFingerTap()1060 void NativeInputManager::notifyTouchpadThreeFingerTap() {
1061     ATRACE_CALL();
1062     JNIEnv* env = jniEnv();
1063     env->CallVoidMethod(mServiceObj, gServiceClassInfo.notifyTouchpadThreeFingerTap);
1064     checkAndClearExceptionFromCallback(env, "notifyTouchpadThreeFingerTap");
1065 }
1066 
getKeyboardLayoutOverlay(const InputDeviceIdentifier & identifier,const std::optional<KeyboardLayoutInfo> keyboardLayoutInfo)1067 std::shared_ptr<KeyCharacterMap> NativeInputManager::getKeyboardLayoutOverlay(
1068         const InputDeviceIdentifier& identifier,
1069         const std::optional<KeyboardLayoutInfo> keyboardLayoutInfo) {
1070     ATRACE_CALL();
1071     JNIEnv* env = jniEnv();
1072 
1073     std::shared_ptr<KeyCharacterMap> result;
1074     ScopedLocalRef<jstring> descriptor(env, env->NewStringUTF(identifier.descriptor.c_str()));
1075     ScopedLocalRef<jstring> languageTag(env,
1076                                         keyboardLayoutInfo
1077                                                 ? env->NewStringUTF(
1078                                                           keyboardLayoutInfo->languageTag.c_str())
1079                                                 : nullptr);
1080     ScopedLocalRef<jstring> layoutType(env,
1081                                        keyboardLayoutInfo
1082                                                ? env->NewStringUTF(
1083                                                          keyboardLayoutInfo->layoutType.c_str())
1084                                                : nullptr);
1085     ScopedLocalRef<jobject> identifierObj(env, env->NewObject(gInputDeviceIdentifierInfo.clazz,
1086             gInputDeviceIdentifierInfo.constructor, descriptor.get(),
1087             identifier.vendor, identifier.product));
1088     ScopedLocalRef<jobjectArray>
1089             arrayObj(env,
1090                      jobjectArray(env->CallObjectMethod(mServiceObj,
1091                                                         gServiceClassInfo.getKeyboardLayoutOverlay,
1092                                                         identifierObj.get(), languageTag.get(),
1093                                                         layoutType.get())));
1094     if (arrayObj.get()) {
1095         ScopedLocalRef<jstring> filenameObj(env,
1096                 jstring(env->GetObjectArrayElement(arrayObj.get(), 0)));
1097         ScopedLocalRef<jstring> contentsObj(env,
1098                 jstring(env->GetObjectArrayElement(arrayObj.get(), 1)));
1099         ScopedUtfChars filenameChars(env, filenameObj.get());
1100         ScopedUtfChars contentsChars(env, contentsObj.get());
1101 
1102         base::Result<std::shared_ptr<KeyCharacterMap>> ret =
1103                 KeyCharacterMap::loadContents(filenameChars.c_str(), contentsChars.c_str(),
1104                                               KeyCharacterMap::Format::OVERLAY);
1105         if (ret.ok()) {
1106             result = *ret;
1107         }
1108     }
1109     checkAndClearExceptionFromCallback(env, "getKeyboardLayoutOverlay");
1110     return result;
1111 }
1112 
getDeviceAlias(const InputDeviceIdentifier & identifier)1113 std::string NativeInputManager::getDeviceAlias(const InputDeviceIdentifier& identifier) {
1114     ATRACE_CALL();
1115     JNIEnv* env = jniEnv();
1116 
1117     ScopedLocalRef<jstring> uniqueIdObj(env, env->NewStringUTF(identifier.uniqueId.c_str()));
1118     ScopedLocalRef<jstring> aliasObj(env, jstring(env->CallObjectMethod(mServiceObj,
1119             gServiceClassInfo.getDeviceAlias, uniqueIdObj.get())));
1120     std::string result;
1121     if (aliasObj.get()) {
1122         ScopedUtfChars aliasChars(env, aliasObj.get());
1123         result = aliasChars.c_str();
1124     }
1125     checkAndClearExceptionFromCallback(env, "getDeviceAlias");
1126     return result;
1127 }
1128 
notifySwitch(nsecs_t when,uint32_t switchValues,uint32_t switchMask,uint32_t)1129 void NativeInputManager::notifySwitch(nsecs_t when,
1130         uint32_t switchValues, uint32_t switchMask, uint32_t /* policyFlags */) {
1131 #if DEBUG_INPUT_DISPATCHER_POLICY
1132     ALOGD("notifySwitch - when=%lld, switchValues=0x%08x, switchMask=0x%08x, policyFlags=0x%x",
1133             when, switchValues, switchMask, policyFlags);
1134 #endif
1135     ATRACE_CALL();
1136 
1137     JNIEnv* env = jniEnv();
1138 
1139     env->CallVoidMethod(mServiceObj, gServiceClassInfo.notifySwitch,
1140             when, switchValues, switchMask);
1141     checkAndClearExceptionFromCallback(env, "notifySwitch");
1142 }
1143 
getInputApplicationHandleObjLocalRef(JNIEnv * env,const std::shared_ptr<InputApplicationHandle> & inputApplicationHandle)1144 static jobject getInputApplicationHandleObjLocalRef(
1145         JNIEnv* env, const std::shared_ptr<InputApplicationHandle>& inputApplicationHandle) {
1146     if (inputApplicationHandle == nullptr) {
1147         return nullptr;
1148     }
1149     NativeInputApplicationHandle* handle =
1150             static_cast<NativeInputApplicationHandle*>(inputApplicationHandle.get());
1151 
1152     return handle->getInputApplicationHandleObjLocalRef(env);
1153 }
1154 
notifyNoFocusedWindowAnr(const std::shared_ptr<InputApplicationHandle> & inputApplicationHandle)1155 void NativeInputManager::notifyNoFocusedWindowAnr(
1156         const std::shared_ptr<InputApplicationHandle>& inputApplicationHandle) {
1157 #if DEBUG_INPUT_DISPATCHER_POLICY
1158     ALOGD("notifyNoFocusedWindowAnr");
1159 #endif
1160     ATRACE_CALL();
1161 
1162     JNIEnv* env = jniEnv();
1163     ScopedLocalFrame localFrame(env);
1164 
1165     jobject inputApplicationHandleObj =
1166             getInputApplicationHandleObjLocalRef(env, inputApplicationHandle);
1167 
1168     env->CallVoidMethod(mServiceObj, gServiceClassInfo.notifyNoFocusedWindowAnr,
1169                         inputApplicationHandleObj);
1170     checkAndClearExceptionFromCallback(env, "notifyNoFocusedWindowAnr");
1171 }
1172 
notifyWindowUnresponsive(const sp<IBinder> & token,std::optional<gui::Pid> pid,const std::string & reason)1173 void NativeInputManager::notifyWindowUnresponsive(const sp<IBinder>& token,
1174                                                   std::optional<gui::Pid> pid,
1175                                                   const std::string& reason) {
1176 #if DEBUG_INPUT_DISPATCHER_POLICY
1177     ALOGD("notifyWindowUnresponsive");
1178 #endif
1179     ATRACE_CALL();
1180 
1181     JNIEnv* env = jniEnv();
1182     ScopedLocalFrame localFrame(env);
1183 
1184     jobject tokenObj = javaObjectForIBinder(env, token);
1185     ScopedLocalRef<jstring> reasonObj(env, env->NewStringUTF(reason.c_str()));
1186 
1187     env->CallVoidMethod(mServiceObj, gServiceClassInfo.notifyWindowUnresponsive, tokenObj,
1188                         pid.value_or(gui::Pid{0}).val(), pid.has_value(), reasonObj.get());
1189     checkAndClearExceptionFromCallback(env, "notifyWindowUnresponsive");
1190 }
1191 
notifyWindowResponsive(const sp<IBinder> & token,std::optional<gui::Pid> pid)1192 void NativeInputManager::notifyWindowResponsive(const sp<IBinder>& token,
1193                                                 std::optional<gui::Pid> pid) {
1194 #if DEBUG_INPUT_DISPATCHER_POLICY
1195     ALOGD("notifyWindowResponsive");
1196 #endif
1197     ATRACE_CALL();
1198 
1199     JNIEnv* env = jniEnv();
1200     ScopedLocalFrame localFrame(env);
1201 
1202     jobject tokenObj = javaObjectForIBinder(env, token);
1203 
1204     env->CallVoidMethod(mServiceObj, gServiceClassInfo.notifyWindowResponsive, tokenObj,
1205                         pid.value_or(gui::Pid{0}).val(), pid.has_value());
1206     checkAndClearExceptionFromCallback(env, "notifyWindowResponsive");
1207 }
1208 
notifyInputChannelBroken(const sp<IBinder> & token)1209 void NativeInputManager::notifyInputChannelBroken(const sp<IBinder>& token) {
1210 #if DEBUG_INPUT_DISPATCHER_POLICY
1211     ALOGD("notifyInputChannelBroken");
1212 #endif
1213     ATRACE_CALL();
1214 
1215     JNIEnv* env = jniEnv();
1216     ScopedLocalFrame localFrame(env);
1217 
1218     jobject tokenObj = javaObjectForIBinder(env, token);
1219     if (tokenObj) {
1220         env->CallVoidMethod(mServiceObj, gServiceClassInfo.notifyInputChannelBroken, tokenObj);
1221         checkAndClearExceptionFromCallback(env, "notifyInputChannelBroken");
1222     }
1223 }
1224 
notifyFocusChanged(const sp<IBinder> & oldToken,const sp<IBinder> & newToken)1225 void NativeInputManager::notifyFocusChanged(const sp<IBinder>& oldToken,
1226         const sp<IBinder>& newToken) {
1227 #if DEBUG_INPUT_DISPATCHER_POLICY
1228     ALOGD("notifyFocusChanged");
1229 #endif
1230     ATRACE_CALL();
1231 
1232     JNIEnv* env = jniEnv();
1233     ScopedLocalFrame localFrame(env);
1234 
1235     jobject oldTokenObj = javaObjectForIBinder(env, oldToken);
1236     jobject newTokenObj = javaObjectForIBinder(env, newToken);
1237     env->CallVoidMethod(mServiceObj, gServiceClassInfo.notifyFocusChanged,
1238             oldTokenObj, newTokenObj);
1239     checkAndClearExceptionFromCallback(env, "notifyFocusChanged");
1240 }
1241 
notifyDropWindow(const sp<IBinder> & token,float x,float y)1242 void NativeInputManager::notifyDropWindow(const sp<IBinder>& token, float x, float y) {
1243 #if DEBUG_INPUT_DISPATCHER_POLICY
1244     ALOGD("notifyDropWindow");
1245 #endif
1246     ATRACE_CALL();
1247 
1248     JNIEnv* env = jniEnv();
1249     ScopedLocalFrame localFrame(env);
1250 
1251     jobject tokenObj = javaObjectForIBinder(env, token);
1252     env->CallVoidMethod(mServiceObj, gServiceClassInfo.notifyDropWindow, tokenObj, x, y);
1253     checkAndClearExceptionFromCallback(env, "notifyDropWindow");
1254 }
1255 
notifyDeviceInteraction(int32_t deviceId,nsecs_t timestamp,const std::set<gui::Uid> & uids)1256 void NativeInputManager::notifyDeviceInteraction(int32_t deviceId, nsecs_t timestamp,
1257                                                  const std::set<gui::Uid>& uids) {
1258     static const bool ENABLE_INPUT_DEVICE_USAGE_METRICS =
1259             sysprop::InputProperties::enable_input_device_usage_metrics().value_or(true);
1260     if (!ENABLE_INPUT_DEVICE_USAGE_METRICS) return;
1261 
1262     mInputManager->getMetricsCollector().notifyDeviceInteraction(deviceId, timestamp, uids);
1263 }
1264 
notifySensorEvent(int32_t deviceId,InputDeviceSensorType sensorType,InputDeviceSensorAccuracy accuracy,nsecs_t timestamp,const std::vector<float> & values)1265 void NativeInputManager::notifySensorEvent(int32_t deviceId, InputDeviceSensorType sensorType,
1266                                            InputDeviceSensorAccuracy accuracy, nsecs_t timestamp,
1267                                            const std::vector<float>& values) {
1268 #if DEBUG_INPUT_DISPATCHER_POLICY
1269     ALOGD("notifySensorEvent");
1270 #endif
1271     ATRACE_CALL();
1272     JNIEnv* env = jniEnv();
1273     ScopedLocalFrame localFrame(env);
1274     jfloatArray arr = env->NewFloatArray(values.size());
1275     env->SetFloatArrayRegion(arr, 0, values.size(), values.data());
1276     env->CallVoidMethod(mServiceObj, gServiceClassInfo.notifySensorEvent, deviceId,
1277                         static_cast<jint>(sensorType), accuracy, timestamp, arr);
1278     checkAndClearExceptionFromCallback(env, "notifySensorEvent");
1279 }
1280 
notifySensorAccuracy(int32_t deviceId,InputDeviceSensorType sensorType,InputDeviceSensorAccuracy accuracy)1281 void NativeInputManager::notifySensorAccuracy(int32_t deviceId, InputDeviceSensorType sensorType,
1282                                               InputDeviceSensorAccuracy accuracy) {
1283 #if DEBUG_INPUT_DISPATCHER_POLICY
1284     ALOGD("notifySensorAccuracy");
1285 #endif
1286     ATRACE_CALL();
1287     JNIEnv* env = jniEnv();
1288     ScopedLocalFrame localFrame(env);
1289     env->CallVoidMethod(mServiceObj, gServiceClassInfo.notifySensorAccuracy, deviceId,
1290                         static_cast<jint>(sensorType), accuracy);
1291     checkAndClearExceptionFromCallback(env, "notifySensorAccuracy");
1292 }
1293 
notifyVibratorState(int32_t deviceId,bool isOn)1294 void NativeInputManager::notifyVibratorState(int32_t deviceId, bool isOn) {
1295 #if DEBUG_INPUT_DISPATCHER_POLICY
1296     ALOGD("notifyVibratorState isOn:%d", isOn);
1297 #endif
1298     ATRACE_CALL();
1299     JNIEnv* env = jniEnv();
1300     ScopedLocalFrame localFrame(env);
1301     env->CallVoidMethod(mServiceObj, gServiceClassInfo.notifyVibratorState,
1302                         static_cast<jint>(deviceId), static_cast<jboolean>(isOn));
1303     checkAndClearExceptionFromCallback(env, "notifyVibratorState");
1304 }
1305 
notifyFocusedDisplayChanged(ui::LogicalDisplayId displayId)1306 void NativeInputManager::notifyFocusedDisplayChanged(ui::LogicalDisplayId displayId) {
1307     mInputManager->getChoreographer().setFocusedDisplay(displayId);
1308 }
1309 
displayRemoved(JNIEnv * env,ui::LogicalDisplayId displayId)1310 void NativeInputManager::displayRemoved(JNIEnv* env, ui::LogicalDisplayId displayId) {
1311     mInputManager->getDispatcher().displayRemoved(displayId);
1312 }
1313 
setFocusedApplication(JNIEnv * env,ui::LogicalDisplayId displayId,jobject applicationHandleObj)1314 void NativeInputManager::setFocusedApplication(JNIEnv* env, ui::LogicalDisplayId displayId,
1315                                                jobject applicationHandleObj) {
1316     if (!applicationHandleObj) {
1317         return;
1318     }
1319     std::shared_ptr<InputApplicationHandle> applicationHandle =
1320             android_view_InputApplicationHandle_getHandle(env, applicationHandleObj);
1321     applicationHandle->updateInfo();
1322     mInputManager->getDispatcher().setFocusedApplication(displayId, applicationHandle);
1323 }
1324 
setFocusedDisplay(ui::LogicalDisplayId displayId)1325 void NativeInputManager::setFocusedDisplay(ui::LogicalDisplayId displayId) {
1326     mInputManager->getDispatcher().setFocusedDisplay(displayId);
1327 }
1328 
setMinTimeBetweenUserActivityPokes(int64_t intervalMillis)1329 void NativeInputManager::setMinTimeBetweenUserActivityPokes(int64_t intervalMillis) {
1330     mInputManager->getDispatcher().setMinTimeBetweenUserActivityPokes(
1331             std::chrono::milliseconds(intervalMillis));
1332 }
1333 
setInputDispatchMode(bool enabled,bool frozen)1334 void NativeInputManager::setInputDispatchMode(bool enabled, bool frozen) {
1335     mInputManager->getDispatcher().setInputDispatchMode(enabled, frozen);
1336 }
1337 
setSystemUiLightsOut(bool lightsOut)1338 void NativeInputManager::setSystemUiLightsOut(bool lightsOut) {
1339     std::scoped_lock _l(mLock);
1340 
1341     if (mLocked.systemUiLightsOut != lightsOut) {
1342         mLocked.systemUiLightsOut = lightsOut;
1343         updateInactivityTimeoutLocked();
1344     }
1345 }
1346 
updateInactivityTimeoutLocked()1347 void NativeInputManager::updateInactivityTimeoutLocked() REQUIRES(mLock) {
1348     forEachPointerControllerLocked([lightsOut = mLocked.systemUiLightsOut](PointerController& pc) {
1349         pc.setInactivityTimeout(lightsOut ? InactivityTimeout::SHORT : InactivityTimeout::NORMAL);
1350     });
1351 }
1352 
setPointerDisplayId(ui::LogicalDisplayId displayId)1353 void NativeInputManager::setPointerDisplayId(ui::LogicalDisplayId displayId) {
1354     mInputManager->getChoreographer().setDefaultMouseDisplayId(displayId);
1355 }
1356 
getMousePointerSpeed()1357 int32_t NativeInputManager::getMousePointerSpeed() {
1358     std::scoped_lock _l(mLock);
1359     return mLocked.pointerSpeed;
1360 }
1361 
setMouseReverseVerticalScrollingEnabled(bool enabled)1362 void NativeInputManager::setMouseReverseVerticalScrollingEnabled(bool enabled) {
1363     { // acquire lock
1364         std::scoped_lock _l(mLock);
1365 
1366         if (mLocked.mouseReverseVerticalScrollingEnabled == enabled) {
1367             return;
1368         }
1369 
1370         mLocked.mouseReverseVerticalScrollingEnabled = enabled;
1371     } // release lock
1372 
1373     mInputManager->getReader().requestRefreshConfiguration(
1374             InputReaderConfiguration::Change::MOUSE_SETTINGS);
1375 }
1376 
setMouseSwapPrimaryButtonEnabled(bool enabled)1377 void NativeInputManager::setMouseSwapPrimaryButtonEnabled(bool enabled) {
1378     { // acquire lock
1379         std::scoped_lock _l(mLock);
1380 
1381         if (mLocked.mouseSwapPrimaryButtonEnabled == enabled) {
1382             return;
1383         }
1384 
1385         mLocked.mouseSwapPrimaryButtonEnabled = enabled;
1386     } // release lock
1387 
1388     mInputManager->getReader().requestRefreshConfiguration(
1389             InputReaderConfiguration::Change::MOUSE_SETTINGS);
1390 }
1391 
setPointerSpeed(int32_t speed)1392 void NativeInputManager::setPointerSpeed(int32_t speed) {
1393     { // acquire lock
1394         std::scoped_lock _l(mLock);
1395 
1396         if (mLocked.pointerSpeed == speed) {
1397             return;
1398         }
1399 
1400         ALOGI("Setting pointer speed to %d.", speed);
1401         mLocked.pointerSpeed = speed;
1402     } // release lock
1403 
1404     mInputManager->getReader().requestRefreshConfiguration(
1405             InputReaderConfiguration::Change::POINTER_SPEED);
1406 }
1407 
setMousePointerAccelerationEnabled(ui::LogicalDisplayId displayId,bool enabled)1408 void NativeInputManager::setMousePointerAccelerationEnabled(ui::LogicalDisplayId displayId,
1409                                                             bool enabled) {
1410     { // acquire lock
1411         std::scoped_lock _l(mLock);
1412 
1413         const bool oldEnabled =
1414                 mLocked.displaysWithMousePointerAccelerationDisabled.count(displayId) == 0;
1415         if (oldEnabled == enabled) {
1416             return;
1417         }
1418 
1419         ALOGI("Setting mouse pointer acceleration to %s on display %s", toString(enabled),
1420               displayId.toString().c_str());
1421         if (enabled) {
1422             mLocked.displaysWithMousePointerAccelerationDisabled.erase(displayId);
1423         } else {
1424             mLocked.displaysWithMousePointerAccelerationDisabled.emplace(displayId);
1425         }
1426     } // release lock
1427 
1428     mInputManager->getReader().requestRefreshConfiguration(
1429             InputReaderConfiguration::Change::POINTER_SPEED);
1430 }
1431 
setTouchpadPointerSpeed(int32_t speed)1432 void NativeInputManager::setTouchpadPointerSpeed(int32_t speed) {
1433     { // acquire lock
1434         std::scoped_lock _l(mLock);
1435 
1436         if (mLocked.touchpadPointerSpeed == speed) {
1437             return;
1438         }
1439 
1440         ALOGI("Setting touchpad pointer speed to %d.", speed);
1441         mLocked.touchpadPointerSpeed = speed;
1442     } // release lock
1443 
1444     mInputManager->getReader().requestRefreshConfiguration(
1445             InputReaderConfiguration::Change::TOUCHPAD_SETTINGS);
1446 }
1447 
setTouchpadNaturalScrollingEnabled(bool enabled)1448 void NativeInputManager::setTouchpadNaturalScrollingEnabled(bool enabled) {
1449     { // acquire lock
1450         std::scoped_lock _l(mLock);
1451 
1452         if (mLocked.touchpadNaturalScrollingEnabled == enabled) {
1453             return;
1454         }
1455 
1456         ALOGI("Setting touchpad natural scrolling to %s.", toString(enabled));
1457         mLocked.touchpadNaturalScrollingEnabled = enabled;
1458     } // release lock
1459 
1460     mInputManager->getReader().requestRefreshConfiguration(
1461             InputReaderConfiguration::Change::TOUCHPAD_SETTINGS);
1462 }
1463 
setTouchpadTapToClickEnabled(bool enabled)1464 void NativeInputManager::setTouchpadTapToClickEnabled(bool enabled) {
1465     { // acquire lock
1466         std::scoped_lock _l(mLock);
1467 
1468         if (mLocked.touchpadTapToClickEnabled == enabled) {
1469             return;
1470         }
1471 
1472         ALOGI("Setting touchpad tap to click to %s.", toString(enabled));
1473         mLocked.touchpadTapToClickEnabled = enabled;
1474     } // release lock
1475 
1476     mInputManager->getReader().requestRefreshConfiguration(
1477             InputReaderConfiguration::Change::TOUCHPAD_SETTINGS);
1478 }
1479 
setTouchpadTapDraggingEnabled(bool enabled)1480 void NativeInputManager::setTouchpadTapDraggingEnabled(bool enabled) {
1481     { // acquire lock
1482         std::scoped_lock _l(mLock);
1483 
1484         if (mLocked.touchpadTapDraggingEnabled == enabled) {
1485             return;
1486         }
1487 
1488         ALOGI("Setting touchpad tap dragging to %s.", toString(enabled));
1489         mLocked.touchpadTapDraggingEnabled = enabled;
1490     } // release lock
1491 
1492     mInputManager->getReader().requestRefreshConfiguration(
1493             InputReaderConfiguration::Change::TOUCHPAD_SETTINGS);
1494 }
1495 
setShouldNotifyTouchpadHardwareState(bool enabled)1496 void NativeInputManager::setShouldNotifyTouchpadHardwareState(bool enabled) {
1497     { // acquire lock
1498         std::scoped_lock _l(mLock);
1499 
1500         if (mLocked.shouldNotifyTouchpadHardwareState == enabled) {
1501             return;
1502         }
1503 
1504         ALOGI("Should touchpad hardware state be notified: %s.", toString(enabled));
1505         mLocked.shouldNotifyTouchpadHardwareState = enabled;
1506     } // release lock
1507 
1508     mInputManager->getReader().requestRefreshConfiguration(
1509             InputReaderConfiguration::Change::TOUCHPAD_SETTINGS);
1510 }
1511 
setTouchpadRightClickZoneEnabled(bool enabled)1512 void NativeInputManager::setTouchpadRightClickZoneEnabled(bool enabled) {
1513     { // acquire lock
1514         std::scoped_lock _l(mLock);
1515 
1516         if (mLocked.touchpadRightClickZoneEnabled == enabled) {
1517             return;
1518         }
1519 
1520         ALOGI("Setting touchpad right click zone to %s.", toString(enabled));
1521         mLocked.touchpadRightClickZoneEnabled = enabled;
1522     } // release lock
1523 
1524     mInputManager->getReader().requestRefreshConfiguration(
1525             InputReaderConfiguration::Change::TOUCHPAD_SETTINGS);
1526 }
1527 
setTouchpadThreeFingerTapShortcutEnabled(bool enabled)1528 void NativeInputManager::setTouchpadThreeFingerTapShortcutEnabled(bool enabled) {
1529     { // acquire lock
1530         std::scoped_lock _l(mLock);
1531 
1532         if (mLocked.touchpadThreeFingerTapShortcutEnabled == enabled) {
1533             return;
1534         }
1535 
1536         ALOGI("Setting touchpad three finger tap shortcut to %s.", toString(enabled));
1537         mLocked.touchpadThreeFingerTapShortcutEnabled = enabled;
1538     } // release lock
1539 
1540     mInputManager->getReader().requestRefreshConfiguration(
1541             InputReaderConfiguration::Change::TOUCHPAD_SETTINGS);
1542 }
1543 
setTouchpadSystemGesturesEnabled(bool enabled)1544 void NativeInputManager::setTouchpadSystemGesturesEnabled(bool enabled) {
1545     { // acquire lock
1546         std::scoped_lock _l(mLock);
1547 
1548         if (mLocked.touchpadSystemGesturesEnabled == enabled) {
1549             return;
1550         }
1551 
1552         ALOGI("Setting touchpad system gestures enabled to %s.", toString(enabled));
1553         mLocked.touchpadSystemGesturesEnabled = enabled;
1554     } // release lock
1555 
1556     mInputManager->getReader().requestRefreshConfiguration(
1557             InputReaderConfiguration::Change::TOUCHPAD_SETTINGS);
1558 }
1559 
setInputDeviceEnabled(uint32_t deviceId,bool enabled)1560 void NativeInputManager::setInputDeviceEnabled(uint32_t deviceId, bool enabled) {
1561     bool refresh = false;
1562 
1563     { // acquire lock
1564         std::scoped_lock _l(mLock);
1565 
1566         auto it = mLocked.disabledInputDevices.find(deviceId);
1567         bool currentlyEnabled = it == mLocked.disabledInputDevices.end();
1568         if (!enabled && currentlyEnabled) {
1569             mLocked.disabledInputDevices.insert(deviceId);
1570             refresh = true;
1571         }
1572         if (enabled && !currentlyEnabled) {
1573             mLocked.disabledInputDevices.erase(deviceId);
1574             refresh = true;
1575         }
1576     } // release lock
1577 
1578     if (refresh) {
1579         mInputManager->getReader().requestRefreshConfiguration(
1580                 InputReaderConfiguration::Change::ENABLED_STATE);
1581     }
1582 }
1583 
setShowTouches(bool enabled)1584 void NativeInputManager::setShowTouches(bool enabled) {
1585     mInputManager->getChoreographer().setShowTouchesEnabled(enabled);
1586 }
1587 
requestPointerCapture(const sp<IBinder> & windowToken,bool enabled)1588 void NativeInputManager::requestPointerCapture(const sp<IBinder>& windowToken, bool enabled) {
1589     mInputManager->getDispatcher().requestPointerCapture(windowToken, enabled);
1590 }
1591 
setNonInteractiveDisplays(const std::set<ui::LogicalDisplayId> & displayIds)1592 void NativeInputManager::setNonInteractiveDisplays(
1593         const std::set<ui::LogicalDisplayId>& displayIds) {
1594     std::scoped_lock _l(mLock);
1595     mLocked.nonInteractiveDisplays = displayIds;
1596 }
1597 
reloadCalibration()1598 void NativeInputManager::reloadCalibration() {
1599     mInputManager->getReader().requestRefreshConfiguration(
1600             InputReaderConfiguration::Change::TOUCH_AFFINE_TRANSFORMATION);
1601 }
1602 
reloadPointerIcons()1603 void NativeInputManager::reloadPointerIcons() {
1604     std::scoped_lock _l(mLock);
1605     forEachPointerControllerLocked([](PointerController& pc) { pc.reloadPointerResources(); });
1606 }
1607 
setPointerIcon(std::variant<std::unique_ptr<SpriteIcon>,PointerIconStyle> icon,ui::LogicalDisplayId displayId,DeviceId deviceId,int32_t pointerId,const sp<IBinder> & inputToken)1608 bool NativeInputManager::setPointerIcon(
1609         std::variant<std::unique_ptr<SpriteIcon>, PointerIconStyle> icon,
1610         ui::LogicalDisplayId displayId, DeviceId deviceId, int32_t pointerId,
1611         const sp<IBinder>& inputToken) {
1612     if (!mInputManager->getDispatcher().isPointerInWindow(inputToken, displayId, deviceId,
1613                                                           pointerId)) {
1614         LOG(WARNING) << "Attempted to change the pointer icon for deviceId " << deviceId
1615                      << " on display " << displayId << " from input token " << inputToken.get()
1616                      << ", but the pointer is not in the window.";
1617         return false;
1618     }
1619 
1620     return mInputManager->getChoreographer().setPointerIcon(std::move(icon), displayId, deviceId);
1621 }
1622 
setPointerIconVisibility(ui::LogicalDisplayId displayId,bool visible)1623 void NativeInputManager::setPointerIconVisibility(ui::LogicalDisplayId displayId, bool visible) {
1624     mInputManager->getChoreographer().setPointerIconVisibility(displayId, visible);
1625 }
1626 
getTouchAffineTransformation(JNIEnv * env,jfloatArray matrixArr)1627 TouchAffineTransformation NativeInputManager::getTouchAffineTransformation(
1628         JNIEnv *env, jfloatArray matrixArr) {
1629     ATRACE_CALL();
1630     ScopedFloatArrayRO matrix(env, matrixArr);
1631     assert(matrix.size() == 6);
1632 
1633     TouchAffineTransformation transform;
1634     transform.x_scale  = matrix[0];
1635     transform.x_ymix   = matrix[1];
1636     transform.x_offset = matrix[2];
1637     transform.y_xmix   = matrix[3];
1638     transform.y_scale  = matrix[4];
1639     transform.y_offset = matrix[5];
1640 
1641     return transform;
1642 }
1643 
getTouchAffineTransformation(const std::string & inputDeviceDescriptor,ui::Rotation surfaceRotation)1644 TouchAffineTransformation NativeInputManager::getTouchAffineTransformation(
1645         const std::string& inputDeviceDescriptor, ui::Rotation surfaceRotation) {
1646     JNIEnv* env = jniEnv();
1647 
1648     ScopedLocalRef<jstring> descriptorObj(env, env->NewStringUTF(inputDeviceDescriptor.c_str()));
1649 
1650     jobject cal = env->CallObjectMethod(mServiceObj,
1651             gServiceClassInfo.getTouchCalibrationForInputDevice, descriptorObj.get(),
1652             surfaceRotation);
1653 
1654     jfloatArray matrixArr = jfloatArray(env->CallObjectMethod(cal,
1655             gTouchCalibrationClassInfo.getAffineTransform));
1656 
1657     TouchAffineTransformation transform = getTouchAffineTransformation(env, matrixArr);
1658 
1659     env->DeleteLocalRef(matrixArr);
1660     env->DeleteLocalRef(cal);
1661 
1662     return transform;
1663 }
1664 
notifyStylusGestureStarted(int32_t deviceId,nsecs_t eventTime)1665 void NativeInputManager::notifyStylusGestureStarted(int32_t deviceId, nsecs_t eventTime) {
1666     JNIEnv* env = jniEnv();
1667     env->CallVoidMethod(mServiceObj, gServiceClassInfo.notifyStylusGestureStarted, deviceId,
1668                         eventTime);
1669     checkAndClearExceptionFromCallback(env, "notifyStylusGestureStarted");
1670 }
1671 
isInputMethodConnectionActive()1672 bool NativeInputManager::isInputMethodConnectionActive() {
1673     std::scoped_lock _l(mLock);
1674     return mLocked.isInputMethodConnectionActive;
1675 }
1676 
getPointerViewportForAssociatedDisplay(ui::LogicalDisplayId associatedDisplayId)1677 std::optional<DisplayViewport> NativeInputManager::getPointerViewportForAssociatedDisplay(
1678         ui::LogicalDisplayId associatedDisplayId) {
1679     return mInputManager->getChoreographer().getViewportForPointerDevice(associatedDisplayId);
1680 }
1681 
filterInputEvent(const InputEvent & inputEvent,uint32_t policyFlags)1682 bool NativeInputManager::filterInputEvent(const InputEvent& inputEvent, uint32_t policyFlags) {
1683     ATRACE_CALL();
1684     JNIEnv* env = jniEnv();
1685 
1686     ScopedLocalRef<jobject> inputEventObj(env);
1687     switch (inputEvent.getType()) {
1688         case InputEventType::KEY:
1689             inputEventObj =
1690                     android_view_KeyEvent_obtainAsCopy(env,
1691                                                        static_cast<const KeyEvent&>(inputEvent));
1692             break;
1693         case InputEventType::MOTION:
1694             inputEventObj = android_view_MotionEvent_obtainAsCopy(env,
1695                                                                   static_cast<const MotionEvent&>(
1696                                                                           inputEvent));
1697             break;
1698         default:
1699             return true; // dispatch the event normally
1700     }
1701 
1702     if (!inputEventObj.get()) {
1703         ALOGE("Failed to obtain input event object for filterInputEvent.");
1704         return true; // dispatch the event normally
1705     }
1706 
1707     // The callee is responsible for recycling the event.
1708     const jboolean continueEventDispatch =
1709             env->CallBooleanMethod(mServiceObj, gServiceClassInfo.filterInputEvent,
1710                                    inputEventObj.get(), policyFlags);
1711     if (checkAndClearExceptionFromCallback(env, "filterInputEvent")) {
1712         return true; // dispatch the event normally
1713     }
1714     return continueEventDispatch;
1715 }
1716 
interceptKeyBeforeQueueing(const KeyEvent & keyEvent,uint32_t & policyFlags)1717 void NativeInputManager::interceptKeyBeforeQueueing(const KeyEvent& keyEvent,
1718                                                     uint32_t& policyFlags) {
1719     ATRACE_CALL();
1720     // Policy:
1721     // - Ignore untrusted events and pass them along.
1722     // - Ask the window manager what to do with normal events and trusted injected events.
1723     // - For normal events wake and brighten the screen if currently off or dim.
1724     const bool interactive = isDisplayInteractive(keyEvent.getDisplayId());
1725     if (interactive) {
1726         policyFlags |= POLICY_FLAG_INTERACTIVE;
1727     }
1728 
1729     if ((policyFlags & POLICY_FLAG_TRUSTED) == 0) {
1730         if (interactive) {
1731             policyFlags |= POLICY_FLAG_PASS_TO_USER;
1732         }
1733         return;
1734     }
1735 
1736     const nsecs_t when = keyEvent.getEventTime();
1737     JNIEnv* env = jniEnv();
1738     ScopedLocalRef<jobject> keyEventObj = android_view_KeyEvent_obtainAsCopy(env, keyEvent);
1739     if (!keyEventObj.get()) {
1740         ALOGE("Failed to obtain key event object for interceptKeyBeforeQueueing.");
1741         return;
1742     }
1743 
1744     jint wmActions = env->CallIntMethod(mServiceObj, gServiceClassInfo.interceptKeyBeforeQueueing,
1745                                         keyEventObj.get(), policyFlags);
1746     if (checkAndClearExceptionFromCallback(env, "interceptKeyBeforeQueueing")) {
1747         wmActions = 0;
1748     }
1749     android_view_KeyEvent_recycle(env, keyEventObj.get());
1750     handleInterceptActions(wmActions, when, /*byref*/ policyFlags);
1751 }
1752 
interceptMotionBeforeQueueing(ui::LogicalDisplayId displayId,uint32_t source,int32_t action,nsecs_t when,uint32_t & policyFlags)1753 void NativeInputManager::interceptMotionBeforeQueueing(ui::LogicalDisplayId displayId,
1754                                                        uint32_t source, int32_t action,
1755                                                        nsecs_t when, uint32_t& policyFlags) {
1756     ATRACE_CALL();
1757     // Policy:
1758     // - Ignore untrusted events and pass them along.
1759     // - No special filtering for injected events required at this time.
1760     // - Filter normal events based on screen state.
1761     // - For normal events brighten (but do not wake) the screen if currently dim.
1762     const bool interactive = isDisplayInteractive(displayId);
1763     if (interactive) {
1764         policyFlags |= POLICY_FLAG_INTERACTIVE;
1765     }
1766 
1767     if ((policyFlags & POLICY_FLAG_TRUSTED) == 0 || (policyFlags & POLICY_FLAG_INJECTED)) {
1768         if (interactive) {
1769             policyFlags |= POLICY_FLAG_PASS_TO_USER;
1770         }
1771         return;
1772     }
1773 
1774     if (policyFlags & POLICY_FLAG_INTERACTIVE) {
1775         policyFlags |= POLICY_FLAG_PASS_TO_USER;
1776         return;
1777     }
1778 
1779     JNIEnv* env = jniEnv();
1780     const jint wmActions =
1781             env->CallIntMethod(mServiceObj,
1782                                gServiceClassInfo.interceptMotionBeforeQueueingNonInteractive,
1783                                displayId, source, action, when, policyFlags);
1784     if (checkAndClearExceptionFromCallback(env, "interceptMotionBeforeQueueingNonInteractive")) {
1785         return;
1786     }
1787     handleInterceptActions(wmActions, when, /*byref*/ policyFlags);
1788 }
1789 
handleInterceptActions(jint wmActions,nsecs_t when,uint32_t & policyFlags)1790 void NativeInputManager::handleInterceptActions(jint wmActions, nsecs_t when,
1791         uint32_t& policyFlags) {
1792     if (wmActions & WM_ACTION_PASS_TO_USER) {
1793         policyFlags |= POLICY_FLAG_PASS_TO_USER;
1794     } else {
1795 #if DEBUG_INPUT_DISPATCHER_POLICY
1796         ALOGD("handleInterceptActions: Not passing key to user.");
1797 #endif
1798     }
1799 }
1800 
isDisplayInteractive(ui::LogicalDisplayId displayId)1801 bool NativeInputManager::isDisplayInteractive(ui::LogicalDisplayId displayId) {
1802     // If an input event doesn't have an associated id, use the default display id
1803     if (displayId == ui::LogicalDisplayId::INVALID) {
1804         displayId = ui::LogicalDisplayId::DEFAULT;
1805     }
1806 
1807     { // acquire lock
1808         std::scoped_lock _l(mLock);
1809 
1810         auto it = mLocked.nonInteractiveDisplays.find(displayId);
1811         if (it != mLocked.nonInteractiveDisplays.end()) {
1812             return false;
1813         }
1814     } // release lock
1815 
1816     return true;
1817 }
1818 
interceptKeyBeforeDispatching(const sp<IBinder> & token,const KeyEvent & keyEvent,uint32_t policyFlags)1819 nsecs_t NativeInputManager::interceptKeyBeforeDispatching(const sp<IBinder>& token,
1820                                                           const KeyEvent& keyEvent,
1821                                                           uint32_t policyFlags) {
1822     ATRACE_CALL();
1823     // Policy:
1824     // - Ignore untrusted events and pass them along.
1825     // - Filter normal events and trusted injected events through the window manager policy to
1826     //   handle the HOME key and the like.
1827     if ((policyFlags & POLICY_FLAG_TRUSTED) == 0) {
1828         return 0;
1829     }
1830 
1831     JNIEnv* env = jniEnv();
1832     ScopedLocalFrame localFrame(env);
1833 
1834     // Token may be null
1835     ScopedLocalRef<jobject> tokenObj(env, javaObjectForIBinder(env, token));
1836     ScopedLocalRef<jobject> keyEventObj = android_view_KeyEvent_obtainAsCopy(env, keyEvent);
1837     if (!keyEventObj.get()) {
1838         ALOGE("Failed to obtain key event object for interceptKeyBeforeDispatching.");
1839         return 0;
1840     }
1841 
1842     const jlong delayMillis =
1843             env->CallLongMethod(mServiceObj, gServiceClassInfo.interceptKeyBeforeDispatching,
1844                                 tokenObj.get(), keyEventObj.get(), policyFlags);
1845     android_view_KeyEvent_recycle(env, keyEventObj.get());
1846     if (checkAndClearExceptionFromCallback(env, "interceptKeyBeforeDispatching")) {
1847         return 0;
1848     }
1849     return delayMillis < 0 ? -1 : milliseconds_to_nanoseconds(delayMillis);
1850 }
1851 
dispatchUnhandledKey(const sp<IBinder> & token,const KeyEvent & keyEvent,uint32_t policyFlags)1852 std::optional<KeyEvent> NativeInputManager::dispatchUnhandledKey(const sp<IBinder>& token,
1853                                                                  const KeyEvent& keyEvent,
1854                                                                  uint32_t policyFlags) {
1855     ATRACE_CALL();
1856     // Policy:
1857     // - Ignore untrusted events and do not perform default handling.
1858     if ((policyFlags & POLICY_FLAG_TRUSTED) == 0) {
1859         return {};
1860     }
1861 
1862     JNIEnv* env = jniEnv();
1863     ScopedLocalFrame localFrame(env);
1864 
1865     // Note: tokenObj may be null.
1866     ScopedLocalRef<jobject> tokenObj(env, javaObjectForIBinder(env, token));
1867     ScopedLocalRef<jobject> keyEventObj = android_view_KeyEvent_obtainAsCopy(env, keyEvent);
1868     if (!keyEventObj.get()) {
1869         ALOGE("Failed to obtain key event object for dispatchUnhandledKey.");
1870         return {};
1871     }
1872 
1873     ScopedLocalRef<jobject>
1874             fallbackKeyEventObj(env,
1875                                 env->CallObjectMethod(mServiceObj,
1876                                                       gServiceClassInfo.dispatchUnhandledKey,
1877                                                       tokenObj.get(), keyEventObj.get(),
1878                                                       policyFlags));
1879 
1880     android_view_KeyEvent_recycle(env, keyEventObj.get());
1881     if (checkAndClearExceptionFromCallback(env, "dispatchUnhandledKey") ||
1882         !fallbackKeyEventObj.get()) {
1883         return {};
1884     }
1885 
1886     const KeyEvent fallbackEvent =
1887             android_view_KeyEvent_obtainAsCopy(env, fallbackKeyEventObj.get());
1888     android_view_KeyEvent_recycle(env, fallbackKeyEventObj.get());
1889     return fallbackEvent;
1890 }
1891 
pokeUserActivity(nsecs_t eventTime,int32_t eventType,ui::LogicalDisplayId displayId)1892 void NativeInputManager::pokeUserActivity(nsecs_t eventTime, int32_t eventType,
1893                                           ui::LogicalDisplayId displayId) {
1894     ATRACE_CALL();
1895     android_server_PowerManagerService_userActivity(eventTime, eventType, displayId);
1896 }
1897 
onPointerDownOutsideFocus(const sp<IBinder> & touchedToken)1898 void NativeInputManager::onPointerDownOutsideFocus(const sp<IBinder>& touchedToken) {
1899     ATRACE_CALL();
1900     JNIEnv* env = jniEnv();
1901     ScopedLocalFrame localFrame(env);
1902 
1903     jobject touchedTokenObj = javaObjectForIBinder(env, touchedToken);
1904     env->CallVoidMethod(mServiceObj, gServiceClassInfo.onPointerDownOutsideFocus, touchedTokenObj);
1905     checkAndClearExceptionFromCallback(env, "onPointerDownOutsideFocus");
1906 }
1907 
setPointerCapture(const PointerCaptureRequest & request)1908 void NativeInputManager::setPointerCapture(const PointerCaptureRequest& request) {
1909     { // acquire lock
1910         std::scoped_lock _l(mLock);
1911 
1912         if (mLocked.pointerCaptureRequest == request) {
1913             return;
1914         }
1915 
1916         ALOGV("%s pointer capture.", request.isEnable() ? "Enabling" : "Disabling");
1917         mLocked.pointerCaptureRequest = request;
1918     } // release lock
1919 
1920     mInputManager->getReader().requestRefreshConfiguration(
1921             InputReaderConfiguration::Change::POINTER_CAPTURE);
1922 }
1923 
loadPointerIcon(SpriteIcon * icon,ui::LogicalDisplayId displayId)1924 void NativeInputManager::loadPointerIcon(SpriteIcon* icon, ui::LogicalDisplayId displayId) {
1925     ATRACE_CALL();
1926     JNIEnv* env = jniEnv();
1927     *icon = toSpriteIcon(loadPointerIcon(env, displayId, PointerIconStyle::TYPE_ARROW));
1928 }
1929 
loadPointerResources(PointerResources * outResources,ui::LogicalDisplayId displayId)1930 void NativeInputManager::loadPointerResources(PointerResources* outResources,
1931                                               ui::LogicalDisplayId displayId) {
1932     ATRACE_CALL();
1933     JNIEnv* env = jniEnv();
1934 
1935     outResources->spotHover =
1936             toSpriteIcon(loadPointerIcon(env, displayId, PointerIconStyle::TYPE_SPOT_HOVER));
1937     outResources->spotTouch =
1938             toSpriteIcon(loadPointerIcon(env, displayId, PointerIconStyle::TYPE_SPOT_TOUCH));
1939     outResources->spotAnchor =
1940             toSpriteIcon(loadPointerIcon(env, displayId, PointerIconStyle::TYPE_SPOT_ANCHOR));
1941 }
1942 
loadAdditionalMouseResources(std::map<PointerIconStyle,SpriteIcon> * outResources,std::map<PointerIconStyle,PointerAnimation> * outAnimationResources,ui::LogicalDisplayId displayId)1943 void NativeInputManager::loadAdditionalMouseResources(
1944         std::map<PointerIconStyle, SpriteIcon>* outResources,
1945         std::map<PointerIconStyle, PointerAnimation>* outAnimationResources,
1946         ui::LogicalDisplayId displayId) {
1947     ATRACE_CALL();
1948     JNIEnv* env = jniEnv();
1949 
1950     constexpr static std::array ADDITIONAL_STYLES{PointerIconStyle::TYPE_CONTEXT_MENU,
1951                                                   PointerIconStyle::TYPE_HAND,
1952                                                   PointerIconStyle::TYPE_HELP,
1953                                                   PointerIconStyle::TYPE_WAIT,
1954                                                   PointerIconStyle::TYPE_CELL,
1955                                                   PointerIconStyle::TYPE_CROSSHAIR,
1956                                                   PointerIconStyle::TYPE_TEXT,
1957                                                   PointerIconStyle::TYPE_VERTICAL_TEXT,
1958                                                   PointerIconStyle::TYPE_ALIAS,
1959                                                   PointerIconStyle::TYPE_COPY,
1960                                                   PointerIconStyle::TYPE_NO_DROP,
1961                                                   PointerIconStyle::TYPE_ALL_SCROLL,
1962                                                   PointerIconStyle::TYPE_HORIZONTAL_DOUBLE_ARROW,
1963                                                   PointerIconStyle::TYPE_VERTICAL_DOUBLE_ARROW,
1964                                                   PointerIconStyle::TYPE_TOP_RIGHT_DOUBLE_ARROW,
1965                                                   PointerIconStyle::TYPE_TOP_LEFT_DOUBLE_ARROW,
1966                                                   PointerIconStyle::TYPE_ZOOM_IN,
1967                                                   PointerIconStyle::TYPE_ZOOM_OUT,
1968                                                   PointerIconStyle::TYPE_GRAB,
1969                                                   PointerIconStyle::TYPE_GRABBING,
1970                                                   PointerIconStyle::TYPE_HANDWRITING,
1971                                                   PointerIconStyle::TYPE_SPOT_HOVER};
1972 
1973     for (const auto pointerIconStyle : ADDITIONAL_STYLES) {
1974         PointerIcon pointerIcon = loadPointerIcon(env, displayId, pointerIconStyle);
1975         (*outResources)[pointerIconStyle] = toSpriteIcon(pointerIcon);
1976         if (!pointerIcon.bitmapFrames.empty()) {
1977             PointerAnimation& animationData = (*outAnimationResources)[pointerIconStyle];
1978             size_t numFrames = pointerIcon.bitmapFrames.size() + 1;
1979             animationData.durationPerFrame =
1980                     milliseconds_to_nanoseconds(pointerIcon.durationPerFrame);
1981             animationData.animationFrames.reserve(numFrames);
1982             animationData.animationFrames.emplace_back(pointerIcon.bitmap, pointerIcon.style,
1983                                                        pointerIcon.hotSpotX, pointerIcon.hotSpotY,
1984                                                        pointerIcon.drawNativeDropShadow);
1985             for (size_t i = 0; i < numFrames - 1; ++i) {
1986                 animationData.animationFrames.emplace_back(pointerIcon.bitmapFrames[i],
1987                                                            pointerIcon.style, pointerIcon.hotSpotX,
1988                                                            pointerIcon.hotSpotY,
1989                                                            pointerIcon.drawNativeDropShadow);
1990             }
1991         }
1992     }
1993 
1994     (*outResources)[PointerIconStyle::TYPE_NULL] =
1995             toSpriteIcon(loadPointerIcon(env, displayId, PointerIconStyle::TYPE_NULL));
1996 }
1997 
getDefaultPointerIconId()1998 PointerIconStyle NativeInputManager::getDefaultPointerIconId() {
1999     return PointerIconStyle::TYPE_ARROW;
2000 }
2001 
getDefaultStylusIconId()2002 PointerIconStyle NativeInputManager::getDefaultStylusIconId() {
2003     // Use the empty icon as the default pointer icon for a hovering stylus.
2004     return PointerIconStyle::TYPE_NULL;
2005 }
2006 
getCustomPointerIconId()2007 PointerIconStyle NativeInputManager::getCustomPointerIconId() {
2008     return PointerIconStyle::TYPE_CUSTOM;
2009 }
2010 
setMotionClassifierEnabled(bool enabled)2011 void NativeInputManager::setMotionClassifierEnabled(bool enabled) {
2012     mInputManager->getProcessor().setMotionClassifierEnabled(enabled);
2013 }
2014 
getBluetoothAddress(int32_t deviceId)2015 std::optional<std::string> NativeInputManager::getBluetoothAddress(int32_t deviceId) {
2016     return mInputManager->getReader().getBluetoothAddress(deviceId);
2017 }
2018 
setStylusButtonMotionEventsEnabled(bool enabled)2019 void NativeInputManager::setStylusButtonMotionEventsEnabled(bool enabled) {
2020     { // acquire lock
2021         std::scoped_lock _l(mLock);
2022 
2023         if (mLocked.stylusButtonMotionEventsEnabled == enabled) {
2024             return;
2025         }
2026 
2027         mLocked.stylusButtonMotionEventsEnabled = enabled;
2028     } // release lock
2029 
2030     mInputManager->getReader().requestRefreshConfiguration(
2031             InputReaderConfiguration::Change::STYLUS_BUTTON_REPORTING);
2032 }
2033 
getMouseCursorPosition(ui::LogicalDisplayId displayId)2034 vec2 NativeInputManager::getMouseCursorPosition(ui::LogicalDisplayId displayId) {
2035     return mInputManager->getChoreographer().getMouseCursorPosition(displayId);
2036 }
2037 
setStylusPointerIconEnabled(bool enabled)2038 void NativeInputManager::setStylusPointerIconEnabled(bool enabled) {
2039     mInputManager->getChoreographer().setStylusPointerIconEnabled(enabled);
2040     return;
2041 }
2042 
setInputMethodConnectionIsActive(bool isActive)2043 void NativeInputManager::setInputMethodConnectionIsActive(bool isActive) {
2044     { // acquire lock
2045         std::scoped_lock _l(mLock);
2046         mLocked.isInputMethodConnectionActive = isActive;
2047     } // release lock
2048 
2049     mInputManager->getDispatcher().setInputMethodConnectionIsActive(isActive);
2050 }
2051 
setKeyRemapping(const std::map<int32_t,int32_t> & keyRemapping)2052 void NativeInputManager::setKeyRemapping(const std::map<int32_t, int32_t>& keyRemapping) {
2053     { // acquire lock
2054         std::scoped_lock _l(mLock);
2055         mLocked.keyRemapping = keyRemapping;
2056     } // release lock
2057 
2058     mInputManager->getReader().requestRefreshConfiguration(
2059             InputReaderConfiguration::Change::KEY_REMAPPING);
2060 }
2061 
2062 // ----------------------------------------------------------------------------
2063 
getNativeInputManager(JNIEnv * env,jobject clazz)2064 static NativeInputManager* getNativeInputManager(JNIEnv* env, jobject clazz) {
2065     return reinterpret_cast<NativeInputManager*>(
2066             env->GetLongField(clazz, gNativeInputManagerServiceImpl.mPtr));
2067 }
2068 
nativeInit(JNIEnv * env,jclass,jobject serviceObj,jobject messageQueueObj)2069 static jlong nativeInit(JNIEnv* env, jclass /* clazz */, jobject serviceObj,
2070                         jobject messageQueueObj) {
2071     sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueObj);
2072     if (messageQueue == nullptr) {
2073         jniThrowRuntimeException(env, "MessageQueue is not initialized.");
2074         return 0;
2075     }
2076 
2077     static std::once_flag nativeInitialize;
2078     NativeInputManager* im = nullptr;
2079     std::call_once(nativeInitialize, [&]() {
2080         // Create the NativeInputManager, which should not be destroyed or deallocated for the
2081         // lifetime of the process.
2082         im = new NativeInputManager(serviceObj, messageQueue->getLooper());
2083     });
2084     LOG_ALWAYS_FATAL_IF(im == nullptr, "NativeInputManager was already initialized.");
2085     return reinterpret_cast<jlong>(im);
2086 }
2087 
nativeStart(JNIEnv * env,jobject nativeImplObj)2088 static void nativeStart(JNIEnv* env, jobject nativeImplObj) {
2089     NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
2090 
2091     status_t result = im->getInputManager()->start();
2092     if (result) {
2093         jniThrowRuntimeException(env, "Input manager could not be started.");
2094     }
2095 }
2096 
nativeSetDisplayViewports(JNIEnv * env,jobject nativeImplObj,jobjectArray viewportObjArray)2097 static void nativeSetDisplayViewports(JNIEnv* env, jobject nativeImplObj,
2098                                       jobjectArray viewportObjArray) {
2099     NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
2100     im->setDisplayViewports(env, viewportObjArray);
2101 }
2102 
nativeSetDisplayTopology(JNIEnv * env,jobject nativeImplObj,jobject displayTopologyObj)2103 static void nativeSetDisplayTopology(JNIEnv* env, jobject nativeImplObj,
2104                                      jobject displayTopologyObj) {
2105     NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
2106     im->setDisplayTopology(env, displayTopologyObj);
2107 }
2108 
nativeGetScanCodeState(JNIEnv * env,jobject nativeImplObj,jint deviceId,jint sourceMask,jint scanCode)2109 static jint nativeGetScanCodeState(JNIEnv* env, jobject nativeImplObj, jint deviceId,
2110                                    jint sourceMask, jint scanCode) {
2111     NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
2112 
2113     return (jint)im->getInputManager()->getReader().getScanCodeState(deviceId, uint32_t(sourceMask),
2114                                                                      scanCode);
2115 }
2116 
nativeGetKeyCodeState(JNIEnv * env,jobject nativeImplObj,jint deviceId,jint sourceMask,jint keyCode)2117 static jint nativeGetKeyCodeState(JNIEnv* env, jobject nativeImplObj, jint deviceId,
2118                                   jint sourceMask, jint keyCode) {
2119     NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
2120 
2121     return (jint)im->getInputManager()->getReader().getKeyCodeState(deviceId, uint32_t(sourceMask),
2122                                                                     keyCode);
2123 }
2124 
nativeGetSwitchState(JNIEnv * env,jobject nativeImplObj,jint deviceId,jint sourceMask,jint sw)2125 static jint nativeGetSwitchState(JNIEnv* env, jobject nativeImplObj, jint deviceId, jint sourceMask,
2126                                  jint sw) {
2127     NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
2128 
2129     return (jint)im->getInputManager()->getReader().getSwitchState(deviceId, uint32_t(sourceMask),
2130                                                                    sw);
2131 }
2132 
getIntArray(JNIEnv * env,jintArray arr)2133 static std::vector<int32_t> getIntArray(JNIEnv* env, jintArray arr) {
2134     int32_t* a = env->GetIntArrayElements(arr, nullptr);
2135     jsize size = env->GetArrayLength(arr);
2136     std::vector<int32_t> vec(a, a + size);
2137     env->ReleaseIntArrayElements(arr, a, 0);
2138     return vec;
2139 }
2140 
nativeSetKeyRemapping(JNIEnv * env,jobject nativeImplObj,jintArray fromKeyCodesArr,jintArray toKeyCodesArr)2141 static void nativeSetKeyRemapping(JNIEnv* env, jobject nativeImplObj, jintArray fromKeyCodesArr,
2142                                   jintArray toKeyCodesArr) {
2143     const std::vector<int32_t> fromKeycodes = getIntArray(env, fromKeyCodesArr);
2144     const std::vector<int32_t> toKeycodes = getIntArray(env, toKeyCodesArr);
2145     if (fromKeycodes.size() != toKeycodes.size()) {
2146         jniThrowRuntimeException(env, "FromKeycodes and toKeycodes cannot match.");
2147     }
2148     NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
2149     std::map<int32_t, int32_t> keyRemapping;
2150     for (int i = 0; i < fromKeycodes.size(); i++) {
2151         keyRemapping.insert_or_assign(fromKeycodes[i], toKeycodes[i]);
2152     }
2153     im->setKeyRemapping(keyRemapping);
2154 }
2155 
nativeHasKeys(JNIEnv * env,jobject nativeImplObj,jint deviceId,jint sourceMask,jintArray keyCodes,jbooleanArray outFlags)2156 static jboolean nativeHasKeys(JNIEnv* env, jobject nativeImplObj, jint deviceId, jint sourceMask,
2157                               jintArray keyCodes, jbooleanArray outFlags) {
2158     NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
2159 
2160     const std::vector codes = getIntArray(env, keyCodes);
2161     uint8_t* flags = env->GetBooleanArrayElements(outFlags, nullptr);
2162     jsize numCodes = env->GetArrayLength(outFlags);
2163     jboolean result;
2164     if (numCodes != codes.size()) {
2165         return JNI_FALSE;
2166     }
2167     if (im->getInputManager()->getReader().hasKeys(deviceId, uint32_t(sourceMask), codes, flags)) {
2168         result = JNI_TRUE;
2169     } else {
2170         result = JNI_FALSE;
2171     }
2172 
2173     env->ReleaseBooleanArrayElements(outFlags, flags, 0);
2174     return result;
2175 }
2176 
nativeGetKeyCodeForKeyLocation(JNIEnv * env,jobject nativeImplObj,jint deviceId,jint locationKeyCode)2177 static jint nativeGetKeyCodeForKeyLocation(JNIEnv* env, jobject nativeImplObj, jint deviceId,
2178                                            jint locationKeyCode) {
2179     NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
2180     return (jint)im->getInputManager()->getReader().getKeyCodeForKeyLocation(deviceId,
2181                                                                              locationKeyCode);
2182 }
2183 
handleInputChannelDisposed(JNIEnv * env,jobject,const std::shared_ptr<InputChannel> & inputChannel,void * data)2184 static void handleInputChannelDisposed(JNIEnv* env, jobject /* inputChannelObj */,
2185                                        const std::shared_ptr<InputChannel>& inputChannel,
2186                                        void* data) {
2187     NativeInputManager* im = static_cast<NativeInputManager*>(data);
2188     im->removeInputChannel(inputChannel->getConnectionToken());
2189 }
2190 
nativeCreateInputChannel(JNIEnv * env,jobject nativeImplObj,jstring nameObj)2191 static jobject nativeCreateInputChannel(JNIEnv* env, jobject nativeImplObj, jstring nameObj) {
2192     NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
2193 
2194     ScopedUtfChars nameChars(env, nameObj);
2195     std::string name = nameChars.c_str();
2196 
2197     base::Result<std::unique_ptr<InputChannel>> inputChannel = im->createInputChannel(name);
2198 
2199     if (!inputChannel.ok()) {
2200         std::string message = inputChannel.error().message();
2201         message += StringPrintf(" Status=%d", static_cast<int>(inputChannel.error().code()));
2202         jniThrowRuntimeException(env, message.c_str());
2203         return nullptr;
2204     }
2205 
2206     jobject inputChannelObj =
2207             android_view_InputChannel_createJavaObject(env, std::move(*inputChannel));
2208     if (!inputChannelObj) {
2209         return nullptr;
2210     }
2211 
2212     android_view_InputChannel_setDisposeCallback(env, inputChannelObj,
2213             handleInputChannelDisposed, im);
2214     return inputChannelObj;
2215 }
2216 
nativeCreateInputMonitor(JNIEnv * env,jobject nativeImplObj,jint displayId,jstring nameObj,jint pid)2217 static jobject nativeCreateInputMonitor(JNIEnv* env, jobject nativeImplObj, jint displayId,
2218                                         jstring nameObj, jint pid) {
2219     NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
2220 
2221     if (ui::LogicalDisplayId{displayId} == ui::LogicalDisplayId::INVALID) {
2222         std::string message = "InputChannel used as a monitor must be associated with a display";
2223         jniThrowRuntimeException(env, message.c_str());
2224         return nullptr;
2225     }
2226 
2227     ScopedUtfChars nameChars(env, nameObj);
2228     std::string name = nameChars.c_str();
2229 
2230     base::Result<std::unique_ptr<InputChannel>> inputChannel =
2231             im->createInputMonitor(ui::LogicalDisplayId{displayId}, name, gui::Pid{pid});
2232 
2233     if (!inputChannel.ok()) {
2234         std::string message = inputChannel.error().message();
2235         message += StringPrintf(" Status=%d", static_cast<int>(inputChannel.error().code()));
2236         jniThrowRuntimeException(env, message.c_str());
2237         return nullptr;
2238     }
2239 
2240     jobject inputChannelObj =
2241             android_view_InputChannel_createJavaObject(env, std::move(*inputChannel));
2242     if (!inputChannelObj) {
2243         return nullptr;
2244     }
2245     return inputChannelObj;
2246 }
2247 
nativeRemoveInputChannel(JNIEnv * env,jobject nativeImplObj,jobject tokenObj)2248 static void nativeRemoveInputChannel(JNIEnv* env, jobject nativeImplObj, jobject tokenObj) {
2249     NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
2250     sp<IBinder> token = ibinderForJavaObject(env, tokenObj);
2251 
2252     status_t status = im->removeInputChannel(token);
2253     if (status && status != BAD_VALUE) { // ignore already removed channel
2254         std::string message;
2255         message += StringPrintf("Failed to remove input channel.  status=%d", status);
2256         jniThrowRuntimeException(env, message.c_str());
2257     }
2258 }
2259 
nativePilferPointers(JNIEnv * env,jobject nativeImplObj,jobject tokenObj)2260 static void nativePilferPointers(JNIEnv* env, jobject nativeImplObj, jobject tokenObj) {
2261     NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
2262     sp<IBinder> token = ibinderForJavaObject(env, tokenObj);
2263     im->pilferPointers(token);
2264 }
2265 
nativeSetInputFilterEnabled(JNIEnv * env,jobject nativeImplObj,jboolean enabled)2266 static void nativeSetInputFilterEnabled(JNIEnv* env, jobject nativeImplObj, jboolean enabled) {
2267     NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
2268 
2269     im->getInputManager()->getDispatcher().setInputFilterEnabled(enabled);
2270 }
2271 
nativeSetInTouchMode(JNIEnv * env,jobject nativeImplObj,jboolean inTouchMode,jint pid,jint uid,jboolean hasPermission,jint displayId)2272 static jboolean nativeSetInTouchMode(JNIEnv* env, jobject nativeImplObj, jboolean inTouchMode,
2273                                      jint pid, jint uid, jboolean hasPermission, jint displayId) {
2274     NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
2275 
2276     return im->getInputManager()->getDispatcher().setInTouchMode(inTouchMode, gui::Pid{pid},
2277                                                                  gui::Uid{static_cast<uid_t>(uid)},
2278                                                                  hasPermission,
2279                                                                  ui::LogicalDisplayId{displayId});
2280 }
2281 
nativeSetMaximumObscuringOpacityForTouch(JNIEnv * env,jobject nativeImplObj,jfloat opacity)2282 static void nativeSetMaximumObscuringOpacityForTouch(JNIEnv* env, jobject nativeImplObj,
2283                                                      jfloat opacity) {
2284     NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
2285 
2286     im->getInputManager()->getDispatcher().setMaximumObscuringOpacityForTouch(opacity);
2287 }
2288 
nativeInjectInputEvent(JNIEnv * env,jobject nativeImplObj,jobject inputEventObj,jboolean injectIntoUid,jint uid,jint syncMode,jint timeoutMillis,jint policyFlags)2289 static jint nativeInjectInputEvent(JNIEnv* env, jobject nativeImplObj, jobject inputEventObj,
2290                                    jboolean injectIntoUid, jint uid, jint syncMode,
2291                                    jint timeoutMillis, jint policyFlags) {
2292     NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
2293 
2294     const auto targetUid = injectIntoUid ? std::make_optional<gui::Uid>(uid) : std::nullopt;
2295     // static_cast is safe because the value was already checked at the Java layer
2296     InputEventInjectionSync mode = static_cast<InputEventInjectionSync>(syncMode);
2297 
2298     if (env->IsInstanceOf(inputEventObj, gKeyEventClassInfo.clazz)) {
2299         const KeyEvent keyEvent = android_view_KeyEvent_obtainAsCopy(env, inputEventObj);
2300         const InputEventInjectionResult result =
2301                 im->getInputManager()->getDispatcher().injectInputEvent(&keyEvent, targetUid, mode,
2302                                                                         std::chrono::milliseconds(
2303                                                                                 timeoutMillis),
2304                                                                         uint32_t(policyFlags));
2305         return static_cast<jint>(result);
2306     } else if (env->IsInstanceOf(inputEventObj, gMotionEventClassInfo.clazz)) {
2307         const MotionEvent* motionEvent = android_view_MotionEvent_getNativePtr(env, inputEventObj);
2308         if (!motionEvent) {
2309             jniThrowRuntimeException(env, "Could not read contents of MotionEvent object.");
2310             return static_cast<jint>(InputEventInjectionResult::FAILED);
2311         }
2312 
2313         const InputEventInjectionResult result =
2314                 im->getInputManager()->getDispatcher().injectInputEvent(motionEvent, targetUid,
2315                                                                         mode,
2316                                                                         std::chrono::milliseconds(
2317                                                                                 timeoutMillis),
2318                                                                         uint32_t(policyFlags));
2319         return static_cast<jint>(result);
2320     } else {
2321         jniThrowRuntimeException(env, "Invalid input event type.");
2322         return static_cast<jint>(InputEventInjectionResult::FAILED);
2323     }
2324 }
2325 
nativeVerifyInputEvent(JNIEnv * env,jobject nativeImplObj,jobject inputEventObj)2326 static jobject nativeVerifyInputEvent(JNIEnv* env, jobject nativeImplObj, jobject inputEventObj) {
2327     NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
2328 
2329     if (env->IsInstanceOf(inputEventObj, gKeyEventClassInfo.clazz)) {
2330         const KeyEvent keyEvent = android_view_KeyEvent_obtainAsCopy(env, inputEventObj);
2331         std::unique_ptr<VerifiedInputEvent> verifiedEvent =
2332                 im->getInputManager()->getDispatcher().verifyInputEvent(keyEvent);
2333         if (verifiedEvent == nullptr) {
2334             return nullptr;
2335         }
2336 
2337         return android_view_VerifiedKeyEvent(env,
2338                                              static_cast<const VerifiedKeyEvent&>(*verifiedEvent));
2339     } else if (env->IsInstanceOf(inputEventObj, gMotionEventClassInfo.clazz)) {
2340         const MotionEvent* motionEvent = android_view_MotionEvent_getNativePtr(env, inputEventObj);
2341         if (!motionEvent) {
2342             jniThrowRuntimeException(env, "Could not read contents of MotionEvent object.");
2343             return nullptr;
2344         }
2345 
2346         std::unique_ptr<VerifiedInputEvent> verifiedEvent =
2347                 im->getInputManager()->getDispatcher().verifyInputEvent(*motionEvent);
2348 
2349         if (verifiedEvent == nullptr) {
2350             return nullptr;
2351         }
2352 
2353         return android_view_VerifiedMotionEvent(env,
2354                                                 static_cast<const VerifiedMotionEvent&>(
2355                                                         *verifiedEvent));
2356     } else {
2357         jniThrowRuntimeException(env, "Invalid input event type.");
2358         return nullptr;
2359     }
2360 }
2361 
nativeToggleCapsLock(JNIEnv * env,jobject nativeImplObj,jint deviceId)2362 static void nativeToggleCapsLock(JNIEnv* env, jobject nativeImplObj, jint deviceId) {
2363     NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
2364 
2365     im->getInputManager()->getReader().toggleCapsLockState(deviceId);
2366 }
2367 
resetLockedModifierState(JNIEnv * env,jobject nativeImplObj)2368 static void resetLockedModifierState(JNIEnv* env, jobject nativeImplObj) {
2369     NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
2370 
2371     im->getInputManager()->getReader().resetLockedModifierState();
2372 }
2373 
nativeDisplayRemoved(JNIEnv * env,jobject nativeImplObj,jint displayId)2374 static void nativeDisplayRemoved(JNIEnv* env, jobject nativeImplObj, jint displayId) {
2375     NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
2376 
2377     im->displayRemoved(env, ui::LogicalDisplayId{displayId});
2378 }
2379 
nativeSetFocusedApplication(JNIEnv * env,jobject nativeImplObj,jint displayId,jobject applicationHandleObj)2380 static void nativeSetFocusedApplication(JNIEnv* env, jobject nativeImplObj, jint displayId,
2381                                         jobject applicationHandleObj) {
2382     NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
2383 
2384     im->setFocusedApplication(env, ui::LogicalDisplayId{displayId}, applicationHandleObj);
2385 }
2386 
nativeSetFocusedDisplay(JNIEnv * env,jobject nativeImplObj,jint displayId)2387 static void nativeSetFocusedDisplay(JNIEnv* env, jobject nativeImplObj, jint displayId) {
2388     NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
2389 
2390     im->setFocusedDisplay(ui::LogicalDisplayId{displayId});
2391 }
2392 
nativeSetUserActivityPokeInterval(JNIEnv * env,jobject nativeImplObj,jlong intervalMillis)2393 static void nativeSetUserActivityPokeInterval(JNIEnv* env, jobject nativeImplObj,
2394                                               jlong intervalMillis) {
2395     NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
2396 
2397     im->setMinTimeBetweenUserActivityPokes(intervalMillis);
2398 }
2399 
nativeRequestPointerCapture(JNIEnv * env,jobject nativeImplObj,jobject tokenObj,jboolean enabled)2400 static void nativeRequestPointerCapture(JNIEnv* env, jobject nativeImplObj, jobject tokenObj,
2401                                         jboolean enabled) {
2402     NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
2403     sp<IBinder> windowToken = ibinderForJavaObject(env, tokenObj);
2404 
2405     im->requestPointerCapture(windowToken, enabled);
2406 }
2407 
nativeSetInputDispatchMode(JNIEnv * env,jobject nativeImplObj,jboolean enabled,jboolean frozen)2408 static void nativeSetInputDispatchMode(JNIEnv* env, jobject nativeImplObj, jboolean enabled,
2409                                        jboolean frozen) {
2410     NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
2411 
2412     im->setInputDispatchMode(enabled, frozen);
2413 }
2414 
nativeSetSystemUiLightsOut(JNIEnv * env,jobject nativeImplObj,jboolean lightsOut)2415 static void nativeSetSystemUiLightsOut(JNIEnv* env, jobject nativeImplObj, jboolean lightsOut) {
2416     NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
2417 
2418     im->setSystemUiLightsOut(lightsOut);
2419 }
2420 
nativeTransferTouchGesture(JNIEnv * env,jobject nativeImplObj,jobject fromChannelTokenObj,jobject toChannelTokenObj,jboolean isDragDrop)2421 static jboolean nativeTransferTouchGesture(JNIEnv* env, jobject nativeImplObj,
2422                                            jobject fromChannelTokenObj, jobject toChannelTokenObj,
2423                                            jboolean isDragDrop) {
2424     if (fromChannelTokenObj == nullptr || toChannelTokenObj == nullptr) {
2425         return JNI_FALSE;
2426     }
2427 
2428     sp<IBinder> fromChannelToken = ibinderForJavaObject(env, fromChannelTokenObj);
2429     sp<IBinder> toChannelToken = ibinderForJavaObject(env, toChannelTokenObj);
2430 
2431     NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
2432     if (im->getInputManager()->getDispatcher().transferTouchGesture(fromChannelToken,
2433                                                                     toChannelToken, isDragDrop)) {
2434         return JNI_TRUE;
2435     } else {
2436         return JNI_FALSE;
2437     }
2438 }
2439 
nativeTransferTouchOnDisplay(JNIEnv * env,jobject nativeImplObj,jobject destChannelTokenObj,jint displayId)2440 static jboolean nativeTransferTouchOnDisplay(JNIEnv* env, jobject nativeImplObj,
2441                                              jobject destChannelTokenObj, jint displayId) {
2442     sp<IBinder> destChannelToken = ibinderForJavaObject(env, destChannelTokenObj);
2443 
2444     NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
2445     if (im->getInputManager()->getDispatcher().transferTouchOnDisplay(destChannelToken,
2446                                                                       ui::LogicalDisplayId{
2447                                                                               displayId})) {
2448         return JNI_TRUE;
2449     } else {
2450         return JNI_FALSE;
2451     }
2452 }
2453 
nativeGetMousePointerSpeed(JNIEnv * env,jobject nativeImplObj)2454 static jint nativeGetMousePointerSpeed(JNIEnv* env, jobject nativeImplObj) {
2455     NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
2456 
2457     return static_cast<jint>(im->getMousePointerSpeed());
2458 }
2459 
nativeSetPointerSpeed(JNIEnv * env,jobject nativeImplObj,jint speed)2460 static void nativeSetPointerSpeed(JNIEnv* env, jobject nativeImplObj, jint speed) {
2461     NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
2462 
2463     im->setPointerSpeed(speed);
2464 }
2465 
nativeSetMousePointerAccelerationEnabled(JNIEnv * env,jobject nativeImplObj,jint displayId,jboolean enabled)2466 static void nativeSetMousePointerAccelerationEnabled(JNIEnv* env, jobject nativeImplObj,
2467                                                      jint displayId, jboolean enabled) {
2468     NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
2469 
2470     im->setMousePointerAccelerationEnabled(ui::LogicalDisplayId{displayId}, enabled);
2471 }
2472 
nativeSetTouchpadPointerSpeed(JNIEnv * env,jobject nativeImplObj,jint speed)2473 static void nativeSetTouchpadPointerSpeed(JNIEnv* env, jobject nativeImplObj, jint speed) {
2474     NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
2475 
2476     im->setTouchpadPointerSpeed(speed);
2477 }
2478 
nativeSetTouchpadNaturalScrollingEnabled(JNIEnv * env,jobject nativeImplObj,jboolean enabled)2479 static void nativeSetTouchpadNaturalScrollingEnabled(JNIEnv* env, jobject nativeImplObj,
2480                                                      jboolean enabled) {
2481     NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
2482 
2483     im->setTouchpadNaturalScrollingEnabled(enabled);
2484 }
2485 
nativeSetTouchpadTapToClickEnabled(JNIEnv * env,jobject nativeImplObj,jboolean enabled)2486 static void nativeSetTouchpadTapToClickEnabled(JNIEnv* env, jobject nativeImplObj,
2487                                                jboolean enabled) {
2488     NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
2489 
2490     im->setTouchpadTapToClickEnabled(enabled);
2491 }
2492 
nativeSetTouchpadTapDraggingEnabled(JNIEnv * env,jobject nativeImplObj,jboolean enabled)2493 static void nativeSetTouchpadTapDraggingEnabled(JNIEnv* env, jobject nativeImplObj,
2494                                                 jboolean enabled) {
2495     NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
2496 
2497     im->setTouchpadTapDraggingEnabled(enabled);
2498 }
2499 
nativeSetShouldNotifyTouchpadHardwareState(JNIEnv * env,jobject nativeImplObj,jboolean enabled)2500 static void nativeSetShouldNotifyTouchpadHardwareState(JNIEnv* env, jobject nativeImplObj,
2501                                                        jboolean enabled) {
2502     NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
2503 
2504     im->setShouldNotifyTouchpadHardwareState(enabled);
2505 }
2506 
nativeSetTouchpadRightClickZoneEnabled(JNIEnv * env,jobject nativeImplObj,jboolean enabled)2507 static void nativeSetTouchpadRightClickZoneEnabled(JNIEnv* env, jobject nativeImplObj,
2508                                                    jboolean enabled) {
2509     NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
2510 
2511     im->setTouchpadRightClickZoneEnabled(enabled);
2512 }
2513 
nativeSetTouchpadThreeFingerTapShortcutEnabled(JNIEnv * env,jobject nativeImplObj,jboolean enabled)2514 static void nativeSetTouchpadThreeFingerTapShortcutEnabled(JNIEnv* env, jobject nativeImplObj,
2515                                                            jboolean enabled) {
2516     getNativeInputManager(env, nativeImplObj)->setTouchpadThreeFingerTapShortcutEnabled(enabled);
2517 }
2518 
nativeSetTouchpadSystemGesturesEnabled(JNIEnv * env,jobject nativeImplObj,jboolean enabled)2519 static void nativeSetTouchpadSystemGesturesEnabled(JNIEnv* env, jobject nativeImplObj,
2520                                                    jboolean enabled) {
2521     NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
2522 
2523     im->setTouchpadSystemGesturesEnabled(enabled);
2524 }
2525 
nativeSetShowTouches(JNIEnv * env,jobject nativeImplObj,jboolean enabled)2526 static void nativeSetShowTouches(JNIEnv* env, jobject nativeImplObj, jboolean enabled) {
2527     NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
2528 
2529     im->setShowTouches(enabled);
2530 }
2531 
nativeSetNonInteractiveDisplays(JNIEnv * env,jobject nativeImplObj,jintArray displayIds)2532 static void nativeSetNonInteractiveDisplays(JNIEnv* env, jobject nativeImplObj,
2533                                             jintArray displayIds) {
2534     NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
2535 
2536     const std::vector displayIdsVec = getIntArray(env, displayIds);
2537     std::set<ui::LogicalDisplayId> logicalDisplayIds;
2538     for (int displayId : displayIdsVec) {
2539         logicalDisplayIds.emplace(ui::LogicalDisplayId{displayId});
2540     }
2541 
2542     im->setNonInteractiveDisplays(logicalDisplayIds);
2543 }
2544 
nativeReloadCalibration(JNIEnv * env,jobject nativeImplObj)2545 static void nativeReloadCalibration(JNIEnv* env, jobject nativeImplObj) {
2546     NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
2547 
2548     im->reloadCalibration();
2549 }
2550 
nativeVibrate(JNIEnv * env,jobject nativeImplObj,jint deviceId,jlongArray patternObj,jintArray amplitudesObj,jint repeat,jint token)2551 static void nativeVibrate(JNIEnv* env, jobject nativeImplObj, jint deviceId, jlongArray patternObj,
2552                           jintArray amplitudesObj, jint repeat, jint token) {
2553     NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
2554 
2555     size_t patternSize = env->GetArrayLength(patternObj);
2556     if (patternSize > MAX_VIBRATE_PATTERN_SIZE) {
2557         ALOGI("Skipped requested vibration because the pattern size is %zu "
2558                 "which is more than the maximum supported size of %d.",
2559                 patternSize, MAX_VIBRATE_PATTERN_SIZE);
2560         return; // limit to reasonable size
2561     }
2562 
2563     jlong* patternMillis = static_cast<jlong*>(env->GetPrimitiveArrayCritical(
2564             patternObj, nullptr));
2565     jint* amplitudes = static_cast<jint*>(env->GetPrimitiveArrayCritical(amplitudesObj, nullptr));
2566 
2567     VibrationSequence sequence(patternSize);
2568     std::vector<int32_t> vibrators = im->getInputManager()->getReader().getVibratorIds(deviceId);
2569     for (size_t i = 0; i < patternSize; i++) {
2570         // VibrationEffect.validate guarantees duration > 0.
2571         std::chrono::milliseconds duration(patternMillis[i]);
2572         VibrationElement element(CHANNEL_SIZE);
2573         element.duration = std::min(duration, MAX_VIBRATE_PATTERN_DELAY_MILLIS);
2574         // Vibrate on both channels
2575         for (int32_t channel = 0; channel < vibrators.size(); channel++) {
2576             element.addChannel(vibrators[channel], static_cast<uint8_t>(amplitudes[i]));
2577         }
2578         sequence.addElement(element);
2579     }
2580     env->ReleasePrimitiveArrayCritical(patternObj, patternMillis, JNI_ABORT);
2581     env->ReleasePrimitiveArrayCritical(amplitudesObj, amplitudes, JNI_ABORT);
2582 
2583     im->getInputManager()->getReader().vibrate(deviceId, sequence, repeat, token);
2584 }
2585 
nativeVibrateCombined(JNIEnv * env,jobject nativeImplObj,jint deviceId,jlongArray patternObj,jobject amplitudesObj,jint repeat,jint token)2586 static void nativeVibrateCombined(JNIEnv* env, jobject nativeImplObj, jint deviceId,
2587                                   jlongArray patternObj, jobject amplitudesObj, jint repeat,
2588                                   jint token) {
2589     NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
2590 
2591     size_t patternSize = env->GetArrayLength(patternObj);
2592 
2593     if (patternSize > MAX_VIBRATE_PATTERN_SIZE) {
2594         ALOGI("Skipped requested vibration because the pattern size is %zu "
2595               "which is more than the maximum supported size of %d.",
2596               patternSize, MAX_VIBRATE_PATTERN_SIZE);
2597         return; // limit to reasonable size
2598     }
2599     const jlong* patternMillis = env->GetLongArrayElements(patternObj, nullptr);
2600 
2601     std::array<jint*, CHANNEL_SIZE> amplitudesArray;
2602     std::array<jint, CHANNEL_SIZE> vibratorIdArray;
2603     jint amplSize = env->CallIntMethod(amplitudesObj, gSparseArrayClassInfo.size);
2604     if (amplSize > CHANNEL_SIZE) {
2605         ALOGE("Can not fit into input device vibration element.");
2606         return;
2607     }
2608 
2609     for (int i = 0; i < amplSize; i++) {
2610         vibratorIdArray[i] = env->CallIntMethod(amplitudesObj, gSparseArrayClassInfo.keyAt, i);
2611         jintArray arr = static_cast<jintArray>(
2612                 env->CallObjectMethod(amplitudesObj, gSparseArrayClassInfo.valueAt, i));
2613         amplitudesArray[i] = env->GetIntArrayElements(arr, nullptr);
2614         if (env->GetArrayLength(arr) != patternSize) {
2615             ALOGE("Amplitude length not equal to pattern length!");
2616             return;
2617         }
2618     }
2619 
2620     VibrationSequence sequence(patternSize);
2621     for (size_t i = 0; i < patternSize; i++) {
2622         VibrationElement element(CHANNEL_SIZE);
2623         // VibrationEffect.validate guarantees duration > 0.
2624         std::chrono::milliseconds duration(patternMillis[i]);
2625         element.duration = std::min(duration, MAX_VIBRATE_PATTERN_DELAY_MILLIS);
2626         for (int32_t channel = 0; channel < amplSize; channel++) {
2627             element.addChannel(vibratorIdArray[channel],
2628                                static_cast<uint8_t>(amplitudesArray[channel][i]));
2629         }
2630         sequence.addElement(element);
2631     }
2632 
2633     im->getInputManager()->getReader().vibrate(deviceId, sequence, repeat, token);
2634 }
2635 
nativeCancelVibrate(JNIEnv * env,jobject nativeImplObj,jint deviceId,jint token)2636 static void nativeCancelVibrate(JNIEnv* env, jobject nativeImplObj, jint deviceId, jint token) {
2637     NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
2638 
2639     im->getInputManager()->getReader().cancelVibrate(deviceId, token);
2640 }
2641 
nativeIsVibrating(JNIEnv * env,jobject nativeImplObj,jint deviceId)2642 static bool nativeIsVibrating(JNIEnv* env, jobject nativeImplObj, jint deviceId) {
2643     NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
2644 
2645     return im->getInputManager()->getReader().isVibrating(deviceId);
2646 }
2647 
nativeGetVibratorIds(JNIEnv * env,jobject nativeImplObj,jint deviceId)2648 static jintArray nativeGetVibratorIds(JNIEnv* env, jobject nativeImplObj, jint deviceId) {
2649     NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
2650     std::vector<int32_t> vibrators = im->getInputManager()->getReader().getVibratorIds(deviceId);
2651 
2652     jintArray vibIdArray = env->NewIntArray(vibrators.size());
2653     if (vibIdArray != nullptr) {
2654         env->SetIntArrayRegion(vibIdArray, 0, vibrators.size(), vibrators.data());
2655     }
2656     return vibIdArray;
2657 }
2658 
nativeGetLights(JNIEnv * env,jobject nativeImplObj,jint deviceId)2659 static jobject nativeGetLights(JNIEnv* env, jobject nativeImplObj, jint deviceId) {
2660     NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
2661     jobject jLights = env->NewObject(gArrayListClassInfo.clazz, gArrayListClassInfo.constructor);
2662 
2663     std::vector<InputDeviceLightInfo> lights =
2664             im->getInputManager()->getReader().getLights(deviceId);
2665 
2666     for (size_t i = 0; i < lights.size(); i++) {
2667         const InputDeviceLightInfo& lightInfo = lights[i];
2668 
2669         jint jTypeId =
2670                 env->GetStaticIntField(gLightClassInfo.clazz, gLightClassInfo.lightTypeInput);
2671         if (lightInfo.type == InputDeviceLightType::INPUT) {
2672             jTypeId = env->GetStaticIntField(gLightClassInfo.clazz, gLightClassInfo.lightTypeInput);
2673         } else if (lightInfo.type == InputDeviceLightType::PLAYER_ID) {
2674             jTypeId = env->GetStaticIntField(gLightClassInfo.clazz,
2675                                                  gLightClassInfo.lightTypePlayerId);
2676         } else if (lightInfo.type == InputDeviceLightType::KEYBOARD_BACKLIGHT) {
2677             jTypeId = env->GetStaticIntField(gLightClassInfo.clazz,
2678                                              gLightClassInfo.lightTypeKeyboardBacklight);
2679         } else if (lightInfo.type == InputDeviceLightType::KEYBOARD_MIC_MUTE) {
2680             jTypeId = env->GetStaticIntField(gLightClassInfo.clazz,
2681                                              gLightClassInfo.lightTypeKeyboardMicMute);
2682         } else if (lightInfo.type == InputDeviceLightType::KEYBOARD_VOLUME_MUTE) {
2683             jTypeId = env->GetStaticIntField(gLightClassInfo.clazz,
2684                                              gLightClassInfo.lightTypeKeyboardVolumeMute);
2685         } else {
2686             ALOGW("Unknown light type %s", ftl::enum_string(lightInfo.type).c_str());
2687             continue;
2688         }
2689 
2690         jint jCapability = 0;
2691         if (lightInfo.capabilityFlags.test(InputDeviceLightCapability::BRIGHTNESS)) {
2692             jCapability |= env->GetStaticIntField(gLightClassInfo.clazz,
2693                                                   gLightClassInfo.lightCapabilityBrightness);
2694         }
2695         if (lightInfo.capabilityFlags.test(InputDeviceLightCapability::RGB)) {
2696             jCapability |= env->GetStaticIntField(gLightClassInfo.clazz,
2697                                                   gLightClassInfo.lightCapabilityColorRgb);
2698         }
2699 
2700         ScopedLocalRef<jintArray> jPreferredBrightnessLevels{env};
2701         if (!lightInfo.preferredBrightnessLevels.empty()) {
2702             std::vector<int32_t> vec;
2703             for (auto it : lightInfo.preferredBrightnessLevels) {
2704               vec.push_back(ftl::to_underlying(it));
2705             }
2706             jPreferredBrightnessLevels.reset(env->NewIntArray(vec.size()));
2707             env->SetIntArrayRegion(jPreferredBrightnessLevels.get(), 0, vec.size(), vec.data());
2708         }
2709 
2710         ScopedLocalRef<jobject> lightObj(env,
2711                                          env->NewObject(gLightClassInfo.clazz,
2712                                                         gLightClassInfo.constructor,
2713                                                         static_cast<jint>(lightInfo.id),
2714                                                         env->NewStringUTF(lightInfo.name.c_str()),
2715                                                         static_cast<jint>(lightInfo.ordinal),
2716                                                         jTypeId, jCapability,
2717                                                         jPreferredBrightnessLevels.get()));
2718         // Add light object to list
2719         env->CallBooleanMethod(jLights, gArrayListClassInfo.add, lightObj.get());
2720     }
2721 
2722     return jLights;
2723 }
2724 
nativeGetLightPlayerId(JNIEnv * env,jobject nativeImplObj,jint deviceId,jint lightId)2725 static jint nativeGetLightPlayerId(JNIEnv* env, jobject nativeImplObj, jint deviceId,
2726                                    jint lightId) {
2727     NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
2728 
2729     std::optional<int32_t> ret =
2730             im->getInputManager()->getReader().getLightPlayerId(deviceId, lightId);
2731 
2732     return static_cast<jint>(ret.value_or(0));
2733 }
2734 
nativeGetLightColor(JNIEnv * env,jobject nativeImplObj,jint deviceId,jint lightId)2735 static jint nativeGetLightColor(JNIEnv* env, jobject nativeImplObj, jint deviceId, jint lightId) {
2736     NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
2737 
2738     std::optional<int32_t> ret =
2739             im->getInputManager()->getReader().getLightColor(deviceId, lightId);
2740     return static_cast<jint>(ret.value_or(0));
2741 }
2742 
nativeSetLightPlayerId(JNIEnv * env,jobject nativeImplObj,jint deviceId,jint lightId,jint playerId)2743 static void nativeSetLightPlayerId(JNIEnv* env, jobject nativeImplObj, jint deviceId, jint lightId,
2744                                    jint playerId) {
2745     NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
2746 
2747     im->getInputManager()->getReader().setLightPlayerId(deviceId, lightId, playerId);
2748 }
2749 
nativeSetLightColor(JNIEnv * env,jobject nativeImplObj,jint deviceId,jint lightId,jint color)2750 static void nativeSetLightColor(JNIEnv* env, jobject nativeImplObj, jint deviceId, jint lightId,
2751                                 jint color) {
2752     NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
2753 
2754     im->getInputManager()->getReader().setLightColor(deviceId, lightId, color);
2755 }
2756 
nativeGetBatteryCapacity(JNIEnv * env,jobject nativeImplObj,jint deviceId)2757 static jint nativeGetBatteryCapacity(JNIEnv* env, jobject nativeImplObj, jint deviceId) {
2758     NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
2759 
2760     std::optional<int32_t> ret = im->getInputManager()->getReader().getBatteryCapacity(deviceId);
2761     return static_cast<jint>(ret.value_or(android::os::IInputConstants::INVALID_BATTERY_CAPACITY));
2762 }
2763 
nativeGetBatteryStatus(JNIEnv * env,jobject nativeImplObj,jint deviceId)2764 static jint nativeGetBatteryStatus(JNIEnv* env, jobject nativeImplObj, jint deviceId) {
2765     NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
2766 
2767     std::optional<int32_t> ret = im->getInputManager()->getReader().getBatteryStatus(deviceId);
2768     return static_cast<jint>(ret.value_or(BATTERY_STATUS_UNKNOWN));
2769 }
2770 
nativeGetBatteryDevicePath(JNIEnv * env,jobject nativeImplObj,jint deviceId)2771 static jstring nativeGetBatteryDevicePath(JNIEnv* env, jobject nativeImplObj, jint deviceId) {
2772     NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
2773 
2774     const std::optional<std::string> batteryPath =
2775             im->getInputManager()->getReader().getBatteryDevicePath(deviceId);
2776     return batteryPath ? env->NewStringUTF(batteryPath->c_str()) : nullptr;
2777 }
2778 
nativeReloadKeyboardLayouts(JNIEnv * env,jobject nativeImplObj)2779 static void nativeReloadKeyboardLayouts(JNIEnv* env, jobject nativeImplObj) {
2780     NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
2781 
2782     im->getInputManager()->getReader().requestRefreshConfiguration(
2783             InputReaderConfiguration::Change::KEYBOARD_LAYOUTS);
2784 }
2785 
nativeReloadDeviceAliases(JNIEnv * env,jobject nativeImplObj)2786 static void nativeReloadDeviceAliases(JNIEnv* env, jobject nativeImplObj) {
2787     NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
2788 
2789     im->getInputManager()->getReader().requestRefreshConfiguration(
2790             InputReaderConfiguration::Change::DEVICE_ALIAS);
2791 }
2792 
nativeSysfsNodeChanged(JNIEnv * env,jobject nativeImplObj,jstring path)2793 static void nativeSysfsNodeChanged(JNIEnv* env, jobject nativeImplObj, jstring path) {
2794     ScopedUtfChars sysfsNodePathChars(env, path);
2795     const std::string sysfsNodePath = sysfsNodePathChars.c_str();
2796 
2797     NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
2798     im->getInputManager()->getReader().sysfsNodeChanged(sysfsNodePath);
2799 }
2800 
dumpInputProperties()2801 static std::string dumpInputProperties() {
2802     std::string out = "Input properties:\n";
2803     const std::string strategy =
2804             server_configurable_flags::GetServerConfigurableFlag(INPUT_NATIVE_BOOT,
2805                                                                  VELOCITYTRACKER_STRATEGY,
2806                                                                  "default");
2807     out += "  velocitytracker_strategy (flag value) = " + strategy + "\n";
2808     out += "\n";
2809     return out;
2810 }
2811 
nativeDump(JNIEnv * env,jobject nativeImplObj)2812 static jstring nativeDump(JNIEnv* env, jobject nativeImplObj) {
2813     std::string dump = dumpInputProperties();
2814 
2815     NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
2816     im->dump(dump);
2817 
2818     return env->NewStringUTF(dump.c_str());
2819 }
2820 
nativeMonitor(JNIEnv * env,jobject nativeImplObj)2821 static void nativeMonitor(JNIEnv* env, jobject nativeImplObj) {
2822     NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
2823 
2824     im->getInputManager()->getReader().monitor();
2825     im->getInputManager()->getDispatcher().monitor();
2826 }
2827 
nativeEnableInputDevice(JNIEnv * env,jobject nativeImplObj,jint deviceId)2828 static void nativeEnableInputDevice(JNIEnv* env, jobject nativeImplObj, jint deviceId) {
2829     NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
2830 
2831     im->setInputDeviceEnabled(deviceId, true);
2832 }
2833 
nativeDisableInputDevice(JNIEnv * env,jobject nativeImplObj,jint deviceId)2834 static void nativeDisableInputDevice(JNIEnv* env, jobject nativeImplObj, jint deviceId) {
2835     NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
2836 
2837     im->setInputDeviceEnabled(deviceId, false);
2838 }
2839 
nativeReloadPointerIcons(JNIEnv * env,jobject nativeImplObj)2840 static void nativeReloadPointerIcons(JNIEnv* env, jobject nativeImplObj) {
2841     NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
2842 
2843     im->reloadPointerIcons();
2844 }
2845 
nativeSetPointerIcon(JNIEnv * env,jobject nativeImplObj,jobject iconObj,jint displayId,jint deviceId,jint pointerId,jobject inputTokenObj)2846 static bool nativeSetPointerIcon(JNIEnv* env, jobject nativeImplObj, jobject iconObj,
2847                                  jint displayId, jint deviceId, jint pointerId,
2848                                  jobject inputTokenObj) {
2849     NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
2850 
2851     PointerIcon pointerIcon = android_view_PointerIcon_toNative(env, iconObj);
2852 
2853     std::variant<std::unique_ptr<SpriteIcon>, PointerIconStyle> icon;
2854     if (pointerIcon.style == PointerIconStyle::TYPE_CUSTOM) {
2855         icon = std::make_unique<SpriteIcon>(pointerIcon.bitmap.copy(
2856                                                     ANDROID_BITMAP_FORMAT_RGBA_8888),
2857                                             pointerIcon.style, pointerIcon.hotSpotX,
2858                                             pointerIcon.hotSpotY, pointerIcon.drawNativeDropShadow);
2859     } else {
2860         icon = pointerIcon.style;
2861     }
2862 
2863     return im->setPointerIcon(std::move(icon), ui::LogicalDisplayId{displayId}, deviceId, pointerId,
2864                               ibinderForJavaObject(env, inputTokenObj));
2865 }
2866 
nativeSetPointerIconVisibility(JNIEnv * env,jobject nativeImplObj,jint displayId,jboolean visible)2867 static void nativeSetPointerIconVisibility(JNIEnv* env, jobject nativeImplObj, jint displayId,
2868                                            jboolean visible) {
2869     NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
2870 
2871     im->setPointerIconVisibility(ui::LogicalDisplayId{displayId}, visible);
2872 }
2873 
nativeCanDispatchToDisplay(JNIEnv * env,jobject nativeImplObj,jint deviceId,jint displayId)2874 static jboolean nativeCanDispatchToDisplay(JNIEnv* env, jobject nativeImplObj, jint deviceId,
2875                                            jint displayId) {
2876     NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
2877     return im->getInputManager()->getReader().canDispatchToDisplay(deviceId,
2878                                                                    ui::LogicalDisplayId{displayId});
2879 }
2880 
nativeNotifyPortAssociationsChanged(JNIEnv * env,jobject nativeImplObj)2881 static void nativeNotifyPortAssociationsChanged(JNIEnv* env, jobject nativeImplObj) {
2882     NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
2883     im->getInputManager()->getReader().requestRefreshConfiguration(
2884             InputReaderConfiguration::Change::DISPLAY_INFO);
2885 }
2886 
nativeSetDisplayEligibilityForPointerCapture(JNIEnv * env,jobject nativeImplObj,jint displayId,jboolean isEligible)2887 static void nativeSetDisplayEligibilityForPointerCapture(JNIEnv* env, jobject nativeImplObj,
2888                                                          jint displayId, jboolean isEligible) {
2889     NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
2890     im->getInputManager()
2891             ->getDispatcher()
2892             .setDisplayEligibilityForPointerCapture(ui::LogicalDisplayId{displayId}, isEligible);
2893 }
2894 
nativeChangeUniqueIdAssociation(JNIEnv * env,jobject nativeImplObj)2895 static void nativeChangeUniqueIdAssociation(JNIEnv* env, jobject nativeImplObj) {
2896     NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
2897     im->getInputManager()->getReader().requestRefreshConfiguration(
2898             InputReaderConfiguration::Change::DISPLAY_INFO);
2899 }
2900 
nativeChangeTypeAssociation(JNIEnv * env,jobject nativeImplObj)2901 static void nativeChangeTypeAssociation(JNIEnv* env, jobject nativeImplObj) {
2902     NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
2903     im->getInputManager()->getReader().requestRefreshConfiguration(
2904             InputReaderConfiguration::Change::DEVICE_TYPE);
2905 }
2906 
changeKeyboardLayoutAssociation(JNIEnv * env,jobject nativeImplObj)2907 static void changeKeyboardLayoutAssociation(JNIEnv* env, jobject nativeImplObj) {
2908     NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
2909     im->getInputManager()->getReader().requestRefreshConfiguration(
2910             InputReaderConfiguration::Change::KEYBOARD_LAYOUT_ASSOCIATION);
2911 }
2912 
nativeSetMotionClassifierEnabled(JNIEnv * env,jobject nativeImplObj,jboolean enabled)2913 static void nativeSetMotionClassifierEnabled(JNIEnv* env, jobject nativeImplObj, jboolean enabled) {
2914     NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
2915 
2916     im->setMotionClassifierEnabled(enabled);
2917 }
2918 
nativeSetKeyRepeatConfiguration(JNIEnv * env,jobject nativeImplObj,jint timeoutMs,jint delayMs,jboolean keyRepeatEnabled)2919 static void nativeSetKeyRepeatConfiguration(JNIEnv* env, jobject nativeImplObj, jint timeoutMs,
2920                                             jint delayMs, jboolean keyRepeatEnabled) {
2921     NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
2922     im->getInputManager()->getDispatcher().setKeyRepeatConfiguration(std::chrono::milliseconds(
2923                                                                              timeoutMs),
2924                                                                      std::chrono::milliseconds(
2925                                                                              delayMs),
2926                                                                      keyRepeatEnabled);
2927 }
2928 
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)2929 static jobject createInputSensorInfo(JNIEnv* env, jstring name, jstring vendor, jint version,
2930                                      jint handle, jint type, jfloat maxRange, jfloat resolution,
2931                                      jfloat power, jfloat minDelay, jint fifoReservedEventCount,
2932                                      jint fifoMaxEventCount, jstring stringType,
2933                                      jstring requiredPermission, jint maxDelay, jint flags,
2934                                      jint id) {
2935     // SensorInfo sensorInfo = new Sensor();
2936     jobject sensorInfo = env->NewObject(gInputSensorInfo.clazz, gInputSensorInfo.init, "");
2937 
2938     if (sensorInfo != NULL) {
2939         env->SetObjectField(sensorInfo, gInputSensorInfo.name, name);
2940         env->SetObjectField(sensorInfo, gInputSensorInfo.vendor, vendor);
2941         env->SetIntField(sensorInfo, gInputSensorInfo.version, version);
2942         env->SetIntField(sensorInfo, gInputSensorInfo.handle, handle);
2943         env->SetFloatField(sensorInfo, gInputSensorInfo.maxRange, maxRange);
2944         env->SetFloatField(sensorInfo, gInputSensorInfo.resolution, resolution);
2945         env->SetFloatField(sensorInfo, gInputSensorInfo.power, power);
2946         env->SetIntField(sensorInfo, gInputSensorInfo.minDelay, minDelay);
2947         env->SetIntField(sensorInfo, gInputSensorInfo.fifoReservedEventCount,
2948                          fifoReservedEventCount);
2949         env->SetIntField(sensorInfo, gInputSensorInfo.fifoMaxEventCount, fifoMaxEventCount);
2950         env->SetObjectField(sensorInfo, gInputSensorInfo.requiredPermission, requiredPermission);
2951         env->SetIntField(sensorInfo, gInputSensorInfo.maxDelay, maxDelay);
2952         env->SetIntField(sensorInfo, gInputSensorInfo.flags, flags);
2953         env->SetObjectField(sensorInfo, gInputSensorInfo.stringType, stringType);
2954         env->SetIntField(sensorInfo, gInputSensorInfo.type, type);
2955         env->SetIntField(sensorInfo, gInputSensorInfo.id, id);
2956     }
2957     return sensorInfo;
2958 }
2959 
nativeGetSensorList(JNIEnv * env,jobject nativeImplObj,jint deviceId)2960 static jobjectArray nativeGetSensorList(JNIEnv* env, jobject nativeImplObj, jint deviceId) {
2961     NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
2962     std::vector<InputDeviceSensorInfo> sensors =
2963             im->getInputManager()->getReader().getSensors(deviceId);
2964 
2965     jobjectArray arr = env->NewObjectArray(sensors.size(), gInputSensorInfo.clazz, nullptr);
2966     for (int i = 0; i < sensors.size(); i++) {
2967         const InputDeviceSensorInfo& sensorInfo = sensors[i];
2968 
2969         jobject info = createInputSensorInfo(env, env->NewStringUTF(sensorInfo.name.c_str()),
2970                                              env->NewStringUTF(sensorInfo.vendor.c_str()),
2971                                              static_cast<jint>(sensorInfo.version), 0 /* handle */,
2972                                              static_cast<jint>(sensorInfo.type),
2973                                              static_cast<jfloat>(sensorInfo.maxRange),
2974                                              static_cast<jfloat>(sensorInfo.resolution),
2975                                              static_cast<jfloat>(sensorInfo.power),
2976                                              static_cast<jfloat>(sensorInfo.minDelay),
2977                                              static_cast<jint>(sensorInfo.fifoReservedEventCount),
2978                                              static_cast<jint>(sensorInfo.fifoMaxEventCount),
2979                                              env->NewStringUTF(sensorInfo.stringType.c_str()),
2980                                              env->NewStringUTF("") /* requiredPermission */,
2981                                              static_cast<jint>(sensorInfo.maxDelay),
2982                                              static_cast<jint>(sensorInfo.flags),
2983                                              static_cast<jint>(sensorInfo.id));
2984         env->SetObjectArrayElement(arr, i, info);
2985         env->DeleteLocalRef(info);
2986     }
2987     return arr;
2988 }
2989 
nativeGetTouchpadHardwareProperties(JNIEnv * env,jobject nativeImplObj,jint deviceId)2990 static jobject nativeGetTouchpadHardwareProperties(JNIEnv* env, jobject nativeImplObj,
2991                                                    jint deviceId) {
2992     NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
2993     std::optional<HardwareProperties> touchpadHardwareProperties =
2994             im->getInputManager()->getReader().getTouchpadHardwareProperties(deviceId);
2995 
2996     jobject hwPropsObj = env->NewObject(gTouchpadHardwarePropertiesOffsets.clazz,
2997                                         gTouchpadHardwarePropertiesOffsets.constructor);
2998     if (hwPropsObj == NULL || !touchpadHardwareProperties.has_value()) {
2999         return hwPropsObj;
3000     }
3001     env->SetFloatField(hwPropsObj, gTouchpadHardwarePropertiesOffsets.left,
3002                        touchpadHardwareProperties->left);
3003     env->SetFloatField(hwPropsObj, gTouchpadHardwarePropertiesOffsets.top,
3004                        touchpadHardwareProperties->top);
3005     env->SetFloatField(hwPropsObj, gTouchpadHardwarePropertiesOffsets.right,
3006                        touchpadHardwareProperties->right);
3007     env->SetFloatField(hwPropsObj, gTouchpadHardwarePropertiesOffsets.bottom,
3008                        touchpadHardwareProperties->bottom);
3009     env->SetFloatField(hwPropsObj, gTouchpadHardwarePropertiesOffsets.resX,
3010                        touchpadHardwareProperties->res_x);
3011     env->SetFloatField(hwPropsObj, gTouchpadHardwarePropertiesOffsets.resY,
3012                        touchpadHardwareProperties->res_y);
3013     env->SetFloatField(hwPropsObj, gTouchpadHardwarePropertiesOffsets.orientationMinimum,
3014                        touchpadHardwareProperties->orientation_minimum);
3015     env->SetFloatField(hwPropsObj, gTouchpadHardwarePropertiesOffsets.orientationMaximum,
3016                        touchpadHardwareProperties->orientation_maximum);
3017     env->SetIntField(hwPropsObj, gTouchpadHardwarePropertiesOffsets.maxFingerCount,
3018                      touchpadHardwareProperties->max_finger_cnt);
3019     env->SetBooleanField(hwPropsObj, gTouchpadHardwarePropertiesOffsets.isButtonPad,
3020                          touchpadHardwareProperties->is_button_pad);
3021     env->SetBooleanField(hwPropsObj, gTouchpadHardwarePropertiesOffsets.isHapticPad,
3022                          touchpadHardwareProperties->is_haptic_pad);
3023     env->SetBooleanField(hwPropsObj, gTouchpadHardwarePropertiesOffsets.reportsPressure,
3024                          touchpadHardwareProperties->reports_pressure);
3025 
3026     return hwPropsObj;
3027 }
3028 
nativeEnableSensor(JNIEnv * env,jobject nativeImplObj,jint deviceId,jint sensorType,jint samplingPeriodUs,jint maxBatchReportLatencyUs)3029 static jboolean nativeEnableSensor(JNIEnv* env, jobject nativeImplObj, jint deviceId,
3030                                    jint sensorType, jint samplingPeriodUs,
3031                                    jint maxBatchReportLatencyUs) {
3032     NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
3033 
3034     return im->getInputManager()
3035             ->getReader()
3036             .enableSensor(deviceId, static_cast<InputDeviceSensorType>(sensorType),
3037                           std::chrono::microseconds(samplingPeriodUs),
3038                           std::chrono::microseconds(maxBatchReportLatencyUs));
3039 }
3040 
nativeDisableSensor(JNIEnv * env,jobject nativeImplObj,jint deviceId,jint sensorType)3041 static void nativeDisableSensor(JNIEnv* env, jobject nativeImplObj, jint deviceId,
3042                                 jint sensorType) {
3043     NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
3044 
3045     im->getInputManager()->getReader().disableSensor(deviceId,
3046                                                      static_cast<InputDeviceSensorType>(
3047                                                              sensorType));
3048 }
3049 
nativeFlushSensor(JNIEnv * env,jobject nativeImplObj,jint deviceId,jint sensorType)3050 static jboolean nativeFlushSensor(JNIEnv* env, jobject nativeImplObj, jint deviceId,
3051                                   jint sensorType) {
3052     NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
3053 
3054     im->getInputManager()->getReader().flushSensor(deviceId,
3055                                                    static_cast<InputDeviceSensorType>(sensorType));
3056     return im->getInputManager()->getDispatcher().flushSensor(deviceId,
3057                                                               static_cast<InputDeviceSensorType>(
3058                                                                       sensorType));
3059 }
3060 
nativeCancelCurrentTouch(JNIEnv * env,jobject nativeImplObj)3061 static void nativeCancelCurrentTouch(JNIEnv* env, jobject nativeImplObj) {
3062     NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
3063     im->getInputManager()->getDispatcher().cancelCurrentTouch();
3064 }
3065 
nativeSetPointerDisplayId(JNIEnv * env,jobject nativeImplObj,jint displayId)3066 static void nativeSetPointerDisplayId(JNIEnv* env, jobject nativeImplObj, jint displayId) {
3067     NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
3068     im->setPointerDisplayId(ui::LogicalDisplayId{displayId});
3069 }
3070 
nativeGetBluetoothAddress(JNIEnv * env,jobject nativeImplObj,jint deviceId)3071 static jstring nativeGetBluetoothAddress(JNIEnv* env, jobject nativeImplObj, jint deviceId) {
3072     NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
3073     const auto address = im->getBluetoothAddress(deviceId);
3074     return address ? env->NewStringUTF(address->c_str()) : nullptr;
3075 }
3076 
nativeSetStylusButtonMotionEventsEnabled(JNIEnv * env,jobject nativeImplObj,jboolean enabled)3077 static void nativeSetStylusButtonMotionEventsEnabled(JNIEnv* env, jobject nativeImplObj,
3078                                                      jboolean enabled) {
3079     NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
3080     im->setStylusButtonMotionEventsEnabled(enabled);
3081 }
3082 
nativeGetMouseCursorPosition(JNIEnv * env,jobject nativeImplObj,jint displayId)3083 static jfloatArray nativeGetMouseCursorPosition(JNIEnv* env, jobject nativeImplObj,
3084                                                 jint displayId) {
3085     NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
3086     const auto p = im->getMouseCursorPosition(ui::LogicalDisplayId{displayId});
3087     const std::array<float, 2> arr = {{p.x, p.y}};
3088     jfloatArray outArr = env->NewFloatArray(2);
3089     env->SetFloatArrayRegion(outArr, 0, arr.size(), arr.data());
3090     return outArr;
3091 }
3092 
nativeSetStylusPointerIconEnabled(JNIEnv * env,jobject nativeImplObj,jboolean enabled)3093 static void nativeSetStylusPointerIconEnabled(JNIEnv* env, jobject nativeImplObj,
3094                                               jboolean enabled) {
3095     NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
3096     im->setStylusPointerIconEnabled(enabled);
3097 }
3098 
nativeSetAccessibilityBounceKeysThreshold(JNIEnv * env,jobject nativeImplObj,jint thresholdTimeMs)3099 static void nativeSetAccessibilityBounceKeysThreshold(JNIEnv* env, jobject nativeImplObj,
3100                                                       jint thresholdTimeMs) {
3101     NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
3102     if (ENABLE_INPUT_FILTER_RUST) {
3103         im->getInputManager()->getInputFilter().setAccessibilityBounceKeysThreshold(
3104                 static_cast<nsecs_t>(thresholdTimeMs) * 1000000);
3105     }
3106 }
3107 
nativeSetAccessibilitySlowKeysThreshold(JNIEnv * env,jobject nativeImplObj,jint thresholdTimeMs)3108 static void nativeSetAccessibilitySlowKeysThreshold(JNIEnv* env, jobject nativeImplObj,
3109                                                     jint thresholdTimeMs) {
3110     NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
3111     if (ENABLE_INPUT_FILTER_RUST) {
3112         im->getInputManager()->getInputFilter().setAccessibilitySlowKeysThreshold(
3113                 static_cast<nsecs_t>(thresholdTimeMs) * 1000000);
3114     }
3115 }
3116 
nativeSetAccessibilityStickyKeysEnabled(JNIEnv * env,jobject nativeImplObj,jboolean enabled)3117 static void nativeSetAccessibilityStickyKeysEnabled(JNIEnv* env, jobject nativeImplObj,
3118                                                     jboolean enabled) {
3119     NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
3120     if (ENABLE_INPUT_FILTER_RUST) {
3121         im->getInputManager()->getInputFilter().setAccessibilityStickyKeysEnabled(enabled);
3122     }
3123 }
3124 
nativeSetInputMethodConnectionIsActive(JNIEnv * env,jobject nativeImplObj,jboolean isActive)3125 static void nativeSetInputMethodConnectionIsActive(JNIEnv* env, jobject nativeImplObj,
3126                                                    jboolean isActive) {
3127     NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
3128     im->setInputMethodConnectionIsActive(isActive);
3129 }
3130 
nativeGetLastUsedInputDeviceId(JNIEnv * env,jobject nativeImplObj)3131 static jint nativeGetLastUsedInputDeviceId(JNIEnv* env, jobject nativeImplObj) {
3132     NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
3133     return static_cast<jint>(im->getInputManager()->getReader().getLastUsedInputDeviceId());
3134 }
3135 
nativeSetMouseReverseVerticalScrollingEnabled(JNIEnv * env,jobject nativeImplObj,bool enabled)3136 static void nativeSetMouseReverseVerticalScrollingEnabled(JNIEnv* env, jobject nativeImplObj,
3137                                                           bool enabled) {
3138     NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
3139     im->setMouseReverseVerticalScrollingEnabled(enabled);
3140 }
3141 
nativeSetMouseSwapPrimaryButtonEnabled(JNIEnv * env,jobject nativeImplObj,bool enabled)3142 static void nativeSetMouseSwapPrimaryButtonEnabled(JNIEnv* env, jobject nativeImplObj,
3143                                                    bool enabled) {
3144     NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
3145     im->setMouseSwapPrimaryButtonEnabled(enabled);
3146 }
3147 
nativeSetKernelWakeEnabled(JNIEnv * env,jobject nativeImplObj,jint deviceId,jboolean enabled)3148 static jboolean nativeSetKernelWakeEnabled(JNIEnv* env, jobject nativeImplObj, jint deviceId,
3149                                       jboolean enabled) {
3150     NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
3151     return im->getInputManager()->getReader().setKernelWakeEnabled(deviceId, enabled);
3152 }
3153 
3154 // ----------------------------------------------------------------------------
3155 
3156 static const JNINativeMethod gInputManagerMethods[] = {
3157         /* name, signature, funcPtr */
3158         {"init",
3159          "(Lcom/android/server/input/InputManagerService;Landroid/os/"
3160          "MessageQueue;)J",
3161          (void*)nativeInit},
3162         {"start", "()V", (void*)nativeStart},
3163         {"setDisplayViewports", "([Landroid/hardware/display/DisplayViewport;)V",
3164          (void*)nativeSetDisplayViewports},
3165         {"setDisplayTopology", "(Landroid/hardware/display/DisplayTopologyGraph;)V",
3166          (void*)nativeSetDisplayTopology},
3167         {"getScanCodeState", "(III)I", (void*)nativeGetScanCodeState},
3168         {"getKeyCodeState", "(III)I", (void*)nativeGetKeyCodeState},
3169         {"getSwitchState", "(III)I", (void*)nativeGetSwitchState},
3170         {"setKeyRemapping", "([I[I)V", (void*)nativeSetKeyRemapping},
3171         {"hasKeys", "(II[I[Z)Z", (void*)nativeHasKeys},
3172         {"getKeyCodeForKeyLocation", "(II)I", (void*)nativeGetKeyCodeForKeyLocation},
3173         {"createInputChannel", "(Ljava/lang/String;)Landroid/view/InputChannel;",
3174          (void*)nativeCreateInputChannel},
3175         {"createInputMonitor", "(ILjava/lang/String;I)Landroid/view/InputChannel;",
3176          (void*)nativeCreateInputMonitor},
3177         {"removeInputChannel", "(Landroid/os/IBinder;)V", (void*)nativeRemoveInputChannel},
3178         {"pilferPointers", "(Landroid/os/IBinder;)V", (void*)nativePilferPointers},
3179         {"setInputFilterEnabled", "(Z)V", (void*)nativeSetInputFilterEnabled},
3180         {"setInTouchMode", "(ZIIZI)Z", (void*)nativeSetInTouchMode},
3181         {"setMaximumObscuringOpacityForTouch", "(F)V",
3182          (void*)nativeSetMaximumObscuringOpacityForTouch},
3183         {"injectInputEvent", "(Landroid/view/InputEvent;ZIIII)I", (void*)nativeInjectInputEvent},
3184         {"verifyInputEvent", "(Landroid/view/InputEvent;)Landroid/view/VerifiedInputEvent;",
3185          (void*)nativeVerifyInputEvent},
3186         {"toggleCapsLock", "(I)V", (void*)nativeToggleCapsLock},
3187         {"resetLockedModifierState", "()V", (void*)resetLockedModifierState},
3188         {"displayRemoved", "(I)V", (void*)nativeDisplayRemoved},
3189         {"setFocusedApplication", "(ILandroid/view/InputApplicationHandle;)V",
3190          (void*)nativeSetFocusedApplication},
3191         {"setFocusedDisplay", "(I)V", (void*)nativeSetFocusedDisplay},
3192         {"setMinTimeBetweenUserActivityPokes", "(J)V", (void*)nativeSetUserActivityPokeInterval},
3193         {"requestPointerCapture", "(Landroid/os/IBinder;Z)V", (void*)nativeRequestPointerCapture},
3194         {"setInputDispatchMode", "(ZZ)V", (void*)nativeSetInputDispatchMode},
3195         {"setSystemUiLightsOut", "(Z)V", (void*)nativeSetSystemUiLightsOut},
3196         {"transferTouchGesture", "(Landroid/os/IBinder;Landroid/os/IBinder;Z)Z",
3197          (void*)nativeTransferTouchGesture},
3198         {"transferTouch", "(Landroid/os/IBinder;I)Z", (void*)nativeTransferTouchOnDisplay},
3199         {"getMousePointerSpeed", "()I", (void*)nativeGetMousePointerSpeed},
3200         {"setPointerSpeed", "(I)V", (void*)nativeSetPointerSpeed},
3201         {"setMousePointerAccelerationEnabled", "(IZ)V",
3202          (void*)nativeSetMousePointerAccelerationEnabled},
3203         {"setMouseReverseVerticalScrollingEnabled", "(Z)V",
3204          (void*)nativeSetMouseReverseVerticalScrollingEnabled},
3205         {"setMouseSwapPrimaryButtonEnabled", "(Z)V", (void*)nativeSetMouseSwapPrimaryButtonEnabled},
3206         {"setTouchpadPointerSpeed", "(I)V", (void*)nativeSetTouchpadPointerSpeed},
3207         {"setTouchpadNaturalScrollingEnabled", "(Z)V",
3208          (void*)nativeSetTouchpadNaturalScrollingEnabled},
3209         {"setTouchpadTapToClickEnabled", "(Z)V", (void*)nativeSetTouchpadTapToClickEnabled},
3210         {"setTouchpadTapDraggingEnabled", "(Z)V", (void*)nativeSetTouchpadTapDraggingEnabled},
3211         {"setShouldNotifyTouchpadHardwareState", "(Z)V",
3212          (void*)nativeSetShouldNotifyTouchpadHardwareState},
3213         {"setTouchpadRightClickZoneEnabled", "(Z)V", (void*)nativeSetTouchpadRightClickZoneEnabled},
3214         {"setTouchpadThreeFingerTapShortcutEnabled", "(Z)V",
3215          (void*)nativeSetTouchpadThreeFingerTapShortcutEnabled},
3216         {"setTouchpadSystemGesturesEnabled", "(Z)V", (void*)nativeSetTouchpadSystemGesturesEnabled},
3217         {"setShowTouches", "(Z)V", (void*)nativeSetShowTouches},
3218         {"setNonInteractiveDisplays", "([I)V", (void*)nativeSetNonInteractiveDisplays},
3219         {"reloadCalibration", "()V", (void*)nativeReloadCalibration},
3220         {"vibrate", "(I[J[III)V", (void*)nativeVibrate},
3221         {"vibrateCombined", "(I[JLandroid/util/SparseArray;II)V", (void*)nativeVibrateCombined},
3222         {"cancelVibrate", "(II)V", (void*)nativeCancelVibrate},
3223         {"isVibrating", "(I)Z", (void*)nativeIsVibrating},
3224         {"getVibratorIds", "(I)[I", (void*)nativeGetVibratorIds},
3225         {"getLights", "(I)Ljava/util/List;", (void*)nativeGetLights},
3226         {"getLightPlayerId", "(II)I", (void*)nativeGetLightPlayerId},
3227         {"getLightColor", "(II)I", (void*)nativeGetLightColor},
3228         {"setLightPlayerId", "(III)V", (void*)nativeSetLightPlayerId},
3229         {"setLightColor", "(III)V", (void*)nativeSetLightColor},
3230         {"getBatteryCapacity", "(I)I", (void*)nativeGetBatteryCapacity},
3231         {"getBatteryStatus", "(I)I", (void*)nativeGetBatteryStatus},
3232         {"getBatteryDevicePath", "(I)Ljava/lang/String;", (void*)nativeGetBatteryDevicePath},
3233         {"reloadKeyboardLayouts", "()V", (void*)nativeReloadKeyboardLayouts},
3234         {"reloadDeviceAliases", "()V", (void*)nativeReloadDeviceAliases},
3235         {"sysfsNodeChanged", "(Ljava/lang/String;)V", (void*)nativeSysfsNodeChanged},
3236         {"dump", "()Ljava/lang/String;", (void*)nativeDump},
3237         {"monitor", "()V", (void*)nativeMonitor},
3238         {"enableInputDevice", "(I)V", (void*)nativeEnableInputDevice},
3239         {"disableInputDevice", "(I)V", (void*)nativeDisableInputDevice},
3240         {"reloadPointerIcons", "()V", (void*)nativeReloadPointerIcons},
3241         {"setPointerIcon", "(Landroid/view/PointerIcon;IIILandroid/os/IBinder;)Z",
3242          (void*)nativeSetPointerIcon},
3243         {"setPointerIconVisibility", "(IZ)V", (void*)nativeSetPointerIconVisibility},
3244         {"canDispatchToDisplay", "(II)Z", (void*)nativeCanDispatchToDisplay},
3245         {"notifyPortAssociationsChanged", "()V", (void*)nativeNotifyPortAssociationsChanged},
3246         {"changeUniqueIdAssociation", "()V", (void*)nativeChangeUniqueIdAssociation},
3247         {"changeTypeAssociation", "()V", (void*)nativeChangeTypeAssociation},
3248         {"changeKeyboardLayoutAssociation", "()V", (void*)changeKeyboardLayoutAssociation},
3249         {"setDisplayEligibilityForPointerCapture", "(IZ)V",
3250          (void*)nativeSetDisplayEligibilityForPointerCapture},
3251         {"setMotionClassifierEnabled", "(Z)V", (void*)nativeSetMotionClassifierEnabled},
3252         {"setKeyRepeatConfiguration", "(IIZ)V", (void*)nativeSetKeyRepeatConfiguration},
3253         {"getSensorList", "(I)[Landroid/hardware/input/InputSensorInfo;",
3254          (void*)nativeGetSensorList},
3255         {"getTouchpadHardwareProperties",
3256          "(I)Lcom/android/server/input/TouchpadHardwareProperties;",
3257          (void*)nativeGetTouchpadHardwareProperties},
3258         {"enableSensor", "(IIII)Z", (void*)nativeEnableSensor},
3259         {"disableSensor", "(II)V", (void*)nativeDisableSensor},
3260         {"flushSensor", "(II)Z", (void*)nativeFlushSensor},
3261         {"cancelCurrentTouch", "()V", (void*)nativeCancelCurrentTouch},
3262         {"setPointerDisplayId", "(I)V", (void*)nativeSetPointerDisplayId},
3263         {"getBluetoothAddress", "(I)Ljava/lang/String;", (void*)nativeGetBluetoothAddress},
3264         {"setStylusButtonMotionEventsEnabled", "(Z)V",
3265          (void*)nativeSetStylusButtonMotionEventsEnabled},
3266         {"getMouseCursorPosition", "(I)[F", (void*)nativeGetMouseCursorPosition},
3267         {"setStylusPointerIconEnabled", "(Z)V", (void*)nativeSetStylusPointerIconEnabled},
3268         {"setAccessibilityBounceKeysThreshold", "(I)V",
3269          (void*)nativeSetAccessibilityBounceKeysThreshold},
3270         {"setAccessibilitySlowKeysThreshold", "(I)V",
3271          (void*)nativeSetAccessibilitySlowKeysThreshold},
3272         {"setAccessibilityStickyKeysEnabled", "(Z)V",
3273          (void*)nativeSetAccessibilityStickyKeysEnabled},
3274         {"setInputMethodConnectionIsActive", "(Z)V", (void*)nativeSetInputMethodConnectionIsActive},
3275         {"getLastUsedInputDeviceId", "()I", (void*)nativeGetLastUsedInputDeviceId},
3276         {"setKernelWakeEnabled", "(IZ)Z", (void*)nativeSetKernelWakeEnabled},
3277 };
3278 
3279 #define FIND_CLASS(var, className) \
3280         var = env->FindClass(className); \
3281         LOG_FATAL_IF(! (var), "Unable to find class " className);
3282 
3283 #define GET_METHOD_ID(var, clazz, methodName, methodDescriptor) \
3284         var = env->GetMethodID(clazz, methodName, methodDescriptor); \
3285         LOG_FATAL_IF(! (var), "Unable to find method " methodName);
3286 
3287 #define GET_STATIC_METHOD_ID(var, clazz, methodName, methodDescriptor) \
3288         var = env->GetStaticMethodID(clazz, methodName, methodDescriptor); \
3289         LOG_FATAL_IF(! (var), "Unable to find static method " methodName);
3290 
3291 #define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \
3292         var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \
3293         LOG_FATAL_IF(! (var), "Unable to find field " fieldName);
3294 
register_android_server_InputManager(JNIEnv * env)3295 int register_android_server_InputManager(JNIEnv* env) {
3296     int res = jniRegisterNativeMethods(env,
3297                                        "com/android/server/input/"
3298                                        "NativeInputManagerService$NativeImpl",
3299                                        gInputManagerMethods, NELEM(gInputManagerMethods));
3300     (void)res; // Faked use when LOG_NDEBUG.
3301     LOG_FATAL_IF(res < 0, "Unable to register native methods.");
3302 
3303     FIND_CLASS(gNativeInputManagerServiceImpl.clazz,
3304                "com/android/server/input/"
3305                "NativeInputManagerService$NativeImpl");
3306     gNativeInputManagerServiceImpl.clazz =
3307             jclass(env->NewGlobalRef(gNativeInputManagerServiceImpl.clazz));
3308     gNativeInputManagerServiceImpl.mPtr =
3309             env->GetFieldID(gNativeInputManagerServiceImpl.clazz, "mPtr", "J");
3310 
3311     // Callbacks
3312 
3313     jclass clazz;
3314     FIND_CLASS(clazz, "com/android/server/input/InputManagerService");
3315     gServiceClassInfo.clazz = reinterpret_cast<jclass>(env->NewGlobalRef(clazz));
3316 
3317     GET_METHOD_ID(gServiceClassInfo.notifyInputDevicesChanged, clazz,
3318             "notifyInputDevicesChanged", "([Landroid/view/InputDevice;)V");
3319 
3320     GET_METHOD_ID(gServiceClassInfo.notifyTouchpadHardwareState, clazz,
3321                   "notifyTouchpadHardwareState",
3322                   "(Lcom/android/server/input/TouchpadHardwareState;I)V")
3323 
3324     GET_METHOD_ID(gServiceClassInfo.notifyTouchpadGestureInfo, clazz, "notifyTouchpadGestureInfo",
3325                   "(II)V")
3326 
3327     GET_METHOD_ID(gServiceClassInfo.notifyTouchpadThreeFingerTap, clazz,
3328                   "notifyTouchpadThreeFingerTap", "()V")
3329     GET_METHOD_ID(gServiceClassInfo.notifySwitch, clazz,
3330             "notifySwitch", "(JII)V");
3331 
3332     GET_METHOD_ID(gServiceClassInfo.notifyInputChannelBroken, clazz,
3333             "notifyInputChannelBroken", "(Landroid/os/IBinder;)V");
3334 
3335     GET_METHOD_ID(gServiceClassInfo.notifyFocusChanged, clazz,
3336             "notifyFocusChanged", "(Landroid/os/IBinder;Landroid/os/IBinder;)V");
3337     GET_METHOD_ID(gServiceClassInfo.notifyDropWindow, clazz, "notifyDropWindow",
3338                   "(Landroid/os/IBinder;FF)V");
3339 
3340     GET_METHOD_ID(gServiceClassInfo.notifySensorEvent, clazz, "notifySensorEvent", "(IIIJ[F)V");
3341 
3342     GET_METHOD_ID(gServiceClassInfo.notifySensorAccuracy, clazz, "notifySensorAccuracy", "(III)V");
3343 
3344     GET_METHOD_ID(gServiceClassInfo.notifyStylusGestureStarted, clazz, "notifyStylusGestureStarted",
3345                   "(IJ)V");
3346 
3347     GET_METHOD_ID(gServiceClassInfo.notifyVibratorState, clazz, "notifyVibratorState", "(IZ)V");
3348 
3349     GET_METHOD_ID(gServiceClassInfo.notifyNoFocusedWindowAnr, clazz, "notifyNoFocusedWindowAnr",
3350                   "(Landroid/view/InputApplicationHandle;)V");
3351 
3352     GET_METHOD_ID(gServiceClassInfo.notifyWindowUnresponsive, clazz, "notifyWindowUnresponsive",
3353                   "(Landroid/os/IBinder;IZLjava/lang/String;)V");
3354 
3355     GET_METHOD_ID(gServiceClassInfo.notifyWindowResponsive, clazz, "notifyWindowResponsive",
3356                   "(Landroid/os/IBinder;IZ)V");
3357 
3358     GET_METHOD_ID(gServiceClassInfo.filterInputEvent, clazz,
3359             "filterInputEvent", "(Landroid/view/InputEvent;I)Z");
3360 
3361     GET_METHOD_ID(gServiceClassInfo.interceptKeyBeforeQueueing, clazz,
3362             "interceptKeyBeforeQueueing", "(Landroid/view/KeyEvent;I)I");
3363 
3364     GET_METHOD_ID(gServiceClassInfo.interceptMotionBeforeQueueingNonInteractive, clazz,
3365             "interceptMotionBeforeQueueingNonInteractive", "(IIIJI)I");
3366 
3367     GET_METHOD_ID(gServiceClassInfo.interceptKeyBeforeDispatching, clazz,
3368             "interceptKeyBeforeDispatching",
3369             "(Landroid/os/IBinder;Landroid/view/KeyEvent;I)J");
3370 
3371     GET_METHOD_ID(gServiceClassInfo.dispatchUnhandledKey, clazz,
3372             "dispatchUnhandledKey",
3373             "(Landroid/os/IBinder;Landroid/view/KeyEvent;I)Landroid/view/KeyEvent;");
3374 
3375     GET_METHOD_ID(gServiceClassInfo.notifyStickyModifierStateChanged, clazz,
3376                   "notifyStickyModifierStateChanged", "(II)V");
3377 
3378     GET_METHOD_ID(gServiceClassInfo.onPointerDownOutsideFocus, clazz,
3379             "onPointerDownOutsideFocus", "(Landroid/os/IBinder;)V");
3380 
3381     GET_METHOD_ID(gServiceClassInfo.getVirtualKeyQuietTimeMillis, clazz,
3382             "getVirtualKeyQuietTimeMillis", "()I");
3383 
3384     GET_STATIC_METHOD_ID(gServiceClassInfo.getExcludedDeviceNames, clazz,
3385             "getExcludedDeviceNames", "()[Ljava/lang/String;");
3386 
3387     GET_METHOD_ID(gServiceClassInfo.getInputPortAssociations, clazz,
3388             "getInputPortAssociations", "()[Ljava/lang/String;");
3389 
3390     GET_METHOD_ID(gServiceClassInfo.getInputUniqueIdAssociationsByPort, clazz,
3391                   "getInputUniqueIdAssociationsByPort", "()[Ljava/lang/String;");
3392 
3393     GET_METHOD_ID(gServiceClassInfo.getInputUniqueIdAssociationsByDescriptor, clazz,
3394                   "getInputUniqueIdAssociationsByDescriptor", "()[Ljava/lang/String;");
3395 
3396     GET_METHOD_ID(gServiceClassInfo.getDeviceTypeAssociations, clazz, "getDeviceTypeAssociations",
3397                   "()[Ljava/lang/String;");
3398 
3399     GET_METHOD_ID(gServiceClassInfo.getKeyboardLayoutAssociations, clazz,
3400                   "getKeyboardLayoutAssociations", "()[Ljava/lang/String;");
3401 
3402     GET_METHOD_ID(gServiceClassInfo.getHoverTapTimeout, clazz,
3403             "getHoverTapTimeout", "()I");
3404 
3405     GET_METHOD_ID(gServiceClassInfo.getHoverTapSlop, clazz,
3406             "getHoverTapSlop", "()I");
3407 
3408     GET_METHOD_ID(gServiceClassInfo.getDoubleTapTimeout, clazz,
3409             "getDoubleTapTimeout", "()I");
3410 
3411     GET_METHOD_ID(gServiceClassInfo.getLongPressTimeout, clazz,
3412             "getLongPressTimeout", "()I");
3413 
3414     GET_METHOD_ID(gServiceClassInfo.getPointerLayer, clazz,
3415             "getPointerLayer", "()I");
3416 
3417     GET_METHOD_ID(gServiceClassInfo.getLoadedPointerIcon, clazz, "getLoadedPointerIcon",
3418                   "(II)Landroid/view/PointerIcon;");
3419 
3420     GET_METHOD_ID(gServiceClassInfo.getKeyboardLayoutOverlay, clazz, "getKeyboardLayoutOverlay",
3421                   "(Landroid/hardware/input/InputDeviceIdentifier;Ljava/lang/String;Ljava/lang/"
3422                   "String;)[Ljava/lang/String;");
3423 
3424     GET_METHOD_ID(gServiceClassInfo.getDeviceAlias, clazz,
3425             "getDeviceAlias", "(Ljava/lang/String;)Ljava/lang/String;");
3426 
3427     GET_METHOD_ID(gServiceClassInfo.getTouchCalibrationForInputDevice, clazz,
3428             "getTouchCalibrationForInputDevice",
3429             "(Ljava/lang/String;I)Landroid/hardware/input/TouchCalibration;");
3430 
3431     GET_METHOD_ID(gServiceClassInfo.getParentSurfaceForPointers, clazz,
3432                   "getParentSurfaceForPointers", "(I)J");
3433 
3434     // InputDevice
3435 
3436     FIND_CLASS(gInputDeviceClassInfo.clazz, "android/view/InputDevice");
3437     gInputDeviceClassInfo.clazz = jclass(env->NewGlobalRef(gInputDeviceClassInfo.clazz));
3438 
3439     // KeyEvent
3440 
3441     FIND_CLASS(gKeyEventClassInfo.clazz, "android/view/KeyEvent");
3442     gKeyEventClassInfo.clazz = jclass(env->NewGlobalRef(gKeyEventClassInfo.clazz));
3443 
3444     // MotionEvent
3445 
3446     FIND_CLASS(gMotionEventClassInfo.clazz, "android/view/MotionEvent");
3447     gMotionEventClassInfo.clazz = jclass(env->NewGlobalRef(gMotionEventClassInfo.clazz));
3448 
3449     // InputDeviceIdentifier
3450 
3451     FIND_CLASS(gInputDeviceIdentifierInfo.clazz, "android/hardware/input/InputDeviceIdentifier");
3452     gInputDeviceIdentifierInfo.clazz = jclass(env->NewGlobalRef(gInputDeviceIdentifierInfo.clazz));
3453     GET_METHOD_ID(gInputDeviceIdentifierInfo.constructor, gInputDeviceIdentifierInfo.clazz,
3454             "<init>", "(Ljava/lang/String;II)V");
3455 
3456     // TouchCalibration
3457 
3458     FIND_CLASS(gTouchCalibrationClassInfo.clazz, "android/hardware/input/TouchCalibration");
3459     gTouchCalibrationClassInfo.clazz = jclass(env->NewGlobalRef(gTouchCalibrationClassInfo.clazz));
3460 
3461     GET_METHOD_ID(gTouchCalibrationClassInfo.getAffineTransform, gTouchCalibrationClassInfo.clazz,
3462             "getAffineTransform", "()[F");
3463 
3464     // Light
3465     FIND_CLASS(gLightClassInfo.clazz, "android/hardware/lights/Light");
3466     gLightClassInfo.clazz = jclass(env->NewGlobalRef(gLightClassInfo.clazz));
3467     GET_METHOD_ID(gLightClassInfo.constructor, gLightClassInfo.clazz, "<init>",
3468                   "(ILjava/lang/String;III[I)V");
3469 
3470     gLightClassInfo.clazz = jclass(env->NewGlobalRef(gLightClassInfo.clazz));
3471     gLightClassInfo.lightTypeInput =
3472             env->GetStaticFieldID(gLightClassInfo.clazz, "LIGHT_TYPE_INPUT", "I");
3473     gLightClassInfo.lightTypePlayerId =
3474             env->GetStaticFieldID(gLightClassInfo.clazz, "LIGHT_TYPE_PLAYER_ID", "I");
3475     gLightClassInfo.lightTypeKeyboardBacklight =
3476             env->GetStaticFieldID(gLightClassInfo.clazz, "LIGHT_TYPE_KEYBOARD_BACKLIGHT", "I");
3477     gLightClassInfo.lightTypeKeyboardMicMute =
3478             env->GetStaticFieldID(gLightClassInfo.clazz, "LIGHT_TYPE_KEYBOARD_MIC_MUTE", "I");
3479     gLightClassInfo.lightTypeKeyboardVolumeMute =
3480             env->GetStaticFieldID(gLightClassInfo.clazz, "LIGHT_TYPE_KEYBOARD_VOLUME_MUTE", "I");
3481     gLightClassInfo.lightCapabilityBrightness =
3482             env->GetStaticFieldID(gLightClassInfo.clazz, "LIGHT_CAPABILITY_BRIGHTNESS", "I");
3483     gLightClassInfo.lightCapabilityColorRgb =
3484             env->GetStaticFieldID(gLightClassInfo.clazz, "LIGHT_CAPABILITY_COLOR_RGB", "I");
3485 
3486     // ArrayList
3487     FIND_CLASS(gArrayListClassInfo.clazz, "java/util/ArrayList");
3488     gArrayListClassInfo.clazz = jclass(env->NewGlobalRef(gArrayListClassInfo.clazz));
3489     GET_METHOD_ID(gArrayListClassInfo.constructor, gArrayListClassInfo.clazz, "<init>", "()V");
3490     GET_METHOD_ID(gArrayListClassInfo.add, gArrayListClassInfo.clazz, "add",
3491                   "(Ljava/lang/Object;)Z");
3492 
3493     // SparseArray
3494     FIND_CLASS(gSparseArrayClassInfo.clazz, "android/util/SparseArray");
3495     gSparseArrayClassInfo.clazz = jclass(env->NewGlobalRef(gSparseArrayClassInfo.clazz));
3496     GET_METHOD_ID(gSparseArrayClassInfo.constructor, gSparseArrayClassInfo.clazz, "<init>", "()V");
3497     GET_METHOD_ID(gSparseArrayClassInfo.keyAt, gSparseArrayClassInfo.clazz, "keyAt", "(I)I");
3498     GET_METHOD_ID(gSparseArrayClassInfo.valueAt, gSparseArrayClassInfo.clazz, "valueAt",
3499                   "(I)Ljava/lang/Object;");
3500     GET_METHOD_ID(gSparseArrayClassInfo.size, gSparseArrayClassInfo.clazz, "size", "()I");
3501     // InputSensorInfo
3502     // android.hardware.input.InputDeviceSensorInfo
3503     FIND_CLASS(clazz, "android/hardware/input/InputSensorInfo");
3504     gInputSensorInfo.clazz = reinterpret_cast<jclass>(env->NewGlobalRef(clazz));
3505 
3506     GET_FIELD_ID(gInputSensorInfo.name, gInputSensorInfo.clazz, "mName", "Ljava/lang/String;");
3507     GET_FIELD_ID(gInputSensorInfo.vendor, gInputSensorInfo.clazz, "mVendor", "Ljava/lang/String;");
3508     GET_FIELD_ID(gInputSensorInfo.version, gInputSensorInfo.clazz, "mVersion", "I");
3509     GET_FIELD_ID(gInputSensorInfo.handle, gInputSensorInfo.clazz, "mHandle", "I");
3510     GET_FIELD_ID(gInputSensorInfo.maxRange, gInputSensorInfo.clazz, "mMaxRange", "F");
3511     GET_FIELD_ID(gInputSensorInfo.resolution, gInputSensorInfo.clazz, "mResolution", "F");
3512     GET_FIELD_ID(gInputSensorInfo.power, gInputSensorInfo.clazz, "mPower", "F");
3513     GET_FIELD_ID(gInputSensorInfo.minDelay, gInputSensorInfo.clazz, "mMinDelay", "I");
3514     GET_FIELD_ID(gInputSensorInfo.fifoReservedEventCount, gInputSensorInfo.clazz,
3515                  "mFifoReservedEventCount", "I");
3516     GET_FIELD_ID(gInputSensorInfo.fifoMaxEventCount, gInputSensorInfo.clazz, "mFifoMaxEventCount",
3517                  "I");
3518     GET_FIELD_ID(gInputSensorInfo.stringType, gInputSensorInfo.clazz, "mStringType",
3519                  "Ljava/lang/String;");
3520     GET_FIELD_ID(gInputSensorInfo.requiredPermission, gInputSensorInfo.clazz, "mRequiredPermission",
3521                  "Ljava/lang/String;");
3522     GET_FIELD_ID(gInputSensorInfo.maxDelay, gInputSensorInfo.clazz, "mMaxDelay", "I");
3523     GET_FIELD_ID(gInputSensorInfo.flags, gInputSensorInfo.clazz, "mFlags", "I");
3524     GET_FIELD_ID(gInputSensorInfo.type, gInputSensorInfo.clazz, "mType", "I");
3525     GET_FIELD_ID(gInputSensorInfo.id, gInputSensorInfo.clazz, "mId", "I");
3526 
3527     GET_METHOD_ID(gInputSensorInfo.init, gInputSensorInfo.clazz, "<init>", "()V");
3528 
3529     // TouchpadHardwareState
3530 
3531     FIND_CLASS(gTouchpadHardwareStateClassInfo.clazz,
3532                "com/android/server/input/TouchpadHardwareState");
3533     gTouchpadHardwareStateClassInfo.clazz =
3534             reinterpret_cast<jclass>(env->NewGlobalRef(gTouchpadHardwareStateClassInfo.clazz));
3535 
3536     GET_FIELD_ID(gTouchpadHardwareStateClassInfo.touchCount, gTouchpadHardwareStateClassInfo.clazz,
3537                  "mTouchCount", "I");
3538     GET_FIELD_ID(gTouchpadHardwareStateClassInfo.fingerCount, gTouchpadHardwareStateClassInfo.clazz,
3539                  "mFingerCount", "I");
3540     GET_FIELD_ID(gTouchpadHardwareStateClassInfo.buttonsDown, gTouchpadHardwareStateClassInfo.clazz,
3541                  "mButtonsDown", "I");
3542     GET_FIELD_ID(gTouchpadHardwareStateClassInfo.timestamp, gTouchpadHardwareStateClassInfo.clazz,
3543                  "mTimestamp", "F");
3544     GET_FIELD_ID(gTouchpadHardwareStateClassInfo.fingerStates,
3545                  gTouchpadHardwareStateClassInfo.clazz, "mFingerStates",
3546                  "[Lcom/android/server/input/TouchpadFingerState;");
3547 
3548     GET_METHOD_ID(gTouchpadHardwareStateClassInfo.init, gTouchpadHardwareStateClassInfo.clazz,
3549                   "<init>", "()V");
3550 
3551     // TouchpadFingerState
3552 
3553     FIND_CLASS(gTouchpadFingerStateClassInfo.clazz, "com/android/server/input/TouchpadFingerState");
3554     gTouchpadFingerStateClassInfo.clazz =
3555             reinterpret_cast<jclass>(env->NewGlobalRef(gTouchpadFingerStateClassInfo.clazz));
3556 
3557     GET_FIELD_ID(gTouchpadFingerStateClassInfo.touchMajor, gTouchpadFingerStateClassInfo.clazz,
3558                  "mTouchMajor", "F");
3559     GET_FIELD_ID(gTouchpadFingerStateClassInfo.touchMinor, gTouchpadFingerStateClassInfo.clazz,
3560                  "mTouchMinor", "F");
3561     GET_FIELD_ID(gTouchpadFingerStateClassInfo.widthMajor, gTouchpadFingerStateClassInfo.clazz,
3562                  "mWidthMajor", "F");
3563     GET_FIELD_ID(gTouchpadFingerStateClassInfo.widthMinor, gTouchpadFingerStateClassInfo.clazz,
3564                  "mWidthMinor", "F");
3565     GET_FIELD_ID(gTouchpadFingerStateClassInfo.pressure, gTouchpadFingerStateClassInfo.clazz,
3566                  "mPressure", "F");
3567     GET_FIELD_ID(gTouchpadFingerStateClassInfo.orientation, gTouchpadFingerStateClassInfo.clazz,
3568                  "mOrientation", "F")
3569     GET_FIELD_ID(gTouchpadFingerStateClassInfo.positionX, gTouchpadFingerStateClassInfo.clazz,
3570                  "mPositionX", "F");
3571     GET_FIELD_ID(gTouchpadFingerStateClassInfo.positionY, gTouchpadFingerStateClassInfo.clazz,
3572                  "mPositionY", "F");
3573     GET_FIELD_ID(gTouchpadFingerStateClassInfo.trackingId, gTouchpadFingerStateClassInfo.clazz,
3574                  "mTrackingId", "I");
3575 
3576     GET_METHOD_ID(gTouchpadFingerStateClassInfo.init, gTouchpadFingerStateClassInfo.clazz, "<init>",
3577                   "()V");
3578 
3579     // TouchpadHardawreProperties
3580     FIND_CLASS(gTouchpadHardwarePropertiesOffsets.clazz,
3581                "com/android/server/input/TouchpadHardwareProperties");
3582     gTouchpadHardwarePropertiesOffsets.clazz =
3583             reinterpret_cast<jclass>(env->NewGlobalRef(gTouchpadHardwarePropertiesOffsets.clazz));
3584 
3585     // Get the constructor ID
3586     GET_METHOD_ID(gTouchpadHardwarePropertiesOffsets.constructor,
3587                   gTouchpadHardwarePropertiesOffsets.clazz, "<init>", "()V");
3588 
3589     // Get the field IDs
3590     GET_FIELD_ID(gTouchpadHardwarePropertiesOffsets.left, gTouchpadHardwarePropertiesOffsets.clazz,
3591                  "mLeft", "F");
3592     GET_FIELD_ID(gTouchpadHardwarePropertiesOffsets.top, gTouchpadHardwarePropertiesOffsets.clazz,
3593                  "mTop", "F");
3594     GET_FIELD_ID(gTouchpadHardwarePropertiesOffsets.right, gTouchpadHardwarePropertiesOffsets.clazz,
3595                  "mRight", "F");
3596     GET_FIELD_ID(gTouchpadHardwarePropertiesOffsets.bottom,
3597                  gTouchpadHardwarePropertiesOffsets.clazz, "mBottom", "F");
3598     GET_FIELD_ID(gTouchpadHardwarePropertiesOffsets.resX, gTouchpadHardwarePropertiesOffsets.clazz,
3599                  "mResX", "F");
3600     GET_FIELD_ID(gTouchpadHardwarePropertiesOffsets.resY, gTouchpadHardwarePropertiesOffsets.clazz,
3601                  "mResY", "F");
3602     GET_FIELD_ID(gTouchpadHardwarePropertiesOffsets.orientationMinimum,
3603                  gTouchpadHardwarePropertiesOffsets.clazz, "mOrientationMinimum", "F");
3604     GET_FIELD_ID(gTouchpadHardwarePropertiesOffsets.orientationMaximum,
3605                  gTouchpadHardwarePropertiesOffsets.clazz, "mOrientationMaximum", "F");
3606     GET_FIELD_ID(gTouchpadHardwarePropertiesOffsets.maxFingerCount,
3607                  gTouchpadHardwarePropertiesOffsets.clazz, "mMaxFingerCount", "S");
3608     GET_FIELD_ID(gTouchpadHardwarePropertiesOffsets.isButtonPad,
3609                  gTouchpadHardwarePropertiesOffsets.clazz, "mIsButtonPad", "Z");
3610     GET_FIELD_ID(gTouchpadHardwarePropertiesOffsets.isHapticPad,
3611                  gTouchpadHardwarePropertiesOffsets.clazz, "mIsHapticPad", "Z");
3612     GET_FIELD_ID(gTouchpadHardwarePropertiesOffsets.reportsPressure,
3613                  gTouchpadHardwarePropertiesOffsets.clazz, "mReportsPressure", "Z");
3614 
3615     return 0;
3616 }
3617 
3618 } /* namespace android */
3619