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
30 #include <nativehelper/JNIHelp.h>
31 #include "jni.h"
32 #include <atomic>
33 #include <cinttypes>
34 #include <limits.h>
35 #include <android-base/parseint.h>
36 #include <android-base/stringprintf.h>
37 #include <android_runtime/AndroidRuntime.h>
38 #include <android_runtime/Log.h>
39
40 #include <utils/Log.h>
41 #include <utils/Looper.h>
42 #include <utils/threads.h>
43 #include <utils/Trace.h>
44 #include <utils/SortedVector.h>
45
46 #include <binder/IServiceManager.h>
47
48 #include <input/PointerController.h>
49 #include <input/SpriteController.h>
50 #include <ui/Region.h>
51
52 #include <inputflinger/InputManager.h>
53
54 #include <android_os_MessageQueue.h>
55 #include <android_view_InputDevice.h>
56 #include <android_view_KeyEvent.h>
57 #include <android_view_MotionEvent.h>
58 #include <android_view_InputChannel.h>
59 #include <android_view_PointerIcon.h>
60 #include <android/graphics/GraphicsJNI.h>
61
62 #include <nativehelper/ScopedLocalFrame.h>
63 #include <nativehelper/ScopedLocalRef.h>
64 #include <nativehelper/ScopedPrimitiveArray.h>
65 #include <nativehelper/ScopedUtfChars.h>
66
67 #include "com_android_server_power_PowerManagerService.h"
68 #include "android_hardware_input_InputApplicationHandle.h"
69 #include "android_hardware_input_InputWindowHandle.h"
70 #include "android_hardware_display_DisplayViewport.h"
71 #include "android_util_Binder.h"
72
73 #include <vector>
74
75 #define INDENT " "
76
77 using android::base::ParseUint;
78 using android::base::StringPrintf;
79
80 namespace android {
81
82 // The exponent used to calculate the pointer speed scaling factor.
83 // The scaling factor is calculated as 2 ^ (speed * exponent),
84 // where the speed ranges from -7 to + 7 and is supplied by the user.
85 static const float POINTER_SPEED_EXPONENT = 1.0f / 4;
86
87 static struct {
88 jclass clazz;
89 jmethodID notifyConfigurationChanged;
90 jmethodID notifyInputDevicesChanged;
91 jmethodID notifySwitch;
92 jmethodID notifyInputChannelBroken;
93 jmethodID notifyANR;
94 jmethodID notifyFocusChanged;
95 jmethodID filterInputEvent;
96 jmethodID interceptKeyBeforeQueueing;
97 jmethodID interceptMotionBeforeQueueingNonInteractive;
98 jmethodID interceptKeyBeforeDispatching;
99 jmethodID dispatchUnhandledKey;
100 jmethodID checkInjectEventsPermission;
101 jmethodID onPointerDownOutsideFocus;
102 jmethodID getVirtualKeyQuietTimeMillis;
103 jmethodID getExcludedDeviceNames;
104 jmethodID getInputPortAssociations;
105 jmethodID getKeyRepeatTimeout;
106 jmethodID getKeyRepeatDelay;
107 jmethodID getHoverTapTimeout;
108 jmethodID getHoverTapSlop;
109 jmethodID getDoubleTapTimeout;
110 jmethodID getLongPressTimeout;
111 jmethodID getPointerLayer;
112 jmethodID getPointerIcon;
113 jmethodID getPointerDisplayId;
114 jmethodID getKeyboardLayoutOverlay;
115 jmethodID getDeviceAlias;
116 jmethodID getTouchCalibrationForInputDevice;
117 jmethodID getContextForDisplay;
118 } gServiceClassInfo;
119
120 static struct {
121 jclass clazz;
122 } gInputDeviceClassInfo;
123
124 static struct {
125 jclass clazz;
126 } gKeyEventClassInfo;
127
128 static struct {
129 jclass clazz;
130 } gMotionEventClassInfo;
131
132 static struct {
133 jclass clazz;
134 jmethodID constructor;
135 } gInputDeviceIdentifierInfo;
136
137 static struct {
138 jclass clazz;
139 jmethodID getAffineTransform;
140 } gTouchCalibrationClassInfo;
141
142 // --- Global functions ---
143
144 template<typename T>
min(const T & a,const T & b)145 inline static T min(const T& a, const T& b) {
146 return a < b ? a : b;
147 }
148
149 template<typename T>
max(const T & a,const T & b)150 inline static T max(const T& a, const T& b) {
151 return a > b ? a : b;
152 }
153
toString(bool value)154 static inline const char* toString(bool value) {
155 return value ? "true" : "false";
156 }
157
loadSystemIconAsSpriteWithPointerIcon(JNIEnv * env,jobject contextObj,int32_t style,PointerIcon * outPointerIcon,SpriteIcon * outSpriteIcon)158 static void loadSystemIconAsSpriteWithPointerIcon(JNIEnv* env, jobject contextObj, int32_t style,
159 PointerIcon* outPointerIcon, SpriteIcon* outSpriteIcon) {
160 status_t status = android_view_PointerIcon_loadSystemIcon(env,
161 contextObj, style, outPointerIcon);
162 if (!status) {
163 SkBitmap* bitmapCopy = &outSpriteIcon->bitmap;
164 SkImageInfo bitmapCopyInfo = outPointerIcon->bitmap.info().makeColorType(kN32_SkColorType);
165 if (bitmapCopy->tryAllocPixels(bitmapCopyInfo)) {
166 outPointerIcon->bitmap.readPixels(bitmapCopy->info(), bitmapCopy->getPixels(),
167 bitmapCopy->rowBytes(), 0, 0);
168 }
169 outSpriteIcon->hotSpotX = outPointerIcon->hotSpotX;
170 outSpriteIcon->hotSpotY = outPointerIcon->hotSpotY;
171 }
172 }
173
loadSystemIconAsSprite(JNIEnv * env,jobject contextObj,int32_t style,SpriteIcon * outSpriteIcon)174 static void loadSystemIconAsSprite(JNIEnv* env, jobject contextObj, int32_t style,
175 SpriteIcon* outSpriteIcon) {
176 PointerIcon pointerIcon;
177 loadSystemIconAsSpriteWithPointerIcon(env, contextObj, style, &pointerIcon, outSpriteIcon);
178 }
179
180 enum {
181 WM_ACTION_PASS_TO_USER = 1,
182 };
183
getStringElementFromJavaArray(JNIEnv * env,jobjectArray array,jsize index)184 static std::string getStringElementFromJavaArray(JNIEnv* env, jobjectArray array, jsize index) {
185 jstring item = jstring(env->GetObjectArrayElement(array, index));
186 ScopedUtfChars chars(env, item);
187 std::string result(chars.c_str());
188 return result;
189 }
190
191 // --- NativeInputManager ---
192
193 class NativeInputManager : public virtual RefBase,
194 public virtual InputReaderPolicyInterface,
195 public virtual InputDispatcherPolicyInterface,
196 public virtual PointerControllerPolicyInterface {
197 protected:
198 virtual ~NativeInputManager();
199
200 public:
201 NativeInputManager(jobject contextObj, jobject serviceObj, const sp<Looper>& looper);
202
getInputManager() const203 inline sp<InputManager> getInputManager() const { return mInputManager; }
204
205 void dump(std::string& dump);
206
207 void setDisplayViewports(JNIEnv* env, jobjectArray viewportObjArray);
208
209 status_t registerInputChannel(JNIEnv* env, const sp<InputChannel>& inputChannel,
210 int32_t displayId);
211 status_t registerInputMonitor(JNIEnv* env, const sp<InputChannel>& inputChannel,
212 int32_t displayId, bool isGestureMonitor);
213 status_t unregisterInputChannel(JNIEnv* env, const sp<InputChannel>& inputChannel);
214 status_t pilferPointers(const sp<IBinder>& token);
215
216 void setInputWindows(JNIEnv* env, jobjectArray windowHandleObjArray, int32_t displayId);
217 void setFocusedApplication(JNIEnv* env, int32_t displayId, jobject applicationHandleObj);
218 void setFocusedDisplay(JNIEnv* env, int32_t displayId);
219 void setInputDispatchMode(bool enabled, bool frozen);
220 void setSystemUiVisibility(int32_t visibility);
221 void setPointerSpeed(int32_t speed);
222 void setInputDeviceEnabled(uint32_t deviceId, bool enabled);
223 void setShowTouches(bool enabled);
224 void setInteractive(bool interactive);
225 void reloadCalibration();
226 void setPointerIconType(int32_t iconId);
227 void reloadPointerIcons();
228 void setCustomPointerIcon(const SpriteIcon& icon);
229 void setPointerCapture(bool enabled);
230
231 /* --- InputReaderPolicyInterface implementation --- */
232
233 virtual void getReaderConfiguration(InputReaderConfiguration* outConfig);
234 virtual sp<PointerControllerInterface> obtainPointerController(int32_t deviceId);
235 virtual void notifyInputDevicesChanged(const std::vector<InputDeviceInfo>& inputDevices);
236 virtual sp<KeyCharacterMap> getKeyboardLayoutOverlay(const InputDeviceIdentifier& identifier);
237 virtual std::string getDeviceAlias(const InputDeviceIdentifier& identifier);
238 virtual TouchAffineTransformation getTouchAffineTransformation(JNIEnv *env,
239 jfloatArray matrixArr);
240 virtual TouchAffineTransformation getTouchAffineTransformation(
241 const std::string& inputDeviceDescriptor, int32_t surfaceRotation);
242
243 /* --- InputDispatcherPolicyInterface implementation --- */
244
245 virtual void notifySwitch(nsecs_t when, uint32_t switchValues, uint32_t switchMask,
246 uint32_t policyFlags);
247 virtual void notifyConfigurationChanged(nsecs_t when);
248 virtual nsecs_t notifyANR(const sp<InputApplicationHandle>& inputApplicationHandle,
249 const sp<IBinder>& token,
250 const std::string& reason);
251 virtual void notifyInputChannelBroken(const sp<IBinder>& token);
252 virtual void notifyFocusChanged(const sp<IBinder>& oldToken, const sp<IBinder>& newToken);
253 virtual bool filterInputEvent(const InputEvent* inputEvent, uint32_t policyFlags);
254 virtual void getDispatcherConfiguration(InputDispatcherConfiguration* outConfig);
255 virtual void interceptKeyBeforeQueueing(const KeyEvent* keyEvent, uint32_t& policyFlags);
256 virtual void interceptMotionBeforeQueueing(const int32_t displayId, nsecs_t when,
257 uint32_t& policyFlags);
258 virtual nsecs_t interceptKeyBeforeDispatching(
259 const sp<IBinder>& token,
260 const KeyEvent* keyEvent, uint32_t policyFlags);
261 virtual bool dispatchUnhandledKey(const sp<IBinder>& token,
262 const KeyEvent* keyEvent, uint32_t policyFlags, KeyEvent* outFallbackKeyEvent);
263 virtual void pokeUserActivity(nsecs_t eventTime, int32_t eventType);
264 virtual bool checkInjectEventsPermissionNonReentrant(
265 int32_t injectorPid, int32_t injectorUid);
266 virtual void onPointerDownOutsideFocus(const sp<IBinder>& touchedToken);
267
268 /* --- PointerControllerPolicyInterface implementation --- */
269
270 virtual void loadPointerIcon(SpriteIcon* icon, int32_t displayId);
271 virtual void loadPointerResources(PointerResources* outResources, int32_t displayId);
272 virtual void loadAdditionalMouseResources(std::map<int32_t, SpriteIcon>* outResources,
273 std::map<int32_t, PointerAnimation>* outAnimationResources, int32_t displayId);
274 virtual int32_t getDefaultPointerIconId();
275 virtual int32_t getCustomPointerIconId();
276
277 private:
278 sp<InputManager> mInputManager;
279
280 jobject mServiceObj;
281 sp<Looper> mLooper;
282
283 Mutex mLock;
284 struct Locked {
285 // Display size information.
286 std::vector<DisplayViewport> viewports;
287
288 // System UI visibility.
289 int32_t systemUiVisibility;
290
291 // Pointer speed.
292 int32_t pointerSpeed;
293
294 // True if pointer gestures are enabled.
295 bool pointerGesturesEnabled;
296
297 // Show touches feature enable/disable.
298 bool showTouches;
299
300 // Pointer capture feature enable/disable.
301 bool pointerCapture;
302
303 // Sprite controller singleton, created on first use.
304 sp<SpriteController> spriteController;
305
306 // Pointer controller singleton, created and destroyed as needed.
307 wp<PointerController> pointerController;
308
309 // Input devices to be disabled
310 SortedVector<int32_t> disabledInputDevices;
311
312 // Associated Pointer controller display.
313 int32_t pointerDisplayId;
314 } mLocked GUARDED_BY(mLock);
315
316 std::atomic<bool> mInteractive;
317
318 void updateInactivityTimeoutLocked();
319 void handleInterceptActions(jint wmActions, nsecs_t when, uint32_t& policyFlags);
320 void ensureSpriteControllerLocked();
321 const DisplayViewport* findDisplayViewportLocked(int32_t displayId);
322 int32_t getPointerDisplayId();
323 void updatePointerDisplayLocked();
324 static bool checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName);
325
jniEnv()326 static inline JNIEnv* jniEnv() {
327 return AndroidRuntime::getJNIEnv();
328 }
329 };
330
331
332
NativeInputManager(jobject contextObj,jobject serviceObj,const sp<Looper> & looper)333 NativeInputManager::NativeInputManager(jobject contextObj,
334 jobject serviceObj, const sp<Looper>& looper) :
335 mLooper(looper), mInteractive(true) {
336 JNIEnv* env = jniEnv();
337
338 mServiceObj = env->NewGlobalRef(serviceObj);
339
340 {
341 AutoMutex _l(mLock);
342 mLocked.systemUiVisibility = ASYSTEM_UI_VISIBILITY_STATUS_BAR_VISIBLE;
343 mLocked.pointerSpeed = 0;
344 mLocked.pointerGesturesEnabled = true;
345 mLocked.showTouches = false;
346 mLocked.pointerCapture = false;
347 mLocked.pointerDisplayId = ADISPLAY_ID_DEFAULT;
348 }
349 mInteractive = true;
350
351 mInputManager = new InputManager(this, this);
352 defaultServiceManager()->addService(String16("inputflinger"),
353 mInputManager, false);
354 }
355
~NativeInputManager()356 NativeInputManager::~NativeInputManager() {
357 JNIEnv* env = jniEnv();
358
359 env->DeleteGlobalRef(mServiceObj);
360 }
361
dump(std::string & dump)362 void NativeInputManager::dump(std::string& dump) {
363 dump += "Input Manager State:\n";
364 {
365 dump += StringPrintf(INDENT "Interactive: %s\n", toString(mInteractive.load()));
366 }
367 {
368 AutoMutex _l(mLock);
369 dump += StringPrintf(INDENT "System UI Visibility: 0x%0" PRIx32 "\n",
370 mLocked.systemUiVisibility);
371 dump += StringPrintf(INDENT "Pointer Speed: %" PRId32 "\n", mLocked.pointerSpeed);
372 dump += StringPrintf(INDENT "Pointer Gestures Enabled: %s\n",
373 toString(mLocked.pointerGesturesEnabled));
374 dump += StringPrintf(INDENT "Show Touches: %s\n", toString(mLocked.showTouches));
375 dump += StringPrintf(INDENT "Pointer Capture Enabled: %s\n", toString(mLocked.pointerCapture));
376 }
377 dump += "\n";
378
379 mInputManager->getReader()->dump(dump);
380 dump += "\n";
381
382 mInputManager->getClassifier()->dump(dump);
383 dump += "\n";
384
385 mInputManager->getDispatcher()->dump(dump);
386 dump += "\n";
387 }
388
checkAndClearExceptionFromCallback(JNIEnv * env,const char * methodName)389 bool NativeInputManager::checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName) {
390 if (env->ExceptionCheck()) {
391 ALOGE("An exception was thrown by callback '%s'.", methodName);
392 LOGE_EX(env);
393 env->ExceptionClear();
394 return true;
395 }
396 return false;
397 }
398
findDisplayViewportLocked(int32_t displayId)399 const DisplayViewport* NativeInputManager::findDisplayViewportLocked(int32_t displayId)
400 REQUIRES(mLock) {
401 for (const DisplayViewport& v : mLocked.viewports) {
402 if (v.displayId == displayId) {
403 return &v;
404 }
405 }
406 return nullptr;
407 }
408
setDisplayViewports(JNIEnv * env,jobjectArray viewportObjArray)409 void NativeInputManager::setDisplayViewports(JNIEnv* env, jobjectArray viewportObjArray) {
410 std::vector<DisplayViewport> viewports;
411
412 if (viewportObjArray) {
413 jsize length = env->GetArrayLength(viewportObjArray);
414 for (jsize i = 0; i < length; i++) {
415 jobject viewportObj = env->GetObjectArrayElement(viewportObjArray, i);
416 if (! viewportObj) {
417 break; // found null element indicating end of used portion of the array
418 }
419
420 DisplayViewport viewport;
421 android_hardware_display_DisplayViewport_toNative(env, viewportObj, &viewport);
422 ALOGI("Viewport [%d] to add: %s", (int) i, viewport.uniqueId.c_str());
423 viewports.push_back(viewport);
424
425 env->DeleteLocalRef(viewportObj);
426 }
427 }
428
429 // Get the preferred pointer controller displayId.
430 int32_t pointerDisplayId = getPointerDisplayId();
431
432 { // acquire lock
433 AutoMutex _l(mLock);
434 mLocked.viewports = viewports;
435 mLocked.pointerDisplayId = pointerDisplayId;
436 } // release lock
437
438 mInputManager->getReader()->requestRefreshConfiguration(
439 InputReaderConfiguration::CHANGE_DISPLAY_INFO);
440 }
441
registerInputChannel(JNIEnv *,const sp<InputChannel> & inputChannel,int32_t displayId)442 status_t NativeInputManager::registerInputChannel(JNIEnv* /* env */,
443 const sp<InputChannel>& inputChannel, int32_t displayId) {
444 ATRACE_CALL();
445 return mInputManager->getDispatcher()->registerInputChannel(
446 inputChannel, displayId);
447 }
448
registerInputMonitor(JNIEnv *,const sp<InputChannel> & inputChannel,int32_t displayId,bool isGestureMonitor)449 status_t NativeInputManager::registerInputMonitor(JNIEnv* /* env */,
450 const sp<InputChannel>& inputChannel, int32_t displayId, bool isGestureMonitor) {
451 ATRACE_CALL();
452 return mInputManager->getDispatcher()->registerInputMonitor(
453 inputChannel, displayId, isGestureMonitor);
454 }
455
unregisterInputChannel(JNIEnv *,const sp<InputChannel> & inputChannel)456 status_t NativeInputManager::unregisterInputChannel(JNIEnv* /* env */,
457 const sp<InputChannel>& inputChannel) {
458 ATRACE_CALL();
459 return mInputManager->getDispatcher()->unregisterInputChannel(inputChannel);
460 }
461
pilferPointers(const sp<IBinder> & token)462 status_t NativeInputManager::pilferPointers(const sp<IBinder>& token) {
463 ATRACE_CALL();
464 return mInputManager->getDispatcher()->pilferPointers(token);
465 }
466
getReaderConfiguration(InputReaderConfiguration * outConfig)467 void NativeInputManager::getReaderConfiguration(InputReaderConfiguration* outConfig) {
468 ATRACE_CALL();
469 JNIEnv* env = jniEnv();
470
471 jint virtualKeyQuietTime = env->CallIntMethod(mServiceObj,
472 gServiceClassInfo.getVirtualKeyQuietTimeMillis);
473 if (!checkAndClearExceptionFromCallback(env, "getVirtualKeyQuietTimeMillis")) {
474 outConfig->virtualKeyQuietTime = milliseconds_to_nanoseconds(virtualKeyQuietTime);
475 }
476
477 outConfig->excludedDeviceNames.clear();
478 jobjectArray excludedDeviceNames = jobjectArray(env->CallStaticObjectMethod(
479 gServiceClassInfo.clazz, gServiceClassInfo.getExcludedDeviceNames));
480 if (!checkAndClearExceptionFromCallback(env, "getExcludedDeviceNames") && excludedDeviceNames) {
481 jsize length = env->GetArrayLength(excludedDeviceNames);
482 for (jsize i = 0; i < length; i++) {
483 std::string deviceName = getStringElementFromJavaArray(env, excludedDeviceNames, i);
484 outConfig->excludedDeviceNames.push_back(deviceName);
485 }
486 env->DeleteLocalRef(excludedDeviceNames);
487 }
488
489 // Associations between input ports and display ports
490 // The java method packs the information in the following manner:
491 // Original data: [{'inputPort1': '1'}, {'inputPort2': '2'}]
492 // Received data: ['inputPort1', '1', 'inputPort2', '2']
493 // So we unpack accordingly here.
494 outConfig->portAssociations.clear();
495 jobjectArray portAssociations = jobjectArray(env->CallStaticObjectMethod(
496 gServiceClassInfo.clazz, gServiceClassInfo.getInputPortAssociations));
497 if (!checkAndClearExceptionFromCallback(env, "getInputPortAssociations") && portAssociations) {
498 jsize length = env->GetArrayLength(portAssociations);
499 for (jsize i = 0; i < length / 2; i++) {
500 std::string inputPort = getStringElementFromJavaArray(env, portAssociations, 2 * i);
501 std::string displayPortStr =
502 getStringElementFromJavaArray(env, portAssociations, 2 * i + 1);
503 uint8_t displayPort;
504 // Should already have been validated earlier, but do it here for safety.
505 bool success = ParseUint(displayPortStr, &displayPort);
506 if (!success) {
507 ALOGE("Could not parse entry in port configuration file, received: %s",
508 displayPortStr.c_str());
509 continue;
510 }
511 outConfig->portAssociations.insert({inputPort, displayPort});
512 }
513 env->DeleteLocalRef(portAssociations);
514 }
515
516 jint hoverTapTimeout = env->CallIntMethod(mServiceObj,
517 gServiceClassInfo.getHoverTapTimeout);
518 if (!checkAndClearExceptionFromCallback(env, "getHoverTapTimeout")) {
519 jint doubleTapTimeout = env->CallIntMethod(mServiceObj,
520 gServiceClassInfo.getDoubleTapTimeout);
521 if (!checkAndClearExceptionFromCallback(env, "getDoubleTapTimeout")) {
522 jint longPressTimeout = env->CallIntMethod(mServiceObj,
523 gServiceClassInfo.getLongPressTimeout);
524 if (!checkAndClearExceptionFromCallback(env, "getLongPressTimeout")) {
525 outConfig->pointerGestureTapInterval = milliseconds_to_nanoseconds(hoverTapTimeout);
526
527 // We must ensure that the tap-drag interval is significantly shorter than
528 // the long-press timeout because the tap is held down for the entire duration
529 // of the double-tap timeout.
530 jint tapDragInterval = max(min(longPressTimeout - 100,
531 doubleTapTimeout), hoverTapTimeout);
532 outConfig->pointerGestureTapDragInterval =
533 milliseconds_to_nanoseconds(tapDragInterval);
534 }
535 }
536 }
537
538 jint hoverTapSlop = env->CallIntMethod(mServiceObj,
539 gServiceClassInfo.getHoverTapSlop);
540 if (!checkAndClearExceptionFromCallback(env, "getHoverTapSlop")) {
541 outConfig->pointerGestureTapSlop = hoverTapSlop;
542 }
543
544 { // acquire lock
545 AutoMutex _l(mLock);
546
547 outConfig->pointerVelocityControlParameters.scale = exp2f(mLocked.pointerSpeed
548 * POINTER_SPEED_EXPONENT);
549 outConfig->pointerGesturesEnabled = mLocked.pointerGesturesEnabled;
550
551 outConfig->showTouches = mLocked.showTouches;
552
553 outConfig->pointerCapture = mLocked.pointerCapture;
554
555 outConfig->setDisplayViewports(mLocked.viewports);
556
557 outConfig->disabledDevices = mLocked.disabledInputDevices;
558 } // release lock
559 }
560
obtainPointerController(int32_t)561 sp<PointerControllerInterface> NativeInputManager::obtainPointerController(int32_t /* deviceId */) {
562 ATRACE_CALL();
563 AutoMutex _l(mLock);
564
565 sp<PointerController> controller = mLocked.pointerController.promote();
566 if (controller == nullptr) {
567 ensureSpriteControllerLocked();
568
569 controller = new PointerController(this, mLooper, mLocked.spriteController);
570 mLocked.pointerController = controller;
571 updateInactivityTimeoutLocked();
572 }
573
574 updatePointerDisplayLocked();
575
576 return controller;
577 }
578
getPointerDisplayId()579 int32_t NativeInputManager::getPointerDisplayId() {
580 JNIEnv* env = jniEnv();
581 jint pointerDisplayId = env->CallIntMethod(mServiceObj,
582 gServiceClassInfo.getPointerDisplayId);
583 if (checkAndClearExceptionFromCallback(env, "getPointerDisplayId")) {
584 pointerDisplayId = ADISPLAY_ID_DEFAULT;
585 }
586
587 return pointerDisplayId;
588 }
589
updatePointerDisplayLocked()590 void NativeInputManager::updatePointerDisplayLocked() REQUIRES(mLock) {
591 ATRACE_CALL();
592
593 sp<PointerController> controller = mLocked.pointerController.promote();
594 if (controller != nullptr) {
595 const DisplayViewport* viewport = findDisplayViewportLocked(mLocked.pointerDisplayId);
596 if (viewport == nullptr) {
597 ALOGW("Can't find pointer display viewport, fallback to default display.");
598 viewport = findDisplayViewportLocked(ADISPLAY_ID_DEFAULT);
599 }
600
601 if (viewport != nullptr) {
602 controller->setDisplayViewport(*viewport);
603 }
604 }
605 }
606
ensureSpriteControllerLocked()607 void NativeInputManager::ensureSpriteControllerLocked() REQUIRES(mLock) {
608 if (mLocked.spriteController == nullptr) {
609 JNIEnv* env = jniEnv();
610 jint layer = env->CallIntMethod(mServiceObj, gServiceClassInfo.getPointerLayer);
611 if (checkAndClearExceptionFromCallback(env, "getPointerLayer")) {
612 layer = -1;
613 }
614 mLocked.spriteController = new SpriteController(mLooper, layer);
615 }
616 }
617
notifyInputDevicesChanged(const std::vector<InputDeviceInfo> & inputDevices)618 void NativeInputManager::notifyInputDevicesChanged(const std::vector<InputDeviceInfo>& inputDevices) {
619 ATRACE_CALL();
620 JNIEnv* env = jniEnv();
621
622 size_t count = inputDevices.size();
623 jobjectArray inputDevicesObjArray = env->NewObjectArray(
624 count, gInputDeviceClassInfo.clazz, nullptr);
625 if (inputDevicesObjArray) {
626 bool error = false;
627 for (size_t i = 0; i < count; i++) {
628 jobject inputDeviceObj = android_view_InputDevice_create(env, inputDevices[i]);
629 if (!inputDeviceObj) {
630 error = true;
631 break;
632 }
633
634 env->SetObjectArrayElement(inputDevicesObjArray, i, inputDeviceObj);
635 env->DeleteLocalRef(inputDeviceObj);
636 }
637
638 if (!error) {
639 env->CallVoidMethod(mServiceObj, gServiceClassInfo.notifyInputDevicesChanged,
640 inputDevicesObjArray);
641 }
642
643 env->DeleteLocalRef(inputDevicesObjArray);
644 }
645
646 checkAndClearExceptionFromCallback(env, "notifyInputDevicesChanged");
647 }
648
getKeyboardLayoutOverlay(const InputDeviceIdentifier & identifier)649 sp<KeyCharacterMap> NativeInputManager::getKeyboardLayoutOverlay(
650 const InputDeviceIdentifier& identifier) {
651 ATRACE_CALL();
652 JNIEnv* env = jniEnv();
653
654 sp<KeyCharacterMap> result;
655 ScopedLocalRef<jstring> descriptor(env, env->NewStringUTF(identifier.descriptor.c_str()));
656 ScopedLocalRef<jobject> identifierObj(env, env->NewObject(gInputDeviceIdentifierInfo.clazz,
657 gInputDeviceIdentifierInfo.constructor, descriptor.get(),
658 identifier.vendor, identifier.product));
659 ScopedLocalRef<jobjectArray> arrayObj(env, jobjectArray(env->CallObjectMethod(mServiceObj,
660 gServiceClassInfo.getKeyboardLayoutOverlay, identifierObj.get())));
661 if (arrayObj.get()) {
662 ScopedLocalRef<jstring> filenameObj(env,
663 jstring(env->GetObjectArrayElement(arrayObj.get(), 0)));
664 ScopedLocalRef<jstring> contentsObj(env,
665 jstring(env->GetObjectArrayElement(arrayObj.get(), 1)));
666 ScopedUtfChars filenameChars(env, filenameObj.get());
667 ScopedUtfChars contentsChars(env, contentsObj.get());
668
669 KeyCharacterMap::loadContents(filenameChars.c_str(),
670 contentsChars.c_str(), KeyCharacterMap::FORMAT_OVERLAY, &result);
671 }
672 checkAndClearExceptionFromCallback(env, "getKeyboardLayoutOverlay");
673 return result;
674 }
675
getDeviceAlias(const InputDeviceIdentifier & identifier)676 std::string NativeInputManager::getDeviceAlias(const InputDeviceIdentifier& identifier) {
677 ATRACE_CALL();
678 JNIEnv* env = jniEnv();
679
680 ScopedLocalRef<jstring> uniqueIdObj(env, env->NewStringUTF(identifier.uniqueId.c_str()));
681 ScopedLocalRef<jstring> aliasObj(env, jstring(env->CallObjectMethod(mServiceObj,
682 gServiceClassInfo.getDeviceAlias, uniqueIdObj.get())));
683 std::string result;
684 if (aliasObj.get()) {
685 ScopedUtfChars aliasChars(env, aliasObj.get());
686 result = aliasChars.c_str();
687 }
688 checkAndClearExceptionFromCallback(env, "getDeviceAlias");
689 return result;
690 }
691
notifySwitch(nsecs_t when,uint32_t switchValues,uint32_t switchMask,uint32_t)692 void NativeInputManager::notifySwitch(nsecs_t when,
693 uint32_t switchValues, uint32_t switchMask, uint32_t /* policyFlags */) {
694 #if DEBUG_INPUT_DISPATCHER_POLICY
695 ALOGD("notifySwitch - when=%lld, switchValues=0x%08x, switchMask=0x%08x, policyFlags=0x%x",
696 when, switchValues, switchMask, policyFlags);
697 #endif
698 ATRACE_CALL();
699
700 JNIEnv* env = jniEnv();
701
702 env->CallVoidMethod(mServiceObj, gServiceClassInfo.notifySwitch,
703 when, switchValues, switchMask);
704 checkAndClearExceptionFromCallback(env, "notifySwitch");
705 }
706
notifyConfigurationChanged(nsecs_t when)707 void NativeInputManager::notifyConfigurationChanged(nsecs_t when) {
708 #if DEBUG_INPUT_DISPATCHER_POLICY
709 ALOGD("notifyConfigurationChanged - when=%lld", when);
710 #endif
711 ATRACE_CALL();
712
713 JNIEnv* env = jniEnv();
714
715 env->CallVoidMethod(mServiceObj, gServiceClassInfo.notifyConfigurationChanged, when);
716 checkAndClearExceptionFromCallback(env, "notifyConfigurationChanged");
717 }
718
notifyANR(const sp<InputApplicationHandle> & inputApplicationHandle,const sp<IBinder> & token,const std::string & reason)719 nsecs_t NativeInputManager::notifyANR(const sp<InputApplicationHandle>& inputApplicationHandle,
720 const sp<IBinder>& token, const std::string& reason) {
721 #if DEBUG_INPUT_DISPATCHER_POLICY
722 ALOGD("notifyANR");
723 #endif
724 ATRACE_CALL();
725
726 JNIEnv* env = jniEnv();
727 ScopedLocalFrame localFrame(env);
728
729 jobject tokenObj = javaObjectForIBinder(env, token);
730 jstring reasonObj = env->NewStringUTF(reason.c_str());
731
732 jlong newTimeout = env->CallLongMethod(mServiceObj,
733 gServiceClassInfo.notifyANR, tokenObj,
734 reasonObj);
735 if (checkAndClearExceptionFromCallback(env, "notifyANR")) {
736 newTimeout = 0; // abort dispatch
737 } else {
738 assert(newTimeout >= 0);
739 }
740 return newTimeout;
741 }
742
notifyInputChannelBroken(const sp<IBinder> & token)743 void NativeInputManager::notifyInputChannelBroken(const sp<IBinder>& token) {
744 #if DEBUG_INPUT_DISPATCHER_POLICY
745 ALOGD("notifyInputChannelBroken");
746 #endif
747 ATRACE_CALL();
748
749 JNIEnv* env = jniEnv();
750 ScopedLocalFrame localFrame(env);
751
752 jobject tokenObj = javaObjectForIBinder(env, token);
753 if (tokenObj) {
754 env->CallVoidMethod(mServiceObj, gServiceClassInfo.notifyInputChannelBroken,
755 tokenObj);
756 checkAndClearExceptionFromCallback(env, "notifyInputChannelBroken");
757 }
758 }
759
notifyFocusChanged(const sp<IBinder> & oldToken,const sp<IBinder> & newToken)760 void NativeInputManager::notifyFocusChanged(const sp<IBinder>& oldToken,
761 const sp<IBinder>& newToken) {
762 #if DEBUG_INPUT_DISPATCHER_POLICY
763 ALOGD("notifyFocusChanged");
764 #endif
765 ATRACE_CALL();
766
767 JNIEnv* env = jniEnv();
768 ScopedLocalFrame localFrame(env);
769
770 jobject oldTokenObj = javaObjectForIBinder(env, oldToken);
771 jobject newTokenObj = javaObjectForIBinder(env, newToken);
772 env->CallVoidMethod(mServiceObj, gServiceClassInfo.notifyFocusChanged,
773 oldTokenObj, newTokenObj);
774 checkAndClearExceptionFromCallback(env, "notifyFocusChanged");
775 }
776
getDispatcherConfiguration(InputDispatcherConfiguration * outConfig)777 void NativeInputManager::getDispatcherConfiguration(InputDispatcherConfiguration* outConfig) {
778 ATRACE_CALL();
779 JNIEnv* env = jniEnv();
780
781 jint keyRepeatTimeout = env->CallIntMethod(mServiceObj,
782 gServiceClassInfo.getKeyRepeatTimeout);
783 if (!checkAndClearExceptionFromCallback(env, "getKeyRepeatTimeout")) {
784 outConfig->keyRepeatTimeout = milliseconds_to_nanoseconds(keyRepeatTimeout);
785 }
786
787 jint keyRepeatDelay = env->CallIntMethod(mServiceObj,
788 gServiceClassInfo.getKeyRepeatDelay);
789 if (!checkAndClearExceptionFromCallback(env, "getKeyRepeatDelay")) {
790 outConfig->keyRepeatDelay = milliseconds_to_nanoseconds(keyRepeatDelay);
791 }
792 }
793
setInputWindows(JNIEnv * env,jobjectArray windowHandleObjArray,int32_t displayId)794 void NativeInputManager::setInputWindows(JNIEnv* env, jobjectArray windowHandleObjArray,
795 int32_t displayId) {
796 std::vector<sp<InputWindowHandle> > windowHandles;
797
798 if (windowHandleObjArray) {
799 jsize length = env->GetArrayLength(windowHandleObjArray);
800 for (jsize i = 0; i < length; i++) {
801 jobject windowHandleObj = env->GetObjectArrayElement(windowHandleObjArray, i);
802 if (! windowHandleObj) {
803 break; // found null element indicating end of used portion of the array
804 }
805
806 sp<InputWindowHandle> windowHandle =
807 android_view_InputWindowHandle_getHandle(env, windowHandleObj);
808 if (windowHandle != nullptr) {
809 windowHandles.push_back(windowHandle);
810 }
811 env->DeleteLocalRef(windowHandleObj);
812 }
813 }
814
815 mInputManager->getDispatcher()->setInputWindows(windowHandles, displayId);
816
817 // Do this after the dispatcher has updated the window handle state.
818 bool newPointerGesturesEnabled = true;
819 size_t numWindows = windowHandles.size();
820 for (size_t i = 0; i < numWindows; i++) {
821 const sp<InputWindowHandle>& windowHandle = windowHandles[i];
822 const InputWindowInfo* windowInfo = windowHandle->getInfo();
823 if (windowInfo && windowInfo->hasFocus && (windowInfo->inputFeatures
824 & InputWindowInfo::INPUT_FEATURE_DISABLE_TOUCH_PAD_GESTURES)) {
825 newPointerGesturesEnabled = false;
826 }
827 }
828
829 uint32_t changes = 0;
830 { // acquire lock
831 AutoMutex _l(mLock);
832
833 if (mLocked.pointerGesturesEnabled != newPointerGesturesEnabled) {
834 mLocked.pointerGesturesEnabled = newPointerGesturesEnabled;
835 changes |= InputReaderConfiguration::CHANGE_POINTER_GESTURE_ENABLEMENT;
836 }
837 } // release lock
838
839 if (changes) {
840 mInputManager->getReader()->requestRefreshConfiguration(changes);
841 }
842 }
843
setFocusedApplication(JNIEnv * env,int32_t displayId,jobject applicationHandleObj)844 void NativeInputManager::setFocusedApplication(JNIEnv* env, int32_t displayId,
845 jobject applicationHandleObj) {
846 sp<InputApplicationHandle> applicationHandle =
847 android_view_InputApplicationHandle_getHandle(env, applicationHandleObj);
848 mInputManager->getDispatcher()->setFocusedApplication(displayId, applicationHandle);
849 }
850
setFocusedDisplay(JNIEnv * env,int32_t displayId)851 void NativeInputManager::setFocusedDisplay(JNIEnv* env, int32_t displayId) {
852 mInputManager->getDispatcher()->setFocusedDisplay(displayId);
853 }
854
setInputDispatchMode(bool enabled,bool frozen)855 void NativeInputManager::setInputDispatchMode(bool enabled, bool frozen) {
856 mInputManager->getDispatcher()->setInputDispatchMode(enabled, frozen);
857 }
858
setSystemUiVisibility(int32_t visibility)859 void NativeInputManager::setSystemUiVisibility(int32_t visibility) {
860 AutoMutex _l(mLock);
861
862 if (mLocked.systemUiVisibility != visibility) {
863 mLocked.systemUiVisibility = visibility;
864 updateInactivityTimeoutLocked();
865 }
866 }
867
updateInactivityTimeoutLocked()868 void NativeInputManager::updateInactivityTimeoutLocked() REQUIRES(mLock) {
869 sp<PointerController> controller = mLocked.pointerController.promote();
870 if (controller == nullptr) {
871 return;
872 }
873
874 bool lightsOut = mLocked.systemUiVisibility & ASYSTEM_UI_VISIBILITY_STATUS_BAR_HIDDEN;
875 controller->setInactivityTimeout(lightsOut
876 ? PointerController::INACTIVITY_TIMEOUT_SHORT
877 : PointerController::INACTIVITY_TIMEOUT_NORMAL);
878 }
879
setPointerSpeed(int32_t speed)880 void NativeInputManager::setPointerSpeed(int32_t speed) {
881 { // acquire lock
882 AutoMutex _l(mLock);
883
884 if (mLocked.pointerSpeed == speed) {
885 return;
886 }
887
888 ALOGI("Setting pointer speed to %d.", speed);
889 mLocked.pointerSpeed = speed;
890 } // release lock
891
892 mInputManager->getReader()->requestRefreshConfiguration(
893 InputReaderConfiguration::CHANGE_POINTER_SPEED);
894 }
895
setInputDeviceEnabled(uint32_t deviceId,bool enabled)896 void NativeInputManager::setInputDeviceEnabled(uint32_t deviceId, bool enabled) {
897 { // acquire lock
898 AutoMutex _l(mLock);
899
900 ssize_t index = mLocked.disabledInputDevices.indexOf(deviceId);
901 bool currentlyEnabled = index < 0;
902 if (!enabled && currentlyEnabled) {
903 mLocked.disabledInputDevices.add(deviceId);
904 }
905 if (enabled && !currentlyEnabled) {
906 mLocked.disabledInputDevices.remove(deviceId);
907 }
908 } // release lock
909
910 mInputManager->getReader()->requestRefreshConfiguration(
911 InputReaderConfiguration::CHANGE_ENABLED_STATE);
912 }
913
setShowTouches(bool enabled)914 void NativeInputManager::setShowTouches(bool enabled) {
915 { // acquire lock
916 AutoMutex _l(mLock);
917
918 if (mLocked.showTouches == enabled) {
919 return;
920 }
921
922 ALOGI("Setting show touches feature to %s.", enabled ? "enabled" : "disabled");
923 mLocked.showTouches = enabled;
924 } // release lock
925
926 mInputManager->getReader()->requestRefreshConfiguration(
927 InputReaderConfiguration::CHANGE_SHOW_TOUCHES);
928 }
929
setPointerCapture(bool enabled)930 void NativeInputManager::setPointerCapture(bool enabled) {
931 { // acquire lock
932 AutoMutex _l(mLock);
933
934 if (mLocked.pointerCapture == enabled) {
935 return;
936 }
937
938 ALOGI("Setting pointer capture to %s.", enabled ? "enabled" : "disabled");
939 mLocked.pointerCapture = enabled;
940 } // release lock
941
942 mInputManager->getReader()->requestRefreshConfiguration(
943 InputReaderConfiguration::CHANGE_POINTER_CAPTURE);
944 }
945
setInteractive(bool interactive)946 void NativeInputManager::setInteractive(bool interactive) {
947 mInteractive = interactive;
948 }
949
reloadCalibration()950 void NativeInputManager::reloadCalibration() {
951 mInputManager->getReader()->requestRefreshConfiguration(
952 InputReaderConfiguration::CHANGE_TOUCH_AFFINE_TRANSFORMATION);
953 }
954
setPointerIconType(int32_t iconId)955 void NativeInputManager::setPointerIconType(int32_t iconId) {
956 AutoMutex _l(mLock);
957 sp<PointerController> controller = mLocked.pointerController.promote();
958 if (controller != nullptr) {
959 controller->updatePointerIcon(iconId);
960 }
961 }
962
reloadPointerIcons()963 void NativeInputManager::reloadPointerIcons() {
964 AutoMutex _l(mLock);
965 sp<PointerController> controller = mLocked.pointerController.promote();
966 if (controller != nullptr) {
967 controller->reloadPointerResources();
968 }
969 }
970
setCustomPointerIcon(const SpriteIcon & icon)971 void NativeInputManager::setCustomPointerIcon(const SpriteIcon& icon) {
972 AutoMutex _l(mLock);
973 sp<PointerController> controller = mLocked.pointerController.promote();
974 if (controller != nullptr) {
975 controller->setCustomPointerIcon(icon);
976 }
977 }
978
getTouchAffineTransformation(JNIEnv * env,jfloatArray matrixArr)979 TouchAffineTransformation NativeInputManager::getTouchAffineTransformation(
980 JNIEnv *env, jfloatArray matrixArr) {
981 ATRACE_CALL();
982 ScopedFloatArrayRO matrix(env, matrixArr);
983 assert(matrix.size() == 6);
984
985 TouchAffineTransformation transform;
986 transform.x_scale = matrix[0];
987 transform.x_ymix = matrix[1];
988 transform.x_offset = matrix[2];
989 transform.y_xmix = matrix[3];
990 transform.y_scale = matrix[4];
991 transform.y_offset = matrix[5];
992
993 return transform;
994 }
995
getTouchAffineTransformation(const std::string & inputDeviceDescriptor,int32_t surfaceRotation)996 TouchAffineTransformation NativeInputManager::getTouchAffineTransformation(
997 const std::string& inputDeviceDescriptor, int32_t surfaceRotation) {
998 JNIEnv* env = jniEnv();
999
1000 ScopedLocalRef<jstring> descriptorObj(env, env->NewStringUTF(inputDeviceDescriptor.c_str()));
1001
1002 jobject cal = env->CallObjectMethod(mServiceObj,
1003 gServiceClassInfo.getTouchCalibrationForInputDevice, descriptorObj.get(),
1004 surfaceRotation);
1005
1006 jfloatArray matrixArr = jfloatArray(env->CallObjectMethod(cal,
1007 gTouchCalibrationClassInfo.getAffineTransform));
1008
1009 TouchAffineTransformation transform = getTouchAffineTransformation(env, matrixArr);
1010
1011 env->DeleteLocalRef(matrixArr);
1012 env->DeleteLocalRef(cal);
1013
1014 return transform;
1015 }
1016
filterInputEvent(const InputEvent * inputEvent,uint32_t policyFlags)1017 bool NativeInputManager::filterInputEvent(const InputEvent* inputEvent, uint32_t policyFlags) {
1018 ATRACE_CALL();
1019 jobject inputEventObj;
1020
1021 JNIEnv* env = jniEnv();
1022 switch (inputEvent->getType()) {
1023 case AINPUT_EVENT_TYPE_KEY:
1024 inputEventObj = android_view_KeyEvent_fromNative(env,
1025 static_cast<const KeyEvent*>(inputEvent));
1026 break;
1027 case AINPUT_EVENT_TYPE_MOTION:
1028 inputEventObj = android_view_MotionEvent_obtainAsCopy(env,
1029 static_cast<const MotionEvent*>(inputEvent));
1030 break;
1031 default:
1032 return true; // dispatch the event normally
1033 }
1034
1035 if (!inputEventObj) {
1036 ALOGE("Failed to obtain input event object for filterInputEvent.");
1037 return true; // dispatch the event normally
1038 }
1039
1040 // The callee is responsible for recycling the event.
1041 jboolean pass = env->CallBooleanMethod(mServiceObj, gServiceClassInfo.filterInputEvent,
1042 inputEventObj, policyFlags);
1043 if (checkAndClearExceptionFromCallback(env, "filterInputEvent")) {
1044 pass = true;
1045 }
1046 env->DeleteLocalRef(inputEventObj);
1047 return pass;
1048 }
1049
interceptKeyBeforeQueueing(const KeyEvent * keyEvent,uint32_t & policyFlags)1050 void NativeInputManager::interceptKeyBeforeQueueing(const KeyEvent* keyEvent,
1051 uint32_t& policyFlags) {
1052 ATRACE_CALL();
1053 // Policy:
1054 // - Ignore untrusted events and pass them along.
1055 // - Ask the window manager what to do with normal events and trusted injected events.
1056 // - For normal events wake and brighten the screen if currently off or dim.
1057 bool interactive = mInteractive.load();
1058 if (interactive) {
1059 policyFlags |= POLICY_FLAG_INTERACTIVE;
1060 }
1061 if ((policyFlags & POLICY_FLAG_TRUSTED)) {
1062 nsecs_t when = keyEvent->getEventTime();
1063 JNIEnv* env = jniEnv();
1064 jobject keyEventObj = android_view_KeyEvent_fromNative(env, keyEvent);
1065 jint wmActions;
1066 if (keyEventObj) {
1067 wmActions = env->CallIntMethod(mServiceObj,
1068 gServiceClassInfo.interceptKeyBeforeQueueing,
1069 keyEventObj, policyFlags);
1070 if (checkAndClearExceptionFromCallback(env, "interceptKeyBeforeQueueing")) {
1071 wmActions = 0;
1072 }
1073 android_view_KeyEvent_recycle(env, keyEventObj);
1074 env->DeleteLocalRef(keyEventObj);
1075 } else {
1076 ALOGE("Failed to obtain key event object for interceptKeyBeforeQueueing.");
1077 wmActions = 0;
1078 }
1079
1080 handleInterceptActions(wmActions, when, /*byref*/ policyFlags);
1081 } else {
1082 if (interactive) {
1083 policyFlags |= POLICY_FLAG_PASS_TO_USER;
1084 }
1085 }
1086 }
1087
interceptMotionBeforeQueueing(const int32_t displayId,nsecs_t when,uint32_t & policyFlags)1088 void NativeInputManager::interceptMotionBeforeQueueing(const int32_t displayId, nsecs_t when,
1089 uint32_t& policyFlags) {
1090 ATRACE_CALL();
1091 // Policy:
1092 // - Ignore untrusted events and pass them along.
1093 // - No special filtering for injected events required at this time.
1094 // - Filter normal events based on screen state.
1095 // - For normal events brighten (but do not wake) the screen if currently dim.
1096 bool interactive = mInteractive.load();
1097 if (interactive) {
1098 policyFlags |= POLICY_FLAG_INTERACTIVE;
1099 }
1100 if ((policyFlags & POLICY_FLAG_TRUSTED) && !(policyFlags & POLICY_FLAG_INJECTED)) {
1101 if (policyFlags & POLICY_FLAG_INTERACTIVE) {
1102 policyFlags |= POLICY_FLAG_PASS_TO_USER;
1103 } else {
1104 JNIEnv* env = jniEnv();
1105 jint wmActions = env->CallIntMethod(mServiceObj,
1106 gServiceClassInfo.interceptMotionBeforeQueueingNonInteractive,
1107 displayId, when, policyFlags);
1108 if (checkAndClearExceptionFromCallback(env,
1109 "interceptMotionBeforeQueueingNonInteractive")) {
1110 wmActions = 0;
1111 }
1112
1113 handleInterceptActions(wmActions, when, /*byref*/ policyFlags);
1114 }
1115 } else {
1116 if (interactive) {
1117 policyFlags |= POLICY_FLAG_PASS_TO_USER;
1118 }
1119 }
1120 }
1121
handleInterceptActions(jint wmActions,nsecs_t when,uint32_t & policyFlags)1122 void NativeInputManager::handleInterceptActions(jint wmActions, nsecs_t when,
1123 uint32_t& policyFlags) {
1124 if (wmActions & WM_ACTION_PASS_TO_USER) {
1125 policyFlags |= POLICY_FLAG_PASS_TO_USER;
1126 } else {
1127 #if DEBUG_INPUT_DISPATCHER_POLICY
1128 ALOGD("handleInterceptActions: Not passing key to user.");
1129 #endif
1130 }
1131 }
1132
interceptKeyBeforeDispatching(const sp<IBinder> & token,const KeyEvent * keyEvent,uint32_t policyFlags)1133 nsecs_t NativeInputManager::interceptKeyBeforeDispatching(
1134 const sp<IBinder>& token,
1135 const KeyEvent* keyEvent, uint32_t policyFlags) {
1136 ATRACE_CALL();
1137 // Policy:
1138 // - Ignore untrusted events and pass them along.
1139 // - Filter normal events and trusted injected events through the window manager policy to
1140 // handle the HOME key and the like.
1141 nsecs_t result = 0;
1142 if (policyFlags & POLICY_FLAG_TRUSTED) {
1143 JNIEnv* env = jniEnv();
1144 ScopedLocalFrame localFrame(env);
1145
1146 // Token may be null
1147 jobject tokenObj = javaObjectForIBinder(env, token);
1148
1149 jobject keyEventObj = android_view_KeyEvent_fromNative(env, keyEvent);
1150 if (keyEventObj) {
1151 jlong delayMillis = env->CallLongMethod(mServiceObj,
1152 gServiceClassInfo.interceptKeyBeforeDispatching,
1153 tokenObj, keyEventObj, policyFlags);
1154 bool error = checkAndClearExceptionFromCallback(env, "interceptKeyBeforeDispatching");
1155 android_view_KeyEvent_recycle(env, keyEventObj);
1156 env->DeleteLocalRef(keyEventObj);
1157 if (!error) {
1158 if (delayMillis < 0) {
1159 result = -1;
1160 } else if (delayMillis > 0) {
1161 result = milliseconds_to_nanoseconds(delayMillis);
1162 }
1163 }
1164 } else {
1165 ALOGE("Failed to obtain key event object for interceptKeyBeforeDispatching.");
1166 }
1167 }
1168 return result;
1169 }
1170
dispatchUnhandledKey(const sp<IBinder> & token,const KeyEvent * keyEvent,uint32_t policyFlags,KeyEvent * outFallbackKeyEvent)1171 bool NativeInputManager::dispatchUnhandledKey(const sp<IBinder>& token,
1172 const KeyEvent* keyEvent, uint32_t policyFlags, KeyEvent* outFallbackKeyEvent) {
1173 ATRACE_CALL();
1174 // Policy:
1175 // - Ignore untrusted events and do not perform default handling.
1176 bool result = false;
1177 if (policyFlags & POLICY_FLAG_TRUSTED) {
1178 JNIEnv* env = jniEnv();
1179 ScopedLocalFrame localFrame(env);
1180
1181 // Note: tokenObj may be null.
1182 jobject tokenObj = javaObjectForIBinder(env, token);
1183 jobject keyEventObj = android_view_KeyEvent_fromNative(env, keyEvent);
1184 if (keyEventObj) {
1185 jobject fallbackKeyEventObj = env->CallObjectMethod(mServiceObj,
1186 gServiceClassInfo.dispatchUnhandledKey,
1187 tokenObj, keyEventObj, policyFlags);
1188 if (checkAndClearExceptionFromCallback(env, "dispatchUnhandledKey")) {
1189 fallbackKeyEventObj = nullptr;
1190 }
1191 android_view_KeyEvent_recycle(env, keyEventObj);
1192 env->DeleteLocalRef(keyEventObj);
1193
1194 if (fallbackKeyEventObj) {
1195 // Note: outFallbackKeyEvent may be the same object as keyEvent.
1196 if (!android_view_KeyEvent_toNative(env, fallbackKeyEventObj,
1197 outFallbackKeyEvent)) {
1198 result = true;
1199 }
1200 android_view_KeyEvent_recycle(env, fallbackKeyEventObj);
1201 env->DeleteLocalRef(fallbackKeyEventObj);
1202 }
1203 } else {
1204 ALOGE("Failed to obtain key event object for dispatchUnhandledKey.");
1205 }
1206 }
1207 return result;
1208 }
1209
pokeUserActivity(nsecs_t eventTime,int32_t eventType)1210 void NativeInputManager::pokeUserActivity(nsecs_t eventTime, int32_t eventType) {
1211 ATRACE_CALL();
1212 android_server_PowerManagerService_userActivity(eventTime, eventType);
1213 }
1214
1215
checkInjectEventsPermissionNonReentrant(int32_t injectorPid,int32_t injectorUid)1216 bool NativeInputManager::checkInjectEventsPermissionNonReentrant(
1217 int32_t injectorPid, int32_t injectorUid) {
1218 ATRACE_CALL();
1219 JNIEnv* env = jniEnv();
1220 jboolean result = env->CallBooleanMethod(mServiceObj,
1221 gServiceClassInfo.checkInjectEventsPermission, injectorPid, injectorUid);
1222 if (checkAndClearExceptionFromCallback(env, "checkInjectEventsPermission")) {
1223 result = false;
1224 }
1225 return result;
1226 }
1227
onPointerDownOutsideFocus(const sp<IBinder> & touchedToken)1228 void NativeInputManager::onPointerDownOutsideFocus(const sp<IBinder>& touchedToken) {
1229 ATRACE_CALL();
1230 JNIEnv* env = jniEnv();
1231 ScopedLocalFrame localFrame(env);
1232
1233 jobject touchedTokenObj = javaObjectForIBinder(env, touchedToken);
1234 env->CallVoidMethod(mServiceObj, gServiceClassInfo.onPointerDownOutsideFocus, touchedTokenObj);
1235 checkAndClearExceptionFromCallback(env, "onPointerDownOutsideFocus");
1236 }
1237
loadPointerIcon(SpriteIcon * icon,int32_t displayId)1238 void NativeInputManager::loadPointerIcon(SpriteIcon* icon, int32_t displayId) {
1239 ATRACE_CALL();
1240 JNIEnv* env = jniEnv();
1241
1242 ScopedLocalRef<jobject> pointerIconObj(env, env->CallObjectMethod(
1243 mServiceObj, gServiceClassInfo.getPointerIcon, displayId));
1244 if (checkAndClearExceptionFromCallback(env, "getPointerIcon")) {
1245 return;
1246 }
1247
1248 ScopedLocalRef<jobject> displayContext(env, env->CallObjectMethod(
1249 mServiceObj, gServiceClassInfo.getContextForDisplay, displayId));
1250
1251 PointerIcon pointerIcon;
1252 status_t status = android_view_PointerIcon_load(env, pointerIconObj.get(),
1253 displayContext.get(), &pointerIcon);
1254 if (!status && !pointerIcon.isNullIcon()) {
1255 *icon = SpriteIcon(pointerIcon.bitmap, pointerIcon.hotSpotX, pointerIcon.hotSpotY);
1256 } else {
1257 *icon = SpriteIcon();
1258 }
1259 }
1260
loadPointerResources(PointerResources * outResources,int32_t displayId)1261 void NativeInputManager::loadPointerResources(PointerResources* outResources, int32_t displayId) {
1262 ATRACE_CALL();
1263 JNIEnv* env = jniEnv();
1264
1265 ScopedLocalRef<jobject> displayContext(env, env->CallObjectMethod(
1266 mServiceObj, gServiceClassInfo.getContextForDisplay, displayId));
1267
1268 loadSystemIconAsSprite(env, displayContext.get(), POINTER_ICON_STYLE_SPOT_HOVER,
1269 &outResources->spotHover);
1270 loadSystemIconAsSprite(env, displayContext.get(), POINTER_ICON_STYLE_SPOT_TOUCH,
1271 &outResources->spotTouch);
1272 loadSystemIconAsSprite(env, displayContext.get(), POINTER_ICON_STYLE_SPOT_ANCHOR,
1273 &outResources->spotAnchor);
1274 }
1275
loadAdditionalMouseResources(std::map<int32_t,SpriteIcon> * outResources,std::map<int32_t,PointerAnimation> * outAnimationResources,int32_t displayId)1276 void NativeInputManager::loadAdditionalMouseResources(std::map<int32_t, SpriteIcon>* outResources,
1277 std::map<int32_t, PointerAnimation>* outAnimationResources, int32_t displayId) {
1278 ATRACE_CALL();
1279 JNIEnv* env = jniEnv();
1280
1281 ScopedLocalRef<jobject> displayContext(env, env->CallObjectMethod(
1282 mServiceObj, gServiceClassInfo.getContextForDisplay, displayId));
1283
1284 for (int iconId = POINTER_ICON_STYLE_CONTEXT_MENU; iconId <= POINTER_ICON_STYLE_GRABBING;
1285 ++iconId) {
1286 PointerIcon pointerIcon;
1287 loadSystemIconAsSpriteWithPointerIcon(
1288 env, displayContext.get(), iconId, &pointerIcon, &((*outResources)[iconId]));
1289 if (!pointerIcon.bitmapFrames.empty()) {
1290 PointerAnimation& animationData = (*outAnimationResources)[iconId];
1291 size_t numFrames = pointerIcon.bitmapFrames.size() + 1;
1292 animationData.durationPerFrame =
1293 milliseconds_to_nanoseconds(pointerIcon.durationPerFrame);
1294 animationData.animationFrames.reserve(numFrames);
1295 animationData.animationFrames.push_back(SpriteIcon(
1296 pointerIcon.bitmap, pointerIcon.hotSpotX, pointerIcon.hotSpotY));
1297 for (size_t i = 0; i < numFrames - 1; ++i) {
1298 animationData.animationFrames.push_back(SpriteIcon(
1299 pointerIcon.bitmapFrames[i], pointerIcon.hotSpotX, pointerIcon.hotSpotY));
1300 }
1301 }
1302 }
1303 loadSystemIconAsSprite(env, displayContext.get(), POINTER_ICON_STYLE_NULL,
1304 &((*outResources)[POINTER_ICON_STYLE_NULL]));
1305 }
1306
getDefaultPointerIconId()1307 int32_t NativeInputManager::getDefaultPointerIconId() {
1308 return POINTER_ICON_STYLE_ARROW;
1309 }
1310
getCustomPointerIconId()1311 int32_t NativeInputManager::getCustomPointerIconId() {
1312 return POINTER_ICON_STYLE_CUSTOM;
1313 }
1314
1315 // ----------------------------------------------------------------------------
1316
nativeInit(JNIEnv * env,jclass,jobject serviceObj,jobject contextObj,jobject messageQueueObj)1317 static jlong nativeInit(JNIEnv* env, jclass /* clazz */,
1318 jobject serviceObj, jobject contextObj, jobject messageQueueObj) {
1319 sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueObj);
1320 if (messageQueue == nullptr) {
1321 jniThrowRuntimeException(env, "MessageQueue is not initialized.");
1322 return 0;
1323 }
1324
1325 NativeInputManager* im = new NativeInputManager(contextObj, serviceObj,
1326 messageQueue->getLooper());
1327 im->incStrong(0);
1328 return reinterpret_cast<jlong>(im);
1329 }
1330
nativeStart(JNIEnv * env,jclass,jlong ptr)1331 static void nativeStart(JNIEnv* env, jclass /* clazz */, jlong ptr) {
1332 NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
1333
1334 status_t result = im->getInputManager()->start();
1335 if (result) {
1336 jniThrowRuntimeException(env, "Input manager could not be started.");
1337 }
1338 }
1339
nativeSetDisplayViewports(JNIEnv * env,jclass,jlong ptr,jobjectArray viewportObjArray)1340 static void nativeSetDisplayViewports(JNIEnv* env, jclass /* clazz */, jlong ptr,
1341 jobjectArray viewportObjArray) {
1342 NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
1343 im->setDisplayViewports(env, viewportObjArray);
1344 }
1345
nativeGetScanCodeState(JNIEnv *,jclass,jlong ptr,jint deviceId,jint sourceMask,jint scanCode)1346 static jint nativeGetScanCodeState(JNIEnv* /* env */, jclass /* clazz */,
1347 jlong ptr, jint deviceId, jint sourceMask, jint scanCode) {
1348 NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
1349
1350 return (jint) im->getInputManager()->getReader()->getScanCodeState(
1351 deviceId, uint32_t(sourceMask), scanCode);
1352 }
1353
nativeGetKeyCodeState(JNIEnv *,jclass,jlong ptr,jint deviceId,jint sourceMask,jint keyCode)1354 static jint nativeGetKeyCodeState(JNIEnv* /* env */, jclass /* clazz */,
1355 jlong ptr, jint deviceId, jint sourceMask, jint keyCode) {
1356 NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
1357
1358 return (jint) im->getInputManager()->getReader()->getKeyCodeState(
1359 deviceId, uint32_t(sourceMask), keyCode);
1360 }
1361
nativeGetSwitchState(JNIEnv *,jclass,jlong ptr,jint deviceId,jint sourceMask,jint sw)1362 static jint nativeGetSwitchState(JNIEnv* /* env */, jclass /* clazz */,
1363 jlong ptr, jint deviceId, jint sourceMask, jint sw) {
1364 NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
1365
1366 return (jint) im->getInputManager()->getReader()->getSwitchState(
1367 deviceId, uint32_t(sourceMask), sw);
1368 }
1369
nativeHasKeys(JNIEnv * env,jclass,jlong ptr,jint deviceId,jint sourceMask,jintArray keyCodes,jbooleanArray outFlags)1370 static jboolean nativeHasKeys(JNIEnv* env, jclass /* clazz */,
1371 jlong ptr, jint deviceId, jint sourceMask, jintArray keyCodes, jbooleanArray outFlags) {
1372 NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
1373
1374 int32_t* codes = env->GetIntArrayElements(keyCodes, nullptr);
1375 uint8_t* flags = env->GetBooleanArrayElements(outFlags, nullptr);
1376 jsize numCodes = env->GetArrayLength(keyCodes);
1377 jboolean result;
1378 if (numCodes == env->GetArrayLength(keyCodes)) {
1379 if (im->getInputManager()->getReader()->hasKeys(
1380 deviceId, uint32_t(sourceMask), numCodes, codes, flags)) {
1381 result = JNI_TRUE;
1382 } else {
1383 result = JNI_FALSE;
1384 }
1385 } else {
1386 result = JNI_FALSE;
1387 }
1388
1389 env->ReleaseBooleanArrayElements(outFlags, flags, 0);
1390 env->ReleaseIntArrayElements(keyCodes, codes, 0);
1391 return result;
1392 }
1393
throwInputChannelNotInitialized(JNIEnv * env)1394 static void throwInputChannelNotInitialized(JNIEnv* env) {
1395 jniThrowException(env, "java/lang/IllegalStateException",
1396 "inputChannel is not initialized");
1397 }
1398
handleInputChannelDisposed(JNIEnv * env,jobject,const sp<InputChannel> & inputChannel,void * data)1399 static void handleInputChannelDisposed(JNIEnv* env,
1400 jobject /* inputChannelObj */, const sp<InputChannel>& inputChannel, void* data) {
1401 NativeInputManager* im = static_cast<NativeInputManager*>(data);
1402
1403 ALOGW("Input channel object '%s' was disposed without first being unregistered with "
1404 "the input manager!", inputChannel->getName().c_str());
1405 im->unregisterInputChannel(env, inputChannel);
1406 }
1407
nativeRegisterInputChannel(JNIEnv * env,jclass,jlong ptr,jobject inputChannelObj,jint displayId)1408 static void nativeRegisterInputChannel(JNIEnv* env, jclass /* clazz */,
1409 jlong ptr, jobject inputChannelObj, jint displayId) {
1410 NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
1411
1412 sp<InputChannel> inputChannel = android_view_InputChannel_getInputChannel(env,
1413 inputChannelObj);
1414 if (inputChannel == nullptr) {
1415 throwInputChannelNotInitialized(env);
1416 return;
1417 }
1418
1419 status_t status = im->registerInputChannel(env, inputChannel, displayId);
1420
1421 if (status) {
1422 std::string message;
1423 message += StringPrintf("Failed to register input channel. status=%d", status);
1424 jniThrowRuntimeException(env, message.c_str());
1425 return;
1426 }
1427
1428 android_view_InputChannel_setDisposeCallback(env, inputChannelObj,
1429 handleInputChannelDisposed, im);
1430 }
1431
nativeRegisterInputMonitor(JNIEnv * env,jclass,jlong ptr,jobject inputChannelObj,jint displayId,jboolean isGestureMonitor)1432 static void nativeRegisterInputMonitor(JNIEnv* env, jclass /* clazz */,
1433 jlong ptr, jobject inputChannelObj, jint displayId, jboolean isGestureMonitor) {
1434 NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
1435
1436 sp<InputChannel> inputChannel = android_view_InputChannel_getInputChannel(env,
1437 inputChannelObj);
1438 if (inputChannel == nullptr) {
1439 throwInputChannelNotInitialized(env);
1440 return;
1441 }
1442
1443 if (displayId == ADISPLAY_ID_NONE) {
1444 std::string message = "InputChannel used as a monitor must be associated with a display";
1445 jniThrowRuntimeException(env, message.c_str());
1446 return;
1447 }
1448
1449 status_t status = im->registerInputMonitor(env, inputChannel, displayId, isGestureMonitor);
1450
1451 if (status) {
1452 std::string message = StringPrintf("Failed to register input channel. status=%d", status);
1453 jniThrowRuntimeException(env, message.c_str());
1454 return;
1455 }
1456 }
1457
nativeUnregisterInputChannel(JNIEnv * env,jclass,jlong ptr,jobject inputChannelObj)1458 static void nativeUnregisterInputChannel(JNIEnv* env, jclass /* clazz */,
1459 jlong ptr, jobject inputChannelObj) {
1460 NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
1461
1462 sp<InputChannel> inputChannel = android_view_InputChannel_getInputChannel(env,
1463 inputChannelObj);
1464 if (inputChannel == nullptr) {
1465 throwInputChannelNotInitialized(env);
1466 return;
1467 }
1468
1469 android_view_InputChannel_setDisposeCallback(env, inputChannelObj, nullptr, nullptr);
1470
1471 status_t status = im->unregisterInputChannel(env, inputChannel);
1472 if (status && status != BAD_VALUE) { // ignore already unregistered channel
1473 std::string message;
1474 message += StringPrintf("Failed to unregister input channel. status=%d", status);
1475 jniThrowRuntimeException(env, message.c_str());
1476 }
1477 }
1478
nativePilferPointers(JNIEnv * env,jclass,jlong ptr,jobject tokenObj)1479 static void nativePilferPointers(JNIEnv* env, jclass /* clazz */, jlong ptr, jobject tokenObj) {
1480 NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
1481 sp<IBinder> token = ibinderForJavaObject(env, tokenObj);
1482 im->pilferPointers(token);
1483 }
1484
1485
nativeSetInputFilterEnabled(JNIEnv *,jclass,jlong ptr,jboolean enabled)1486 static void nativeSetInputFilterEnabled(JNIEnv* /* env */, jclass /* clazz */,
1487 jlong ptr, jboolean enabled) {
1488 NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
1489
1490 im->getInputManager()->getDispatcher()->setInputFilterEnabled(enabled);
1491 }
1492
nativeInjectInputEvent(JNIEnv * env,jclass,jlong ptr,jobject inputEventObj,jint injectorPid,jint injectorUid,jint syncMode,jint timeoutMillis,jint policyFlags)1493 static jint nativeInjectInputEvent(JNIEnv* env, jclass /* clazz */,
1494 jlong ptr, jobject inputEventObj, jint injectorPid, jint injectorUid,
1495 jint syncMode, jint timeoutMillis, jint policyFlags) {
1496 NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
1497
1498 if (env->IsInstanceOf(inputEventObj, gKeyEventClassInfo.clazz)) {
1499 KeyEvent keyEvent;
1500 status_t status = android_view_KeyEvent_toNative(env, inputEventObj, & keyEvent);
1501 if (status) {
1502 jniThrowRuntimeException(env, "Could not read contents of KeyEvent object.");
1503 return INPUT_EVENT_INJECTION_FAILED;
1504 }
1505
1506 return (jint) im->getInputManager()->getDispatcher()->injectInputEvent(
1507 & keyEvent, injectorPid, injectorUid, syncMode, timeoutMillis,
1508 uint32_t(policyFlags));
1509 } else if (env->IsInstanceOf(inputEventObj, gMotionEventClassInfo.clazz)) {
1510 const MotionEvent* motionEvent = android_view_MotionEvent_getNativePtr(env, inputEventObj);
1511 if (!motionEvent) {
1512 jniThrowRuntimeException(env, "Could not read contents of MotionEvent object.");
1513 return INPUT_EVENT_INJECTION_FAILED;
1514 }
1515
1516 return (jint) im->getInputManager()->getDispatcher()->injectInputEvent(
1517 motionEvent, injectorPid, injectorUid, syncMode, timeoutMillis,
1518 uint32_t(policyFlags));
1519 } else {
1520 jniThrowRuntimeException(env, "Invalid input event type.");
1521 return INPUT_EVENT_INJECTION_FAILED;
1522 }
1523 }
1524
nativeToggleCapsLock(JNIEnv * env,jclass,jlong ptr,jint deviceId)1525 static void nativeToggleCapsLock(JNIEnv* env, jclass /* clazz */,
1526 jlong ptr, jint deviceId) {
1527 NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
1528
1529 im->getInputManager()->getReader()->toggleCapsLockState(deviceId);
1530 }
1531
nativeSetInputWindows(JNIEnv * env,jclass,jlong ptr,jobjectArray windowHandleObjArray,jint displayId)1532 static void nativeSetInputWindows(JNIEnv* env, jclass /* clazz */,
1533 jlong ptr, jobjectArray windowHandleObjArray, jint displayId) {
1534 NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
1535
1536 im->setInputWindows(env, windowHandleObjArray, displayId);
1537 }
1538
nativeSetFocusedApplication(JNIEnv * env,jclass,jlong ptr,jint displayId,jobject applicationHandleObj)1539 static void nativeSetFocusedApplication(JNIEnv* env, jclass /* clazz */,
1540 jlong ptr, jint displayId, jobject applicationHandleObj) {
1541 NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
1542
1543 im->setFocusedApplication(env, displayId, applicationHandleObj);
1544 }
1545
nativeSetFocusedDisplay(JNIEnv * env,jclass,jlong ptr,jint displayId)1546 static void nativeSetFocusedDisplay(JNIEnv* env, jclass /* clazz */,
1547 jlong ptr, jint displayId) {
1548 NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
1549
1550 im->setFocusedDisplay(env, displayId);
1551 }
1552
nativeSetPointerCapture(JNIEnv * env,jclass,jlong ptr,jboolean enabled)1553 static void nativeSetPointerCapture(JNIEnv* env, jclass /* clazz */, jlong ptr,
1554 jboolean enabled) {
1555 NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
1556
1557 im->setPointerCapture(enabled);
1558 }
1559
nativeSetInputDispatchMode(JNIEnv *,jclass,jlong ptr,jboolean enabled,jboolean frozen)1560 static void nativeSetInputDispatchMode(JNIEnv* /* env */,
1561 jclass /* clazz */, jlong ptr, jboolean enabled, jboolean frozen) {
1562 NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
1563
1564 im->setInputDispatchMode(enabled, frozen);
1565 }
1566
nativeSetSystemUiVisibility(JNIEnv *,jclass,jlong ptr,jint visibility)1567 static void nativeSetSystemUiVisibility(JNIEnv* /* env */,
1568 jclass /* clazz */, jlong ptr, jint visibility) {
1569 NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
1570
1571 im->setSystemUiVisibility(visibility);
1572 }
1573
nativeSetPointerSpeed(JNIEnv *,jclass,jlong ptr,jint speed)1574 static void nativeSetPointerSpeed(JNIEnv* /* env */,
1575 jclass /* clazz */, jlong ptr, jint speed) {
1576 NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
1577
1578 im->setPointerSpeed(speed);
1579 }
1580
nativeSetShowTouches(JNIEnv *,jclass,jlong ptr,jboolean enabled)1581 static void nativeSetShowTouches(JNIEnv* /* env */,
1582 jclass /* clazz */, jlong ptr, jboolean enabled) {
1583 NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
1584
1585 im->setShowTouches(enabled);
1586 }
1587
nativeSetInteractive(JNIEnv * env,jclass clazz,jlong ptr,jboolean interactive)1588 static void nativeSetInteractive(JNIEnv* env,
1589 jclass clazz, jlong ptr, jboolean interactive) {
1590 NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
1591
1592 im->setInteractive(interactive);
1593 }
1594
nativeReloadCalibration(JNIEnv * env,jclass clazz,jlong ptr)1595 static void nativeReloadCalibration(JNIEnv* env, jclass clazz, jlong ptr) {
1596 NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
1597
1598 im->reloadCalibration();
1599 }
1600
nativeVibrate(JNIEnv * env,jclass,jlong ptr,jint deviceId,jlongArray patternObj,jint repeat,jint token)1601 static void nativeVibrate(JNIEnv* env,
1602 jclass /* clazz */, jlong ptr, jint deviceId, jlongArray patternObj,
1603 jint repeat, jint token) {
1604 NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
1605
1606 size_t patternSize = env->GetArrayLength(patternObj);
1607 if (patternSize > MAX_VIBRATE_PATTERN_SIZE) {
1608 ALOGI("Skipped requested vibration because the pattern size is %zu "
1609 "which is more than the maximum supported size of %d.",
1610 patternSize, MAX_VIBRATE_PATTERN_SIZE);
1611 return; // limit to reasonable size
1612 }
1613
1614 jlong* patternMillis = static_cast<jlong*>(env->GetPrimitiveArrayCritical(
1615 patternObj, nullptr));
1616 nsecs_t pattern[patternSize];
1617 for (size_t i = 0; i < patternSize; i++) {
1618 pattern[i] = max(jlong(0), min(patternMillis[i],
1619 (jlong)(MAX_VIBRATE_PATTERN_DELAY_NSECS / 1000000LL))) * 1000000LL;
1620 }
1621 env->ReleasePrimitiveArrayCritical(patternObj, patternMillis, JNI_ABORT);
1622
1623 im->getInputManager()->getReader()->vibrate(deviceId, pattern, patternSize, repeat, token);
1624 }
1625
nativeCancelVibrate(JNIEnv *,jclass,jlong ptr,jint deviceId,jint token)1626 static void nativeCancelVibrate(JNIEnv* /* env */,
1627 jclass /* clazz */, jlong ptr, jint deviceId, jint token) {
1628 NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
1629
1630 im->getInputManager()->getReader()->cancelVibrate(deviceId, token);
1631 }
1632
nativeReloadKeyboardLayouts(JNIEnv *,jclass,jlong ptr)1633 static void nativeReloadKeyboardLayouts(JNIEnv* /* env */,
1634 jclass /* clazz */, jlong ptr) {
1635 NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
1636
1637 im->getInputManager()->getReader()->requestRefreshConfiguration(
1638 InputReaderConfiguration::CHANGE_KEYBOARD_LAYOUTS);
1639 }
1640
nativeReloadDeviceAliases(JNIEnv *,jclass,jlong ptr)1641 static void nativeReloadDeviceAliases(JNIEnv* /* env */,
1642 jclass /* clazz */, jlong ptr) {
1643 NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
1644
1645 im->getInputManager()->getReader()->requestRefreshConfiguration(
1646 InputReaderConfiguration::CHANGE_DEVICE_ALIAS);
1647 }
1648
nativeDump(JNIEnv * env,jclass,jlong ptr)1649 static jstring nativeDump(JNIEnv* env, jclass /* clazz */, jlong ptr) {
1650 NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
1651
1652 std::string dump;
1653 im->dump(dump);
1654 return env->NewStringUTF(dump.c_str());
1655 }
1656
nativeMonitor(JNIEnv *,jclass,jlong ptr)1657 static void nativeMonitor(JNIEnv* /* env */, jclass /* clazz */, jlong ptr) {
1658 NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
1659
1660 im->getInputManager()->getReader()->monitor();
1661 im->getInputManager()->getDispatcher()->monitor();
1662 }
1663
nativeIsInputDeviceEnabled(JNIEnv * env,jclass,jlong ptr,jint deviceId)1664 static jboolean nativeIsInputDeviceEnabled(JNIEnv* env /* env */,
1665 jclass /* clazz */, jlong ptr, jint deviceId) {
1666 NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
1667
1668 return im->getInputManager()->getReader()->isInputDeviceEnabled(deviceId);
1669 }
1670
nativeEnableInputDevice(JNIEnv *,jclass,jlong ptr,jint deviceId)1671 static void nativeEnableInputDevice(JNIEnv* /* env */,
1672 jclass /* clazz */, jlong ptr, jint deviceId) {
1673 NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
1674
1675 im->setInputDeviceEnabled(deviceId, true);
1676 }
1677
nativeDisableInputDevice(JNIEnv *,jclass,jlong ptr,jint deviceId)1678 static void nativeDisableInputDevice(JNIEnv* /* env */,
1679 jclass /* clazz */, jlong ptr, jint deviceId) {
1680 NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
1681
1682 im->setInputDeviceEnabled(deviceId, false);
1683 }
1684
nativeSetPointerIconType(JNIEnv *,jclass,jlong ptr,jint iconId)1685 static void nativeSetPointerIconType(JNIEnv* /* env */, jclass /* clazz */, jlong ptr, jint iconId) {
1686 NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
1687
1688 im->setPointerIconType(iconId);
1689 }
1690
nativeReloadPointerIcons(JNIEnv *,jclass,jlong ptr)1691 static void nativeReloadPointerIcons(JNIEnv* /* env */, jclass /* clazz */, jlong ptr) {
1692 NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
1693
1694 im->reloadPointerIcons();
1695 }
1696
nativeSetCustomPointerIcon(JNIEnv * env,jclass,jlong ptr,jobject iconObj)1697 static void nativeSetCustomPointerIcon(JNIEnv* env, jclass /* clazz */,
1698 jlong ptr, jobject iconObj) {
1699 NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
1700
1701 PointerIcon pointerIcon;
1702 status_t result = android_view_PointerIcon_getLoadedIcon(env, iconObj, &pointerIcon);
1703 if (result) {
1704 jniThrowRuntimeException(env, "Failed to load custom pointer icon.");
1705 return;
1706 }
1707
1708 SpriteIcon spriteIcon;
1709 SkImageInfo spriteInfo = pointerIcon.bitmap.info().makeColorType(kN32_SkColorType);
1710 if (spriteIcon.bitmap.tryAllocPixels(spriteInfo)) {
1711 pointerIcon.bitmap.readPixels(spriteInfo, spriteIcon.bitmap.getPixels(),
1712 spriteIcon.bitmap.rowBytes(), 0, 0);
1713 }
1714 spriteIcon.hotSpotX = pointerIcon.hotSpotX;
1715 spriteIcon.hotSpotY = pointerIcon.hotSpotY;
1716 im->setCustomPointerIcon(spriteIcon);
1717 }
1718
nativeCanDispatchToDisplay(JNIEnv * env,jclass,jlong ptr,jint deviceId,jint displayId)1719 static jboolean nativeCanDispatchToDisplay(JNIEnv* env, jclass /* clazz */, jlong ptr,
1720 jint deviceId, jint displayId) {
1721
1722 NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
1723 return im->getInputManager()->getReader()->canDispatchToDisplay(deviceId, displayId);
1724 }
1725
1726 // ----------------------------------------------------------------------------
1727
1728 static const JNINativeMethod gInputManagerMethods[] = {
1729 /* name, signature, funcPtr */
1730 { "nativeInit",
1731 "(Lcom/android/server/input/InputManagerService;Landroid/content/Context;Landroid/os/MessageQueue;)J",
1732 (void*) nativeInit },
1733 { "nativeStart", "(J)V",
1734 (void*) nativeStart },
1735 { "nativeSetDisplayViewports", "(J[Landroid/hardware/display/DisplayViewport;)V",
1736 (void*) nativeSetDisplayViewports },
1737 { "nativeGetScanCodeState", "(JIII)I",
1738 (void*) nativeGetScanCodeState },
1739 { "nativeGetKeyCodeState", "(JIII)I",
1740 (void*) nativeGetKeyCodeState },
1741 { "nativeGetSwitchState", "(JIII)I",
1742 (void*) nativeGetSwitchState },
1743 { "nativeHasKeys", "(JII[I[Z)Z",
1744 (void*) nativeHasKeys },
1745 { "nativeRegisterInputChannel",
1746 "(JLandroid/view/InputChannel;I)V",
1747 (void*) nativeRegisterInputChannel },
1748 { "nativeRegisterInputMonitor",
1749 "(JLandroid/view/InputChannel;IZ)V",
1750 (void*) nativeRegisterInputMonitor},
1751 { "nativeUnregisterInputChannel", "(JLandroid/view/InputChannel;)V",
1752 (void*) nativeUnregisterInputChannel },
1753 { "nativePilferPointers", "(JLandroid/os/IBinder;)V",
1754 (void*) nativePilferPointers },
1755 { "nativeSetInputFilterEnabled", "(JZ)V",
1756 (void*) nativeSetInputFilterEnabled },
1757 { "nativeInjectInputEvent", "(JLandroid/view/InputEvent;IIIII)I",
1758 (void*) nativeInjectInputEvent },
1759 { "nativeToggleCapsLock", "(JI)V",
1760 (void*) nativeToggleCapsLock },
1761 { "nativeSetInputWindows", "(J[Landroid/view/InputWindowHandle;I)V",
1762 (void*) nativeSetInputWindows },
1763 { "nativeSetFocusedApplication", "(JILandroid/view/InputApplicationHandle;)V",
1764 (void*) nativeSetFocusedApplication },
1765 { "nativeSetFocusedDisplay", "(JI)V",
1766 (void*) nativeSetFocusedDisplay },
1767 { "nativeSetPointerCapture", "(JZ)V",
1768 (void*) nativeSetPointerCapture },
1769 { "nativeSetInputDispatchMode", "(JZZ)V",
1770 (void*) nativeSetInputDispatchMode },
1771 { "nativeSetSystemUiVisibility", "(JI)V",
1772 (void*) nativeSetSystemUiVisibility },
1773 { "nativeSetPointerSpeed", "(JI)V",
1774 (void*) nativeSetPointerSpeed },
1775 { "nativeSetShowTouches", "(JZ)V",
1776 (void*) nativeSetShowTouches },
1777 { "nativeSetInteractive", "(JZ)V",
1778 (void*) nativeSetInteractive },
1779 { "nativeReloadCalibration", "(J)V",
1780 (void*) nativeReloadCalibration },
1781 { "nativeVibrate", "(JI[JII)V",
1782 (void*) nativeVibrate },
1783 { "nativeCancelVibrate", "(JII)V",
1784 (void*) nativeCancelVibrate },
1785 { "nativeReloadKeyboardLayouts", "(J)V",
1786 (void*) nativeReloadKeyboardLayouts },
1787 { "nativeReloadDeviceAliases", "(J)V",
1788 (void*) nativeReloadDeviceAliases },
1789 { "nativeDump", "(J)Ljava/lang/String;",
1790 (void*) nativeDump },
1791 { "nativeMonitor", "(J)V",
1792 (void*) nativeMonitor },
1793 { "nativeIsInputDeviceEnabled", "(JI)Z",
1794 (void*) nativeIsInputDeviceEnabled },
1795 { "nativeEnableInputDevice", "(JI)V",
1796 (void*) nativeEnableInputDevice },
1797 { "nativeDisableInputDevice", "(JI)V",
1798 (void*) nativeDisableInputDevice },
1799 { "nativeSetPointerIconType", "(JI)V",
1800 (void*) nativeSetPointerIconType },
1801 { "nativeReloadPointerIcons", "(J)V",
1802 (void*) nativeReloadPointerIcons },
1803 { "nativeSetCustomPointerIcon", "(JLandroid/view/PointerIcon;)V",
1804 (void*) nativeSetCustomPointerIcon },
1805 { "nativeCanDispatchToDisplay", "(JII)Z",
1806 (void*) nativeCanDispatchToDisplay },
1807 };
1808
1809 #define FIND_CLASS(var, className) \
1810 var = env->FindClass(className); \
1811 LOG_FATAL_IF(! (var), "Unable to find class " className);
1812
1813 #define GET_METHOD_ID(var, clazz, methodName, methodDescriptor) \
1814 var = env->GetMethodID(clazz, methodName, methodDescriptor); \
1815 LOG_FATAL_IF(! (var), "Unable to find method " methodName);
1816
1817 #define GET_STATIC_METHOD_ID(var, clazz, methodName, methodDescriptor) \
1818 var = env->GetStaticMethodID(clazz, methodName, methodDescriptor); \
1819 LOG_FATAL_IF(! (var), "Unable to find static method " methodName);
1820
1821 #define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \
1822 var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \
1823 LOG_FATAL_IF(! (var), "Unable to find field " fieldName);
1824
register_android_server_InputManager(JNIEnv * env)1825 int register_android_server_InputManager(JNIEnv* env) {
1826 int res = jniRegisterNativeMethods(env, "com/android/server/input/InputManagerService",
1827 gInputManagerMethods, NELEM(gInputManagerMethods));
1828 (void) res; // Faked use when LOG_NDEBUG.
1829 LOG_FATAL_IF(res < 0, "Unable to register native methods.");
1830
1831 // Callbacks
1832
1833 jclass clazz;
1834 FIND_CLASS(clazz, "com/android/server/input/InputManagerService");
1835 gServiceClassInfo.clazz = reinterpret_cast<jclass>(env->NewGlobalRef(clazz));
1836
1837 GET_METHOD_ID(gServiceClassInfo.notifyConfigurationChanged, clazz,
1838 "notifyConfigurationChanged", "(J)V");
1839
1840 GET_METHOD_ID(gServiceClassInfo.notifyInputDevicesChanged, clazz,
1841 "notifyInputDevicesChanged", "([Landroid/view/InputDevice;)V");
1842
1843 GET_METHOD_ID(gServiceClassInfo.notifySwitch, clazz,
1844 "notifySwitch", "(JII)V");
1845
1846 GET_METHOD_ID(gServiceClassInfo.notifyInputChannelBroken, clazz,
1847 "notifyInputChannelBroken", "(Landroid/os/IBinder;)V");
1848
1849 GET_METHOD_ID(gServiceClassInfo.notifyFocusChanged, clazz,
1850 "notifyFocusChanged", "(Landroid/os/IBinder;Landroid/os/IBinder;)V");
1851
1852 GET_METHOD_ID(gServiceClassInfo.notifyANR, clazz,
1853 "notifyANR",
1854 "(Landroid/os/IBinder;Ljava/lang/String;)J");
1855
1856 GET_METHOD_ID(gServiceClassInfo.filterInputEvent, clazz,
1857 "filterInputEvent", "(Landroid/view/InputEvent;I)Z");
1858
1859 GET_METHOD_ID(gServiceClassInfo.interceptKeyBeforeQueueing, clazz,
1860 "interceptKeyBeforeQueueing", "(Landroid/view/KeyEvent;I)I");
1861
1862 GET_METHOD_ID(gServiceClassInfo.interceptMotionBeforeQueueingNonInteractive, clazz,
1863 "interceptMotionBeforeQueueingNonInteractive", "(IJI)I");
1864
1865 GET_METHOD_ID(gServiceClassInfo.interceptKeyBeforeDispatching, clazz,
1866 "interceptKeyBeforeDispatching",
1867 "(Landroid/os/IBinder;Landroid/view/KeyEvent;I)J");
1868
1869 GET_METHOD_ID(gServiceClassInfo.dispatchUnhandledKey, clazz,
1870 "dispatchUnhandledKey",
1871 "(Landroid/os/IBinder;Landroid/view/KeyEvent;I)Landroid/view/KeyEvent;");
1872
1873 GET_METHOD_ID(gServiceClassInfo.checkInjectEventsPermission, clazz,
1874 "checkInjectEventsPermission", "(II)Z");
1875
1876 GET_METHOD_ID(gServiceClassInfo.onPointerDownOutsideFocus, clazz,
1877 "onPointerDownOutsideFocus", "(Landroid/os/IBinder;)V");
1878
1879 GET_METHOD_ID(gServiceClassInfo.getVirtualKeyQuietTimeMillis, clazz,
1880 "getVirtualKeyQuietTimeMillis", "()I");
1881
1882 GET_STATIC_METHOD_ID(gServiceClassInfo.getExcludedDeviceNames, clazz,
1883 "getExcludedDeviceNames", "()[Ljava/lang/String;");
1884
1885 GET_STATIC_METHOD_ID(gServiceClassInfo.getInputPortAssociations, clazz,
1886 "getInputPortAssociations", "()[Ljava/lang/String;");
1887
1888 GET_METHOD_ID(gServiceClassInfo.getKeyRepeatTimeout, clazz,
1889 "getKeyRepeatTimeout", "()I");
1890
1891 GET_METHOD_ID(gServiceClassInfo.getKeyRepeatDelay, clazz,
1892 "getKeyRepeatDelay", "()I");
1893
1894 GET_METHOD_ID(gServiceClassInfo.getHoverTapTimeout, clazz,
1895 "getHoverTapTimeout", "()I");
1896
1897 GET_METHOD_ID(gServiceClassInfo.getHoverTapSlop, clazz,
1898 "getHoverTapSlop", "()I");
1899
1900 GET_METHOD_ID(gServiceClassInfo.getDoubleTapTimeout, clazz,
1901 "getDoubleTapTimeout", "()I");
1902
1903 GET_METHOD_ID(gServiceClassInfo.getLongPressTimeout, clazz,
1904 "getLongPressTimeout", "()I");
1905
1906 GET_METHOD_ID(gServiceClassInfo.getPointerLayer, clazz,
1907 "getPointerLayer", "()I");
1908
1909 GET_METHOD_ID(gServiceClassInfo.getPointerIcon, clazz,
1910 "getPointerIcon", "(I)Landroid/view/PointerIcon;");
1911
1912 GET_METHOD_ID(gServiceClassInfo.getPointerDisplayId, clazz,
1913 "getPointerDisplayId", "()I");
1914
1915 GET_METHOD_ID(gServiceClassInfo.getKeyboardLayoutOverlay, clazz,
1916 "getKeyboardLayoutOverlay",
1917 "(Landroid/hardware/input/InputDeviceIdentifier;)[Ljava/lang/String;");
1918
1919 GET_METHOD_ID(gServiceClassInfo.getDeviceAlias, clazz,
1920 "getDeviceAlias", "(Ljava/lang/String;)Ljava/lang/String;");
1921
1922 GET_METHOD_ID(gServiceClassInfo.getTouchCalibrationForInputDevice, clazz,
1923 "getTouchCalibrationForInputDevice",
1924 "(Ljava/lang/String;I)Landroid/hardware/input/TouchCalibration;");
1925
1926 GET_METHOD_ID(gServiceClassInfo.getContextForDisplay, clazz,
1927 "getContextForDisplay",
1928 "(I)Landroid/content/Context;")
1929
1930 // InputDevice
1931
1932 FIND_CLASS(gInputDeviceClassInfo.clazz, "android/view/InputDevice");
1933 gInputDeviceClassInfo.clazz = jclass(env->NewGlobalRef(gInputDeviceClassInfo.clazz));
1934
1935 // KeyEvent
1936
1937 FIND_CLASS(gKeyEventClassInfo.clazz, "android/view/KeyEvent");
1938 gKeyEventClassInfo.clazz = jclass(env->NewGlobalRef(gKeyEventClassInfo.clazz));
1939
1940 // MotionEvent
1941
1942 FIND_CLASS(gMotionEventClassInfo.clazz, "android/view/MotionEvent");
1943 gMotionEventClassInfo.clazz = jclass(env->NewGlobalRef(gMotionEventClassInfo.clazz));
1944
1945 // InputDeviceIdentifier
1946
1947 FIND_CLASS(gInputDeviceIdentifierInfo.clazz, "android/hardware/input/InputDeviceIdentifier");
1948 gInputDeviceIdentifierInfo.clazz = jclass(env->NewGlobalRef(gInputDeviceIdentifierInfo.clazz));
1949 GET_METHOD_ID(gInputDeviceIdentifierInfo.constructor, gInputDeviceIdentifierInfo.clazz,
1950 "<init>", "(Ljava/lang/String;II)V");
1951
1952 // TouchCalibration
1953
1954 FIND_CLASS(gTouchCalibrationClassInfo.clazz, "android/hardware/input/TouchCalibration");
1955 gTouchCalibrationClassInfo.clazz = jclass(env->NewGlobalRef(gTouchCalibrationClassInfo.clazz));
1956
1957 GET_METHOD_ID(gTouchCalibrationClassInfo.getAffineTransform, gTouchCalibrationClassInfo.clazz,
1958 "getAffineTransform", "()[F");
1959
1960 return 0;
1961 }
1962
1963 } /* namespace android */
1964