blob: 6f52f24678ff5c9361bb082c3152efa9defc68c1 [file] [log] [blame]
Jeff Brown46b9ac02010-04-22 18:58:52 -07001/*
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
Jeff Brown9c3cda02010-06-15 01:31:58 -070019//#define LOG_NDEBUG 0
20
21// Log debug messages about InputReaderPolicy
Jeff Brown349703e2010-06-22 01:27:15 -070022#define DEBUG_INPUT_READER_POLICY 0
Jeff Brown9c3cda02010-06-15 01:31:58 -070023
24// Log debug messages about InputDispatcherPolicy
Jeff Brown349703e2010-06-22 01:27:15 -070025#define DEBUG_INPUT_DISPATCHER_POLICY 0
Jeff Brown9c3cda02010-06-15 01:31:58 -070026
Jeff Brown46b9ac02010-04-22 18:58:52 -070027#include "JNIHelp.h"
28#include "jni.h"
Jeff Brown349703e2010-06-22 01:27:15 -070029#include <limits.h>
Jeff Brown46b9ac02010-04-22 18:58:52 -070030#include <android_runtime/AndroidRuntime.h>
Jeff Brown9c3cda02010-06-15 01:31:58 -070031#include <ui/InputReader.h>
32#include <ui/InputDispatcher.h>
Jeff Brown46b9ac02010-04-22 18:58:52 -070033#include <ui/InputManager.h>
34#include <ui/InputTransport.h>
35#include <utils/Log.h>
36#include <utils/threads.h>
37#include "../../core/jni/android_view_KeyEvent.h"
38#include "../../core/jni/android_view_MotionEvent.h"
39#include "../../core/jni/android_view_InputChannel.h"
Jeff Brown00fa7bd2010-07-02 15:37:36 -070040#include "com_android_server_PowerManagerService.h"
Jeff Brown46b9ac02010-04-22 18:58:52 -070041
42namespace android {
43
Jeff Brown9c3cda02010-06-15 01:31:58 -070044// ----------------------------------------------------------------------------
Jeff Brown46b9ac02010-04-22 18:58:52 -070045
46static struct {
47 jclass clazz;
48
Jeff Brown46b9ac02010-04-22 18:58:52 -070049 jmethodID notifyConfigurationChanged;
50 jmethodID notifyLidSwitchChanged;
Jeff Brown7fbdc842010-06-17 20:52:56 -070051 jmethodID notifyInputChannelBroken;
Jeff Brown349703e2010-06-22 01:27:15 -070052 jmethodID notifyANR;
Jeff Brown00fa7bd2010-07-02 15:37:36 -070053 jmethodID virtualKeyDownFeedback;
Jeff Brown349703e2010-06-22 01:27:15 -070054 jmethodID interceptKeyBeforeQueueing;
55 jmethodID interceptKeyBeforeDispatching;
56 jmethodID checkInjectEventsPermission;
Jeff Brown46b9ac02010-04-22 18:58:52 -070057 jmethodID filterTouchEvents;
58 jmethodID filterJumpyTouchEvents;
59 jmethodID getVirtualKeyDefinitions;
Jeff Brown8d608662010-08-30 03:02:23 -070060 jmethodID getInputDeviceCalibration;
Jeff Brown46b9ac02010-04-22 18:58:52 -070061 jmethodID getExcludedDeviceNames;
Jeff Brownae9fc032010-08-18 15:51:08 -070062 jmethodID getMaxEventsPerSecond;
Jeff Brown46b9ac02010-04-22 18:58:52 -070063} gCallbacksClassInfo;
64
65static struct {
66 jclass clazz;
67
68 jfieldID scanCode;
69 jfieldID centerX;
70 jfieldID centerY;
71 jfieldID width;
72 jfieldID height;
73} gVirtualKeyDefinitionClassInfo;
74
Jeff Brown7fbdc842010-06-17 20:52:56 -070075static struct {
76 jclass clazz;
77
Jeff Brown8d608662010-08-30 03:02:23 -070078 jfieldID keys;
79 jfieldID values;
80} gInputDeviceCalibrationClassInfo;
81
82static struct {
83 jclass clazz;
84
Jeff Brown349703e2010-06-22 01:27:15 -070085 jfieldID inputChannel;
Jeff Brown519e0242010-09-15 15:18:56 -070086 jfieldID name;
Jeff Brown349703e2010-06-22 01:27:15 -070087 jfieldID layoutParamsFlags;
88 jfieldID layoutParamsType;
89 jfieldID dispatchingTimeoutNanos;
90 jfieldID frameLeft;
91 jfieldID frameTop;
Jeff Brown85a31762010-09-01 17:01:00 -070092 jfieldID frameRight;
93 jfieldID frameBottom;
94 jfieldID visibleFrameLeft;
95 jfieldID visibleFrameTop;
96 jfieldID visibleFrameRight;
97 jfieldID visibleFrameBottom;
Jeff Brown349703e2010-06-22 01:27:15 -070098 jfieldID touchableAreaLeft;
99 jfieldID touchableAreaTop;
100 jfieldID touchableAreaRight;
101 jfieldID touchableAreaBottom;
102 jfieldID visible;
Jeff Brown519e0242010-09-15 15:18:56 -0700103 jfieldID canReceiveKeys;
Jeff Brown349703e2010-06-22 01:27:15 -0700104 jfieldID hasFocus;
105 jfieldID hasWallpaper;
106 jfieldID paused;
Jeff Brown519e0242010-09-15 15:18:56 -0700107 jfieldID layer;
Jeff Brown349703e2010-06-22 01:27:15 -0700108 jfieldID ownerPid;
109 jfieldID ownerUid;
110} gInputWindowClassInfo;
111
112static struct {
113 jclass clazz;
114
115 jfieldID name;
116 jfieldID dispatchingTimeoutNanos;
117 jfieldID token;
118} gInputApplicationClassInfo;
119
Jeff Brown6ec402b2010-07-28 15:48:59 -0700120static struct {
121 jclass clazz;
122} gKeyEventClassInfo;
123
124static struct {
125 jclass clazz;
126} gMotionEventClassInfo;
127
Jeff Brown8d608662010-08-30 03:02:23 -0700128static struct {
129 jclass clazz;
130
131 jmethodID ctor;
132 jmethodID addMotionRange;
133
134 jfieldID mId;
135 jfieldID mName;
136 jfieldID mSources;
137 jfieldID mKeyboardType;
138 jfieldID mMotionRanges;
139} gInputDeviceClassInfo;
140
Jeff Brown57c59372010-09-21 18:22:55 -0700141static struct {
142 jclass clazz;
143
144 jfieldID touchscreen;
145 jfieldID keyboard;
146 jfieldID navigation;
147} gConfigurationClassInfo;
148
Jeff Brown349703e2010-06-22 01:27:15 -0700149// ----------------------------------------------------------------------------
150
151static inline nsecs_t now() {
152 return systemTime(SYSTEM_TIME_MONOTONIC);
153}
Jeff Brown7fbdc842010-06-17 20:52:56 -0700154
Jeff Brown9c3cda02010-06-15 01:31:58 -0700155// ----------------------------------------------------------------------------
156
157class NativeInputManager : public virtual RefBase,
158 public virtual InputReaderPolicyInterface,
159 public virtual InputDispatcherPolicyInterface {
160protected:
161 virtual ~NativeInputManager();
162
163public:
164 NativeInputManager(jobject callbacksObj);
165
166 inline sp<InputManager> getInputManager() const { return mInputManager; }
167
Jeff Brownb88102f2010-09-08 11:49:43 -0700168 void dump(String8& dump);
Jeff Browne33348b2010-07-15 23:54:05 -0700169
Jeff Brown9c3cda02010-06-15 01:31:58 -0700170 void setDisplaySize(int32_t displayId, int32_t width, int32_t height);
171 void setDisplayOrientation(int32_t displayId, int32_t orientation);
172
Jeff Brown7fbdc842010-06-17 20:52:56 -0700173 status_t registerInputChannel(JNIEnv* env, const sp<InputChannel>& inputChannel,
Jeff Browna41ca772010-08-11 14:46:32 -0700174 jweak inputChannelObjWeak, bool monitor);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700175 status_t unregisterInputChannel(JNIEnv* env, const sp<InputChannel>& inputChannel);
176
Jeff Brown349703e2010-06-22 01:27:15 -0700177 void setInputWindows(JNIEnv* env, jobjectArray windowObjArray);
178 void setFocusedApplication(JNIEnv* env, jobject applicationObj);
179 void setInputDispatchMode(bool enabled, bool frozen);
Jeff Brown349703e2010-06-22 01:27:15 -0700180
Jeff Brown9c3cda02010-06-15 01:31:58 -0700181 /* --- InputReaderPolicyInterface implementation --- */
182
183 virtual bool getDisplayInfo(int32_t displayId,
184 int32_t* width, int32_t* height, int32_t* orientation);
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700185 virtual void virtualKeyDownFeedback();
Jeff Brown9c3cda02010-06-15 01:31:58 -0700186 virtual int32_t interceptKey(nsecs_t when, int32_t deviceId,
Jeff Brown6d0fec22010-07-23 21:28:06 -0700187 bool down, int32_t keyCode, int32_t scanCode, uint32_t& policyFlags);
188 virtual int32_t interceptSwitch(nsecs_t when, int32_t switchCode, int32_t switchValue,
189 uint32_t& policyFlags);
190 virtual int32_t interceptGeneric(nsecs_t when, uint32_t& policyFlags);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700191 virtual bool filterTouchEvents();
192 virtual bool filterJumpyTouchEvents();
193 virtual void getVirtualKeyDefinitions(const String8& deviceName,
Jeff Brown8d608662010-08-30 03:02:23 -0700194 Vector<VirtualKeyDefinition>& outVirtualKeyDefinitions);
195 virtual void getInputDeviceCalibration(const String8& deviceName,
196 InputDeviceCalibration& outCalibration);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700197 virtual void getExcludedDeviceNames(Vector<String8>& outExcludedDeviceNames);
198
199 /* --- InputDispatcherPolicyInterface implementation --- */
200
201 virtual void notifyConfigurationChanged(nsecs_t when);
Jeff Brown519e0242010-09-15 15:18:56 -0700202 virtual nsecs_t notifyANR(const sp<InputApplicationHandle>& inputApplicationHandle,
203 const sp<InputChannel>& inputChannel);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700204 virtual void notifyInputChannelBroken(const sp<InputChannel>& inputChannel);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700205 virtual nsecs_t getKeyRepeatTimeout();
Jeff Brownb21fb102010-09-07 10:44:57 -0700206 virtual nsecs_t getKeyRepeatDelay();
Jeff Brownae9fc032010-08-18 15:51:08 -0700207 virtual int32_t getMaxEventsPerSecond();
Jeff Brownb88102f2010-09-08 11:49:43 -0700208 virtual bool interceptKeyBeforeDispatching(const sp<InputChannel>& inputChannel,
209 const KeyEvent* keyEvent, uint32_t policyFlags);
Jeff Brown01ce2e92010-09-26 22:20:12 -0700210 virtual void pokeUserActivity(nsecs_t eventTime, int32_t eventType);
Jeff Brownb88102f2010-09-08 11:49:43 -0700211 virtual bool checkInjectEventsPermissionNonReentrant(
212 int32_t injectorPid, int32_t injectorUid);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700213
214private:
Jeff Brownb88102f2010-09-08 11:49:43 -0700215 class ApplicationToken : public InputApplicationHandle {
216 jweak mTokenObjWeak;
Jeff Brown349703e2010-06-22 01:27:15 -0700217
218 public:
Jeff Brownb88102f2010-09-08 11:49:43 -0700219 ApplicationToken(jweak tokenObjWeak) :
220 mTokenObjWeak(tokenObjWeak) { }
Jeff Brown349703e2010-06-22 01:27:15 -0700221
Jeff Brownb88102f2010-09-08 11:49:43 -0700222 virtual ~ApplicationToken() {
223 JNIEnv* env = NativeInputManager::jniEnv();
224 env->DeleteWeakGlobalRef(mTokenObjWeak);
225 }
Jeff Brown349703e2010-06-22 01:27:15 -0700226
Jeff Brownb88102f2010-09-08 11:49:43 -0700227 inline jweak getTokenObj() { return mTokenObjWeak; }
Jeff Brown349703e2010-06-22 01:27:15 -0700228 };
229
Jeff Brown9c3cda02010-06-15 01:31:58 -0700230 sp<InputManager> mInputManager;
231
232 jobject mCallbacksObj;
233
234 // Cached filtering policies.
235 int32_t mFilterTouchEvents;
236 int32_t mFilterJumpyTouchEvents;
237
Jeff Brownae9fc032010-08-18 15:51:08 -0700238 // Cached throttling policy.
239 int32_t mMaxEventsPerSecond;
240
Jeff Brown9c3cda02010-06-15 01:31:58 -0700241 // Cached display state. (lock mDisplayLock)
242 Mutex mDisplayLock;
243 int32_t mDisplayWidth, mDisplayHeight;
244 int32_t mDisplayOrientation;
245
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700246 // Power manager interactions.
Jeff Brown9c3cda02010-06-15 01:31:58 -0700247 bool isScreenOn();
248 bool isScreenBright();
249
Jeff Brown2cbecea2010-08-17 15:59:26 -0700250 // Weak references to all currently registered input channels by connection pointer.
Jeff Brown7fbdc842010-06-17 20:52:56 -0700251 Mutex mInputChannelRegistryLock;
Jeff Brown2cbecea2010-08-17 15:59:26 -0700252 KeyedVector<InputChannel*, jweak> mInputChannelObjWeakTable;
Jeff Brown7fbdc842010-06-17 20:52:56 -0700253
254 jobject getInputChannelObjLocal(JNIEnv* env, const sp<InputChannel>& inputChannel);
255
Jeff Brown349703e2010-06-22 01:27:15 -0700256 static bool populateWindow(JNIEnv* env, jobject windowObj, InputWindow& outWindow);
Jeff Brown349703e2010-06-22 01:27:15 -0700257
Jeff Brownb88102f2010-09-08 11:49:43 -0700258 static bool isPolicyKey(int32_t keyCode, bool isScreenOn);
259 static bool checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName);
Jeff Browna41ca772010-08-11 14:46:32 -0700260
Jeff Brown9c3cda02010-06-15 01:31:58 -0700261 static inline JNIEnv* jniEnv() {
262 return AndroidRuntime::getJNIEnv();
263 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700264};
265
266// ----------------------------------------------------------------------------
267
268NativeInputManager::NativeInputManager(jobject callbacksObj) :
269 mFilterTouchEvents(-1), mFilterJumpyTouchEvents(-1),
Jeff Brownae9fc032010-08-18 15:51:08 -0700270 mMaxEventsPerSecond(-1),
Jeff Brownb88102f2010-09-08 11:49:43 -0700271 mDisplayWidth(-1), mDisplayHeight(-1), mDisplayOrientation(ROTATION_0) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700272 JNIEnv* env = jniEnv();
273
274 mCallbacksObj = env->NewGlobalRef(callbacksObj);
275
276 sp<EventHub> eventHub = new EventHub();
277 mInputManager = new InputManager(eventHub, this, this);
278}
279
280NativeInputManager::~NativeInputManager() {
281 JNIEnv* env = jniEnv();
282
283 env->DeleteGlobalRef(mCallbacksObj);
284}
285
Jeff Brownb88102f2010-09-08 11:49:43 -0700286void NativeInputManager::dump(String8& dump) {
287 dump.append("Input Reader State:\n");
288 mInputManager->getReader()->dump(dump);
289 dump.append("\n");
Jeff Brown6d0fec22010-07-23 21:28:06 -0700290
Jeff Brownb88102f2010-09-08 11:49:43 -0700291 dump.append("Input Dispatcher State:\n");
292 mInputManager->getDispatcher()->dump(dump);
293 dump.append("\n");
Jeff Brown9c3cda02010-06-15 01:31:58 -0700294}
295
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700296bool NativeInputManager::isPolicyKey(int32_t keyCode, bool isScreenOn) {
297 // Special keys that the WindowManagerPolicy might care about.
298 switch (keyCode) {
Jeff Brownfd035822010-06-30 16:10:35 -0700299 case AKEYCODE_VOLUME_UP:
300 case AKEYCODE_VOLUME_DOWN:
301 case AKEYCODE_ENDCALL:
302 case AKEYCODE_POWER:
303 case AKEYCODE_CALL:
304 case AKEYCODE_HOME:
305 case AKEYCODE_MENU:
306 case AKEYCODE_SEARCH:
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700307 // media keys
Jeff Brownfd035822010-06-30 16:10:35 -0700308 case AKEYCODE_HEADSETHOOK:
309 case AKEYCODE_MEDIA_PLAY_PAUSE:
310 case AKEYCODE_MEDIA_STOP:
311 case AKEYCODE_MEDIA_NEXT:
312 case AKEYCODE_MEDIA_PREVIOUS:
313 case AKEYCODE_MEDIA_REWIND:
314 case AKEYCODE_MEDIA_FAST_FORWARD:
Jeff Brownb88102f2010-09-08 11:49:43 -0700315 // The policy always cares about these keys.
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700316 return true;
317 default:
318 // We need to pass all keys to the policy in the following cases:
319 // - screen is off
320 // - keyguard is visible
321 // - policy is performing key chording
322 //return ! isScreenOn || keyguardVisible || chording;
323 return true; // XXX stubbed out for now
324 }
325}
326
Jeff Brown7fbdc842010-06-17 20:52:56 -0700327bool NativeInputManager::checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700328 if (env->ExceptionCheck()) {
329 LOGE("An exception was thrown by callback '%s'.", methodName);
330 LOGE_EX(env);
331 env->ExceptionClear();
332 return true;
333 }
334 return false;
335}
336
337void NativeInputManager::setDisplaySize(int32_t displayId, int32_t width, int32_t height) {
338 if (displayId == 0) {
339 AutoMutex _l(mDisplayLock);
340
341 mDisplayWidth = width;
342 mDisplayHeight = height;
343 }
344}
345
346void NativeInputManager::setDisplayOrientation(int32_t displayId, int32_t orientation) {
347 if (displayId == 0) {
348 AutoMutex _l(mDisplayLock);
349
350 mDisplayOrientation = orientation;
351 }
352}
353
Jeff Brown7fbdc842010-06-17 20:52:56 -0700354status_t NativeInputManager::registerInputChannel(JNIEnv* env,
Jeff Browna41ca772010-08-11 14:46:32 -0700355 const sp<InputChannel>& inputChannel, jobject inputChannelObj, bool monitor) {
Jeff Brown7fbdc842010-06-17 20:52:56 -0700356 jweak inputChannelObjWeak = env->NewWeakGlobalRef(inputChannelObj);
357 if (! inputChannelObjWeak) {
358 LOGE("Could not create weak reference for input channel.");
359 LOGE_EX(env);
360 return NO_MEMORY;
361 }
362
363 status_t status;
364 {
365 AutoMutex _l(mInputChannelRegistryLock);
366
Jeff Brown2cbecea2010-08-17 15:59:26 -0700367 ssize_t index = mInputChannelObjWeakTable.indexOfKey(inputChannel.get());
Jeff Brown7fbdc842010-06-17 20:52:56 -0700368 if (index >= 0) {
369 LOGE("Input channel object '%s' has already been registered",
370 inputChannel->getName().string());
371 status = INVALID_OPERATION;
372 goto DeleteWeakRef;
373 }
374
Jeff Brown2cbecea2010-08-17 15:59:26 -0700375 mInputChannelObjWeakTable.add(inputChannel.get(), inputChannelObjWeak);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700376 }
377
Jeff Brownb88102f2010-09-08 11:49:43 -0700378 status = mInputManager->getDispatcher()->registerInputChannel(inputChannel, monitor);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700379 if (! status) {
Jeff Browna41ca772010-08-11 14:46:32 -0700380 // Success.
Jeff Brown7fbdc842010-06-17 20:52:56 -0700381 return OK;
382 }
383
Jeff Browna41ca772010-08-11 14:46:32 -0700384 // Failed!
Jeff Brown7fbdc842010-06-17 20:52:56 -0700385 {
386 AutoMutex _l(mInputChannelRegistryLock);
Jeff Brown2cbecea2010-08-17 15:59:26 -0700387 mInputChannelObjWeakTable.removeItem(inputChannel.get());
Jeff Brown7fbdc842010-06-17 20:52:56 -0700388 }
389
390DeleteWeakRef:
391 env->DeleteWeakGlobalRef(inputChannelObjWeak);
392 return status;
393}
394
395status_t NativeInputManager::unregisterInputChannel(JNIEnv* env,
396 const sp<InputChannel>& inputChannel) {
397 jweak inputChannelObjWeak;
398 {
399 AutoMutex _l(mInputChannelRegistryLock);
400
Jeff Brown2cbecea2010-08-17 15:59:26 -0700401 ssize_t index = mInputChannelObjWeakTable.indexOfKey(inputChannel.get());
Jeff Brown7fbdc842010-06-17 20:52:56 -0700402 if (index < 0) {
403 LOGE("Input channel object '%s' is not currently registered",
404 inputChannel->getName().string());
405 return INVALID_OPERATION;
406 }
407
Jeff Brown2cbecea2010-08-17 15:59:26 -0700408 inputChannelObjWeak = mInputChannelObjWeakTable.valueAt(index);
409 mInputChannelObjWeakTable.removeItemsAt(index);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700410 }
411
412 env->DeleteWeakGlobalRef(inputChannelObjWeak);
413
Jeff Brownb88102f2010-09-08 11:49:43 -0700414 return mInputManager->getDispatcher()->unregisterInputChannel(inputChannel);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700415}
416
417jobject NativeInputManager::getInputChannelObjLocal(JNIEnv* env,
418 const sp<InputChannel>& inputChannel) {
Jeff Brown54a18252010-09-16 14:07:33 -0700419 InputChannel* inputChannelPtr = inputChannel.get();
420 if (! inputChannelPtr) {
421 return NULL;
422 }
423
Jeff Brown7fbdc842010-06-17 20:52:56 -0700424 {
425 AutoMutex _l(mInputChannelRegistryLock);
426
Jeff Brown54a18252010-09-16 14:07:33 -0700427 ssize_t index = mInputChannelObjWeakTable.indexOfKey(inputChannelPtr);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700428 if (index < 0) {
429 return NULL;
430 }
431
Jeff Brown2cbecea2010-08-17 15:59:26 -0700432 jweak inputChannelObjWeak = mInputChannelObjWeakTable.valueAt(index);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700433 return env->NewLocalRef(inputChannelObjWeak);
434 }
435}
436
Jeff Brown9c3cda02010-06-15 01:31:58 -0700437bool NativeInputManager::getDisplayInfo(int32_t displayId,
438 int32_t* width, int32_t* height, int32_t* orientation) {
439 bool result = false;
440 if (displayId == 0) {
441 AutoMutex _l(mDisplayLock);
442
443 if (mDisplayWidth > 0) {
Jeff Brown6d0fec22010-07-23 21:28:06 -0700444 if (width) {
445 *width = mDisplayWidth;
446 }
447 if (height) {
448 *height = mDisplayHeight;
449 }
450 if (orientation) {
451 *orientation = mDisplayOrientation;
452 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700453 result = true;
454 }
455 }
456 return result;
457}
458
459bool NativeInputManager::isScreenOn() {
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700460 return android_server_PowerManagerService_isScreenOn();
Jeff Brown9c3cda02010-06-15 01:31:58 -0700461}
462
463bool NativeInputManager::isScreenBright() {
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700464 return android_server_PowerManagerService_isScreenBright();
Jeff Brown9c3cda02010-06-15 01:31:58 -0700465}
466
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700467void NativeInputManager::virtualKeyDownFeedback() {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700468#if DEBUG_INPUT_READER_POLICY
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700469 LOGD("virtualKeyDownFeedback");
Jeff Brown9c3cda02010-06-15 01:31:58 -0700470#endif
471
472 JNIEnv* env = jniEnv();
473
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700474 env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.virtualKeyDownFeedback);
475 checkAndClearExceptionFromCallback(env, "virtualKeyDownFeedback");
Jeff Brown9c3cda02010-06-15 01:31:58 -0700476}
477
478int32_t NativeInputManager::interceptKey(nsecs_t when,
Jeff Brown6d0fec22010-07-23 21:28:06 -0700479 int32_t deviceId, bool down, int32_t keyCode, int32_t scanCode, uint32_t& policyFlags) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700480#if DEBUG_INPUT_READER_POLICY
481 LOGD("interceptKey - when=%lld, deviceId=%d, down=%d, keyCode=%d, scanCode=%d, "
Jeff Brown349703e2010-06-22 01:27:15 -0700482 "policyFlags=0x%x",
Jeff Brown9c3cda02010-06-15 01:31:58 -0700483 when, deviceId, down, keyCode, scanCode, policyFlags);
484#endif
485
486 const int32_t WM_ACTION_PASS_TO_USER = 1;
487 const int32_t WM_ACTION_POKE_USER_ACTIVITY = 2;
488 const int32_t WM_ACTION_GO_TO_SLEEP = 4;
489
Jeff Brown9c3cda02010-06-15 01:31:58 -0700490 bool isScreenOn = this->isScreenOn();
491 bool isScreenBright = this->isScreenBright();
492
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700493 jint wmActions = 0;
494 if (isPolicyKey(keyCode, isScreenOn)) {
495 JNIEnv* env = jniEnv();
496
497 wmActions = env->CallIntMethod(mCallbacksObj,
498 gCallbacksClassInfo.interceptKeyBeforeQueueing,
499 when, keyCode, down, policyFlags, isScreenOn);
500 if (checkAndClearExceptionFromCallback(env, "interceptKeyBeforeQueueing")) {
501 wmActions = 0;
502 }
503 } else {
504 wmActions = WM_ACTION_PASS_TO_USER;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700505 }
506
507 int32_t actions = InputReaderPolicyInterface::ACTION_NONE;
508 if (! isScreenOn) {
509 // Key presses and releases wake the device.
Jeff Brown6d0fec22010-07-23 21:28:06 -0700510 policyFlags |= POLICY_FLAG_WOKE_HERE;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700511 }
512
513 if (! isScreenBright) {
514 // Key presses and releases brighten the screen if dimmed.
Jeff Brown6d0fec22010-07-23 21:28:06 -0700515 policyFlags |= POLICY_FLAG_BRIGHT_HERE;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700516 }
517
518 if (wmActions & WM_ACTION_GO_TO_SLEEP) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700519 android_server_PowerManagerService_goToSleep(when);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700520 }
521
522 if (wmActions & WM_ACTION_POKE_USER_ACTIVITY) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700523 android_server_PowerManagerService_userActivity(when, POWER_MANAGER_BUTTON_EVENT);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700524 }
525
526 if (wmActions & WM_ACTION_PASS_TO_USER) {
527 actions |= InputReaderPolicyInterface::ACTION_DISPATCH;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700528 }
Jeff Brown349703e2010-06-22 01:27:15 -0700529
Jeff Brown9c3cda02010-06-15 01:31:58 -0700530 return actions;
531}
532
Jeff Brown6d0fec22010-07-23 21:28:06 -0700533int32_t NativeInputManager::interceptGeneric(nsecs_t when, uint32_t& policyFlags) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700534#if DEBUG_INPUT_READER_POLICY
Jeff Brown6d0fec22010-07-23 21:28:06 -0700535 LOGD("interceptGeneric - when=%lld, policyFlags=0x%x", when, policyFlags);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700536#endif
537
Jeff Brown5c225b12010-06-16 01:53:36 -0700538 int32_t actions = InputReaderPolicyInterface::ACTION_NONE;
539 if (isScreenOn()) {
Jeff Brown6d0fec22010-07-23 21:28:06 -0700540 // Only dispatch events when the device is awake.
Jeff Brown349703e2010-06-22 01:27:15 -0700541 // Do not wake the device.
Jeff Brown5c225b12010-06-16 01:53:36 -0700542 actions |= InputReaderPolicyInterface::ACTION_DISPATCH;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700543
Jeff Brown349703e2010-06-22 01:27:15 -0700544 if (! isScreenBright()) {
545 // Brighten the screen if dimmed.
Jeff Brown6d0fec22010-07-23 21:28:06 -0700546 policyFlags |= POLICY_FLAG_BRIGHT_HERE;
Jeff Brown349703e2010-06-22 01:27:15 -0700547 }
Jeff Brown5c225b12010-06-16 01:53:36 -0700548 }
549
550 return actions;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700551}
552
553int32_t NativeInputManager::interceptSwitch(nsecs_t when, int32_t switchCode,
Jeff Brown6d0fec22010-07-23 21:28:06 -0700554 int32_t switchValue, uint32_t& policyFlags) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700555#if DEBUG_INPUT_READER_POLICY
Jeff Brown6d0fec22010-07-23 21:28:06 -0700556 LOGD("interceptSwitch - when=%lld, switchCode=%d, switchValue=%d, policyFlags=0x%x",
557 when, switchCode, switchValue, policyFlags);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700558#endif
559
560 JNIEnv* env = jniEnv();
561
562 switch (switchCode) {
563 case SW_LID:
564 env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyLidSwitchChanged,
565 when, switchValue == 0);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700566 checkAndClearExceptionFromCallback(env, "notifyLidSwitchChanged");
Jeff Brown9c3cda02010-06-15 01:31:58 -0700567 break;
568 }
569
570 return InputReaderPolicyInterface::ACTION_NONE;
571}
572
573bool NativeInputManager::filterTouchEvents() {
574 if (mFilterTouchEvents < 0) {
575 JNIEnv* env = jniEnv();
576
577 jboolean result = env->CallBooleanMethod(mCallbacksObj,
578 gCallbacksClassInfo.filterTouchEvents);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700579 if (checkAndClearExceptionFromCallback(env, "filterTouchEvents")) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700580 result = false;
581 }
582
583 mFilterTouchEvents = result ? 1 : 0;
584 }
585 return mFilterTouchEvents;
586}
587
588bool NativeInputManager::filterJumpyTouchEvents() {
589 if (mFilterJumpyTouchEvents < 0) {
590 JNIEnv* env = jniEnv();
591
592 jboolean result = env->CallBooleanMethod(mCallbacksObj,
593 gCallbacksClassInfo.filterJumpyTouchEvents);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700594 if (checkAndClearExceptionFromCallback(env, "filterJumpyTouchEvents")) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700595 result = false;
596 }
597
598 mFilterJumpyTouchEvents = result ? 1 : 0;
599 }
600 return mFilterJumpyTouchEvents;
601}
602
603void NativeInputManager::getVirtualKeyDefinitions(const String8& deviceName,
Jeff Brown8d608662010-08-30 03:02:23 -0700604 Vector<VirtualKeyDefinition>& outVirtualKeyDefinitions) {
605 outVirtualKeyDefinitions.clear();
606
Jeff Brown9c3cda02010-06-15 01:31:58 -0700607 JNIEnv* env = jniEnv();
608
609 jstring deviceNameStr = env->NewStringUTF(deviceName.string());
Jeff Brown7fbdc842010-06-17 20:52:56 -0700610 if (! checkAndClearExceptionFromCallback(env, "getVirtualKeyDefinitions")) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700611 jobjectArray result = jobjectArray(env->CallObjectMethod(mCallbacksObj,
612 gCallbacksClassInfo.getVirtualKeyDefinitions, deviceNameStr));
Jeff Brown7fbdc842010-06-17 20:52:56 -0700613 if (! checkAndClearExceptionFromCallback(env, "getVirtualKeyDefinitions") && result) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700614 jsize length = env->GetArrayLength(result);
615 for (jsize i = 0; i < length; i++) {
616 jobject item = env->GetObjectArrayElement(result, i);
617
618 outVirtualKeyDefinitions.add();
619 outVirtualKeyDefinitions.editTop().scanCode =
620 int32_t(env->GetIntField(item, gVirtualKeyDefinitionClassInfo.scanCode));
621 outVirtualKeyDefinitions.editTop().centerX =
622 int32_t(env->GetIntField(item, gVirtualKeyDefinitionClassInfo.centerX));
623 outVirtualKeyDefinitions.editTop().centerY =
624 int32_t(env->GetIntField(item, gVirtualKeyDefinitionClassInfo.centerY));
625 outVirtualKeyDefinitions.editTop().width =
626 int32_t(env->GetIntField(item, gVirtualKeyDefinitionClassInfo.width));
627 outVirtualKeyDefinitions.editTop().height =
628 int32_t(env->GetIntField(item, gVirtualKeyDefinitionClassInfo.height));
629
630 env->DeleteLocalRef(item);
631 }
632 env->DeleteLocalRef(result);
633 }
634 env->DeleteLocalRef(deviceNameStr);
635 }
636}
637
Jeff Brown8d608662010-08-30 03:02:23 -0700638void NativeInputManager::getInputDeviceCalibration(const String8& deviceName,
639 InputDeviceCalibration& outCalibration) {
640 outCalibration.clear();
641
642 JNIEnv* env = jniEnv();
643
644 jstring deviceNameStr = env->NewStringUTF(deviceName.string());
645 if (! checkAndClearExceptionFromCallback(env, "getInputDeviceCalibration")) {
646 jobject result = env->CallObjectMethod(mCallbacksObj,
647 gCallbacksClassInfo.getInputDeviceCalibration, deviceNameStr);
648 if (! checkAndClearExceptionFromCallback(env, "getInputDeviceCalibration") && result) {
649 jobjectArray keys = jobjectArray(env->GetObjectField(result,
650 gInputDeviceCalibrationClassInfo.keys));
651 jobjectArray values = jobjectArray(env->GetObjectField(result,
652 gInputDeviceCalibrationClassInfo.values));
653
654 jsize length = env->GetArrayLength(keys);
655 for (jsize i = 0; i < length; i++) {
656 jstring keyStr = jstring(env->GetObjectArrayElement(keys, i));
657 jstring valueStr = jstring(env->GetObjectArrayElement(values, i));
658
659 const char* keyChars = env->GetStringUTFChars(keyStr, NULL);
660 String8 key(keyChars);
661 env->ReleaseStringUTFChars(keyStr, keyChars);
662
663 const char* valueChars = env->GetStringUTFChars(valueStr, NULL);
664 String8 value(valueChars);
665 env->ReleaseStringUTFChars(valueStr, valueChars);
666
667 outCalibration.addProperty(key, value);
668
669 env->DeleteLocalRef(keyStr);
670 env->DeleteLocalRef(valueStr);
671 }
672 env->DeleteLocalRef(keys);
673 env->DeleteLocalRef(values);
674 env->DeleteLocalRef(result);
675 }
676 env->DeleteLocalRef(deviceNameStr);
677 }
678}
679
Jeff Brown9c3cda02010-06-15 01:31:58 -0700680void NativeInputManager::getExcludedDeviceNames(Vector<String8>& outExcludedDeviceNames) {
Jeff Brown8d608662010-08-30 03:02:23 -0700681 outExcludedDeviceNames.clear();
682
Jeff Brown9c3cda02010-06-15 01:31:58 -0700683 JNIEnv* env = jniEnv();
684
685 jobjectArray result = jobjectArray(env->CallObjectMethod(mCallbacksObj,
686 gCallbacksClassInfo.getExcludedDeviceNames));
Jeff Brown7fbdc842010-06-17 20:52:56 -0700687 if (! checkAndClearExceptionFromCallback(env, "getExcludedDeviceNames") && result) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700688 jsize length = env->GetArrayLength(result);
689 for (jsize i = 0; i < length; i++) {
690 jstring item = jstring(env->GetObjectArrayElement(result, i));
691
692 const char* deviceNameChars = env->GetStringUTFChars(item, NULL);
693 outExcludedDeviceNames.add(String8(deviceNameChars));
694 env->ReleaseStringUTFChars(item, deviceNameChars);
695
696 env->DeleteLocalRef(item);
697 }
698 env->DeleteLocalRef(result);
699 }
700}
701
702void NativeInputManager::notifyConfigurationChanged(nsecs_t when) {
703#if DEBUG_INPUT_DISPATCHER_POLICY
704 LOGD("notifyConfigurationChanged - when=%lld", when);
705#endif
706
707 JNIEnv* env = jniEnv();
708
Jeff Brown57c59372010-09-21 18:22:55 -0700709 env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyConfigurationChanged, when);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700710 checkAndClearExceptionFromCallback(env, "notifyConfigurationChanged");
Jeff Brown9c3cda02010-06-15 01:31:58 -0700711}
712
Jeff Brown519e0242010-09-15 15:18:56 -0700713nsecs_t NativeInputManager::notifyANR(const sp<InputApplicationHandle>& inputApplicationHandle,
714 const sp<InputChannel>& inputChannel) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700715#if DEBUG_INPUT_DISPATCHER_POLICY
716 LOGD("notifyANR");
717#endif
718
719 JNIEnv* env = jniEnv();
720
Jeff Brown519e0242010-09-15 15:18:56 -0700721 jobject tokenObjLocal;
722 if (inputApplicationHandle.get()) {
723 ApplicationToken* token = static_cast<ApplicationToken*>(inputApplicationHandle.get());
724 jweak tokenObjWeak = token->getTokenObj();
725 tokenObjLocal = env->NewLocalRef(tokenObjWeak);
Jeff Brownb88102f2010-09-08 11:49:43 -0700726 } else {
Jeff Brown519e0242010-09-15 15:18:56 -0700727 tokenObjLocal = NULL;
Jeff Brownb88102f2010-09-08 11:49:43 -0700728 }
729
Jeff Brown54a18252010-09-16 14:07:33 -0700730 jobject inputChannelObjLocal = getInputChannelObjLocal(env, inputChannel);
Jeff Brown519e0242010-09-15 15:18:56 -0700731 jlong newTimeout = env->CallLongMethod(mCallbacksObj,
732 gCallbacksClassInfo.notifyANR, tokenObjLocal, inputChannelObjLocal);
733 if (checkAndClearExceptionFromCallback(env, "notifyANR")) {
734 newTimeout = 0; // abort dispatch
735 } else {
736 assert(newTimeout >= 0);
737 }
738
739 env->DeleteLocalRef(tokenObjLocal);
740 env->DeleteLocalRef(inputChannelObjLocal);
Jeff Brownb88102f2010-09-08 11:49:43 -0700741 return newTimeout;
742}
743
Jeff Brown9c3cda02010-06-15 01:31:58 -0700744void NativeInputManager::notifyInputChannelBroken(const sp<InputChannel>& inputChannel) {
745#if DEBUG_INPUT_DISPATCHER_POLICY
746 LOGD("notifyInputChannelBroken - inputChannel='%s'", inputChannel->getName().string());
747#endif
748
Jeff Brown7fbdc842010-06-17 20:52:56 -0700749 JNIEnv* env = jniEnv();
750
751 jobject inputChannelObjLocal = getInputChannelObjLocal(env, inputChannel);
752 if (inputChannelObjLocal) {
753 env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyInputChannelBroken,
754 inputChannelObjLocal);
755 checkAndClearExceptionFromCallback(env, "notifyInputChannelBroken");
756
757 env->DeleteLocalRef(inputChannelObjLocal);
758 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700759}
760
Jeff Brown9c3cda02010-06-15 01:31:58 -0700761nsecs_t NativeInputManager::getKeyRepeatTimeout() {
762 if (! isScreenOn()) {
763 // Disable key repeat when the screen is off.
764 return -1;
765 } else {
766 // TODO use ViewConfiguration.getLongPressTimeout()
767 return milliseconds_to_nanoseconds(500);
768 }
769}
770
Jeff Brownb21fb102010-09-07 10:44:57 -0700771nsecs_t NativeInputManager::getKeyRepeatDelay() {
772 return milliseconds_to_nanoseconds(50);
773}
774
Jeff Brownae9fc032010-08-18 15:51:08 -0700775int32_t NativeInputManager::getMaxEventsPerSecond() {
776 if (mMaxEventsPerSecond < 0) {
777 JNIEnv* env = jniEnv();
778
779 jint result = env->CallIntMethod(mCallbacksObj,
780 gCallbacksClassInfo.getMaxEventsPerSecond);
781 if (checkAndClearExceptionFromCallback(env, "getMaxEventsPerSecond")) {
Jeff Brown3d8c9bd2010-08-18 17:48:53 -0700782 result = 60;
Jeff Brownae9fc032010-08-18 15:51:08 -0700783 }
784
785 mMaxEventsPerSecond = result;
786 }
787 return mMaxEventsPerSecond;
788}
789
Jeff Brown349703e2010-06-22 01:27:15 -0700790void NativeInputManager::setInputWindows(JNIEnv* env, jobjectArray windowObjArray) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700791 Vector<InputWindow> windows;
Jeff Brown349703e2010-06-22 01:27:15 -0700792
Jeff Brownb88102f2010-09-08 11:49:43 -0700793 jsize length = env->GetArrayLength(windowObjArray);
794 for (jsize i = 0; i < length; i++) {
795 jobject inputTargetObj = env->GetObjectArrayElement(windowObjArray, i);
796 if (! inputTargetObj) {
797 break; // found null element indicating end of used portion of the array
Jeff Brown349703e2010-06-22 01:27:15 -0700798 }
799
Jeff Brownb88102f2010-09-08 11:49:43 -0700800 windows.push();
801 InputWindow& window = windows.editTop();
802 bool valid = populateWindow(env, inputTargetObj, window);
803 if (! valid) {
804 windows.pop();
Jeff Brown349703e2010-06-22 01:27:15 -0700805 }
806
Jeff Brownb88102f2010-09-08 11:49:43 -0700807 env->DeleteLocalRef(inputTargetObj);
808 }
Jeff Brown349703e2010-06-22 01:27:15 -0700809
Jeff Brownb88102f2010-09-08 11:49:43 -0700810 mInputManager->getDispatcher()->setInputWindows(windows);
Jeff Brown349703e2010-06-22 01:27:15 -0700811}
812
813bool NativeInputManager::populateWindow(JNIEnv* env, jobject windowObj,
814 InputWindow& outWindow) {
815 bool valid = false;
816
817 jobject inputChannelObj = env->GetObjectField(windowObj,
818 gInputWindowClassInfo.inputChannel);
819 if (inputChannelObj) {
820 sp<InputChannel> inputChannel =
821 android_view_InputChannel_getInputChannel(env, inputChannelObj);
822 if (inputChannel != NULL) {
Jeff Brown519e0242010-09-15 15:18:56 -0700823 jstring name = jstring(env->GetObjectField(windowObj,
824 gInputWindowClassInfo.name));
Jeff Brown349703e2010-06-22 01:27:15 -0700825 jint layoutParamsFlags = env->GetIntField(windowObj,
826 gInputWindowClassInfo.layoutParamsFlags);
827 jint layoutParamsType = env->GetIntField(windowObj,
828 gInputWindowClassInfo.layoutParamsType);
829 jlong dispatchingTimeoutNanos = env->GetLongField(windowObj,
830 gInputWindowClassInfo.dispatchingTimeoutNanos);
831 jint frameLeft = env->GetIntField(windowObj,
832 gInputWindowClassInfo.frameLeft);
833 jint frameTop = env->GetIntField(windowObj,
834 gInputWindowClassInfo.frameTop);
Jeff Brown85a31762010-09-01 17:01:00 -0700835 jint frameRight = env->GetIntField(windowObj,
836 gInputWindowClassInfo.frameRight);
837 jint frameBottom = env->GetIntField(windowObj,
838 gInputWindowClassInfo.frameBottom);
839 jint visibleFrameLeft = env->GetIntField(windowObj,
840 gInputWindowClassInfo.visibleFrameLeft);
841 jint visibleFrameTop = env->GetIntField(windowObj,
842 gInputWindowClassInfo.visibleFrameTop);
843 jint visibleFrameRight = env->GetIntField(windowObj,
844 gInputWindowClassInfo.visibleFrameRight);
845 jint visibleFrameBottom = env->GetIntField(windowObj,
846 gInputWindowClassInfo.visibleFrameBottom);
Jeff Brown349703e2010-06-22 01:27:15 -0700847 jint touchableAreaLeft = env->GetIntField(windowObj,
848 gInputWindowClassInfo.touchableAreaLeft);
849 jint touchableAreaTop = env->GetIntField(windowObj,
850 gInputWindowClassInfo.touchableAreaTop);
851 jint touchableAreaRight = env->GetIntField(windowObj,
852 gInputWindowClassInfo.touchableAreaRight);
853 jint touchableAreaBottom = env->GetIntField(windowObj,
854 gInputWindowClassInfo.touchableAreaBottom);
855 jboolean visible = env->GetBooleanField(windowObj,
856 gInputWindowClassInfo.visible);
Jeff Brown519e0242010-09-15 15:18:56 -0700857 jboolean canReceiveKeys = env->GetBooleanField(windowObj,
858 gInputWindowClassInfo.canReceiveKeys);
Jeff Brown349703e2010-06-22 01:27:15 -0700859 jboolean hasFocus = env->GetBooleanField(windowObj,
860 gInputWindowClassInfo.hasFocus);
861 jboolean hasWallpaper = env->GetBooleanField(windowObj,
862 gInputWindowClassInfo.hasWallpaper);
863 jboolean paused = env->GetBooleanField(windowObj,
864 gInputWindowClassInfo.paused);
Jeff Brown519e0242010-09-15 15:18:56 -0700865 jint layer = env->GetIntField(windowObj,
866 gInputWindowClassInfo.layer);
Jeff Brown349703e2010-06-22 01:27:15 -0700867 jint ownerPid = env->GetIntField(windowObj,
868 gInputWindowClassInfo.ownerPid);
869 jint ownerUid = env->GetIntField(windowObj,
870 gInputWindowClassInfo.ownerUid);
871
Jeff Brown519e0242010-09-15 15:18:56 -0700872 const char* nameStr = env->GetStringUTFChars(name, NULL);
873
Jeff Brown349703e2010-06-22 01:27:15 -0700874 outWindow.inputChannel = inputChannel;
Jeff Brown519e0242010-09-15 15:18:56 -0700875 outWindow.name.setTo(nameStr);
Jeff Brown349703e2010-06-22 01:27:15 -0700876 outWindow.layoutParamsFlags = layoutParamsFlags;
877 outWindow.layoutParamsType = layoutParamsType;
878 outWindow.dispatchingTimeout = dispatchingTimeoutNanos;
879 outWindow.frameLeft = frameLeft;
880 outWindow.frameTop = frameTop;
Jeff Brown85a31762010-09-01 17:01:00 -0700881 outWindow.frameRight = frameRight;
882 outWindow.frameBottom = frameBottom;
883 outWindow.visibleFrameLeft = visibleFrameLeft;
884 outWindow.visibleFrameTop = visibleFrameTop;
885 outWindow.visibleFrameRight = visibleFrameRight;
886 outWindow.visibleFrameBottom = visibleFrameBottom;
Jeff Brown349703e2010-06-22 01:27:15 -0700887 outWindow.touchableAreaLeft = touchableAreaLeft;
888 outWindow.touchableAreaTop = touchableAreaTop;
889 outWindow.touchableAreaRight = touchableAreaRight;
890 outWindow.touchableAreaBottom = touchableAreaBottom;
891 outWindow.visible = visible;
Jeff Brown519e0242010-09-15 15:18:56 -0700892 outWindow.canReceiveKeys = canReceiveKeys;
Jeff Brown349703e2010-06-22 01:27:15 -0700893 outWindow.hasFocus = hasFocus;
894 outWindow.hasWallpaper = hasWallpaper;
895 outWindow.paused = paused;
Jeff Brown519e0242010-09-15 15:18:56 -0700896 outWindow.layer = layer;
Jeff Brown349703e2010-06-22 01:27:15 -0700897 outWindow.ownerPid = ownerPid;
898 outWindow.ownerUid = ownerUid;
Jeff Brown519e0242010-09-15 15:18:56 -0700899
900 env->ReleaseStringUTFChars(name, nameStr);
Jeff Brown349703e2010-06-22 01:27:15 -0700901 valid = true;
902 } else {
903 LOGW("Dropping input target because its input channel is not initialized.");
904 }
905
906 env->DeleteLocalRef(inputChannelObj);
907 } else {
908 LOGW("Dropping input target because the input channel object was null.");
909 }
910 return valid;
911}
912
913void NativeInputManager::setFocusedApplication(JNIEnv* env, jobject applicationObj) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700914 if (applicationObj) {
915 jstring nameObj = jstring(env->GetObjectField(applicationObj,
916 gInputApplicationClassInfo.name));
917 jlong dispatchingTimeoutNanos = env->GetLongField(applicationObj,
918 gInputApplicationClassInfo.dispatchingTimeoutNanos);
919 jobject tokenObj = env->GetObjectField(applicationObj,
920 gInputApplicationClassInfo.token);
921 jweak tokenObjWeak = env->NewWeakGlobalRef(tokenObj);
922 if (! tokenObjWeak) {
923 LOGE("Could not create weak reference for application token.");
924 LOGE_EX(env);
925 env->ExceptionClear();
926 }
927 env->DeleteLocalRef(tokenObj);
Jeff Brown349703e2010-06-22 01:27:15 -0700928
Jeff Brownb88102f2010-09-08 11:49:43 -0700929 String8 name;
930 if (nameObj) {
931 const char* nameStr = env->GetStringUTFChars(nameObj, NULL);
932 name.setTo(nameStr);
933 env->ReleaseStringUTFChars(nameObj, nameStr);
934 env->DeleteLocalRef(nameObj);
935 } else {
936 LOGE("InputApplication.name should not be null.");
937 name.setTo("unknown");
Jeff Brown349703e2010-06-22 01:27:15 -0700938 }
939
Jeff Brownb88102f2010-09-08 11:49:43 -0700940 InputApplication application;
941 application.name = name;
942 application.dispatchingTimeout = dispatchingTimeoutNanos;
943 application.handle = new ApplicationToken(tokenObjWeak);
944 mInputManager->getDispatcher()->setFocusedApplication(& application);
945 } else {
946 mInputManager->getDispatcher()->setFocusedApplication(NULL);
Jeff Brown349703e2010-06-22 01:27:15 -0700947 }
948}
949
950void NativeInputManager::setInputDispatchMode(bool enabled, bool frozen) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700951 mInputManager->getDispatcher()->setInputDispatchMode(enabled, frozen);
Jeff Brown349703e2010-06-22 01:27:15 -0700952}
953
Jeff Brownb88102f2010-09-08 11:49:43 -0700954bool NativeInputManager::interceptKeyBeforeDispatching(const sp<InputChannel>& inputChannel,
Jeff Brownd0097872010-06-30 14:41:59 -0700955 const KeyEvent* keyEvent, uint32_t policyFlags) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700956 bool isScreenOn = this->isScreenOn();
957 if (! isPolicyKey(keyEvent->getKeyCode(), isScreenOn)) {
958 return false;
959 }
960
Jeff Brownd0097872010-06-30 14:41:59 -0700961 JNIEnv* env = jniEnv();
962
Jeff Brown54a18252010-09-16 14:07:33 -0700963 // Note: inputChannel may be null.
Jeff Brownb88102f2010-09-08 11:49:43 -0700964 jobject inputChannelObj = getInputChannelObjLocal(env, inputChannel);
Jeff Brown54a18252010-09-16 14:07:33 -0700965 jboolean consumed = env->CallBooleanMethod(mCallbacksObj,
966 gCallbacksClassInfo.interceptKeyBeforeDispatching,
967 inputChannelObj, keyEvent->getAction(), keyEvent->getFlags(),
968 keyEvent->getKeyCode(), keyEvent->getMetaState(),
969 keyEvent->getRepeatCount(), policyFlags);
970 bool error = checkAndClearExceptionFromCallback(env, "interceptKeyBeforeDispatching");
Jeff Brownd0097872010-06-30 14:41:59 -0700971
Jeff Brown54a18252010-09-16 14:07:33 -0700972 env->DeleteLocalRef(inputChannelObj);
973 return consumed && ! error;
Jeff Brownd0097872010-06-30 14:41:59 -0700974}
975
Jeff Brown01ce2e92010-09-26 22:20:12 -0700976void NativeInputManager::pokeUserActivity(nsecs_t eventTime, int32_t eventType) {
977 android_server_PowerManagerService_userActivity(eventTime, eventType);
Jeff Brown349703e2010-06-22 01:27:15 -0700978}
979
Jeff Brown349703e2010-06-22 01:27:15 -0700980
Jeff Brownb88102f2010-09-08 11:49:43 -0700981bool NativeInputManager::checkInjectEventsPermissionNonReentrant(
982 int32_t injectorPid, int32_t injectorUid) {
983 JNIEnv* env = jniEnv();
984 jboolean result = env->CallBooleanMethod(mCallbacksObj,
985 gCallbacksClassInfo.checkInjectEventsPermission, injectorPid, injectorUid);
986 checkAndClearExceptionFromCallback(env, "checkInjectEventsPermission");
Jeff Brown349703e2010-06-22 01:27:15 -0700987 return result;
988}
989
Jeff Brown9c3cda02010-06-15 01:31:58 -0700990// ----------------------------------------------------------------------------
991
992static sp<NativeInputManager> gNativeInputManager;
993
Jeff Brown46b9ac02010-04-22 18:58:52 -0700994static bool checkInputManagerUnitialized(JNIEnv* env) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700995 if (gNativeInputManager == NULL) {
Jeff Brown46b9ac02010-04-22 18:58:52 -0700996 LOGE("Input manager not initialized.");
997 jniThrowRuntimeException(env, "Input manager not initialized.");
998 return true;
999 }
1000 return false;
1001}
1002
1003static void android_server_InputManager_nativeInit(JNIEnv* env, jclass clazz,
1004 jobject callbacks) {
Jeff Brown9c3cda02010-06-15 01:31:58 -07001005 if (gNativeInputManager == NULL) {
1006 gNativeInputManager = new NativeInputManager(callbacks);
1007 } else {
1008 LOGE("Input manager already initialized.");
1009 jniThrowRuntimeException(env, "Input manager already initialized.");
Jeff Brown46b9ac02010-04-22 18:58:52 -07001010 }
1011}
1012
1013static void android_server_InputManager_nativeStart(JNIEnv* env, jclass clazz) {
1014 if (checkInputManagerUnitialized(env)) {
1015 return;
1016 }
1017
Jeff Brown9c3cda02010-06-15 01:31:58 -07001018 status_t result = gNativeInputManager->getInputManager()->start();
Jeff Brown46b9ac02010-04-22 18:58:52 -07001019 if (result) {
1020 jniThrowRuntimeException(env, "Input manager could not be started.");
1021 }
1022}
1023
1024static void android_server_InputManager_nativeSetDisplaySize(JNIEnv* env, jclass clazz,
1025 jint displayId, jint width, jint height) {
1026 if (checkInputManagerUnitialized(env)) {
1027 return;
1028 }
1029
1030 // XXX we could get this from the SurfaceFlinger directly instead of requiring it
1031 // to be passed in like this, not sure which is better but leaving it like this
1032 // keeps the window manager in direct control of when display transitions propagate down
1033 // to the input dispatcher
Jeff Brown9c3cda02010-06-15 01:31:58 -07001034 gNativeInputManager->setDisplaySize(displayId, width, height);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001035}
1036
1037static void android_server_InputManager_nativeSetDisplayOrientation(JNIEnv* env, jclass clazz,
1038 jint displayId, jint orientation) {
1039 if (checkInputManagerUnitialized(env)) {
1040 return;
1041 }
1042
Jeff Brown9c3cda02010-06-15 01:31:58 -07001043 gNativeInputManager->setDisplayOrientation(displayId, orientation);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001044}
1045
1046static jint android_server_InputManager_nativeGetScanCodeState(JNIEnv* env, jclass clazz,
Jeff Brown6d0fec22010-07-23 21:28:06 -07001047 jint deviceId, jint sourceMask, jint scanCode) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07001048 if (checkInputManagerUnitialized(env)) {
Jeff Brownc5ed5912010-07-14 18:48:53 -07001049 return AKEY_STATE_UNKNOWN;
Jeff Brown46b9ac02010-04-22 18:58:52 -07001050 }
1051
Jeff Brownb88102f2010-09-08 11:49:43 -07001052 return gNativeInputManager->getInputManager()->getReader()->getScanCodeState(
Jeff Brown6d0fec22010-07-23 21:28:06 -07001053 deviceId, uint32_t(sourceMask), scanCode);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001054}
1055
1056static jint android_server_InputManager_nativeGetKeyCodeState(JNIEnv* env, jclass clazz,
Jeff Brown6d0fec22010-07-23 21:28:06 -07001057 jint deviceId, jint sourceMask, jint keyCode) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07001058 if (checkInputManagerUnitialized(env)) {
Jeff Brownc5ed5912010-07-14 18:48:53 -07001059 return AKEY_STATE_UNKNOWN;
Jeff Brown46b9ac02010-04-22 18:58:52 -07001060 }
1061
Jeff Brownb88102f2010-09-08 11:49:43 -07001062 return gNativeInputManager->getInputManager()->getReader()->getKeyCodeState(
Jeff Brown6d0fec22010-07-23 21:28:06 -07001063 deviceId, uint32_t(sourceMask), keyCode);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001064}
1065
1066static jint android_server_InputManager_nativeGetSwitchState(JNIEnv* env, jclass clazz,
Jeff Brown6d0fec22010-07-23 21:28:06 -07001067 jint deviceId, jint sourceMask, jint sw) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07001068 if (checkInputManagerUnitialized(env)) {
Jeff Brownc5ed5912010-07-14 18:48:53 -07001069 return AKEY_STATE_UNKNOWN;
Jeff Brown46b9ac02010-04-22 18:58:52 -07001070 }
1071
Jeff Brownb88102f2010-09-08 11:49:43 -07001072 return gNativeInputManager->getInputManager()->getReader()->getSwitchState(
Jeff Brown6d0fec22010-07-23 21:28:06 -07001073 deviceId, uint32_t(sourceMask), sw);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001074}
1075
1076static jboolean android_server_InputManager_nativeHasKeys(JNIEnv* env, jclass clazz,
Jeff Brown6d0fec22010-07-23 21:28:06 -07001077 jint deviceId, jint sourceMask, jintArray keyCodes, jbooleanArray outFlags) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07001078 if (checkInputManagerUnitialized(env)) {
1079 return JNI_FALSE;
1080 }
1081
1082 int32_t* codes = env->GetIntArrayElements(keyCodes, NULL);
1083 uint8_t* flags = env->GetBooleanArrayElements(outFlags, NULL);
1084 jsize numCodes = env->GetArrayLength(keyCodes);
1085 jboolean result;
Jeff Brown6d0fec22010-07-23 21:28:06 -07001086 if (numCodes == env->GetArrayLength(keyCodes)) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001087 result = gNativeInputManager->getInputManager()->getReader()->hasKeys(
Jeff Brown6d0fec22010-07-23 21:28:06 -07001088 deviceId, uint32_t(sourceMask), numCodes, codes, flags);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001089 } else {
1090 result = JNI_FALSE;
1091 }
1092
1093 env->ReleaseBooleanArrayElements(outFlags, flags, 0);
1094 env->ReleaseIntArrayElements(keyCodes, codes, 0);
1095 return result;
1096}
1097
1098static void throwInputChannelNotInitialized(JNIEnv* env) {
1099 jniThrowException(env, "java/lang/IllegalStateException",
1100 "inputChannel is not initialized");
1101}
1102
1103static void android_server_InputManager_handleInputChannelDisposed(JNIEnv* env,
1104 jobject inputChannelObj, const sp<InputChannel>& inputChannel, void* data) {
1105 LOGW("Input channel object '%s' was disposed without first being unregistered with "
1106 "the input manager!", inputChannel->getName().string());
1107
Jeff Brown9c3cda02010-06-15 01:31:58 -07001108 if (gNativeInputManager != NULL) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07001109 gNativeInputManager->unregisterInputChannel(env, inputChannel);
Jeff Brown9c3cda02010-06-15 01:31:58 -07001110 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07001111}
1112
1113static void android_server_InputManager_nativeRegisterInputChannel(JNIEnv* env, jclass clazz,
Jeff Browna41ca772010-08-11 14:46:32 -07001114 jobject inputChannelObj, jboolean monitor) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07001115 if (checkInputManagerUnitialized(env)) {
1116 return;
1117 }
1118
1119 sp<InputChannel> inputChannel = android_view_InputChannel_getInputChannel(env,
1120 inputChannelObj);
1121 if (inputChannel == NULL) {
1122 throwInputChannelNotInitialized(env);
1123 return;
1124 }
1125
Jeff Brown7fbdc842010-06-17 20:52:56 -07001126
1127 status_t status = gNativeInputManager->registerInputChannel(
Jeff Browna41ca772010-08-11 14:46:32 -07001128 env, inputChannel, inputChannelObj, monitor);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001129 if (status) {
1130 jniThrowRuntimeException(env, "Failed to register input channel. "
1131 "Check logs for details.");
1132 return;
1133 }
1134
Jeff Browna41ca772010-08-11 14:46:32 -07001135 if (! monitor) {
1136 android_view_InputChannel_setDisposeCallback(env, inputChannelObj,
1137 android_server_InputManager_handleInputChannelDisposed, NULL);
1138 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07001139}
1140
1141static void android_server_InputManager_nativeUnregisterInputChannel(JNIEnv* env, jclass clazz,
1142 jobject inputChannelObj) {
1143 if (checkInputManagerUnitialized(env)) {
1144 return;
1145 }
1146
1147 sp<InputChannel> inputChannel = android_view_InputChannel_getInputChannel(env,
1148 inputChannelObj);
1149 if (inputChannel == NULL) {
1150 throwInputChannelNotInitialized(env);
1151 return;
1152 }
1153
1154 android_view_InputChannel_setDisposeCallback(env, inputChannelObj, NULL, NULL);
1155
Jeff Brown7fbdc842010-06-17 20:52:56 -07001156 status_t status = gNativeInputManager->unregisterInputChannel(env, inputChannel);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001157 if (status) {
1158 jniThrowRuntimeException(env, "Failed to unregister input channel. "
1159 "Check logs for details.");
1160 }
1161}
1162
Jeff Brown6ec402b2010-07-28 15:48:59 -07001163static jint android_server_InputManager_nativeInjectInputEvent(JNIEnv* env, jclass clazz,
1164 jobject inputEventObj, jint injectorPid, jint injectorUid,
1165 jint syncMode, jint timeoutMillis) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07001166 if (checkInputManagerUnitialized(env)) {
1167 return INPUT_EVENT_INJECTION_FAILED;
1168 }
1169
Jeff Brown6ec402b2010-07-28 15:48:59 -07001170 if (env->IsInstanceOf(inputEventObj, gKeyEventClassInfo.clazz)) {
1171 KeyEvent keyEvent;
1172 android_view_KeyEvent_toNative(env, inputEventObj, & keyEvent);
Jeff Brown7fbdc842010-06-17 20:52:56 -07001173
Jeff Brownb88102f2010-09-08 11:49:43 -07001174 return gNativeInputManager->getInputManager()->getDispatcher()->injectInputEvent(
1175 & keyEvent, injectorPid, injectorUid, syncMode, timeoutMillis);
Jeff Brown6ec402b2010-07-28 15:48:59 -07001176 } else if (env->IsInstanceOf(inputEventObj, gMotionEventClassInfo.clazz)) {
1177 MotionEvent motionEvent;
1178 android_view_MotionEvent_toNative(env, inputEventObj, & motionEvent);
Jeff Brown7fbdc842010-06-17 20:52:56 -07001179
Jeff Brownb88102f2010-09-08 11:49:43 -07001180 return gNativeInputManager->getInputManager()->getDispatcher()->injectInputEvent(
1181 & motionEvent, injectorPid, injectorUid, syncMode, timeoutMillis);
Jeff Brown6ec402b2010-07-28 15:48:59 -07001182 } else {
1183 jniThrowRuntimeException(env, "Invalid input event type.");
Jeff Brown7fbdc842010-06-17 20:52:56 -07001184 return INPUT_EVENT_INJECTION_FAILED;
1185 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07001186}
1187
Jeff Brown349703e2010-06-22 01:27:15 -07001188static void android_server_InputManager_nativeSetInputWindows(JNIEnv* env, jclass clazz,
1189 jobjectArray windowObjArray) {
1190 if (checkInputManagerUnitialized(env)) {
1191 return;
1192 }
1193
1194 gNativeInputManager->setInputWindows(env, windowObjArray);
1195}
1196
1197static void android_server_InputManager_nativeSetFocusedApplication(JNIEnv* env, jclass clazz,
1198 jobject applicationObj) {
1199 if (checkInputManagerUnitialized(env)) {
1200 return;
1201 }
1202
1203 gNativeInputManager->setFocusedApplication(env, applicationObj);
1204}
1205
1206static void android_server_InputManager_nativeSetInputDispatchMode(JNIEnv* env,
1207 jclass clazz, jboolean enabled, jboolean frozen) {
1208 if (checkInputManagerUnitialized(env)) {
1209 return;
1210 }
1211
1212 gNativeInputManager->setInputDispatchMode(enabled, frozen);
1213}
1214
Jeff Brown8d608662010-08-30 03:02:23 -07001215static jobject android_server_InputManager_nativeGetInputDevice(JNIEnv* env,
1216 jclass clazz, jint deviceId) {
1217 if (checkInputManagerUnitialized(env)) {
1218 return NULL;
1219 }
1220
1221 InputDeviceInfo deviceInfo;
Jeff Brownb88102f2010-09-08 11:49:43 -07001222 status_t status = gNativeInputManager->getInputManager()->getReader()->getInputDeviceInfo(
Jeff Brown8d608662010-08-30 03:02:23 -07001223 deviceId, & deviceInfo);
1224 if (status) {
1225 return NULL;
1226 }
1227
1228 jobject deviceObj = env->NewObject(gInputDeviceClassInfo.clazz, gInputDeviceClassInfo.ctor);
1229 if (! deviceObj) {
1230 return NULL;
1231 }
1232
1233 jstring deviceNameObj = env->NewStringUTF(deviceInfo.getName().string());
1234 if (! deviceNameObj) {
1235 return NULL;
1236 }
1237
1238 env->SetIntField(deviceObj, gInputDeviceClassInfo.mId, deviceInfo.getId());
1239 env->SetObjectField(deviceObj, gInputDeviceClassInfo.mName, deviceNameObj);
1240 env->SetIntField(deviceObj, gInputDeviceClassInfo.mSources, deviceInfo.getSources());
1241 env->SetIntField(deviceObj, gInputDeviceClassInfo.mKeyboardType, deviceInfo.getKeyboardType());
1242
1243 const KeyedVector<int, InputDeviceInfo::MotionRange>& ranges = deviceInfo.getMotionRanges();
1244 for (size_t i = 0; i < ranges.size(); i++) {
1245 int rangeType = ranges.keyAt(i);
1246 const InputDeviceInfo::MotionRange& range = ranges.valueAt(i);
1247 env->CallVoidMethod(deviceObj, gInputDeviceClassInfo.addMotionRange,
1248 rangeType, range.min, range.max, range.flat, range.fuzz);
1249 if (env->ExceptionCheck()) {
1250 return NULL;
1251 }
1252 }
1253
1254 return deviceObj;
1255}
1256
1257static jintArray android_server_InputManager_nativeGetInputDeviceIds(JNIEnv* env,
1258 jclass clazz) {
1259 if (checkInputManagerUnitialized(env)) {
1260 return NULL;
1261 }
1262
1263 Vector<int> deviceIds;
Jeff Brownb88102f2010-09-08 11:49:43 -07001264 gNativeInputManager->getInputManager()->getReader()->getInputDeviceIds(deviceIds);
Jeff Brown8d608662010-08-30 03:02:23 -07001265
1266 jintArray deviceIdsObj = env->NewIntArray(deviceIds.size());
1267 if (! deviceIdsObj) {
1268 return NULL;
1269 }
1270
1271 env->SetIntArrayRegion(deviceIdsObj, 0, deviceIds.size(), deviceIds.array());
1272 return deviceIdsObj;
1273}
1274
Jeff Brown57c59372010-09-21 18:22:55 -07001275static void android_server_InputManager_nativeGetInputConfiguration(JNIEnv* env,
1276 jclass clazz, jobject configObj) {
1277 if (checkInputManagerUnitialized(env)) {
1278 return;
1279 }
1280
1281 InputConfiguration config;
1282 gNativeInputManager->getInputManager()->getReader()->getInputConfiguration(& config);
1283
1284 env->SetIntField(configObj, gConfigurationClassInfo.touchscreen, config.touchScreen);
1285 env->SetIntField(configObj, gConfigurationClassInfo.keyboard, config.keyboard);
1286 env->SetIntField(configObj, gConfigurationClassInfo.navigation, config.navigation);
1287}
1288
Jeff Browne33348b2010-07-15 23:54:05 -07001289static jstring android_server_InputManager_nativeDump(JNIEnv* env, jclass clazz) {
1290 if (checkInputManagerUnitialized(env)) {
1291 return NULL;
1292 }
1293
Jeff Brownb88102f2010-09-08 11:49:43 -07001294 String8 dump;
1295 gNativeInputManager->dump(dump);
Jeff Browne33348b2010-07-15 23:54:05 -07001296 return env->NewStringUTF(dump.string());
1297}
1298
Jeff Brown9c3cda02010-06-15 01:31:58 -07001299// ----------------------------------------------------------------------------
1300
Jeff Brown46b9ac02010-04-22 18:58:52 -07001301static JNINativeMethod gInputManagerMethods[] = {
1302 /* name, signature, funcPtr */
1303 { "nativeInit", "(Lcom/android/server/InputManager$Callbacks;)V",
1304 (void*) android_server_InputManager_nativeInit },
1305 { "nativeStart", "()V",
1306 (void*) android_server_InputManager_nativeStart },
1307 { "nativeSetDisplaySize", "(III)V",
1308 (void*) android_server_InputManager_nativeSetDisplaySize },
1309 { "nativeSetDisplayOrientation", "(II)V",
1310 (void*) android_server_InputManager_nativeSetDisplayOrientation },
1311 { "nativeGetScanCodeState", "(III)I",
1312 (void*) android_server_InputManager_nativeGetScanCodeState },
1313 { "nativeGetKeyCodeState", "(III)I",
1314 (void*) android_server_InputManager_nativeGetKeyCodeState },
1315 { "nativeGetSwitchState", "(III)I",
1316 (void*) android_server_InputManager_nativeGetSwitchState },
Jeff Brown6d0fec22010-07-23 21:28:06 -07001317 { "nativeHasKeys", "(II[I[Z)Z",
Jeff Brown46b9ac02010-04-22 18:58:52 -07001318 (void*) android_server_InputManager_nativeHasKeys },
Jeff Browna41ca772010-08-11 14:46:32 -07001319 { "nativeRegisterInputChannel", "(Landroid/view/InputChannel;Z)V",
Jeff Brown46b9ac02010-04-22 18:58:52 -07001320 (void*) android_server_InputManager_nativeRegisterInputChannel },
1321 { "nativeUnregisterInputChannel", "(Landroid/view/InputChannel;)V",
Jeff Brown7fbdc842010-06-17 20:52:56 -07001322 (void*) android_server_InputManager_nativeUnregisterInputChannel },
Jeff Brown6ec402b2010-07-28 15:48:59 -07001323 { "nativeInjectInputEvent", "(Landroid/view/InputEvent;IIII)I",
1324 (void*) android_server_InputManager_nativeInjectInputEvent },
Jeff Brown349703e2010-06-22 01:27:15 -07001325 { "nativeSetInputWindows", "([Lcom/android/server/InputWindow;)V",
1326 (void*) android_server_InputManager_nativeSetInputWindows },
1327 { "nativeSetFocusedApplication", "(Lcom/android/server/InputApplication;)V",
1328 (void*) android_server_InputManager_nativeSetFocusedApplication },
1329 { "nativeSetInputDispatchMode", "(ZZ)V",
1330 (void*) android_server_InputManager_nativeSetInputDispatchMode },
Jeff Brown8d608662010-08-30 03:02:23 -07001331 { "nativeGetInputDevice", "(I)Landroid/view/InputDevice;",
1332 (void*) android_server_InputManager_nativeGetInputDevice },
1333 { "nativeGetInputDeviceIds", "()[I",
1334 (void*) android_server_InputManager_nativeGetInputDeviceIds },
Jeff Brown57c59372010-09-21 18:22:55 -07001335 { "nativeGetInputConfiguration", "(Landroid/content/res/Configuration;)V",
1336 (void*) android_server_InputManager_nativeGetInputConfiguration },
Jeff Browne33348b2010-07-15 23:54:05 -07001337 { "nativeDump", "()Ljava/lang/String;",
1338 (void*) android_server_InputManager_nativeDump },
Jeff Brown46b9ac02010-04-22 18:58:52 -07001339};
1340
1341#define FIND_CLASS(var, className) \
1342 var = env->FindClass(className); \
1343 LOG_FATAL_IF(! var, "Unable to find class " className); \
1344 var = jclass(env->NewGlobalRef(var));
1345
1346#define GET_METHOD_ID(var, clazz, methodName, methodDescriptor) \
1347 var = env->GetMethodID(clazz, methodName, methodDescriptor); \
1348 LOG_FATAL_IF(! var, "Unable to find method " methodName);
1349
1350#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \
1351 var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \
1352 LOG_FATAL_IF(! var, "Unable to find field " fieldName);
1353
1354int register_android_server_InputManager(JNIEnv* env) {
1355 int res = jniRegisterNativeMethods(env, "com/android/server/InputManager",
1356 gInputManagerMethods, NELEM(gInputManagerMethods));
1357 LOG_FATAL_IF(res < 0, "Unable to register native methods.");
1358
Jeff Brown9c3cda02010-06-15 01:31:58 -07001359 // Callbacks
Jeff Brown46b9ac02010-04-22 18:58:52 -07001360
1361 FIND_CLASS(gCallbacksClassInfo.clazz, "com/android/server/InputManager$Callbacks");
1362
Jeff Brown46b9ac02010-04-22 18:58:52 -07001363 GET_METHOD_ID(gCallbacksClassInfo.notifyConfigurationChanged, gCallbacksClassInfo.clazz,
Jeff Brown57c59372010-09-21 18:22:55 -07001364 "notifyConfigurationChanged", "(J)V");
Jeff Brown46b9ac02010-04-22 18:58:52 -07001365
1366 GET_METHOD_ID(gCallbacksClassInfo.notifyLidSwitchChanged, gCallbacksClassInfo.clazz,
1367 "notifyLidSwitchChanged", "(JZ)V");
1368
Jeff Brown7fbdc842010-06-17 20:52:56 -07001369 GET_METHOD_ID(gCallbacksClassInfo.notifyInputChannelBroken, gCallbacksClassInfo.clazz,
1370 "notifyInputChannelBroken", "(Landroid/view/InputChannel;)V");
1371
Jeff Brown349703e2010-06-22 01:27:15 -07001372 GET_METHOD_ID(gCallbacksClassInfo.notifyANR, gCallbacksClassInfo.clazz,
Jeff Brown519e0242010-09-15 15:18:56 -07001373 "notifyANR", "(Ljava/lang/Object;Landroid/view/InputChannel;)J");
Jeff Brown349703e2010-06-22 01:27:15 -07001374
Jeff Brown00fa7bd2010-07-02 15:37:36 -07001375 GET_METHOD_ID(gCallbacksClassInfo.virtualKeyDownFeedback, gCallbacksClassInfo.clazz,
1376 "virtualKeyDownFeedback", "()V");
Jeff Brown46b9ac02010-04-22 18:58:52 -07001377
Jeff Brown349703e2010-06-22 01:27:15 -07001378 GET_METHOD_ID(gCallbacksClassInfo.interceptKeyBeforeQueueing, gCallbacksClassInfo.clazz,
Jeff Brown00fa7bd2010-07-02 15:37:36 -07001379 "interceptKeyBeforeQueueing", "(JIZIZ)I");
Jeff Brown349703e2010-06-22 01:27:15 -07001380
1381 GET_METHOD_ID(gCallbacksClassInfo.interceptKeyBeforeDispatching, gCallbacksClassInfo.clazz,
Jeff Brown00fa7bd2010-07-02 15:37:36 -07001382 "interceptKeyBeforeDispatching", "(Landroid/view/InputChannel;IIIIII)Z");
Jeff Brown349703e2010-06-22 01:27:15 -07001383
1384 GET_METHOD_ID(gCallbacksClassInfo.checkInjectEventsPermission, gCallbacksClassInfo.clazz,
1385 "checkInjectEventsPermission", "(II)Z");
Jeff Brown46b9ac02010-04-22 18:58:52 -07001386
Jeff Brown46b9ac02010-04-22 18:58:52 -07001387 GET_METHOD_ID(gCallbacksClassInfo.filterTouchEvents, gCallbacksClassInfo.clazz,
1388 "filterTouchEvents", "()Z");
1389
1390 GET_METHOD_ID(gCallbacksClassInfo.filterJumpyTouchEvents, gCallbacksClassInfo.clazz,
1391 "filterJumpyTouchEvents", "()Z");
1392
1393 GET_METHOD_ID(gCallbacksClassInfo.getVirtualKeyDefinitions, gCallbacksClassInfo.clazz,
1394 "getVirtualKeyDefinitions",
1395 "(Ljava/lang/String;)[Lcom/android/server/InputManager$VirtualKeyDefinition;");
1396
Jeff Brown8d608662010-08-30 03:02:23 -07001397 GET_METHOD_ID(gCallbacksClassInfo.getInputDeviceCalibration, gCallbacksClassInfo.clazz,
1398 "getInputDeviceCalibration",
1399 "(Ljava/lang/String;)Lcom/android/server/InputManager$InputDeviceCalibration;");
1400
Jeff Brown46b9ac02010-04-22 18:58:52 -07001401 GET_METHOD_ID(gCallbacksClassInfo.getExcludedDeviceNames, gCallbacksClassInfo.clazz,
1402 "getExcludedDeviceNames", "()[Ljava/lang/String;");
1403
Jeff Brownae9fc032010-08-18 15:51:08 -07001404 GET_METHOD_ID(gCallbacksClassInfo.getMaxEventsPerSecond, gCallbacksClassInfo.clazz,
1405 "getMaxEventsPerSecond", "()I");
1406
Jeff Brown46b9ac02010-04-22 18:58:52 -07001407 // VirtualKeyDefinition
1408
1409 FIND_CLASS(gVirtualKeyDefinitionClassInfo.clazz,
1410 "com/android/server/InputManager$VirtualKeyDefinition");
1411
1412 GET_FIELD_ID(gVirtualKeyDefinitionClassInfo.scanCode, gVirtualKeyDefinitionClassInfo.clazz,
1413 "scanCode", "I");
1414
1415 GET_FIELD_ID(gVirtualKeyDefinitionClassInfo.centerX, gVirtualKeyDefinitionClassInfo.clazz,
1416 "centerX", "I");
1417
1418 GET_FIELD_ID(gVirtualKeyDefinitionClassInfo.centerY, gVirtualKeyDefinitionClassInfo.clazz,
1419 "centerY", "I");
1420
1421 GET_FIELD_ID(gVirtualKeyDefinitionClassInfo.width, gVirtualKeyDefinitionClassInfo.clazz,
1422 "width", "I");
1423
1424 GET_FIELD_ID(gVirtualKeyDefinitionClassInfo.height, gVirtualKeyDefinitionClassInfo.clazz,
1425 "height", "I");
1426
Jeff Brown8d608662010-08-30 03:02:23 -07001427 // InputDeviceCalibration
1428
1429 FIND_CLASS(gInputDeviceCalibrationClassInfo.clazz,
1430 "com/android/server/InputManager$InputDeviceCalibration");
1431
1432 GET_FIELD_ID(gInputDeviceCalibrationClassInfo.keys, gInputDeviceCalibrationClassInfo.clazz,
1433 "keys", "[Ljava/lang/String;");
1434
1435 GET_FIELD_ID(gInputDeviceCalibrationClassInfo.values, gInputDeviceCalibrationClassInfo.clazz,
1436 "values", "[Ljava/lang/String;");
1437
Jeff Brown349703e2010-06-22 01:27:15 -07001438 // InputWindow
Jeff Brown7fbdc842010-06-17 20:52:56 -07001439
Jeff Brown349703e2010-06-22 01:27:15 -07001440 FIND_CLASS(gInputWindowClassInfo.clazz, "com/android/server/InputWindow");
Jeff Brown7fbdc842010-06-17 20:52:56 -07001441
Jeff Brown349703e2010-06-22 01:27:15 -07001442 GET_FIELD_ID(gInputWindowClassInfo.inputChannel, gInputWindowClassInfo.clazz,
1443 "inputChannel", "Landroid/view/InputChannel;");
Jeff Brown7fbdc842010-06-17 20:52:56 -07001444
Jeff Brown519e0242010-09-15 15:18:56 -07001445 GET_FIELD_ID(gInputWindowClassInfo.name, gInputWindowClassInfo.clazz,
1446 "name", "Ljava/lang/String;");
1447
Jeff Brown349703e2010-06-22 01:27:15 -07001448 GET_FIELD_ID(gInputWindowClassInfo.layoutParamsFlags, gInputWindowClassInfo.clazz,
1449 "layoutParamsFlags", "I");
1450
1451 GET_FIELD_ID(gInputWindowClassInfo.layoutParamsType, gInputWindowClassInfo.clazz,
1452 "layoutParamsType", "I");
1453
1454 GET_FIELD_ID(gInputWindowClassInfo.dispatchingTimeoutNanos, gInputWindowClassInfo.clazz,
1455 "dispatchingTimeoutNanos", "J");
1456
1457 GET_FIELD_ID(gInputWindowClassInfo.frameLeft, gInputWindowClassInfo.clazz,
1458 "frameLeft", "I");
1459
1460 GET_FIELD_ID(gInputWindowClassInfo.frameTop, gInputWindowClassInfo.clazz,
1461 "frameTop", "I");
1462
Jeff Brown85a31762010-09-01 17:01:00 -07001463 GET_FIELD_ID(gInputWindowClassInfo.frameRight, gInputWindowClassInfo.clazz,
1464 "frameRight", "I");
1465
1466 GET_FIELD_ID(gInputWindowClassInfo.frameBottom, gInputWindowClassInfo.clazz,
1467 "frameBottom", "I");
1468
1469 GET_FIELD_ID(gInputWindowClassInfo.visibleFrameLeft, gInputWindowClassInfo.clazz,
1470 "visibleFrameLeft", "I");
1471
1472 GET_FIELD_ID(gInputWindowClassInfo.visibleFrameTop, gInputWindowClassInfo.clazz,
1473 "visibleFrameTop", "I");
1474
1475 GET_FIELD_ID(gInputWindowClassInfo.visibleFrameRight, gInputWindowClassInfo.clazz,
1476 "visibleFrameRight", "I");
1477
1478 GET_FIELD_ID(gInputWindowClassInfo.visibleFrameBottom, gInputWindowClassInfo.clazz,
1479 "visibleFrameBottom", "I");
1480
Jeff Brown349703e2010-06-22 01:27:15 -07001481 GET_FIELD_ID(gInputWindowClassInfo.touchableAreaLeft, gInputWindowClassInfo.clazz,
1482 "touchableAreaLeft", "I");
1483
1484 GET_FIELD_ID(gInputWindowClassInfo.touchableAreaTop, gInputWindowClassInfo.clazz,
1485 "touchableAreaTop", "I");
1486
1487 GET_FIELD_ID(gInputWindowClassInfo.touchableAreaRight, gInputWindowClassInfo.clazz,
1488 "touchableAreaRight", "I");
1489
1490 GET_FIELD_ID(gInputWindowClassInfo.touchableAreaBottom, gInputWindowClassInfo.clazz,
1491 "touchableAreaBottom", "I");
1492
1493 GET_FIELD_ID(gInputWindowClassInfo.visible, gInputWindowClassInfo.clazz,
1494 "visible", "Z");
1495
Jeff Brown519e0242010-09-15 15:18:56 -07001496 GET_FIELD_ID(gInputWindowClassInfo.canReceiveKeys, gInputWindowClassInfo.clazz,
1497 "canReceiveKeys", "Z");
1498
Jeff Brown349703e2010-06-22 01:27:15 -07001499 GET_FIELD_ID(gInputWindowClassInfo.hasFocus, gInputWindowClassInfo.clazz,
1500 "hasFocus", "Z");
1501
1502 GET_FIELD_ID(gInputWindowClassInfo.hasWallpaper, gInputWindowClassInfo.clazz,
1503 "hasWallpaper", "Z");
1504
1505 GET_FIELD_ID(gInputWindowClassInfo.paused, gInputWindowClassInfo.clazz,
1506 "paused", "Z");
1507
Jeff Brown519e0242010-09-15 15:18:56 -07001508 GET_FIELD_ID(gInputWindowClassInfo.layer, gInputWindowClassInfo.clazz,
1509 "layer", "I");
1510
Jeff Brown349703e2010-06-22 01:27:15 -07001511 GET_FIELD_ID(gInputWindowClassInfo.ownerPid, gInputWindowClassInfo.clazz,
1512 "ownerPid", "I");
1513
1514 GET_FIELD_ID(gInputWindowClassInfo.ownerUid, gInputWindowClassInfo.clazz,
1515 "ownerUid", "I");
1516
1517 // InputApplication
1518
1519 FIND_CLASS(gInputApplicationClassInfo.clazz, "com/android/server/InputApplication");
1520
1521 GET_FIELD_ID(gInputApplicationClassInfo.name, gInputApplicationClassInfo.clazz,
1522 "name", "Ljava/lang/String;");
1523
1524 GET_FIELD_ID(gInputApplicationClassInfo.dispatchingTimeoutNanos,
1525 gInputApplicationClassInfo.clazz,
1526 "dispatchingTimeoutNanos", "J");
1527
1528 GET_FIELD_ID(gInputApplicationClassInfo.token, gInputApplicationClassInfo.clazz,
1529 "token", "Ljava/lang/Object;");
Jeff Brown7fbdc842010-06-17 20:52:56 -07001530
Jeff Brown6ec402b2010-07-28 15:48:59 -07001531 // KeyEvent
1532
1533 FIND_CLASS(gKeyEventClassInfo.clazz, "android/view/KeyEvent");
1534
Jeff Brown8d608662010-08-30 03:02:23 -07001535 // MotionEvent
Jeff Brown6ec402b2010-07-28 15:48:59 -07001536
1537 FIND_CLASS(gMotionEventClassInfo.clazz, "android/view/MotionEvent");
1538
Jeff Brown8d608662010-08-30 03:02:23 -07001539 // InputDevice
1540
1541 FIND_CLASS(gInputDeviceClassInfo.clazz, "android/view/InputDevice");
1542
1543 GET_METHOD_ID(gInputDeviceClassInfo.ctor, gInputDeviceClassInfo.clazz,
1544 "<init>", "()V");
1545
1546 GET_METHOD_ID(gInputDeviceClassInfo.addMotionRange, gInputDeviceClassInfo.clazz,
1547 "addMotionRange", "(IFFFF)V");
1548
1549 GET_FIELD_ID(gInputDeviceClassInfo.mId, gInputDeviceClassInfo.clazz,
1550 "mId", "I");
1551
1552 GET_FIELD_ID(gInputDeviceClassInfo.mName, gInputDeviceClassInfo.clazz,
1553 "mName", "Ljava/lang/String;");
1554
1555 GET_FIELD_ID(gInputDeviceClassInfo.mSources, gInputDeviceClassInfo.clazz,
1556 "mSources", "I");
1557
1558 GET_FIELD_ID(gInputDeviceClassInfo.mKeyboardType, gInputDeviceClassInfo.clazz,
1559 "mKeyboardType", "I");
1560
1561 GET_FIELD_ID(gInputDeviceClassInfo.mMotionRanges, gInputDeviceClassInfo.clazz,
1562 "mMotionRanges", "[Landroid/view/InputDevice$MotionRange;");
1563
Jeff Brown57c59372010-09-21 18:22:55 -07001564 // Configuration
1565
1566 FIND_CLASS(gConfigurationClassInfo.clazz, "android/content/res/Configuration");
1567
1568 GET_FIELD_ID(gConfigurationClassInfo.touchscreen, gConfigurationClassInfo.clazz,
1569 "touchscreen", "I");
1570
1571 GET_FIELD_ID(gConfigurationClassInfo.keyboard, gConfigurationClassInfo.clazz,
1572 "keyboard", "I");
1573
1574 GET_FIELD_ID(gConfigurationClassInfo.navigation, gConfigurationClassInfo.clazz,
1575 "navigation", "I");
1576
Jeff Brown46b9ac02010-04-22 18:58:52 -07001577 return 0;
1578}
1579
Jeff Brown46b9ac02010-04-22 18:58:52 -07001580} /* namespace android */