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