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