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