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