blob: cbdfba949290a073466a5bebf1e99e06539feae4 [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 Brown349703e2010-06-22 01:27:15 -0700141// ----------------------------------------------------------------------------
142
143static inline nsecs_t now() {
144 return systemTime(SYSTEM_TIME_MONOTONIC);
145}
Jeff Brown7fbdc842010-06-17 20:52:56 -0700146
Jeff Brown9c3cda02010-06-15 01:31:58 -0700147// ----------------------------------------------------------------------------
148
149class NativeInputManager : public virtual RefBase,
150 public virtual InputReaderPolicyInterface,
151 public virtual InputDispatcherPolicyInterface {
152protected:
153 virtual ~NativeInputManager();
154
155public:
156 NativeInputManager(jobject callbacksObj);
157
158 inline sp<InputManager> getInputManager() const { return mInputManager; }
159
Jeff Brownb88102f2010-09-08 11:49:43 -0700160 void dump(String8& dump);
Jeff Browne33348b2010-07-15 23:54:05 -0700161
Jeff Brown9c3cda02010-06-15 01:31:58 -0700162 void setDisplaySize(int32_t displayId, int32_t width, int32_t height);
163 void setDisplayOrientation(int32_t displayId, int32_t orientation);
164
Jeff Brown7fbdc842010-06-17 20:52:56 -0700165 status_t registerInputChannel(JNIEnv* env, const sp<InputChannel>& inputChannel,
Jeff Browna41ca772010-08-11 14:46:32 -0700166 jweak inputChannelObjWeak, bool monitor);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700167 status_t unregisterInputChannel(JNIEnv* env, const sp<InputChannel>& inputChannel);
168
Jeff Brown349703e2010-06-22 01:27:15 -0700169 void setInputWindows(JNIEnv* env, jobjectArray windowObjArray);
170 void setFocusedApplication(JNIEnv* env, jobject applicationObj);
171 void setInputDispatchMode(bool enabled, bool frozen);
Jeff Brown349703e2010-06-22 01:27:15 -0700172
Jeff Brown9c3cda02010-06-15 01:31:58 -0700173 /* --- InputReaderPolicyInterface implementation --- */
174
175 virtual bool getDisplayInfo(int32_t displayId,
176 int32_t* width, int32_t* height, int32_t* orientation);
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700177 virtual void virtualKeyDownFeedback();
Jeff Brown9c3cda02010-06-15 01:31:58 -0700178 virtual int32_t interceptKey(nsecs_t when, int32_t deviceId,
Jeff Brown6d0fec22010-07-23 21:28:06 -0700179 bool down, int32_t keyCode, int32_t scanCode, uint32_t& policyFlags);
180 virtual int32_t interceptSwitch(nsecs_t when, int32_t switchCode, int32_t switchValue,
181 uint32_t& policyFlags);
182 virtual int32_t interceptGeneric(nsecs_t when, uint32_t& policyFlags);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700183 virtual bool filterTouchEvents();
184 virtual bool filterJumpyTouchEvents();
185 virtual void getVirtualKeyDefinitions(const String8& deviceName,
Jeff Brown8d608662010-08-30 03:02:23 -0700186 Vector<VirtualKeyDefinition>& outVirtualKeyDefinitions);
187 virtual void getInputDeviceCalibration(const String8& deviceName,
188 InputDeviceCalibration& outCalibration);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700189 virtual void getExcludedDeviceNames(Vector<String8>& outExcludedDeviceNames);
190
191 /* --- InputDispatcherPolicyInterface implementation --- */
192
193 virtual void notifyConfigurationChanged(nsecs_t when);
Jeff Brown519e0242010-09-15 15:18:56 -0700194 virtual nsecs_t notifyANR(const sp<InputApplicationHandle>& inputApplicationHandle,
195 const sp<InputChannel>& inputChannel);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700196 virtual void notifyInputChannelBroken(const sp<InputChannel>& inputChannel);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700197 virtual nsecs_t getKeyRepeatTimeout();
Jeff Brownb21fb102010-09-07 10:44:57 -0700198 virtual nsecs_t getKeyRepeatDelay();
Jeff Brownae9fc032010-08-18 15:51:08 -0700199 virtual int32_t getMaxEventsPerSecond();
Jeff Brownb88102f2010-09-08 11:49:43 -0700200 virtual bool interceptKeyBeforeDispatching(const sp<InputChannel>& inputChannel,
201 const KeyEvent* keyEvent, uint32_t policyFlags);
202 virtual void pokeUserActivity(nsecs_t eventTime, int32_t windowType, int32_t eventType);
203 virtual bool checkInjectEventsPermissionNonReentrant(
204 int32_t injectorPid, int32_t injectorUid);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700205
206private:
Jeff Brownb88102f2010-09-08 11:49:43 -0700207 class ApplicationToken : public InputApplicationHandle {
208 jweak mTokenObjWeak;
Jeff Brown349703e2010-06-22 01:27:15 -0700209
210 public:
Jeff Brownb88102f2010-09-08 11:49:43 -0700211 ApplicationToken(jweak tokenObjWeak) :
212 mTokenObjWeak(tokenObjWeak) { }
Jeff Brown349703e2010-06-22 01:27:15 -0700213
Jeff Brownb88102f2010-09-08 11:49:43 -0700214 virtual ~ApplicationToken() {
215 JNIEnv* env = NativeInputManager::jniEnv();
216 env->DeleteWeakGlobalRef(mTokenObjWeak);
217 }
Jeff Brown349703e2010-06-22 01:27:15 -0700218
Jeff Brownb88102f2010-09-08 11:49:43 -0700219 inline jweak getTokenObj() { return mTokenObjWeak; }
Jeff Brown349703e2010-06-22 01:27:15 -0700220 };
221
Jeff Brown9c3cda02010-06-15 01:31:58 -0700222 sp<InputManager> mInputManager;
223
224 jobject mCallbacksObj;
225
226 // Cached filtering policies.
227 int32_t mFilterTouchEvents;
228 int32_t mFilterJumpyTouchEvents;
229
Jeff Brownae9fc032010-08-18 15:51:08 -0700230 // Cached throttling policy.
231 int32_t mMaxEventsPerSecond;
232
Jeff Brown9c3cda02010-06-15 01:31:58 -0700233 // Cached display state. (lock mDisplayLock)
234 Mutex mDisplayLock;
235 int32_t mDisplayWidth, mDisplayHeight;
236 int32_t mDisplayOrientation;
237
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700238 // Power manager interactions.
Jeff Brown9c3cda02010-06-15 01:31:58 -0700239 bool isScreenOn();
240 bool isScreenBright();
241
Jeff Brown2cbecea2010-08-17 15:59:26 -0700242 // Weak references to all currently registered input channels by connection pointer.
Jeff Brown7fbdc842010-06-17 20:52:56 -0700243 Mutex mInputChannelRegistryLock;
Jeff Brown2cbecea2010-08-17 15:59:26 -0700244 KeyedVector<InputChannel*, jweak> mInputChannelObjWeakTable;
Jeff Brown7fbdc842010-06-17 20:52:56 -0700245
246 jobject getInputChannelObjLocal(JNIEnv* env, const sp<InputChannel>& inputChannel);
247
Jeff Brown349703e2010-06-22 01:27:15 -0700248 static bool populateWindow(JNIEnv* env, jobject windowObj, InputWindow& outWindow);
Jeff Brown349703e2010-06-22 01:27:15 -0700249
Jeff Brownb88102f2010-09-08 11:49:43 -0700250 static bool isPolicyKey(int32_t keyCode, bool isScreenOn);
251 static bool checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName);
Jeff Browna41ca772010-08-11 14:46:32 -0700252
Jeff Brown9c3cda02010-06-15 01:31:58 -0700253 static inline JNIEnv* jniEnv() {
254 return AndroidRuntime::getJNIEnv();
255 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700256};
257
258// ----------------------------------------------------------------------------
259
260NativeInputManager::NativeInputManager(jobject callbacksObj) :
261 mFilterTouchEvents(-1), mFilterJumpyTouchEvents(-1),
Jeff Brownae9fc032010-08-18 15:51:08 -0700262 mMaxEventsPerSecond(-1),
Jeff Brownb88102f2010-09-08 11:49:43 -0700263 mDisplayWidth(-1), mDisplayHeight(-1), mDisplayOrientation(ROTATION_0) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700264 JNIEnv* env = jniEnv();
265
266 mCallbacksObj = env->NewGlobalRef(callbacksObj);
267
268 sp<EventHub> eventHub = new EventHub();
269 mInputManager = new InputManager(eventHub, this, this);
270}
271
272NativeInputManager::~NativeInputManager() {
273 JNIEnv* env = jniEnv();
274
275 env->DeleteGlobalRef(mCallbacksObj);
276}
277
Jeff Brownb88102f2010-09-08 11:49:43 -0700278void NativeInputManager::dump(String8& dump) {
279 dump.append("Input Reader State:\n");
280 mInputManager->getReader()->dump(dump);
281 dump.append("\n");
Jeff Brown6d0fec22010-07-23 21:28:06 -0700282
Jeff Brownb88102f2010-09-08 11:49:43 -0700283 dump.append("Input Dispatcher State:\n");
284 mInputManager->getDispatcher()->dump(dump);
285 dump.append("\n");
Jeff Brown9c3cda02010-06-15 01:31:58 -0700286}
287
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700288bool NativeInputManager::isPolicyKey(int32_t keyCode, bool isScreenOn) {
289 // Special keys that the WindowManagerPolicy might care about.
290 switch (keyCode) {
Jeff Brownfd035822010-06-30 16:10:35 -0700291 case AKEYCODE_VOLUME_UP:
292 case AKEYCODE_VOLUME_DOWN:
293 case AKEYCODE_ENDCALL:
294 case AKEYCODE_POWER:
295 case AKEYCODE_CALL:
296 case AKEYCODE_HOME:
297 case AKEYCODE_MENU:
298 case AKEYCODE_SEARCH:
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700299 // media keys
Jeff Brownfd035822010-06-30 16:10:35 -0700300 case AKEYCODE_HEADSETHOOK:
301 case AKEYCODE_MEDIA_PLAY_PAUSE:
302 case AKEYCODE_MEDIA_STOP:
303 case AKEYCODE_MEDIA_NEXT:
304 case AKEYCODE_MEDIA_PREVIOUS:
305 case AKEYCODE_MEDIA_REWIND:
306 case AKEYCODE_MEDIA_FAST_FORWARD:
Jeff Brownb88102f2010-09-08 11:49:43 -0700307 // The policy always cares about these keys.
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700308 return true;
309 default:
310 // We need to pass all keys to the policy in the following cases:
311 // - screen is off
312 // - keyguard is visible
313 // - policy is performing key chording
314 //return ! isScreenOn || keyguardVisible || chording;
315 return true; // XXX stubbed out for now
316 }
317}
318
Jeff Brown7fbdc842010-06-17 20:52:56 -0700319bool NativeInputManager::checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700320 if (env->ExceptionCheck()) {
321 LOGE("An exception was thrown by callback '%s'.", methodName);
322 LOGE_EX(env);
323 env->ExceptionClear();
324 return true;
325 }
326 return false;
327}
328
329void NativeInputManager::setDisplaySize(int32_t displayId, int32_t width, int32_t height) {
330 if (displayId == 0) {
331 AutoMutex _l(mDisplayLock);
332
333 mDisplayWidth = width;
334 mDisplayHeight = height;
335 }
336}
337
338void NativeInputManager::setDisplayOrientation(int32_t displayId, int32_t orientation) {
339 if (displayId == 0) {
340 AutoMutex _l(mDisplayLock);
341
342 mDisplayOrientation = orientation;
343 }
344}
345
Jeff Brown7fbdc842010-06-17 20:52:56 -0700346status_t NativeInputManager::registerInputChannel(JNIEnv* env,
Jeff Browna41ca772010-08-11 14:46:32 -0700347 const sp<InputChannel>& inputChannel, jobject inputChannelObj, bool monitor) {
Jeff Brown7fbdc842010-06-17 20:52:56 -0700348 jweak inputChannelObjWeak = env->NewWeakGlobalRef(inputChannelObj);
349 if (! inputChannelObjWeak) {
350 LOGE("Could not create weak reference for input channel.");
351 LOGE_EX(env);
352 return NO_MEMORY;
353 }
354
355 status_t status;
356 {
357 AutoMutex _l(mInputChannelRegistryLock);
358
Jeff Brown2cbecea2010-08-17 15:59:26 -0700359 ssize_t index = mInputChannelObjWeakTable.indexOfKey(inputChannel.get());
Jeff Brown7fbdc842010-06-17 20:52:56 -0700360 if (index >= 0) {
361 LOGE("Input channel object '%s' has already been registered",
362 inputChannel->getName().string());
363 status = INVALID_OPERATION;
364 goto DeleteWeakRef;
365 }
366
Jeff Brown2cbecea2010-08-17 15:59:26 -0700367 mInputChannelObjWeakTable.add(inputChannel.get(), inputChannelObjWeak);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700368 }
369
Jeff Brownb88102f2010-09-08 11:49:43 -0700370 status = mInputManager->getDispatcher()->registerInputChannel(inputChannel, monitor);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700371 if (! status) {
Jeff Browna41ca772010-08-11 14:46:32 -0700372 // Success.
Jeff Brown7fbdc842010-06-17 20:52:56 -0700373 return OK;
374 }
375
Jeff Browna41ca772010-08-11 14:46:32 -0700376 // Failed!
Jeff Brown7fbdc842010-06-17 20:52:56 -0700377 {
378 AutoMutex _l(mInputChannelRegistryLock);
Jeff Brown2cbecea2010-08-17 15:59:26 -0700379 mInputChannelObjWeakTable.removeItem(inputChannel.get());
Jeff Brown7fbdc842010-06-17 20:52:56 -0700380 }
381
382DeleteWeakRef:
383 env->DeleteWeakGlobalRef(inputChannelObjWeak);
384 return status;
385}
386
387status_t NativeInputManager::unregisterInputChannel(JNIEnv* env,
388 const sp<InputChannel>& inputChannel) {
389 jweak inputChannelObjWeak;
390 {
391 AutoMutex _l(mInputChannelRegistryLock);
392
Jeff Brown2cbecea2010-08-17 15:59:26 -0700393 ssize_t index = mInputChannelObjWeakTable.indexOfKey(inputChannel.get());
Jeff Brown7fbdc842010-06-17 20:52:56 -0700394 if (index < 0) {
395 LOGE("Input channel object '%s' is not currently registered",
396 inputChannel->getName().string());
397 return INVALID_OPERATION;
398 }
399
Jeff Brown2cbecea2010-08-17 15:59:26 -0700400 inputChannelObjWeak = mInputChannelObjWeakTable.valueAt(index);
401 mInputChannelObjWeakTable.removeItemsAt(index);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700402 }
403
404 env->DeleteWeakGlobalRef(inputChannelObjWeak);
405
Jeff Brownb88102f2010-09-08 11:49:43 -0700406 return mInputManager->getDispatcher()->unregisterInputChannel(inputChannel);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700407}
408
409jobject NativeInputManager::getInputChannelObjLocal(JNIEnv* env,
410 const sp<InputChannel>& inputChannel) {
411 {
412 AutoMutex _l(mInputChannelRegistryLock);
413
Jeff Brown2cbecea2010-08-17 15:59:26 -0700414 ssize_t index = mInputChannelObjWeakTable.indexOfKey(inputChannel.get());
Jeff Brown7fbdc842010-06-17 20:52:56 -0700415 if (index < 0) {
416 return NULL;
417 }
418
Jeff Brown2cbecea2010-08-17 15:59:26 -0700419 jweak inputChannelObjWeak = mInputChannelObjWeakTable.valueAt(index);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700420 return env->NewLocalRef(inputChannelObjWeak);
421 }
422}
423
Jeff Brown9c3cda02010-06-15 01:31:58 -0700424bool NativeInputManager::getDisplayInfo(int32_t displayId,
425 int32_t* width, int32_t* height, int32_t* orientation) {
426 bool result = false;
427 if (displayId == 0) {
428 AutoMutex _l(mDisplayLock);
429
430 if (mDisplayWidth > 0) {
Jeff Brown6d0fec22010-07-23 21:28:06 -0700431 if (width) {
432 *width = mDisplayWidth;
433 }
434 if (height) {
435 *height = mDisplayHeight;
436 }
437 if (orientation) {
438 *orientation = mDisplayOrientation;
439 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700440 result = true;
441 }
442 }
443 return result;
444}
445
446bool NativeInputManager::isScreenOn() {
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700447 return android_server_PowerManagerService_isScreenOn();
Jeff Brown9c3cda02010-06-15 01:31:58 -0700448}
449
450bool NativeInputManager::isScreenBright() {
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700451 return android_server_PowerManagerService_isScreenBright();
Jeff Brown9c3cda02010-06-15 01:31:58 -0700452}
453
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700454void NativeInputManager::virtualKeyDownFeedback() {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700455#if DEBUG_INPUT_READER_POLICY
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700456 LOGD("virtualKeyDownFeedback");
Jeff Brown9c3cda02010-06-15 01:31:58 -0700457#endif
458
459 JNIEnv* env = jniEnv();
460
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700461 env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.virtualKeyDownFeedback);
462 checkAndClearExceptionFromCallback(env, "virtualKeyDownFeedback");
Jeff Brown9c3cda02010-06-15 01:31:58 -0700463}
464
465int32_t NativeInputManager::interceptKey(nsecs_t when,
Jeff Brown6d0fec22010-07-23 21:28:06 -0700466 int32_t deviceId, bool down, int32_t keyCode, int32_t scanCode, uint32_t& policyFlags) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700467#if DEBUG_INPUT_READER_POLICY
468 LOGD("interceptKey - when=%lld, deviceId=%d, down=%d, keyCode=%d, scanCode=%d, "
Jeff Brown349703e2010-06-22 01:27:15 -0700469 "policyFlags=0x%x",
Jeff Brown9c3cda02010-06-15 01:31:58 -0700470 when, deviceId, down, keyCode, scanCode, policyFlags);
471#endif
472
473 const int32_t WM_ACTION_PASS_TO_USER = 1;
474 const int32_t WM_ACTION_POKE_USER_ACTIVITY = 2;
475 const int32_t WM_ACTION_GO_TO_SLEEP = 4;
476
Jeff Brown9c3cda02010-06-15 01:31:58 -0700477 bool isScreenOn = this->isScreenOn();
478 bool isScreenBright = this->isScreenBright();
479
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700480 jint wmActions = 0;
481 if (isPolicyKey(keyCode, isScreenOn)) {
482 JNIEnv* env = jniEnv();
483
484 wmActions = env->CallIntMethod(mCallbacksObj,
485 gCallbacksClassInfo.interceptKeyBeforeQueueing,
486 when, keyCode, down, policyFlags, isScreenOn);
487 if (checkAndClearExceptionFromCallback(env, "interceptKeyBeforeQueueing")) {
488 wmActions = 0;
489 }
490 } else {
491 wmActions = WM_ACTION_PASS_TO_USER;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700492 }
493
494 int32_t actions = InputReaderPolicyInterface::ACTION_NONE;
495 if (! isScreenOn) {
496 // Key presses and releases wake the device.
Jeff Brown6d0fec22010-07-23 21:28:06 -0700497 policyFlags |= POLICY_FLAG_WOKE_HERE;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700498 }
499
500 if (! isScreenBright) {
501 // Key presses and releases brighten the screen if dimmed.
Jeff Brown6d0fec22010-07-23 21:28:06 -0700502 policyFlags |= POLICY_FLAG_BRIGHT_HERE;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700503 }
504
505 if (wmActions & WM_ACTION_GO_TO_SLEEP) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700506 android_server_PowerManagerService_goToSleep(when);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700507 }
508
509 if (wmActions & WM_ACTION_POKE_USER_ACTIVITY) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700510 android_server_PowerManagerService_userActivity(when, POWER_MANAGER_BUTTON_EVENT);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700511 }
512
513 if (wmActions & WM_ACTION_PASS_TO_USER) {
514 actions |= InputReaderPolicyInterface::ACTION_DISPATCH;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700515 }
Jeff Brown349703e2010-06-22 01:27:15 -0700516
Jeff Brown9c3cda02010-06-15 01:31:58 -0700517 return actions;
518}
519
Jeff Brown6d0fec22010-07-23 21:28:06 -0700520int32_t NativeInputManager::interceptGeneric(nsecs_t when, uint32_t& policyFlags) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700521#if DEBUG_INPUT_READER_POLICY
Jeff Brown6d0fec22010-07-23 21:28:06 -0700522 LOGD("interceptGeneric - when=%lld, policyFlags=0x%x", when, policyFlags);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700523#endif
524
Jeff Brown5c225b12010-06-16 01:53:36 -0700525 int32_t actions = InputReaderPolicyInterface::ACTION_NONE;
526 if (isScreenOn()) {
Jeff Brown6d0fec22010-07-23 21:28:06 -0700527 // Only dispatch events when the device is awake.
Jeff Brown349703e2010-06-22 01:27:15 -0700528 // Do not wake the device.
Jeff Brown5c225b12010-06-16 01:53:36 -0700529 actions |= InputReaderPolicyInterface::ACTION_DISPATCH;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700530
Jeff Brown349703e2010-06-22 01:27:15 -0700531 if (! isScreenBright()) {
532 // Brighten the screen if dimmed.
Jeff Brown6d0fec22010-07-23 21:28:06 -0700533 policyFlags |= POLICY_FLAG_BRIGHT_HERE;
Jeff Brown349703e2010-06-22 01:27:15 -0700534 }
Jeff Brown5c225b12010-06-16 01:53:36 -0700535 }
536
537 return actions;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700538}
539
540int32_t NativeInputManager::interceptSwitch(nsecs_t when, int32_t switchCode,
Jeff Brown6d0fec22010-07-23 21:28:06 -0700541 int32_t switchValue, uint32_t& policyFlags) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700542#if DEBUG_INPUT_READER_POLICY
Jeff Brown6d0fec22010-07-23 21:28:06 -0700543 LOGD("interceptSwitch - when=%lld, switchCode=%d, switchValue=%d, policyFlags=0x%x",
544 when, switchCode, switchValue, policyFlags);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700545#endif
546
547 JNIEnv* env = jniEnv();
548
549 switch (switchCode) {
550 case SW_LID:
551 env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyLidSwitchChanged,
552 when, switchValue == 0);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700553 checkAndClearExceptionFromCallback(env, "notifyLidSwitchChanged");
Jeff Brown9c3cda02010-06-15 01:31:58 -0700554 break;
555 }
556
557 return InputReaderPolicyInterface::ACTION_NONE;
558}
559
560bool NativeInputManager::filterTouchEvents() {
561 if (mFilterTouchEvents < 0) {
562 JNIEnv* env = jniEnv();
563
564 jboolean result = env->CallBooleanMethod(mCallbacksObj,
565 gCallbacksClassInfo.filterTouchEvents);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700566 if (checkAndClearExceptionFromCallback(env, "filterTouchEvents")) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700567 result = false;
568 }
569
570 mFilterTouchEvents = result ? 1 : 0;
571 }
572 return mFilterTouchEvents;
573}
574
575bool NativeInputManager::filterJumpyTouchEvents() {
576 if (mFilterJumpyTouchEvents < 0) {
577 JNIEnv* env = jniEnv();
578
579 jboolean result = env->CallBooleanMethod(mCallbacksObj,
580 gCallbacksClassInfo.filterJumpyTouchEvents);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700581 if (checkAndClearExceptionFromCallback(env, "filterJumpyTouchEvents")) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700582 result = false;
583 }
584
585 mFilterJumpyTouchEvents = result ? 1 : 0;
586 }
587 return mFilterJumpyTouchEvents;
588}
589
590void NativeInputManager::getVirtualKeyDefinitions(const String8& deviceName,
Jeff Brown8d608662010-08-30 03:02:23 -0700591 Vector<VirtualKeyDefinition>& outVirtualKeyDefinitions) {
592 outVirtualKeyDefinitions.clear();
593
Jeff Brown9c3cda02010-06-15 01:31:58 -0700594 JNIEnv* env = jniEnv();
595
596 jstring deviceNameStr = env->NewStringUTF(deviceName.string());
Jeff Brown7fbdc842010-06-17 20:52:56 -0700597 if (! checkAndClearExceptionFromCallback(env, "getVirtualKeyDefinitions")) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700598 jobjectArray result = jobjectArray(env->CallObjectMethod(mCallbacksObj,
599 gCallbacksClassInfo.getVirtualKeyDefinitions, deviceNameStr));
Jeff Brown7fbdc842010-06-17 20:52:56 -0700600 if (! checkAndClearExceptionFromCallback(env, "getVirtualKeyDefinitions") && result) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700601 jsize length = env->GetArrayLength(result);
602 for (jsize i = 0; i < length; i++) {
603 jobject item = env->GetObjectArrayElement(result, i);
604
605 outVirtualKeyDefinitions.add();
606 outVirtualKeyDefinitions.editTop().scanCode =
607 int32_t(env->GetIntField(item, gVirtualKeyDefinitionClassInfo.scanCode));
608 outVirtualKeyDefinitions.editTop().centerX =
609 int32_t(env->GetIntField(item, gVirtualKeyDefinitionClassInfo.centerX));
610 outVirtualKeyDefinitions.editTop().centerY =
611 int32_t(env->GetIntField(item, gVirtualKeyDefinitionClassInfo.centerY));
612 outVirtualKeyDefinitions.editTop().width =
613 int32_t(env->GetIntField(item, gVirtualKeyDefinitionClassInfo.width));
614 outVirtualKeyDefinitions.editTop().height =
615 int32_t(env->GetIntField(item, gVirtualKeyDefinitionClassInfo.height));
616
617 env->DeleteLocalRef(item);
618 }
619 env->DeleteLocalRef(result);
620 }
621 env->DeleteLocalRef(deviceNameStr);
622 }
623}
624
Jeff Brown8d608662010-08-30 03:02:23 -0700625void NativeInputManager::getInputDeviceCalibration(const String8& deviceName,
626 InputDeviceCalibration& outCalibration) {
627 outCalibration.clear();
628
629 JNIEnv* env = jniEnv();
630
631 jstring deviceNameStr = env->NewStringUTF(deviceName.string());
632 if (! checkAndClearExceptionFromCallback(env, "getInputDeviceCalibration")) {
633 jobject result = env->CallObjectMethod(mCallbacksObj,
634 gCallbacksClassInfo.getInputDeviceCalibration, deviceNameStr);
635 if (! checkAndClearExceptionFromCallback(env, "getInputDeviceCalibration") && result) {
636 jobjectArray keys = jobjectArray(env->GetObjectField(result,
637 gInputDeviceCalibrationClassInfo.keys));
638 jobjectArray values = jobjectArray(env->GetObjectField(result,
639 gInputDeviceCalibrationClassInfo.values));
640
641 jsize length = env->GetArrayLength(keys);
642 for (jsize i = 0; i < length; i++) {
643 jstring keyStr = jstring(env->GetObjectArrayElement(keys, i));
644 jstring valueStr = jstring(env->GetObjectArrayElement(values, i));
645
646 const char* keyChars = env->GetStringUTFChars(keyStr, NULL);
647 String8 key(keyChars);
648 env->ReleaseStringUTFChars(keyStr, keyChars);
649
650 const char* valueChars = env->GetStringUTFChars(valueStr, NULL);
651 String8 value(valueChars);
652 env->ReleaseStringUTFChars(valueStr, valueChars);
653
654 outCalibration.addProperty(key, value);
655
656 env->DeleteLocalRef(keyStr);
657 env->DeleteLocalRef(valueStr);
658 }
659 env->DeleteLocalRef(keys);
660 env->DeleteLocalRef(values);
661 env->DeleteLocalRef(result);
662 }
663 env->DeleteLocalRef(deviceNameStr);
664 }
665}
666
Jeff Brown9c3cda02010-06-15 01:31:58 -0700667void NativeInputManager::getExcludedDeviceNames(Vector<String8>& outExcludedDeviceNames) {
Jeff Brown8d608662010-08-30 03:02:23 -0700668 outExcludedDeviceNames.clear();
669
Jeff Brown9c3cda02010-06-15 01:31:58 -0700670 JNIEnv* env = jniEnv();
671
672 jobjectArray result = jobjectArray(env->CallObjectMethod(mCallbacksObj,
673 gCallbacksClassInfo.getExcludedDeviceNames));
Jeff Brown7fbdc842010-06-17 20:52:56 -0700674 if (! checkAndClearExceptionFromCallback(env, "getExcludedDeviceNames") && result) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700675 jsize length = env->GetArrayLength(result);
676 for (jsize i = 0; i < length; i++) {
677 jstring item = jstring(env->GetObjectArrayElement(result, i));
678
679 const char* deviceNameChars = env->GetStringUTFChars(item, NULL);
680 outExcludedDeviceNames.add(String8(deviceNameChars));
681 env->ReleaseStringUTFChars(item, deviceNameChars);
682
683 env->DeleteLocalRef(item);
684 }
685 env->DeleteLocalRef(result);
686 }
687}
688
689void NativeInputManager::notifyConfigurationChanged(nsecs_t when) {
690#if DEBUG_INPUT_DISPATCHER_POLICY
691 LOGD("notifyConfigurationChanged - when=%lld", when);
692#endif
693
694 JNIEnv* env = jniEnv();
695
696 InputConfiguration config;
Jeff Brownb88102f2010-09-08 11:49:43 -0700697 mInputManager->getReader()->getInputConfiguration(& config);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700698
699 env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyConfigurationChanged,
700 when, config.touchScreen, config.keyboard, config.navigation);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700701 checkAndClearExceptionFromCallback(env, "notifyConfigurationChanged");
Jeff Brown9c3cda02010-06-15 01:31:58 -0700702}
703
Jeff Brown519e0242010-09-15 15:18:56 -0700704nsecs_t NativeInputManager::notifyANR(const sp<InputApplicationHandle>& inputApplicationHandle,
705 const sp<InputChannel>& inputChannel) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700706#if DEBUG_INPUT_DISPATCHER_POLICY
707 LOGD("notifyANR");
708#endif
709
710 JNIEnv* env = jniEnv();
711
Jeff Brown519e0242010-09-15 15:18:56 -0700712 jobject tokenObjLocal;
713 if (inputApplicationHandle.get()) {
714 ApplicationToken* token = static_cast<ApplicationToken*>(inputApplicationHandle.get());
715 jweak tokenObjWeak = token->getTokenObj();
716 tokenObjLocal = env->NewLocalRef(tokenObjWeak);
Jeff Brownb88102f2010-09-08 11:49:43 -0700717 } else {
Jeff Brown519e0242010-09-15 15:18:56 -0700718 tokenObjLocal = NULL;
Jeff Brownb88102f2010-09-08 11:49:43 -0700719 }
720
Jeff Brown519e0242010-09-15 15:18:56 -0700721 jobject inputChannelObjLocal;
722 if (inputChannel.get()) {
723 inputChannelObjLocal = getInputChannelObjLocal(env, inputChannel);
724 } else {
725 inputChannelObjLocal = NULL;
726 }
727
728 jlong newTimeout = env->CallLongMethod(mCallbacksObj,
729 gCallbacksClassInfo.notifyANR, tokenObjLocal, inputChannelObjLocal);
730 if (checkAndClearExceptionFromCallback(env, "notifyANR")) {
731 newTimeout = 0; // abort dispatch
732 } else {
733 assert(newTimeout >= 0);
734 }
735
736 env->DeleteLocalRef(tokenObjLocal);
737 env->DeleteLocalRef(inputChannelObjLocal);
Jeff Brownb88102f2010-09-08 11:49:43 -0700738 return newTimeout;
739}
740
Jeff Brown9c3cda02010-06-15 01:31:58 -0700741void NativeInputManager::notifyInputChannelBroken(const sp<InputChannel>& inputChannel) {
742#if DEBUG_INPUT_DISPATCHER_POLICY
743 LOGD("notifyInputChannelBroken - inputChannel='%s'", inputChannel->getName().string());
744#endif
745
Jeff Brown7fbdc842010-06-17 20:52:56 -0700746 JNIEnv* env = jniEnv();
747
748 jobject inputChannelObjLocal = getInputChannelObjLocal(env, inputChannel);
749 if (inputChannelObjLocal) {
750 env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyInputChannelBroken,
751 inputChannelObjLocal);
752 checkAndClearExceptionFromCallback(env, "notifyInputChannelBroken");
753
754 env->DeleteLocalRef(inputChannelObjLocal);
755 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700756}
757
Jeff Brown9c3cda02010-06-15 01:31:58 -0700758nsecs_t NativeInputManager::getKeyRepeatTimeout() {
759 if (! isScreenOn()) {
760 // Disable key repeat when the screen is off.
761 return -1;
762 } else {
763 // TODO use ViewConfiguration.getLongPressTimeout()
764 return milliseconds_to_nanoseconds(500);
765 }
766}
767
Jeff Brownb21fb102010-09-07 10:44:57 -0700768nsecs_t NativeInputManager::getKeyRepeatDelay() {
769 return milliseconds_to_nanoseconds(50);
770}
771
Jeff Brownae9fc032010-08-18 15:51:08 -0700772int32_t NativeInputManager::getMaxEventsPerSecond() {
773 if (mMaxEventsPerSecond < 0) {
774 JNIEnv* env = jniEnv();
775
776 jint result = env->CallIntMethod(mCallbacksObj,
777 gCallbacksClassInfo.getMaxEventsPerSecond);
778 if (checkAndClearExceptionFromCallback(env, "getMaxEventsPerSecond")) {
Jeff Brown3d8c9bd2010-08-18 17:48:53 -0700779 result = 60;
Jeff Brownae9fc032010-08-18 15:51:08 -0700780 }
781
782 mMaxEventsPerSecond = result;
783 }
784 return mMaxEventsPerSecond;
785}
786
Jeff Brown349703e2010-06-22 01:27:15 -0700787void NativeInputManager::setInputWindows(JNIEnv* env, jobjectArray windowObjArray) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700788 Vector<InputWindow> windows;
Jeff Brown349703e2010-06-22 01:27:15 -0700789
Jeff Brownb88102f2010-09-08 11:49:43 -0700790 jsize length = env->GetArrayLength(windowObjArray);
791 for (jsize i = 0; i < length; i++) {
792 jobject inputTargetObj = env->GetObjectArrayElement(windowObjArray, i);
793 if (! inputTargetObj) {
794 break; // found null element indicating end of used portion of the array
Jeff Brown349703e2010-06-22 01:27:15 -0700795 }
796
Jeff Brownb88102f2010-09-08 11:49:43 -0700797 windows.push();
798 InputWindow& window = windows.editTop();
799 bool valid = populateWindow(env, inputTargetObj, window);
800 if (! valid) {
801 windows.pop();
Jeff Brown349703e2010-06-22 01:27:15 -0700802 }
803
Jeff Brownb88102f2010-09-08 11:49:43 -0700804 env->DeleteLocalRef(inputTargetObj);
805 }
Jeff Brown349703e2010-06-22 01:27:15 -0700806
Jeff Brownb88102f2010-09-08 11:49:43 -0700807 mInputManager->getDispatcher()->setInputWindows(windows);
Jeff Brown349703e2010-06-22 01:27:15 -0700808}
809
810bool NativeInputManager::populateWindow(JNIEnv* env, jobject windowObj,
811 InputWindow& outWindow) {
812 bool valid = false;
813
814 jobject inputChannelObj = env->GetObjectField(windowObj,
815 gInputWindowClassInfo.inputChannel);
816 if (inputChannelObj) {
817 sp<InputChannel> inputChannel =
818 android_view_InputChannel_getInputChannel(env, inputChannelObj);
819 if (inputChannel != NULL) {
Jeff Brown519e0242010-09-15 15:18:56 -0700820 jstring name = jstring(env->GetObjectField(windowObj,
821 gInputWindowClassInfo.name));
Jeff Brown349703e2010-06-22 01:27:15 -0700822 jint layoutParamsFlags = env->GetIntField(windowObj,
823 gInputWindowClassInfo.layoutParamsFlags);
824 jint layoutParamsType = env->GetIntField(windowObj,
825 gInputWindowClassInfo.layoutParamsType);
826 jlong dispatchingTimeoutNanos = env->GetLongField(windowObj,
827 gInputWindowClassInfo.dispatchingTimeoutNanos);
828 jint frameLeft = env->GetIntField(windowObj,
829 gInputWindowClassInfo.frameLeft);
830 jint frameTop = env->GetIntField(windowObj,
831 gInputWindowClassInfo.frameTop);
Jeff Brown85a31762010-09-01 17:01:00 -0700832 jint frameRight = env->GetIntField(windowObj,
833 gInputWindowClassInfo.frameRight);
834 jint frameBottom = env->GetIntField(windowObj,
835 gInputWindowClassInfo.frameBottom);
836 jint visibleFrameLeft = env->GetIntField(windowObj,
837 gInputWindowClassInfo.visibleFrameLeft);
838 jint visibleFrameTop = env->GetIntField(windowObj,
839 gInputWindowClassInfo.visibleFrameTop);
840 jint visibleFrameRight = env->GetIntField(windowObj,
841 gInputWindowClassInfo.visibleFrameRight);
842 jint visibleFrameBottom = env->GetIntField(windowObj,
843 gInputWindowClassInfo.visibleFrameBottom);
Jeff Brown349703e2010-06-22 01:27:15 -0700844 jint touchableAreaLeft = env->GetIntField(windowObj,
845 gInputWindowClassInfo.touchableAreaLeft);
846 jint touchableAreaTop = env->GetIntField(windowObj,
847 gInputWindowClassInfo.touchableAreaTop);
848 jint touchableAreaRight = env->GetIntField(windowObj,
849 gInputWindowClassInfo.touchableAreaRight);
850 jint touchableAreaBottom = env->GetIntField(windowObj,
851 gInputWindowClassInfo.touchableAreaBottom);
852 jboolean visible = env->GetBooleanField(windowObj,
853 gInputWindowClassInfo.visible);
Jeff Brown519e0242010-09-15 15:18:56 -0700854 jboolean canReceiveKeys = env->GetBooleanField(windowObj,
855 gInputWindowClassInfo.canReceiveKeys);
Jeff Brown349703e2010-06-22 01:27:15 -0700856 jboolean hasFocus = env->GetBooleanField(windowObj,
857 gInputWindowClassInfo.hasFocus);
858 jboolean hasWallpaper = env->GetBooleanField(windowObj,
859 gInputWindowClassInfo.hasWallpaper);
860 jboolean paused = env->GetBooleanField(windowObj,
861 gInputWindowClassInfo.paused);
Jeff Brown519e0242010-09-15 15:18:56 -0700862 jint layer = env->GetIntField(windowObj,
863 gInputWindowClassInfo.layer);
Jeff Brown349703e2010-06-22 01:27:15 -0700864 jint ownerPid = env->GetIntField(windowObj,
865 gInputWindowClassInfo.ownerPid);
866 jint ownerUid = env->GetIntField(windowObj,
867 gInputWindowClassInfo.ownerUid);
868
Jeff Brown519e0242010-09-15 15:18:56 -0700869 const char* nameStr = env->GetStringUTFChars(name, NULL);
870
Jeff Brown349703e2010-06-22 01:27:15 -0700871 outWindow.inputChannel = inputChannel;
Jeff Brown519e0242010-09-15 15:18:56 -0700872 outWindow.name.setTo(nameStr);
Jeff Brown349703e2010-06-22 01:27:15 -0700873 outWindow.layoutParamsFlags = layoutParamsFlags;
874 outWindow.layoutParamsType = layoutParamsType;
875 outWindow.dispatchingTimeout = dispatchingTimeoutNanos;
876 outWindow.frameLeft = frameLeft;
877 outWindow.frameTop = frameTop;
Jeff Brown85a31762010-09-01 17:01:00 -0700878 outWindow.frameRight = frameRight;
879 outWindow.frameBottom = frameBottom;
880 outWindow.visibleFrameLeft = visibleFrameLeft;
881 outWindow.visibleFrameTop = visibleFrameTop;
882 outWindow.visibleFrameRight = visibleFrameRight;
883 outWindow.visibleFrameBottom = visibleFrameBottom;
Jeff Brown349703e2010-06-22 01:27:15 -0700884 outWindow.touchableAreaLeft = touchableAreaLeft;
885 outWindow.touchableAreaTop = touchableAreaTop;
886 outWindow.touchableAreaRight = touchableAreaRight;
887 outWindow.touchableAreaBottom = touchableAreaBottom;
888 outWindow.visible = visible;
Jeff Brown519e0242010-09-15 15:18:56 -0700889 outWindow.canReceiveKeys = canReceiveKeys;
Jeff Brown349703e2010-06-22 01:27:15 -0700890 outWindow.hasFocus = hasFocus;
891 outWindow.hasWallpaper = hasWallpaper;
892 outWindow.paused = paused;
Jeff Brown519e0242010-09-15 15:18:56 -0700893 outWindow.layer = layer;
Jeff Brown349703e2010-06-22 01:27:15 -0700894 outWindow.ownerPid = ownerPid;
895 outWindow.ownerUid = ownerUid;
Jeff Brown519e0242010-09-15 15:18:56 -0700896
897 env->ReleaseStringUTFChars(name, nameStr);
Jeff Brown349703e2010-06-22 01:27:15 -0700898 valid = true;
899 } else {
900 LOGW("Dropping input target because its input channel is not initialized.");
901 }
902
903 env->DeleteLocalRef(inputChannelObj);
904 } else {
905 LOGW("Dropping input target because the input channel object was null.");
906 }
907 return valid;
908}
909
910void NativeInputManager::setFocusedApplication(JNIEnv* env, jobject applicationObj) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700911 if (applicationObj) {
912 jstring nameObj = jstring(env->GetObjectField(applicationObj,
913 gInputApplicationClassInfo.name));
914 jlong dispatchingTimeoutNanos = env->GetLongField(applicationObj,
915 gInputApplicationClassInfo.dispatchingTimeoutNanos);
916 jobject tokenObj = env->GetObjectField(applicationObj,
917 gInputApplicationClassInfo.token);
918 jweak tokenObjWeak = env->NewWeakGlobalRef(tokenObj);
919 if (! tokenObjWeak) {
920 LOGE("Could not create weak reference for application token.");
921 LOGE_EX(env);
922 env->ExceptionClear();
923 }
924 env->DeleteLocalRef(tokenObj);
Jeff Brown349703e2010-06-22 01:27:15 -0700925
Jeff Brownb88102f2010-09-08 11:49:43 -0700926 String8 name;
927 if (nameObj) {
928 const char* nameStr = env->GetStringUTFChars(nameObj, NULL);
929 name.setTo(nameStr);
930 env->ReleaseStringUTFChars(nameObj, nameStr);
931 env->DeleteLocalRef(nameObj);
932 } else {
933 LOGE("InputApplication.name should not be null.");
934 name.setTo("unknown");
Jeff Brown349703e2010-06-22 01:27:15 -0700935 }
936
Jeff Brownb88102f2010-09-08 11:49:43 -0700937 InputApplication application;
938 application.name = name;
939 application.dispatchingTimeout = dispatchingTimeoutNanos;
940 application.handle = new ApplicationToken(tokenObjWeak);
941 mInputManager->getDispatcher()->setFocusedApplication(& application);
942 } else {
943 mInputManager->getDispatcher()->setFocusedApplication(NULL);
Jeff Brown349703e2010-06-22 01:27:15 -0700944 }
945}
946
947void NativeInputManager::setInputDispatchMode(bool enabled, bool frozen) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700948 mInputManager->getDispatcher()->setInputDispatchMode(enabled, frozen);
Jeff Brown349703e2010-06-22 01:27:15 -0700949}
950
Jeff Brownb88102f2010-09-08 11:49:43 -0700951bool NativeInputManager::interceptKeyBeforeDispatching(const sp<InputChannel>& inputChannel,
Jeff Brownd0097872010-06-30 14:41:59 -0700952 const KeyEvent* keyEvent, uint32_t policyFlags) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700953 bool isScreenOn = this->isScreenOn();
954 if (! isPolicyKey(keyEvent->getKeyCode(), isScreenOn)) {
955 return false;
956 }
957
Jeff Brownd0097872010-06-30 14:41:59 -0700958 JNIEnv* env = jniEnv();
959
Jeff Brownb88102f2010-09-08 11:49:43 -0700960 jobject inputChannelObj = getInputChannelObjLocal(env, inputChannel);
Jeff Brownd0097872010-06-30 14:41:59 -0700961 if (inputChannelObj) {
962 jboolean consumed = env->CallBooleanMethod(mCallbacksObj,
963 gCallbacksClassInfo.interceptKeyBeforeDispatching,
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700964 inputChannelObj, keyEvent->getAction(), keyEvent->getFlags(),
965 keyEvent->getKeyCode(), keyEvent->getMetaState(),
Jeff Brownd0097872010-06-30 14:41:59 -0700966 keyEvent->getRepeatCount(), policyFlags);
967 bool error = checkAndClearExceptionFromCallback(env, "interceptKeyBeforeDispatching");
968
969 env->DeleteLocalRef(inputChannelObj);
970
971 return consumed && ! error;
972 } else {
973 LOGW("Could not apply key dispatch policy because input channel '%s' is "
Jeff Brownb88102f2010-09-08 11:49:43 -0700974 "no longer valid.", inputChannel->getName().string());
Jeff Brownd0097872010-06-30 14:41:59 -0700975 return false;
976 }
977}
978
Jeff Brownb88102f2010-09-08 11:49:43 -0700979void NativeInputManager::pokeUserActivity(nsecs_t eventTime, int32_t windowType, int32_t eventType) {
980 if (windowType != InputWindow::TYPE_KEYGUARD) {
981 android_server_PowerManagerService_userActivity(eventTime, eventType);
Jeff Brown349703e2010-06-22 01:27:15 -0700982 }
983}
984
Jeff Brown349703e2010-06-22 01:27:15 -0700985
Jeff Brownb88102f2010-09-08 11:49:43 -0700986bool NativeInputManager::checkInjectEventsPermissionNonReentrant(
987 int32_t injectorPid, int32_t injectorUid) {
988 JNIEnv* env = jniEnv();
989 jboolean result = env->CallBooleanMethod(mCallbacksObj,
990 gCallbacksClassInfo.checkInjectEventsPermission, injectorPid, injectorUid);
991 checkAndClearExceptionFromCallback(env, "checkInjectEventsPermission");
Jeff Brown349703e2010-06-22 01:27:15 -0700992 return result;
993}
994
Jeff Brown9c3cda02010-06-15 01:31:58 -0700995// ----------------------------------------------------------------------------
996
997static sp<NativeInputManager> gNativeInputManager;
998
Jeff Brown46b9ac02010-04-22 18:58:52 -0700999static bool checkInputManagerUnitialized(JNIEnv* env) {
Jeff Brown9c3cda02010-06-15 01:31:58 -07001000 if (gNativeInputManager == NULL) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07001001 LOGE("Input manager not initialized.");
1002 jniThrowRuntimeException(env, "Input manager not initialized.");
1003 return true;
1004 }
1005 return false;
1006}
1007
1008static void android_server_InputManager_nativeInit(JNIEnv* env, jclass clazz,
1009 jobject callbacks) {
Jeff Brown9c3cda02010-06-15 01:31:58 -07001010 if (gNativeInputManager == NULL) {
1011 gNativeInputManager = new NativeInputManager(callbacks);
1012 } else {
1013 LOGE("Input manager already initialized.");
1014 jniThrowRuntimeException(env, "Input manager already initialized.");
Jeff Brown46b9ac02010-04-22 18:58:52 -07001015 }
1016}
1017
1018static void android_server_InputManager_nativeStart(JNIEnv* env, jclass clazz) {
1019 if (checkInputManagerUnitialized(env)) {
1020 return;
1021 }
1022
Jeff Brown9c3cda02010-06-15 01:31:58 -07001023 status_t result = gNativeInputManager->getInputManager()->start();
Jeff Brown46b9ac02010-04-22 18:58:52 -07001024 if (result) {
1025 jniThrowRuntimeException(env, "Input manager could not be started.");
1026 }
1027}
1028
1029static void android_server_InputManager_nativeSetDisplaySize(JNIEnv* env, jclass clazz,
1030 jint displayId, jint width, jint height) {
1031 if (checkInputManagerUnitialized(env)) {
1032 return;
1033 }
1034
1035 // XXX we could get this from the SurfaceFlinger directly instead of requiring it
1036 // to be passed in like this, not sure which is better but leaving it like this
1037 // keeps the window manager in direct control of when display transitions propagate down
1038 // to the input dispatcher
Jeff Brown9c3cda02010-06-15 01:31:58 -07001039 gNativeInputManager->setDisplaySize(displayId, width, height);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001040}
1041
1042static void android_server_InputManager_nativeSetDisplayOrientation(JNIEnv* env, jclass clazz,
1043 jint displayId, jint orientation) {
1044 if (checkInputManagerUnitialized(env)) {
1045 return;
1046 }
1047
Jeff Brown9c3cda02010-06-15 01:31:58 -07001048 gNativeInputManager->setDisplayOrientation(displayId, orientation);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001049}
1050
1051static jint android_server_InputManager_nativeGetScanCodeState(JNIEnv* env, jclass clazz,
Jeff Brown6d0fec22010-07-23 21:28:06 -07001052 jint deviceId, jint sourceMask, jint scanCode) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07001053 if (checkInputManagerUnitialized(env)) {
Jeff Brownc5ed5912010-07-14 18:48:53 -07001054 return AKEY_STATE_UNKNOWN;
Jeff Brown46b9ac02010-04-22 18:58:52 -07001055 }
1056
Jeff Brownb88102f2010-09-08 11:49:43 -07001057 return gNativeInputManager->getInputManager()->getReader()->getScanCodeState(
Jeff Brown6d0fec22010-07-23 21:28:06 -07001058 deviceId, uint32_t(sourceMask), scanCode);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001059}
1060
1061static jint android_server_InputManager_nativeGetKeyCodeState(JNIEnv* env, jclass clazz,
Jeff Brown6d0fec22010-07-23 21:28:06 -07001062 jint deviceId, jint sourceMask, jint keyCode) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07001063 if (checkInputManagerUnitialized(env)) {
Jeff Brownc5ed5912010-07-14 18:48:53 -07001064 return AKEY_STATE_UNKNOWN;
Jeff Brown46b9ac02010-04-22 18:58:52 -07001065 }
1066
Jeff Brownb88102f2010-09-08 11:49:43 -07001067 return gNativeInputManager->getInputManager()->getReader()->getKeyCodeState(
Jeff Brown6d0fec22010-07-23 21:28:06 -07001068 deviceId, uint32_t(sourceMask), keyCode);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001069}
1070
1071static jint android_server_InputManager_nativeGetSwitchState(JNIEnv* env, jclass clazz,
Jeff Brown6d0fec22010-07-23 21:28:06 -07001072 jint deviceId, jint sourceMask, jint sw) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07001073 if (checkInputManagerUnitialized(env)) {
Jeff Brownc5ed5912010-07-14 18:48:53 -07001074 return AKEY_STATE_UNKNOWN;
Jeff Brown46b9ac02010-04-22 18:58:52 -07001075 }
1076
Jeff Brownb88102f2010-09-08 11:49:43 -07001077 return gNativeInputManager->getInputManager()->getReader()->getSwitchState(
Jeff Brown6d0fec22010-07-23 21:28:06 -07001078 deviceId, uint32_t(sourceMask), sw);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001079}
1080
1081static jboolean android_server_InputManager_nativeHasKeys(JNIEnv* env, jclass clazz,
Jeff Brown6d0fec22010-07-23 21:28:06 -07001082 jint deviceId, jint sourceMask, jintArray keyCodes, jbooleanArray outFlags) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07001083 if (checkInputManagerUnitialized(env)) {
1084 return JNI_FALSE;
1085 }
1086
1087 int32_t* codes = env->GetIntArrayElements(keyCodes, NULL);
1088 uint8_t* flags = env->GetBooleanArrayElements(outFlags, NULL);
1089 jsize numCodes = env->GetArrayLength(keyCodes);
1090 jboolean result;
Jeff Brown6d0fec22010-07-23 21:28:06 -07001091 if (numCodes == env->GetArrayLength(keyCodes)) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001092 result = gNativeInputManager->getInputManager()->getReader()->hasKeys(
Jeff Brown6d0fec22010-07-23 21:28:06 -07001093 deviceId, uint32_t(sourceMask), numCodes, codes, flags);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001094 } else {
1095 result = JNI_FALSE;
1096 }
1097
1098 env->ReleaseBooleanArrayElements(outFlags, flags, 0);
1099 env->ReleaseIntArrayElements(keyCodes, codes, 0);
1100 return result;
1101}
1102
1103static void throwInputChannelNotInitialized(JNIEnv* env) {
1104 jniThrowException(env, "java/lang/IllegalStateException",
1105 "inputChannel is not initialized");
1106}
1107
1108static void android_server_InputManager_handleInputChannelDisposed(JNIEnv* env,
1109 jobject inputChannelObj, const sp<InputChannel>& inputChannel, void* data) {
1110 LOGW("Input channel object '%s' was disposed without first being unregistered with "
1111 "the input manager!", inputChannel->getName().string());
1112
Jeff Brown9c3cda02010-06-15 01:31:58 -07001113 if (gNativeInputManager != NULL) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07001114 gNativeInputManager->unregisterInputChannel(env, inputChannel);
Jeff Brown9c3cda02010-06-15 01:31:58 -07001115 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07001116}
1117
1118static void android_server_InputManager_nativeRegisterInputChannel(JNIEnv* env, jclass clazz,
Jeff Browna41ca772010-08-11 14:46:32 -07001119 jobject inputChannelObj, jboolean monitor) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07001120 if (checkInputManagerUnitialized(env)) {
1121 return;
1122 }
1123
1124 sp<InputChannel> inputChannel = android_view_InputChannel_getInputChannel(env,
1125 inputChannelObj);
1126 if (inputChannel == NULL) {
1127 throwInputChannelNotInitialized(env);
1128 return;
1129 }
1130
Jeff Brown7fbdc842010-06-17 20:52:56 -07001131
1132 status_t status = gNativeInputManager->registerInputChannel(
Jeff Browna41ca772010-08-11 14:46:32 -07001133 env, inputChannel, inputChannelObj, monitor);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001134 if (status) {
1135 jniThrowRuntimeException(env, "Failed to register input channel. "
1136 "Check logs for details.");
1137 return;
1138 }
1139
Jeff Browna41ca772010-08-11 14:46:32 -07001140 if (! monitor) {
1141 android_view_InputChannel_setDisposeCallback(env, inputChannelObj,
1142 android_server_InputManager_handleInputChannelDisposed, NULL);
1143 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07001144}
1145
1146static void android_server_InputManager_nativeUnregisterInputChannel(JNIEnv* env, jclass clazz,
1147 jobject inputChannelObj) {
1148 if (checkInputManagerUnitialized(env)) {
1149 return;
1150 }
1151
1152 sp<InputChannel> inputChannel = android_view_InputChannel_getInputChannel(env,
1153 inputChannelObj);
1154 if (inputChannel == NULL) {
1155 throwInputChannelNotInitialized(env);
1156 return;
1157 }
1158
1159 android_view_InputChannel_setDisposeCallback(env, inputChannelObj, NULL, NULL);
1160
Jeff Brown7fbdc842010-06-17 20:52:56 -07001161 status_t status = gNativeInputManager->unregisterInputChannel(env, inputChannel);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001162 if (status) {
1163 jniThrowRuntimeException(env, "Failed to unregister input channel. "
1164 "Check logs for details.");
1165 }
1166}
1167
Jeff Brown6ec402b2010-07-28 15:48:59 -07001168static jint android_server_InputManager_nativeInjectInputEvent(JNIEnv* env, jclass clazz,
1169 jobject inputEventObj, jint injectorPid, jint injectorUid,
1170 jint syncMode, jint timeoutMillis) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07001171 if (checkInputManagerUnitialized(env)) {
1172 return INPUT_EVENT_INJECTION_FAILED;
1173 }
1174
Jeff Brown6ec402b2010-07-28 15:48:59 -07001175 if (env->IsInstanceOf(inputEventObj, gKeyEventClassInfo.clazz)) {
1176 KeyEvent keyEvent;
1177 android_view_KeyEvent_toNative(env, inputEventObj, & keyEvent);
Jeff Brown7fbdc842010-06-17 20:52:56 -07001178
Jeff Brownb88102f2010-09-08 11:49:43 -07001179 return gNativeInputManager->getInputManager()->getDispatcher()->injectInputEvent(
1180 & keyEvent, injectorPid, injectorUid, syncMode, timeoutMillis);
Jeff Brown6ec402b2010-07-28 15:48:59 -07001181 } else if (env->IsInstanceOf(inputEventObj, gMotionEventClassInfo.clazz)) {
1182 MotionEvent motionEvent;
1183 android_view_MotionEvent_toNative(env, inputEventObj, & motionEvent);
Jeff Brown7fbdc842010-06-17 20:52:56 -07001184
Jeff Brownb88102f2010-09-08 11:49:43 -07001185 return gNativeInputManager->getInputManager()->getDispatcher()->injectInputEvent(
1186 & motionEvent, injectorPid, injectorUid, syncMode, timeoutMillis);
Jeff Brown6ec402b2010-07-28 15:48:59 -07001187 } else {
1188 jniThrowRuntimeException(env, "Invalid input event type.");
Jeff Brown7fbdc842010-06-17 20:52:56 -07001189 return INPUT_EVENT_INJECTION_FAILED;
1190 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07001191}
1192
Jeff Brown349703e2010-06-22 01:27:15 -07001193static void android_server_InputManager_nativeSetInputWindows(JNIEnv* env, jclass clazz,
1194 jobjectArray windowObjArray) {
1195 if (checkInputManagerUnitialized(env)) {
1196 return;
1197 }
1198
1199 gNativeInputManager->setInputWindows(env, windowObjArray);
1200}
1201
1202static void android_server_InputManager_nativeSetFocusedApplication(JNIEnv* env, jclass clazz,
1203 jobject applicationObj) {
1204 if (checkInputManagerUnitialized(env)) {
1205 return;
1206 }
1207
1208 gNativeInputManager->setFocusedApplication(env, applicationObj);
1209}
1210
1211static void android_server_InputManager_nativeSetInputDispatchMode(JNIEnv* env,
1212 jclass clazz, jboolean enabled, jboolean frozen) {
1213 if (checkInputManagerUnitialized(env)) {
1214 return;
1215 }
1216
1217 gNativeInputManager->setInputDispatchMode(enabled, frozen);
1218}
1219
Jeff Brown8d608662010-08-30 03:02:23 -07001220static jobject android_server_InputManager_nativeGetInputDevice(JNIEnv* env,
1221 jclass clazz, jint deviceId) {
1222 if (checkInputManagerUnitialized(env)) {
1223 return NULL;
1224 }
1225
1226 InputDeviceInfo deviceInfo;
Jeff Brownb88102f2010-09-08 11:49:43 -07001227 status_t status = gNativeInputManager->getInputManager()->getReader()->getInputDeviceInfo(
Jeff Brown8d608662010-08-30 03:02:23 -07001228 deviceId, & deviceInfo);
1229 if (status) {
1230 return NULL;
1231 }
1232
1233 jobject deviceObj = env->NewObject(gInputDeviceClassInfo.clazz, gInputDeviceClassInfo.ctor);
1234 if (! deviceObj) {
1235 return NULL;
1236 }
1237
1238 jstring deviceNameObj = env->NewStringUTF(deviceInfo.getName().string());
1239 if (! deviceNameObj) {
1240 return NULL;
1241 }
1242
1243 env->SetIntField(deviceObj, gInputDeviceClassInfo.mId, deviceInfo.getId());
1244 env->SetObjectField(deviceObj, gInputDeviceClassInfo.mName, deviceNameObj);
1245 env->SetIntField(deviceObj, gInputDeviceClassInfo.mSources, deviceInfo.getSources());
1246 env->SetIntField(deviceObj, gInputDeviceClassInfo.mKeyboardType, deviceInfo.getKeyboardType());
1247
1248 const KeyedVector<int, InputDeviceInfo::MotionRange>& ranges = deviceInfo.getMotionRanges();
1249 for (size_t i = 0; i < ranges.size(); i++) {
1250 int rangeType = ranges.keyAt(i);
1251 const InputDeviceInfo::MotionRange& range = ranges.valueAt(i);
1252 env->CallVoidMethod(deviceObj, gInputDeviceClassInfo.addMotionRange,
1253 rangeType, range.min, range.max, range.flat, range.fuzz);
1254 if (env->ExceptionCheck()) {
1255 return NULL;
1256 }
1257 }
1258
1259 return deviceObj;
1260}
1261
1262static jintArray android_server_InputManager_nativeGetInputDeviceIds(JNIEnv* env,
1263 jclass clazz) {
1264 if (checkInputManagerUnitialized(env)) {
1265 return NULL;
1266 }
1267
1268 Vector<int> deviceIds;
Jeff Brownb88102f2010-09-08 11:49:43 -07001269 gNativeInputManager->getInputManager()->getReader()->getInputDeviceIds(deviceIds);
Jeff Brown8d608662010-08-30 03:02:23 -07001270
1271 jintArray deviceIdsObj = env->NewIntArray(deviceIds.size());
1272 if (! deviceIdsObj) {
1273 return NULL;
1274 }
1275
1276 env->SetIntArrayRegion(deviceIdsObj, 0, deviceIds.size(), deviceIds.array());
1277 return deviceIdsObj;
1278}
1279
Jeff Browne33348b2010-07-15 23:54:05 -07001280static jstring android_server_InputManager_nativeDump(JNIEnv* env, jclass clazz) {
1281 if (checkInputManagerUnitialized(env)) {
1282 return NULL;
1283 }
1284
Jeff Brownb88102f2010-09-08 11:49:43 -07001285 String8 dump;
1286 gNativeInputManager->dump(dump);
Jeff Browne33348b2010-07-15 23:54:05 -07001287 return env->NewStringUTF(dump.string());
1288}
1289
Jeff Brown9c3cda02010-06-15 01:31:58 -07001290// ----------------------------------------------------------------------------
1291
Jeff Brown46b9ac02010-04-22 18:58:52 -07001292static JNINativeMethod gInputManagerMethods[] = {
1293 /* name, signature, funcPtr */
1294 { "nativeInit", "(Lcom/android/server/InputManager$Callbacks;)V",
1295 (void*) android_server_InputManager_nativeInit },
1296 { "nativeStart", "()V",
1297 (void*) android_server_InputManager_nativeStart },
1298 { "nativeSetDisplaySize", "(III)V",
1299 (void*) android_server_InputManager_nativeSetDisplaySize },
1300 { "nativeSetDisplayOrientation", "(II)V",
1301 (void*) android_server_InputManager_nativeSetDisplayOrientation },
1302 { "nativeGetScanCodeState", "(III)I",
1303 (void*) android_server_InputManager_nativeGetScanCodeState },
1304 { "nativeGetKeyCodeState", "(III)I",
1305 (void*) android_server_InputManager_nativeGetKeyCodeState },
1306 { "nativeGetSwitchState", "(III)I",
1307 (void*) android_server_InputManager_nativeGetSwitchState },
Jeff Brown6d0fec22010-07-23 21:28:06 -07001308 { "nativeHasKeys", "(II[I[Z)Z",
Jeff Brown46b9ac02010-04-22 18:58:52 -07001309 (void*) android_server_InputManager_nativeHasKeys },
Jeff Browna41ca772010-08-11 14:46:32 -07001310 { "nativeRegisterInputChannel", "(Landroid/view/InputChannel;Z)V",
Jeff Brown46b9ac02010-04-22 18:58:52 -07001311 (void*) android_server_InputManager_nativeRegisterInputChannel },
1312 { "nativeUnregisterInputChannel", "(Landroid/view/InputChannel;)V",
Jeff Brown7fbdc842010-06-17 20:52:56 -07001313 (void*) android_server_InputManager_nativeUnregisterInputChannel },
Jeff Brown6ec402b2010-07-28 15:48:59 -07001314 { "nativeInjectInputEvent", "(Landroid/view/InputEvent;IIII)I",
1315 (void*) android_server_InputManager_nativeInjectInputEvent },
Jeff Brown349703e2010-06-22 01:27:15 -07001316 { "nativeSetInputWindows", "([Lcom/android/server/InputWindow;)V",
1317 (void*) android_server_InputManager_nativeSetInputWindows },
1318 { "nativeSetFocusedApplication", "(Lcom/android/server/InputApplication;)V",
1319 (void*) android_server_InputManager_nativeSetFocusedApplication },
1320 { "nativeSetInputDispatchMode", "(ZZ)V",
1321 (void*) android_server_InputManager_nativeSetInputDispatchMode },
Jeff Brown8d608662010-08-30 03:02:23 -07001322 { "nativeGetInputDevice", "(I)Landroid/view/InputDevice;",
1323 (void*) android_server_InputManager_nativeGetInputDevice },
1324 { "nativeGetInputDeviceIds", "()[I",
1325 (void*) android_server_InputManager_nativeGetInputDeviceIds },
Jeff Browne33348b2010-07-15 23:54:05 -07001326 { "nativeDump", "()Ljava/lang/String;",
1327 (void*) android_server_InputManager_nativeDump },
Jeff Brown46b9ac02010-04-22 18:58:52 -07001328};
1329
1330#define FIND_CLASS(var, className) \
1331 var = env->FindClass(className); \
1332 LOG_FATAL_IF(! var, "Unable to find class " className); \
1333 var = jclass(env->NewGlobalRef(var));
1334
1335#define GET_METHOD_ID(var, clazz, methodName, methodDescriptor) \
1336 var = env->GetMethodID(clazz, methodName, methodDescriptor); \
1337 LOG_FATAL_IF(! var, "Unable to find method " methodName);
1338
1339#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \
1340 var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \
1341 LOG_FATAL_IF(! var, "Unable to find field " fieldName);
1342
1343int register_android_server_InputManager(JNIEnv* env) {
1344 int res = jniRegisterNativeMethods(env, "com/android/server/InputManager",
1345 gInputManagerMethods, NELEM(gInputManagerMethods));
1346 LOG_FATAL_IF(res < 0, "Unable to register native methods.");
1347
Jeff Brown9c3cda02010-06-15 01:31:58 -07001348 // Callbacks
Jeff Brown46b9ac02010-04-22 18:58:52 -07001349
1350 FIND_CLASS(gCallbacksClassInfo.clazz, "com/android/server/InputManager$Callbacks");
1351
Jeff Brown46b9ac02010-04-22 18:58:52 -07001352 GET_METHOD_ID(gCallbacksClassInfo.notifyConfigurationChanged, gCallbacksClassInfo.clazz,
1353 "notifyConfigurationChanged", "(JIII)V");
1354
1355 GET_METHOD_ID(gCallbacksClassInfo.notifyLidSwitchChanged, gCallbacksClassInfo.clazz,
1356 "notifyLidSwitchChanged", "(JZ)V");
1357
Jeff Brown7fbdc842010-06-17 20:52:56 -07001358 GET_METHOD_ID(gCallbacksClassInfo.notifyInputChannelBroken, gCallbacksClassInfo.clazz,
1359 "notifyInputChannelBroken", "(Landroid/view/InputChannel;)V");
1360
Jeff Brown349703e2010-06-22 01:27:15 -07001361 GET_METHOD_ID(gCallbacksClassInfo.notifyANR, gCallbacksClassInfo.clazz,
Jeff Brown519e0242010-09-15 15:18:56 -07001362 "notifyANR", "(Ljava/lang/Object;Landroid/view/InputChannel;)J");
Jeff Brown349703e2010-06-22 01:27:15 -07001363
Jeff Brown00fa7bd2010-07-02 15:37:36 -07001364 GET_METHOD_ID(gCallbacksClassInfo.virtualKeyDownFeedback, gCallbacksClassInfo.clazz,
1365 "virtualKeyDownFeedback", "()V");
Jeff Brown46b9ac02010-04-22 18:58:52 -07001366
Jeff Brown349703e2010-06-22 01:27:15 -07001367 GET_METHOD_ID(gCallbacksClassInfo.interceptKeyBeforeQueueing, gCallbacksClassInfo.clazz,
Jeff Brown00fa7bd2010-07-02 15:37:36 -07001368 "interceptKeyBeforeQueueing", "(JIZIZ)I");
Jeff Brown349703e2010-06-22 01:27:15 -07001369
1370 GET_METHOD_ID(gCallbacksClassInfo.interceptKeyBeforeDispatching, gCallbacksClassInfo.clazz,
Jeff Brown00fa7bd2010-07-02 15:37:36 -07001371 "interceptKeyBeforeDispatching", "(Landroid/view/InputChannel;IIIIII)Z");
Jeff Brown349703e2010-06-22 01:27:15 -07001372
1373 GET_METHOD_ID(gCallbacksClassInfo.checkInjectEventsPermission, gCallbacksClassInfo.clazz,
1374 "checkInjectEventsPermission", "(II)Z");
Jeff Brown46b9ac02010-04-22 18:58:52 -07001375
Jeff Brown46b9ac02010-04-22 18:58:52 -07001376 GET_METHOD_ID(gCallbacksClassInfo.filterTouchEvents, gCallbacksClassInfo.clazz,
1377 "filterTouchEvents", "()Z");
1378
1379 GET_METHOD_ID(gCallbacksClassInfo.filterJumpyTouchEvents, gCallbacksClassInfo.clazz,
1380 "filterJumpyTouchEvents", "()Z");
1381
1382 GET_METHOD_ID(gCallbacksClassInfo.getVirtualKeyDefinitions, gCallbacksClassInfo.clazz,
1383 "getVirtualKeyDefinitions",
1384 "(Ljava/lang/String;)[Lcom/android/server/InputManager$VirtualKeyDefinition;");
1385
Jeff Brown8d608662010-08-30 03:02:23 -07001386 GET_METHOD_ID(gCallbacksClassInfo.getInputDeviceCalibration, gCallbacksClassInfo.clazz,
1387 "getInputDeviceCalibration",
1388 "(Ljava/lang/String;)Lcom/android/server/InputManager$InputDeviceCalibration;");
1389
Jeff Brown46b9ac02010-04-22 18:58:52 -07001390 GET_METHOD_ID(gCallbacksClassInfo.getExcludedDeviceNames, gCallbacksClassInfo.clazz,
1391 "getExcludedDeviceNames", "()[Ljava/lang/String;");
1392
Jeff Brownae9fc032010-08-18 15:51:08 -07001393 GET_METHOD_ID(gCallbacksClassInfo.getMaxEventsPerSecond, gCallbacksClassInfo.clazz,
1394 "getMaxEventsPerSecond", "()I");
1395
Jeff Brown46b9ac02010-04-22 18:58:52 -07001396 // VirtualKeyDefinition
1397
1398 FIND_CLASS(gVirtualKeyDefinitionClassInfo.clazz,
1399 "com/android/server/InputManager$VirtualKeyDefinition");
1400
1401 GET_FIELD_ID(gVirtualKeyDefinitionClassInfo.scanCode, gVirtualKeyDefinitionClassInfo.clazz,
1402 "scanCode", "I");
1403
1404 GET_FIELD_ID(gVirtualKeyDefinitionClassInfo.centerX, gVirtualKeyDefinitionClassInfo.clazz,
1405 "centerX", "I");
1406
1407 GET_FIELD_ID(gVirtualKeyDefinitionClassInfo.centerY, gVirtualKeyDefinitionClassInfo.clazz,
1408 "centerY", "I");
1409
1410 GET_FIELD_ID(gVirtualKeyDefinitionClassInfo.width, gVirtualKeyDefinitionClassInfo.clazz,
1411 "width", "I");
1412
1413 GET_FIELD_ID(gVirtualKeyDefinitionClassInfo.height, gVirtualKeyDefinitionClassInfo.clazz,
1414 "height", "I");
1415
Jeff Brown8d608662010-08-30 03:02:23 -07001416 // InputDeviceCalibration
1417
1418 FIND_CLASS(gInputDeviceCalibrationClassInfo.clazz,
1419 "com/android/server/InputManager$InputDeviceCalibration");
1420
1421 GET_FIELD_ID(gInputDeviceCalibrationClassInfo.keys, gInputDeviceCalibrationClassInfo.clazz,
1422 "keys", "[Ljava/lang/String;");
1423
1424 GET_FIELD_ID(gInputDeviceCalibrationClassInfo.values, gInputDeviceCalibrationClassInfo.clazz,
1425 "values", "[Ljava/lang/String;");
1426
Jeff Brown349703e2010-06-22 01:27:15 -07001427 // InputWindow
Jeff Brown7fbdc842010-06-17 20:52:56 -07001428
Jeff Brown349703e2010-06-22 01:27:15 -07001429 FIND_CLASS(gInputWindowClassInfo.clazz, "com/android/server/InputWindow");
Jeff Brown7fbdc842010-06-17 20:52:56 -07001430
Jeff Brown349703e2010-06-22 01:27:15 -07001431 GET_FIELD_ID(gInputWindowClassInfo.inputChannel, gInputWindowClassInfo.clazz,
1432 "inputChannel", "Landroid/view/InputChannel;");
Jeff Brown7fbdc842010-06-17 20:52:56 -07001433
Jeff Brown519e0242010-09-15 15:18:56 -07001434 GET_FIELD_ID(gInputWindowClassInfo.name, gInputWindowClassInfo.clazz,
1435 "name", "Ljava/lang/String;");
1436
Jeff Brown349703e2010-06-22 01:27:15 -07001437 GET_FIELD_ID(gInputWindowClassInfo.layoutParamsFlags, gInputWindowClassInfo.clazz,
1438 "layoutParamsFlags", "I");
1439
1440 GET_FIELD_ID(gInputWindowClassInfo.layoutParamsType, gInputWindowClassInfo.clazz,
1441 "layoutParamsType", "I");
1442
1443 GET_FIELD_ID(gInputWindowClassInfo.dispatchingTimeoutNanos, gInputWindowClassInfo.clazz,
1444 "dispatchingTimeoutNanos", "J");
1445
1446 GET_FIELD_ID(gInputWindowClassInfo.frameLeft, gInputWindowClassInfo.clazz,
1447 "frameLeft", "I");
1448
1449 GET_FIELD_ID(gInputWindowClassInfo.frameTop, gInputWindowClassInfo.clazz,
1450 "frameTop", "I");
1451
Jeff Brown85a31762010-09-01 17:01:00 -07001452 GET_FIELD_ID(gInputWindowClassInfo.frameRight, gInputWindowClassInfo.clazz,
1453 "frameRight", "I");
1454
1455 GET_FIELD_ID(gInputWindowClassInfo.frameBottom, gInputWindowClassInfo.clazz,
1456 "frameBottom", "I");
1457
1458 GET_FIELD_ID(gInputWindowClassInfo.visibleFrameLeft, gInputWindowClassInfo.clazz,
1459 "visibleFrameLeft", "I");
1460
1461 GET_FIELD_ID(gInputWindowClassInfo.visibleFrameTop, gInputWindowClassInfo.clazz,
1462 "visibleFrameTop", "I");
1463
1464 GET_FIELD_ID(gInputWindowClassInfo.visibleFrameRight, gInputWindowClassInfo.clazz,
1465 "visibleFrameRight", "I");
1466
1467 GET_FIELD_ID(gInputWindowClassInfo.visibleFrameBottom, gInputWindowClassInfo.clazz,
1468 "visibleFrameBottom", "I");
1469
Jeff Brown349703e2010-06-22 01:27:15 -07001470 GET_FIELD_ID(gInputWindowClassInfo.touchableAreaLeft, gInputWindowClassInfo.clazz,
1471 "touchableAreaLeft", "I");
1472
1473 GET_FIELD_ID(gInputWindowClassInfo.touchableAreaTop, gInputWindowClassInfo.clazz,
1474 "touchableAreaTop", "I");
1475
1476 GET_FIELD_ID(gInputWindowClassInfo.touchableAreaRight, gInputWindowClassInfo.clazz,
1477 "touchableAreaRight", "I");
1478
1479 GET_FIELD_ID(gInputWindowClassInfo.touchableAreaBottom, gInputWindowClassInfo.clazz,
1480 "touchableAreaBottom", "I");
1481
1482 GET_FIELD_ID(gInputWindowClassInfo.visible, gInputWindowClassInfo.clazz,
1483 "visible", "Z");
1484
Jeff Brown519e0242010-09-15 15:18:56 -07001485 GET_FIELD_ID(gInputWindowClassInfo.canReceiveKeys, gInputWindowClassInfo.clazz,
1486 "canReceiveKeys", "Z");
1487
Jeff Brown349703e2010-06-22 01:27:15 -07001488 GET_FIELD_ID(gInputWindowClassInfo.hasFocus, gInputWindowClassInfo.clazz,
1489 "hasFocus", "Z");
1490
1491 GET_FIELD_ID(gInputWindowClassInfo.hasWallpaper, gInputWindowClassInfo.clazz,
1492 "hasWallpaper", "Z");
1493
1494 GET_FIELD_ID(gInputWindowClassInfo.paused, gInputWindowClassInfo.clazz,
1495 "paused", "Z");
1496
Jeff Brown519e0242010-09-15 15:18:56 -07001497 GET_FIELD_ID(gInputWindowClassInfo.layer, gInputWindowClassInfo.clazz,
1498 "layer", "I");
1499
Jeff Brown349703e2010-06-22 01:27:15 -07001500 GET_FIELD_ID(gInputWindowClassInfo.ownerPid, gInputWindowClassInfo.clazz,
1501 "ownerPid", "I");
1502
1503 GET_FIELD_ID(gInputWindowClassInfo.ownerUid, gInputWindowClassInfo.clazz,
1504 "ownerUid", "I");
1505
1506 // InputApplication
1507
1508 FIND_CLASS(gInputApplicationClassInfo.clazz, "com/android/server/InputApplication");
1509
1510 GET_FIELD_ID(gInputApplicationClassInfo.name, gInputApplicationClassInfo.clazz,
1511 "name", "Ljava/lang/String;");
1512
1513 GET_FIELD_ID(gInputApplicationClassInfo.dispatchingTimeoutNanos,
1514 gInputApplicationClassInfo.clazz,
1515 "dispatchingTimeoutNanos", "J");
1516
1517 GET_FIELD_ID(gInputApplicationClassInfo.token, gInputApplicationClassInfo.clazz,
1518 "token", "Ljava/lang/Object;");
Jeff Brown7fbdc842010-06-17 20:52:56 -07001519
Jeff Brown6ec402b2010-07-28 15:48:59 -07001520 // KeyEvent
1521
1522 FIND_CLASS(gKeyEventClassInfo.clazz, "android/view/KeyEvent");
1523
Jeff Brown8d608662010-08-30 03:02:23 -07001524 // MotionEvent
Jeff Brown6ec402b2010-07-28 15:48:59 -07001525
1526 FIND_CLASS(gMotionEventClassInfo.clazz, "android/view/MotionEvent");
1527
Jeff Brown8d608662010-08-30 03:02:23 -07001528 // InputDevice
1529
1530 FIND_CLASS(gInputDeviceClassInfo.clazz, "android/view/InputDevice");
1531
1532 GET_METHOD_ID(gInputDeviceClassInfo.ctor, gInputDeviceClassInfo.clazz,
1533 "<init>", "()V");
1534
1535 GET_METHOD_ID(gInputDeviceClassInfo.addMotionRange, gInputDeviceClassInfo.clazz,
1536 "addMotionRange", "(IFFFF)V");
1537
1538 GET_FIELD_ID(gInputDeviceClassInfo.mId, gInputDeviceClassInfo.clazz,
1539 "mId", "I");
1540
1541 GET_FIELD_ID(gInputDeviceClassInfo.mName, gInputDeviceClassInfo.clazz,
1542 "mName", "Ljava/lang/String;");
1543
1544 GET_FIELD_ID(gInputDeviceClassInfo.mSources, gInputDeviceClassInfo.clazz,
1545 "mSources", "I");
1546
1547 GET_FIELD_ID(gInputDeviceClassInfo.mKeyboardType, gInputDeviceClassInfo.clazz,
1548 "mKeyboardType", "I");
1549
1550 GET_FIELD_ID(gInputDeviceClassInfo.mMotionRanges, gInputDeviceClassInfo.clazz,
1551 "mMotionRanges", "[Landroid/view/InputDevice$MotionRange;");
1552
Jeff Brown46b9ac02010-04-22 18:58:52 -07001553 return 0;
1554}
1555
Jeff Brown46b9ac02010-04-22 18:58:52 -07001556} /* namespace android */