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