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