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