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