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