blob: 6dd619c5417b9c70f63119588df9673ada90d81e [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;
52 jmethodID notifyInputChannelANR;
53 jmethodID notifyInputChannelRecoveredFromANR;
Jeff Brown349703e2010-06-22 01:27:15 -070054 jmethodID notifyANR;
Jeff Brown00fa7bd2010-07-02 15:37:36 -070055 jmethodID virtualKeyDownFeedback;
Jeff Brown349703e2010-06-22 01:27:15 -070056 jmethodID interceptKeyBeforeQueueing;
57 jmethodID interceptKeyBeforeDispatching;
58 jmethodID checkInjectEventsPermission;
Jeff Brown46b9ac02010-04-22 18:58:52 -070059 jmethodID filterTouchEvents;
60 jmethodID filterJumpyTouchEvents;
61 jmethodID getVirtualKeyDefinitions;
Jeff Brown8d608662010-08-30 03:02:23 -070062 jmethodID getInputDeviceCalibration;
Jeff Brown46b9ac02010-04-22 18:58:52 -070063 jmethodID getExcludedDeviceNames;
Jeff Brownae9fc032010-08-18 15:51:08 -070064 jmethodID getMaxEventsPerSecond;
Jeff Brown46b9ac02010-04-22 18:58:52 -070065} gCallbacksClassInfo;
66
67static struct {
68 jclass clazz;
69
70 jfieldID scanCode;
71 jfieldID centerX;
72 jfieldID centerY;
73 jfieldID width;
74 jfieldID height;
75} gVirtualKeyDefinitionClassInfo;
76
Jeff Brown7fbdc842010-06-17 20:52:56 -070077static struct {
78 jclass clazz;
79
Jeff Brown8d608662010-08-30 03:02:23 -070080 jfieldID keys;
81 jfieldID values;
82} gInputDeviceCalibrationClassInfo;
83
84static struct {
85 jclass clazz;
86
Jeff Brown349703e2010-06-22 01:27:15 -070087 jfieldID inputChannel;
88 jfieldID layoutParamsFlags;
89 jfieldID layoutParamsType;
90 jfieldID dispatchingTimeoutNanos;
91 jfieldID frameLeft;
92 jfieldID frameTop;
Jeff Brown85a31762010-09-01 17:01:00 -070093 jfieldID frameRight;
94 jfieldID frameBottom;
95 jfieldID visibleFrameLeft;
96 jfieldID visibleFrameTop;
97 jfieldID visibleFrameRight;
98 jfieldID visibleFrameBottom;
Jeff Brown349703e2010-06-22 01:27:15 -070099 jfieldID touchableAreaLeft;
100 jfieldID touchableAreaTop;
101 jfieldID touchableAreaRight;
102 jfieldID touchableAreaBottom;
103 jfieldID visible;
104 jfieldID hasFocus;
105 jfieldID hasWallpaper;
106 jfieldID paused;
107 jfieldID ownerPid;
108 jfieldID ownerUid;
109} gInputWindowClassInfo;
110
111static struct {
112 jclass clazz;
113
114 jfieldID name;
115 jfieldID dispatchingTimeoutNanos;
116 jfieldID token;
117} gInputApplicationClassInfo;
118
Jeff Brown6ec402b2010-07-28 15:48:59 -0700119static struct {
120 jclass clazz;
121} gKeyEventClassInfo;
122
123static struct {
124 jclass clazz;
125} gMotionEventClassInfo;
126
Jeff Brown8d608662010-08-30 03:02:23 -0700127static struct {
128 jclass clazz;
129
130 jmethodID ctor;
131 jmethodID addMotionRange;
132
133 jfieldID mId;
134 jfieldID mName;
135 jfieldID mSources;
136 jfieldID mKeyboardType;
137 jfieldID mMotionRanges;
138} gInputDeviceClassInfo;
139
Jeff Brown349703e2010-06-22 01:27:15 -0700140// ----------------------------------------------------------------------------
141
142static inline nsecs_t now() {
143 return systemTime(SYSTEM_TIME_MONOTONIC);
144}
Jeff Brown7fbdc842010-06-17 20:52:56 -0700145
Jeff Brown9c3cda02010-06-15 01:31:58 -0700146// ----------------------------------------------------------------------------
147
148class NativeInputManager : public virtual RefBase,
149 public virtual InputReaderPolicyInterface,
150 public virtual InputDispatcherPolicyInterface {
151protected:
152 virtual ~NativeInputManager();
153
154public:
155 NativeInputManager(jobject callbacksObj);
156
157 inline sp<InputManager> getInputManager() const { return mInputManager; }
158
Jeff Brownb88102f2010-09-08 11:49:43 -0700159 void dump(String8& dump);
Jeff Browne33348b2010-07-15 23:54:05 -0700160
Jeff Brown9c3cda02010-06-15 01:31:58 -0700161 void setDisplaySize(int32_t displayId, int32_t width, int32_t height);
162 void setDisplayOrientation(int32_t displayId, int32_t orientation);
163
Jeff Brown7fbdc842010-06-17 20:52:56 -0700164 status_t registerInputChannel(JNIEnv* env, const sp<InputChannel>& inputChannel,
Jeff Browna41ca772010-08-11 14:46:32 -0700165 jweak inputChannelObjWeak, bool monitor);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700166 status_t unregisterInputChannel(JNIEnv* env, const sp<InputChannel>& inputChannel);
167
Jeff Brown349703e2010-06-22 01:27:15 -0700168 void setInputWindows(JNIEnv* env, jobjectArray windowObjArray);
169 void setFocusedApplication(JNIEnv* env, jobject applicationObj);
170 void setInputDispatchMode(bool enabled, bool frozen);
171 void preemptInputDispatch();
172
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 Brownb88102f2010-09-08 11:49:43 -0700194 virtual nsecs_t notifyANR(const sp<InputApplicationHandle>& inputApplicationHandle);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700195 virtual void notifyInputChannelBroken(const sp<InputChannel>& inputChannel);
Jeff Brownb88102f2010-09-08 11:49:43 -0700196 virtual nsecs_t notifyInputChannelANR(const sp<InputChannel>& inputChannel);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700197 virtual void notifyInputChannelRecoveredFromANR(const sp<InputChannel>& inputChannel);
198 virtual nsecs_t getKeyRepeatTimeout();
Jeff Brownb21fb102010-09-07 10:44:57 -0700199 virtual nsecs_t getKeyRepeatDelay();
Jeff Brownae9fc032010-08-18 15:51:08 -0700200 virtual int32_t getMaxEventsPerSecond();
Jeff Brownb88102f2010-09-08 11:49:43 -0700201 virtual bool interceptKeyBeforeDispatching(const sp<InputChannel>& inputChannel,
202 const KeyEvent* keyEvent, uint32_t policyFlags);
203 virtual void pokeUserActivity(nsecs_t eventTime, int32_t windowType, int32_t eventType);
204 virtual bool checkInjectEventsPermissionNonReentrant(
205 int32_t injectorPid, int32_t injectorUid);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700206
207private:
Jeff Brownb88102f2010-09-08 11:49:43 -0700208 class ApplicationToken : public InputApplicationHandle {
209 jweak mTokenObjWeak;
Jeff Brown349703e2010-06-22 01:27:15 -0700210
211 public:
Jeff Brownb88102f2010-09-08 11:49:43 -0700212 ApplicationToken(jweak tokenObjWeak) :
213 mTokenObjWeak(tokenObjWeak) { }
Jeff Brown349703e2010-06-22 01:27:15 -0700214
Jeff Brownb88102f2010-09-08 11:49:43 -0700215 virtual ~ApplicationToken() {
216 JNIEnv* env = NativeInputManager::jniEnv();
217 env->DeleteWeakGlobalRef(mTokenObjWeak);
218 }
Jeff Brown349703e2010-06-22 01:27:15 -0700219
Jeff Brownb88102f2010-09-08 11:49:43 -0700220 inline jweak getTokenObj() { return mTokenObjWeak; }
Jeff Brown349703e2010-06-22 01:27:15 -0700221 };
222
Jeff Brown9c3cda02010-06-15 01:31:58 -0700223 sp<InputManager> mInputManager;
224
225 jobject mCallbacksObj;
226
227 // Cached filtering policies.
228 int32_t mFilterTouchEvents;
229 int32_t mFilterJumpyTouchEvents;
230
Jeff Brownae9fc032010-08-18 15:51:08 -0700231 // Cached throttling policy.
232 int32_t mMaxEventsPerSecond;
233
Jeff Brown9c3cda02010-06-15 01:31:58 -0700234 // Cached display state. (lock mDisplayLock)
235 Mutex mDisplayLock;
236 int32_t mDisplayWidth, mDisplayHeight;
237 int32_t mDisplayOrientation;
238
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700239 // Power manager interactions.
Jeff Brown9c3cda02010-06-15 01:31:58 -0700240 bool isScreenOn();
241 bool isScreenBright();
242
Jeff Brown2cbecea2010-08-17 15:59:26 -0700243 // Weak references to all currently registered input channels by connection pointer.
Jeff Brown7fbdc842010-06-17 20:52:56 -0700244 Mutex mInputChannelRegistryLock;
Jeff Brown2cbecea2010-08-17 15:59:26 -0700245 KeyedVector<InputChannel*, jweak> mInputChannelObjWeakTable;
Jeff Brown7fbdc842010-06-17 20:52:56 -0700246
247 jobject getInputChannelObjLocal(JNIEnv* env, const sp<InputChannel>& inputChannel);
248
Jeff Brown349703e2010-06-22 01:27:15 -0700249 static bool populateWindow(JNIEnv* env, jobject windowObj, InputWindow& outWindow);
Jeff Brown349703e2010-06-22 01:27:15 -0700250
Jeff Brownb88102f2010-09-08 11:49:43 -0700251 static bool isPolicyKey(int32_t keyCode, bool isScreenOn);
252 static bool checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName);
Jeff Browna41ca772010-08-11 14:46:32 -0700253
Jeff Brown9c3cda02010-06-15 01:31:58 -0700254 static inline JNIEnv* jniEnv() {
255 return AndroidRuntime::getJNIEnv();
256 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700257};
258
259// ----------------------------------------------------------------------------
260
261NativeInputManager::NativeInputManager(jobject callbacksObj) :
262 mFilterTouchEvents(-1), mFilterJumpyTouchEvents(-1),
Jeff Brownae9fc032010-08-18 15:51:08 -0700263 mMaxEventsPerSecond(-1),
Jeff Brownb88102f2010-09-08 11:49:43 -0700264 mDisplayWidth(-1), mDisplayHeight(-1), mDisplayOrientation(ROTATION_0) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700265 JNIEnv* env = jniEnv();
266
267 mCallbacksObj = env->NewGlobalRef(callbacksObj);
268
269 sp<EventHub> eventHub = new EventHub();
270 mInputManager = new InputManager(eventHub, this, this);
271}
272
273NativeInputManager::~NativeInputManager() {
274 JNIEnv* env = jniEnv();
275
276 env->DeleteGlobalRef(mCallbacksObj);
277}
278
Jeff Brownb88102f2010-09-08 11:49:43 -0700279void NativeInputManager::dump(String8& dump) {
280 dump.append("Input Reader State:\n");
281 mInputManager->getReader()->dump(dump);
282 dump.append("\n");
Jeff Brown6d0fec22010-07-23 21:28:06 -0700283
Jeff Brownb88102f2010-09-08 11:49:43 -0700284 dump.append("Input Dispatcher State:\n");
285 mInputManager->getDispatcher()->dump(dump);
286 dump.append("\n");
Jeff Brown9c3cda02010-06-15 01:31:58 -0700287}
288
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700289bool NativeInputManager::isPolicyKey(int32_t keyCode, bool isScreenOn) {
290 // Special keys that the WindowManagerPolicy might care about.
291 switch (keyCode) {
Jeff Brownfd035822010-06-30 16:10:35 -0700292 case AKEYCODE_VOLUME_UP:
293 case AKEYCODE_VOLUME_DOWN:
294 case AKEYCODE_ENDCALL:
295 case AKEYCODE_POWER:
296 case AKEYCODE_CALL:
297 case AKEYCODE_HOME:
298 case AKEYCODE_MENU:
299 case AKEYCODE_SEARCH:
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700300 // media keys
Jeff Brownfd035822010-06-30 16:10:35 -0700301 case AKEYCODE_HEADSETHOOK:
302 case AKEYCODE_MEDIA_PLAY_PAUSE:
303 case AKEYCODE_MEDIA_STOP:
304 case AKEYCODE_MEDIA_NEXT:
305 case AKEYCODE_MEDIA_PREVIOUS:
306 case AKEYCODE_MEDIA_REWIND:
307 case AKEYCODE_MEDIA_FAST_FORWARD:
Jeff Brownb88102f2010-09-08 11:49:43 -0700308 // The policy always cares about these keys.
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700309 return true;
310 default:
311 // We need to pass all keys to the policy in the following cases:
312 // - screen is off
313 // - keyguard is visible
314 // - policy is performing key chording
315 //return ! isScreenOn || keyguardVisible || chording;
316 return true; // XXX stubbed out for now
317 }
318}
319
Jeff Brown7fbdc842010-06-17 20:52:56 -0700320bool NativeInputManager::checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700321 if (env->ExceptionCheck()) {
322 LOGE("An exception was thrown by callback '%s'.", methodName);
323 LOGE_EX(env);
324 env->ExceptionClear();
325 return true;
326 }
327 return false;
328}
329
330void NativeInputManager::setDisplaySize(int32_t displayId, int32_t width, int32_t height) {
331 if (displayId == 0) {
332 AutoMutex _l(mDisplayLock);
333
334 mDisplayWidth = width;
335 mDisplayHeight = height;
336 }
337}
338
339void NativeInputManager::setDisplayOrientation(int32_t displayId, int32_t orientation) {
340 if (displayId == 0) {
341 AutoMutex _l(mDisplayLock);
342
343 mDisplayOrientation = orientation;
344 }
345}
346
Jeff Brown7fbdc842010-06-17 20:52:56 -0700347status_t NativeInputManager::registerInputChannel(JNIEnv* env,
Jeff Browna41ca772010-08-11 14:46:32 -0700348 const sp<InputChannel>& inputChannel, jobject inputChannelObj, bool monitor) {
Jeff Brown7fbdc842010-06-17 20:52:56 -0700349 jweak inputChannelObjWeak = env->NewWeakGlobalRef(inputChannelObj);
350 if (! inputChannelObjWeak) {
351 LOGE("Could not create weak reference for input channel.");
352 LOGE_EX(env);
353 return NO_MEMORY;
354 }
355
356 status_t status;
357 {
358 AutoMutex _l(mInputChannelRegistryLock);
359
Jeff Brown2cbecea2010-08-17 15:59:26 -0700360 ssize_t index = mInputChannelObjWeakTable.indexOfKey(inputChannel.get());
Jeff Brown7fbdc842010-06-17 20:52:56 -0700361 if (index >= 0) {
362 LOGE("Input channel object '%s' has already been registered",
363 inputChannel->getName().string());
364 status = INVALID_OPERATION;
365 goto DeleteWeakRef;
366 }
367
Jeff Brown2cbecea2010-08-17 15:59:26 -0700368 mInputChannelObjWeakTable.add(inputChannel.get(), inputChannelObjWeak);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700369 }
370
Jeff Brownb88102f2010-09-08 11:49:43 -0700371 status = mInputManager->getDispatcher()->registerInputChannel(inputChannel, monitor);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700372 if (! status) {
Jeff Browna41ca772010-08-11 14:46:32 -0700373 // Success.
Jeff Brown7fbdc842010-06-17 20:52:56 -0700374 return OK;
375 }
376
Jeff Browna41ca772010-08-11 14:46:32 -0700377 // Failed!
Jeff Brown7fbdc842010-06-17 20:52:56 -0700378 {
379 AutoMutex _l(mInputChannelRegistryLock);
Jeff Brown2cbecea2010-08-17 15:59:26 -0700380 mInputChannelObjWeakTable.removeItem(inputChannel.get());
Jeff Brown7fbdc842010-06-17 20:52:56 -0700381 }
382
383DeleteWeakRef:
384 env->DeleteWeakGlobalRef(inputChannelObjWeak);
385 return status;
386}
387
388status_t NativeInputManager::unregisterInputChannel(JNIEnv* env,
389 const sp<InputChannel>& inputChannel) {
390 jweak inputChannelObjWeak;
391 {
392 AutoMutex _l(mInputChannelRegistryLock);
393
Jeff Brown2cbecea2010-08-17 15:59:26 -0700394 ssize_t index = mInputChannelObjWeakTable.indexOfKey(inputChannel.get());
Jeff Brown7fbdc842010-06-17 20:52:56 -0700395 if (index < 0) {
396 LOGE("Input channel object '%s' is not currently registered",
397 inputChannel->getName().string());
398 return INVALID_OPERATION;
399 }
400
Jeff Brown2cbecea2010-08-17 15:59:26 -0700401 inputChannelObjWeak = mInputChannelObjWeakTable.valueAt(index);
402 mInputChannelObjWeakTable.removeItemsAt(index);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700403 }
404
405 env->DeleteWeakGlobalRef(inputChannelObjWeak);
406
Jeff Brownb88102f2010-09-08 11:49:43 -0700407 return mInputManager->getDispatcher()->unregisterInputChannel(inputChannel);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700408}
409
410jobject NativeInputManager::getInputChannelObjLocal(JNIEnv* env,
411 const sp<InputChannel>& inputChannel) {
412 {
413 AutoMutex _l(mInputChannelRegistryLock);
414
Jeff Brown2cbecea2010-08-17 15:59:26 -0700415 ssize_t index = mInputChannelObjWeakTable.indexOfKey(inputChannel.get());
Jeff Brown7fbdc842010-06-17 20:52:56 -0700416 if (index < 0) {
417 return NULL;
418 }
419
Jeff Brown2cbecea2010-08-17 15:59:26 -0700420 jweak inputChannelObjWeak = mInputChannelObjWeakTable.valueAt(index);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700421 return env->NewLocalRef(inputChannelObjWeak);
422 }
423}
424
Jeff Brown9c3cda02010-06-15 01:31:58 -0700425bool NativeInputManager::getDisplayInfo(int32_t displayId,
426 int32_t* width, int32_t* height, int32_t* orientation) {
427 bool result = false;
428 if (displayId == 0) {
429 AutoMutex _l(mDisplayLock);
430
431 if (mDisplayWidth > 0) {
Jeff Brown6d0fec22010-07-23 21:28:06 -0700432 if (width) {
433 *width = mDisplayWidth;
434 }
435 if (height) {
436 *height = mDisplayHeight;
437 }
438 if (orientation) {
439 *orientation = mDisplayOrientation;
440 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700441 result = true;
442 }
443 }
444 return result;
445}
446
447bool NativeInputManager::isScreenOn() {
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700448 return android_server_PowerManagerService_isScreenOn();
Jeff Brown9c3cda02010-06-15 01:31:58 -0700449}
450
451bool NativeInputManager::isScreenBright() {
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700452 return android_server_PowerManagerService_isScreenBright();
Jeff Brown9c3cda02010-06-15 01:31:58 -0700453}
454
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700455void NativeInputManager::virtualKeyDownFeedback() {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700456#if DEBUG_INPUT_READER_POLICY
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700457 LOGD("virtualKeyDownFeedback");
Jeff Brown9c3cda02010-06-15 01:31:58 -0700458#endif
459
460 JNIEnv* env = jniEnv();
461
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700462 env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.virtualKeyDownFeedback);
463 checkAndClearExceptionFromCallback(env, "virtualKeyDownFeedback");
Jeff Brown9c3cda02010-06-15 01:31:58 -0700464}
465
466int32_t NativeInputManager::interceptKey(nsecs_t when,
Jeff Brown6d0fec22010-07-23 21:28:06 -0700467 int32_t deviceId, bool down, int32_t keyCode, int32_t scanCode, uint32_t& policyFlags) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700468#if DEBUG_INPUT_READER_POLICY
469 LOGD("interceptKey - when=%lld, deviceId=%d, down=%d, keyCode=%d, scanCode=%d, "
Jeff Brown349703e2010-06-22 01:27:15 -0700470 "policyFlags=0x%x",
Jeff Brown9c3cda02010-06-15 01:31:58 -0700471 when, deviceId, down, keyCode, scanCode, policyFlags);
472#endif
473
474 const int32_t WM_ACTION_PASS_TO_USER = 1;
475 const int32_t WM_ACTION_POKE_USER_ACTIVITY = 2;
476 const int32_t WM_ACTION_GO_TO_SLEEP = 4;
477
Jeff Brown9c3cda02010-06-15 01:31:58 -0700478 bool isScreenOn = this->isScreenOn();
479 bool isScreenBright = this->isScreenBright();
480
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700481 jint wmActions = 0;
482 if (isPolicyKey(keyCode, isScreenOn)) {
483 JNIEnv* env = jniEnv();
484
485 wmActions = env->CallIntMethod(mCallbacksObj,
486 gCallbacksClassInfo.interceptKeyBeforeQueueing,
487 when, keyCode, down, policyFlags, isScreenOn);
488 if (checkAndClearExceptionFromCallback(env, "interceptKeyBeforeQueueing")) {
489 wmActions = 0;
490 }
491 } else {
492 wmActions = WM_ACTION_PASS_TO_USER;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700493 }
494
495 int32_t actions = InputReaderPolicyInterface::ACTION_NONE;
496 if (! isScreenOn) {
497 // Key presses and releases wake the device.
Jeff Brown6d0fec22010-07-23 21:28:06 -0700498 policyFlags |= POLICY_FLAG_WOKE_HERE;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700499 }
500
501 if (! isScreenBright) {
502 // Key presses and releases brighten the screen if dimmed.
Jeff Brown6d0fec22010-07-23 21:28:06 -0700503 policyFlags |= POLICY_FLAG_BRIGHT_HERE;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700504 }
505
506 if (wmActions & WM_ACTION_GO_TO_SLEEP) {
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700507 android_server_PowerManagerService_goToSleep(when);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700508 }
509
510 if (wmActions & WM_ACTION_POKE_USER_ACTIVITY) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700511 android_server_PowerManagerService_userActivity(when, POWER_MANAGER_BUTTON_EVENT);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700512 }
513
514 if (wmActions & WM_ACTION_PASS_TO_USER) {
515 actions |= InputReaderPolicyInterface::ACTION_DISPATCH;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700516 }
Jeff Brown349703e2010-06-22 01:27:15 -0700517
Jeff Brown9c3cda02010-06-15 01:31:58 -0700518 return actions;
519}
520
Jeff Brown6d0fec22010-07-23 21:28:06 -0700521int32_t NativeInputManager::interceptGeneric(nsecs_t when, uint32_t& policyFlags) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700522#if DEBUG_INPUT_READER_POLICY
Jeff Brown6d0fec22010-07-23 21:28:06 -0700523 LOGD("interceptGeneric - when=%lld, policyFlags=0x%x", when, policyFlags);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700524#endif
525
Jeff Brown5c225b12010-06-16 01:53:36 -0700526 int32_t actions = InputReaderPolicyInterface::ACTION_NONE;
527 if (isScreenOn()) {
Jeff Brown6d0fec22010-07-23 21:28:06 -0700528 // Only dispatch events when the device is awake.
Jeff Brown349703e2010-06-22 01:27:15 -0700529 // Do not wake the device.
Jeff Brown5c225b12010-06-16 01:53:36 -0700530 actions |= InputReaderPolicyInterface::ACTION_DISPATCH;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700531
Jeff Brown349703e2010-06-22 01:27:15 -0700532 if (! isScreenBright()) {
533 // Brighten the screen if dimmed.
Jeff Brown6d0fec22010-07-23 21:28:06 -0700534 policyFlags |= POLICY_FLAG_BRIGHT_HERE;
Jeff Brown349703e2010-06-22 01:27:15 -0700535 }
Jeff Brown5c225b12010-06-16 01:53:36 -0700536 }
537
538 return actions;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700539}
540
541int32_t NativeInputManager::interceptSwitch(nsecs_t when, int32_t switchCode,
Jeff Brown6d0fec22010-07-23 21:28:06 -0700542 int32_t switchValue, uint32_t& policyFlags) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700543#if DEBUG_INPUT_READER_POLICY
Jeff Brown6d0fec22010-07-23 21:28:06 -0700544 LOGD("interceptSwitch - when=%lld, switchCode=%d, switchValue=%d, policyFlags=0x%x",
545 when, switchCode, switchValue, policyFlags);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700546#endif
547
548 JNIEnv* env = jniEnv();
549
550 switch (switchCode) {
551 case SW_LID:
552 env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyLidSwitchChanged,
553 when, switchValue == 0);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700554 checkAndClearExceptionFromCallback(env, "notifyLidSwitchChanged");
Jeff Brown9c3cda02010-06-15 01:31:58 -0700555 break;
556 }
557
558 return InputReaderPolicyInterface::ACTION_NONE;
559}
560
561bool NativeInputManager::filterTouchEvents() {
562 if (mFilterTouchEvents < 0) {
563 JNIEnv* env = jniEnv();
564
565 jboolean result = env->CallBooleanMethod(mCallbacksObj,
566 gCallbacksClassInfo.filterTouchEvents);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700567 if (checkAndClearExceptionFromCallback(env, "filterTouchEvents")) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700568 result = false;
569 }
570
571 mFilterTouchEvents = result ? 1 : 0;
572 }
573 return mFilterTouchEvents;
574}
575
576bool NativeInputManager::filterJumpyTouchEvents() {
577 if (mFilterJumpyTouchEvents < 0) {
578 JNIEnv* env = jniEnv();
579
580 jboolean result = env->CallBooleanMethod(mCallbacksObj,
581 gCallbacksClassInfo.filterJumpyTouchEvents);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700582 if (checkAndClearExceptionFromCallback(env, "filterJumpyTouchEvents")) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700583 result = false;
584 }
585
586 mFilterJumpyTouchEvents = result ? 1 : 0;
587 }
588 return mFilterJumpyTouchEvents;
589}
590
591void NativeInputManager::getVirtualKeyDefinitions(const String8& deviceName,
Jeff Brown8d608662010-08-30 03:02:23 -0700592 Vector<VirtualKeyDefinition>& outVirtualKeyDefinitions) {
593 outVirtualKeyDefinitions.clear();
594
Jeff Brown9c3cda02010-06-15 01:31:58 -0700595 JNIEnv* env = jniEnv();
596
597 jstring deviceNameStr = env->NewStringUTF(deviceName.string());
Jeff Brown7fbdc842010-06-17 20:52:56 -0700598 if (! checkAndClearExceptionFromCallback(env, "getVirtualKeyDefinitions")) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700599 jobjectArray result = jobjectArray(env->CallObjectMethod(mCallbacksObj,
600 gCallbacksClassInfo.getVirtualKeyDefinitions, deviceNameStr));
Jeff Brown7fbdc842010-06-17 20:52:56 -0700601 if (! checkAndClearExceptionFromCallback(env, "getVirtualKeyDefinitions") && result) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700602 jsize length = env->GetArrayLength(result);
603 for (jsize i = 0; i < length; i++) {
604 jobject item = env->GetObjectArrayElement(result, i);
605
606 outVirtualKeyDefinitions.add();
607 outVirtualKeyDefinitions.editTop().scanCode =
608 int32_t(env->GetIntField(item, gVirtualKeyDefinitionClassInfo.scanCode));
609 outVirtualKeyDefinitions.editTop().centerX =
610 int32_t(env->GetIntField(item, gVirtualKeyDefinitionClassInfo.centerX));
611 outVirtualKeyDefinitions.editTop().centerY =
612 int32_t(env->GetIntField(item, gVirtualKeyDefinitionClassInfo.centerY));
613 outVirtualKeyDefinitions.editTop().width =
614 int32_t(env->GetIntField(item, gVirtualKeyDefinitionClassInfo.width));
615 outVirtualKeyDefinitions.editTop().height =
616 int32_t(env->GetIntField(item, gVirtualKeyDefinitionClassInfo.height));
617
618 env->DeleteLocalRef(item);
619 }
620 env->DeleteLocalRef(result);
621 }
622 env->DeleteLocalRef(deviceNameStr);
623 }
624}
625
Jeff Brown8d608662010-08-30 03:02:23 -0700626void NativeInputManager::getInputDeviceCalibration(const String8& deviceName,
627 InputDeviceCalibration& outCalibration) {
628 outCalibration.clear();
629
630 JNIEnv* env = jniEnv();
631
632 jstring deviceNameStr = env->NewStringUTF(deviceName.string());
633 if (! checkAndClearExceptionFromCallback(env, "getInputDeviceCalibration")) {
634 jobject result = env->CallObjectMethod(mCallbacksObj,
635 gCallbacksClassInfo.getInputDeviceCalibration, deviceNameStr);
636 if (! checkAndClearExceptionFromCallback(env, "getInputDeviceCalibration") && result) {
637 jobjectArray keys = jobjectArray(env->GetObjectField(result,
638 gInputDeviceCalibrationClassInfo.keys));
639 jobjectArray values = jobjectArray(env->GetObjectField(result,
640 gInputDeviceCalibrationClassInfo.values));
641
642 jsize length = env->GetArrayLength(keys);
643 for (jsize i = 0; i < length; i++) {
644 jstring keyStr = jstring(env->GetObjectArrayElement(keys, i));
645 jstring valueStr = jstring(env->GetObjectArrayElement(values, i));
646
647 const char* keyChars = env->GetStringUTFChars(keyStr, NULL);
648 String8 key(keyChars);
649 env->ReleaseStringUTFChars(keyStr, keyChars);
650
651 const char* valueChars = env->GetStringUTFChars(valueStr, NULL);
652 String8 value(valueChars);
653 env->ReleaseStringUTFChars(valueStr, valueChars);
654
655 outCalibration.addProperty(key, value);
656
657 env->DeleteLocalRef(keyStr);
658 env->DeleteLocalRef(valueStr);
659 }
660 env->DeleteLocalRef(keys);
661 env->DeleteLocalRef(values);
662 env->DeleteLocalRef(result);
663 }
664 env->DeleteLocalRef(deviceNameStr);
665 }
666}
667
Jeff Brown9c3cda02010-06-15 01:31:58 -0700668void NativeInputManager::getExcludedDeviceNames(Vector<String8>& outExcludedDeviceNames) {
Jeff Brown8d608662010-08-30 03:02:23 -0700669 outExcludedDeviceNames.clear();
670
Jeff Brown9c3cda02010-06-15 01:31:58 -0700671 JNIEnv* env = jniEnv();
672
673 jobjectArray result = jobjectArray(env->CallObjectMethod(mCallbacksObj,
674 gCallbacksClassInfo.getExcludedDeviceNames));
Jeff Brown7fbdc842010-06-17 20:52:56 -0700675 if (! checkAndClearExceptionFromCallback(env, "getExcludedDeviceNames") && result) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700676 jsize length = env->GetArrayLength(result);
677 for (jsize i = 0; i < length; i++) {
678 jstring item = jstring(env->GetObjectArrayElement(result, i));
679
680 const char* deviceNameChars = env->GetStringUTFChars(item, NULL);
681 outExcludedDeviceNames.add(String8(deviceNameChars));
682 env->ReleaseStringUTFChars(item, deviceNameChars);
683
684 env->DeleteLocalRef(item);
685 }
686 env->DeleteLocalRef(result);
687 }
688}
689
690void NativeInputManager::notifyConfigurationChanged(nsecs_t when) {
691#if DEBUG_INPUT_DISPATCHER_POLICY
692 LOGD("notifyConfigurationChanged - when=%lld", when);
693#endif
694
695 JNIEnv* env = jniEnv();
696
697 InputConfiguration config;
Jeff Brownb88102f2010-09-08 11:49:43 -0700698 mInputManager->getReader()->getInputConfiguration(& config);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700699
700 env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyConfigurationChanged,
701 when, config.touchScreen, config.keyboard, config.navigation);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700702 checkAndClearExceptionFromCallback(env, "notifyConfigurationChanged");
Jeff Brown9c3cda02010-06-15 01:31:58 -0700703}
704
Jeff Brownb88102f2010-09-08 11:49:43 -0700705nsecs_t NativeInputManager::notifyANR(const sp<InputApplicationHandle>& inputApplicationHandle) {
706#if DEBUG_INPUT_DISPATCHER_POLICY
707 LOGD("notifyANR");
708#endif
709
710 JNIEnv* env = jniEnv();
711
712 ApplicationToken* token = static_cast<ApplicationToken*>(inputApplicationHandle.get());
713 jweak tokenObjWeak = token->getTokenObj();
714
715 jlong newTimeout;
716 jobject tokenObjLocal = env->NewLocalRef(tokenObjWeak);
717 if (tokenObjLocal) {
718 newTimeout = env->CallLongMethod(mCallbacksObj,
719 gCallbacksClassInfo.notifyANR, tokenObjLocal);
720 if (checkAndClearExceptionFromCallback(env, "notifyANR")) {
721 newTimeout = 0; // abort dispatch
722 } else {
723 assert(newTimeout >= 0);
724 }
725
726 env->DeleteLocalRef(tokenObjLocal);
727 } else {
728 newTimeout = 0; // abort dispatch
729 }
730
731 return newTimeout;
732}
733
Jeff Brown9c3cda02010-06-15 01:31:58 -0700734void NativeInputManager::notifyInputChannelBroken(const sp<InputChannel>& inputChannel) {
735#if DEBUG_INPUT_DISPATCHER_POLICY
736 LOGD("notifyInputChannelBroken - inputChannel='%s'", inputChannel->getName().string());
737#endif
738
Jeff Brown7fbdc842010-06-17 20:52:56 -0700739 JNIEnv* env = jniEnv();
740
741 jobject inputChannelObjLocal = getInputChannelObjLocal(env, inputChannel);
742 if (inputChannelObjLocal) {
743 env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyInputChannelBroken,
744 inputChannelObjLocal);
745 checkAndClearExceptionFromCallback(env, "notifyInputChannelBroken");
746
747 env->DeleteLocalRef(inputChannelObjLocal);
748 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700749}
750
Jeff Brownb88102f2010-09-08 11:49:43 -0700751nsecs_t NativeInputManager::notifyInputChannelANR(const sp<InputChannel>& inputChannel) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700752#if DEBUG_INPUT_DISPATCHER_POLICY
753 LOGD("notifyInputChannelANR - inputChannel='%s'",
754 inputChannel->getName().string());
755#endif
756
Jeff Brown7fbdc842010-06-17 20:52:56 -0700757 JNIEnv* env = jniEnv();
758
759 jlong newTimeout;
760 jobject inputChannelObjLocal = getInputChannelObjLocal(env, inputChannel);
761 if (inputChannelObjLocal) {
762 newTimeout = env->CallLongMethod(mCallbacksObj,
763 gCallbacksClassInfo.notifyInputChannelANR, inputChannelObjLocal);
764 if (checkAndClearExceptionFromCallback(env, "notifyInputChannelANR")) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700765 newTimeout = 0; // abort dispatch
766 } else {
767 assert(newTimeout >= 0);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700768 }
769
770 env->DeleteLocalRef(inputChannelObjLocal);
771 } else {
Jeff Brownb88102f2010-09-08 11:49:43 -0700772 newTimeout = 0; // abort dispatch
Jeff Brown7fbdc842010-06-17 20:52:56 -0700773 }
774
Jeff Brownb88102f2010-09-08 11:49:43 -0700775 return newTimeout;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700776}
777
778void NativeInputManager::notifyInputChannelRecoveredFromANR(const sp<InputChannel>& inputChannel) {
779#if DEBUG_INPUT_DISPATCHER_POLICY
780 LOGD("notifyInputChannelRecoveredFromANR - inputChannel='%s'",
781 inputChannel->getName().string());
782#endif
783
Jeff Brown7fbdc842010-06-17 20:52:56 -0700784 JNIEnv* env = jniEnv();
785
786 jobject inputChannelObjLocal = getInputChannelObjLocal(env, inputChannel);
787 if (inputChannelObjLocal) {
788 env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyInputChannelRecoveredFromANR,
789 inputChannelObjLocal);
790 checkAndClearExceptionFromCallback(env, "notifyInputChannelRecoveredFromANR");
791
792 env->DeleteLocalRef(inputChannelObjLocal);
793 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700794}
795
796nsecs_t NativeInputManager::getKeyRepeatTimeout() {
797 if (! isScreenOn()) {
798 // Disable key repeat when the screen is off.
799 return -1;
800 } else {
801 // TODO use ViewConfiguration.getLongPressTimeout()
802 return milliseconds_to_nanoseconds(500);
803 }
804}
805
Jeff Brownb21fb102010-09-07 10:44:57 -0700806nsecs_t NativeInputManager::getKeyRepeatDelay() {
807 return milliseconds_to_nanoseconds(50);
808}
809
Jeff Brownae9fc032010-08-18 15:51:08 -0700810int32_t NativeInputManager::getMaxEventsPerSecond() {
811 if (mMaxEventsPerSecond < 0) {
812 JNIEnv* env = jniEnv();
813
814 jint result = env->CallIntMethod(mCallbacksObj,
815 gCallbacksClassInfo.getMaxEventsPerSecond);
816 if (checkAndClearExceptionFromCallback(env, "getMaxEventsPerSecond")) {
Jeff Brown3d8c9bd2010-08-18 17:48:53 -0700817 result = 60;
Jeff Brownae9fc032010-08-18 15:51:08 -0700818 }
819
820 mMaxEventsPerSecond = result;
821 }
822 return mMaxEventsPerSecond;
823}
824
Jeff Brown349703e2010-06-22 01:27:15 -0700825void NativeInputManager::setInputWindows(JNIEnv* env, jobjectArray windowObjArray) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700826 Vector<InputWindow> windows;
Jeff Brown349703e2010-06-22 01:27:15 -0700827
Jeff Brownb88102f2010-09-08 11:49:43 -0700828 jsize length = env->GetArrayLength(windowObjArray);
829 for (jsize i = 0; i < length; i++) {
830 jobject inputTargetObj = env->GetObjectArrayElement(windowObjArray, i);
831 if (! inputTargetObj) {
832 break; // found null element indicating end of used portion of the array
Jeff Brown349703e2010-06-22 01:27:15 -0700833 }
834
Jeff Brownb88102f2010-09-08 11:49:43 -0700835 windows.push();
836 InputWindow& window = windows.editTop();
837 bool valid = populateWindow(env, inputTargetObj, window);
838 if (! valid) {
839 windows.pop();
Jeff Brown349703e2010-06-22 01:27:15 -0700840 }
841
Jeff Brownb88102f2010-09-08 11:49:43 -0700842 env->DeleteLocalRef(inputTargetObj);
843 }
Jeff Brown349703e2010-06-22 01:27:15 -0700844
Jeff Brownb88102f2010-09-08 11:49:43 -0700845 mInputManager->getDispatcher()->setInputWindows(windows);
Jeff Brown349703e2010-06-22 01:27:15 -0700846}
847
848bool NativeInputManager::populateWindow(JNIEnv* env, jobject windowObj,
849 InputWindow& outWindow) {
850 bool valid = false;
851
852 jobject inputChannelObj = env->GetObjectField(windowObj,
853 gInputWindowClassInfo.inputChannel);
854 if (inputChannelObj) {
855 sp<InputChannel> inputChannel =
856 android_view_InputChannel_getInputChannel(env, inputChannelObj);
857 if (inputChannel != NULL) {
858 jint layoutParamsFlags = env->GetIntField(windowObj,
859 gInputWindowClassInfo.layoutParamsFlags);
860 jint layoutParamsType = env->GetIntField(windowObj,
861 gInputWindowClassInfo.layoutParamsType);
862 jlong dispatchingTimeoutNanos = env->GetLongField(windowObj,
863 gInputWindowClassInfo.dispatchingTimeoutNanos);
864 jint frameLeft = env->GetIntField(windowObj,
865 gInputWindowClassInfo.frameLeft);
866 jint frameTop = env->GetIntField(windowObj,
867 gInputWindowClassInfo.frameTop);
Jeff Brown85a31762010-09-01 17:01:00 -0700868 jint frameRight = env->GetIntField(windowObj,
869 gInputWindowClassInfo.frameRight);
870 jint frameBottom = env->GetIntField(windowObj,
871 gInputWindowClassInfo.frameBottom);
872 jint visibleFrameLeft = env->GetIntField(windowObj,
873 gInputWindowClassInfo.visibleFrameLeft);
874 jint visibleFrameTop = env->GetIntField(windowObj,
875 gInputWindowClassInfo.visibleFrameTop);
876 jint visibleFrameRight = env->GetIntField(windowObj,
877 gInputWindowClassInfo.visibleFrameRight);
878 jint visibleFrameBottom = env->GetIntField(windowObj,
879 gInputWindowClassInfo.visibleFrameBottom);
Jeff Brown349703e2010-06-22 01:27:15 -0700880 jint touchableAreaLeft = env->GetIntField(windowObj,
881 gInputWindowClassInfo.touchableAreaLeft);
882 jint touchableAreaTop = env->GetIntField(windowObj,
883 gInputWindowClassInfo.touchableAreaTop);
884 jint touchableAreaRight = env->GetIntField(windowObj,
885 gInputWindowClassInfo.touchableAreaRight);
886 jint touchableAreaBottom = env->GetIntField(windowObj,
887 gInputWindowClassInfo.touchableAreaBottom);
888 jboolean visible = env->GetBooleanField(windowObj,
889 gInputWindowClassInfo.visible);
890 jboolean hasFocus = env->GetBooleanField(windowObj,
891 gInputWindowClassInfo.hasFocus);
892 jboolean hasWallpaper = env->GetBooleanField(windowObj,
893 gInputWindowClassInfo.hasWallpaper);
894 jboolean paused = env->GetBooleanField(windowObj,
895 gInputWindowClassInfo.paused);
896 jint ownerPid = env->GetIntField(windowObj,
897 gInputWindowClassInfo.ownerPid);
898 jint ownerUid = env->GetIntField(windowObj,
899 gInputWindowClassInfo.ownerUid);
900
901 outWindow.inputChannel = inputChannel;
902 outWindow.layoutParamsFlags = layoutParamsFlags;
903 outWindow.layoutParamsType = layoutParamsType;
904 outWindow.dispatchingTimeout = dispatchingTimeoutNanos;
905 outWindow.frameLeft = frameLeft;
906 outWindow.frameTop = frameTop;
Jeff Brown85a31762010-09-01 17:01:00 -0700907 outWindow.frameRight = frameRight;
908 outWindow.frameBottom = frameBottom;
909 outWindow.visibleFrameLeft = visibleFrameLeft;
910 outWindow.visibleFrameTop = visibleFrameTop;
911 outWindow.visibleFrameRight = visibleFrameRight;
912 outWindow.visibleFrameBottom = visibleFrameBottom;
Jeff Brown349703e2010-06-22 01:27:15 -0700913 outWindow.touchableAreaLeft = touchableAreaLeft;
914 outWindow.touchableAreaTop = touchableAreaTop;
915 outWindow.touchableAreaRight = touchableAreaRight;
916 outWindow.touchableAreaBottom = touchableAreaBottom;
917 outWindow.visible = visible;
918 outWindow.hasFocus = hasFocus;
919 outWindow.hasWallpaper = hasWallpaper;
920 outWindow.paused = paused;
921 outWindow.ownerPid = ownerPid;
922 outWindow.ownerUid = ownerUid;
923 valid = true;
924 } else {
925 LOGW("Dropping input target because its input channel is not initialized.");
926 }
927
928 env->DeleteLocalRef(inputChannelObj);
929 } else {
930 LOGW("Dropping input target because the input channel object was null.");
931 }
932 return valid;
933}
934
935void NativeInputManager::setFocusedApplication(JNIEnv* env, jobject applicationObj) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700936 if (applicationObj) {
937 jstring nameObj = jstring(env->GetObjectField(applicationObj,
938 gInputApplicationClassInfo.name));
939 jlong dispatchingTimeoutNanos = env->GetLongField(applicationObj,
940 gInputApplicationClassInfo.dispatchingTimeoutNanos);
941 jobject tokenObj = env->GetObjectField(applicationObj,
942 gInputApplicationClassInfo.token);
943 jweak tokenObjWeak = env->NewWeakGlobalRef(tokenObj);
944 if (! tokenObjWeak) {
945 LOGE("Could not create weak reference for application token.");
946 LOGE_EX(env);
947 env->ExceptionClear();
948 }
949 env->DeleteLocalRef(tokenObj);
Jeff Brown349703e2010-06-22 01:27:15 -0700950
Jeff Brownb88102f2010-09-08 11:49:43 -0700951 String8 name;
952 if (nameObj) {
953 const char* nameStr = env->GetStringUTFChars(nameObj, NULL);
954 name.setTo(nameStr);
955 env->ReleaseStringUTFChars(nameObj, nameStr);
956 env->DeleteLocalRef(nameObj);
957 } else {
958 LOGE("InputApplication.name should not be null.");
959 name.setTo("unknown");
Jeff Brown349703e2010-06-22 01:27:15 -0700960 }
961
Jeff Brownb88102f2010-09-08 11:49:43 -0700962 InputApplication application;
963 application.name = name;
964 application.dispatchingTimeout = dispatchingTimeoutNanos;
965 application.handle = new ApplicationToken(tokenObjWeak);
966 mInputManager->getDispatcher()->setFocusedApplication(& application);
967 } else {
968 mInputManager->getDispatcher()->setFocusedApplication(NULL);
Jeff Brown349703e2010-06-22 01:27:15 -0700969 }
970}
971
972void NativeInputManager::setInputDispatchMode(bool enabled, bool frozen) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700973 mInputManager->getDispatcher()->setInputDispatchMode(enabled, frozen);
Jeff Brown349703e2010-06-22 01:27:15 -0700974}
975
976void NativeInputManager::preemptInputDispatch() {
Jeff Brownb88102f2010-09-08 11:49:43 -0700977 mInputManager->getDispatcher()->preemptInputDispatch();
Jeff Brown349703e2010-06-22 01:27:15 -0700978}
979
Jeff Brownb88102f2010-09-08 11:49:43 -0700980bool NativeInputManager::interceptKeyBeforeDispatching(const sp<InputChannel>& inputChannel,
Jeff Brownd0097872010-06-30 14:41:59 -0700981 const KeyEvent* keyEvent, uint32_t policyFlags) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700982 bool isScreenOn = this->isScreenOn();
983 if (! isPolicyKey(keyEvent->getKeyCode(), isScreenOn)) {
984 return false;
985 }
986
Jeff Brownd0097872010-06-30 14:41:59 -0700987 JNIEnv* env = jniEnv();
988
Jeff Brownb88102f2010-09-08 11:49:43 -0700989 jobject inputChannelObj = getInputChannelObjLocal(env, inputChannel);
Jeff Brownd0097872010-06-30 14:41:59 -0700990 if (inputChannelObj) {
991 jboolean consumed = env->CallBooleanMethod(mCallbacksObj,
992 gCallbacksClassInfo.interceptKeyBeforeDispatching,
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700993 inputChannelObj, keyEvent->getAction(), keyEvent->getFlags(),
994 keyEvent->getKeyCode(), keyEvent->getMetaState(),
Jeff Brownd0097872010-06-30 14:41:59 -0700995 keyEvent->getRepeatCount(), policyFlags);
996 bool error = checkAndClearExceptionFromCallback(env, "interceptKeyBeforeDispatching");
997
998 env->DeleteLocalRef(inputChannelObj);
999
1000 return consumed && ! error;
1001 } else {
1002 LOGW("Could not apply key dispatch policy because input channel '%s' is "
Jeff Brownb88102f2010-09-08 11:49:43 -07001003 "no longer valid.", inputChannel->getName().string());
Jeff Brownd0097872010-06-30 14:41:59 -07001004 return false;
1005 }
1006}
1007
Jeff Brownb88102f2010-09-08 11:49:43 -07001008void NativeInputManager::pokeUserActivity(nsecs_t eventTime, int32_t windowType, int32_t eventType) {
1009 if (windowType != InputWindow::TYPE_KEYGUARD) {
1010 android_server_PowerManagerService_userActivity(eventTime, eventType);
Jeff Brown349703e2010-06-22 01:27:15 -07001011 }
1012}
1013
Jeff Brown349703e2010-06-22 01:27:15 -07001014
Jeff Brownb88102f2010-09-08 11:49:43 -07001015bool NativeInputManager::checkInjectEventsPermissionNonReentrant(
1016 int32_t injectorPid, int32_t injectorUid) {
1017 JNIEnv* env = jniEnv();
1018 jboolean result = env->CallBooleanMethod(mCallbacksObj,
1019 gCallbacksClassInfo.checkInjectEventsPermission, injectorPid, injectorUid);
1020 checkAndClearExceptionFromCallback(env, "checkInjectEventsPermission");
Jeff Brown349703e2010-06-22 01:27:15 -07001021 return result;
1022}
1023
Jeff Brown9c3cda02010-06-15 01:31:58 -07001024// ----------------------------------------------------------------------------
1025
1026static sp<NativeInputManager> gNativeInputManager;
1027
Jeff Brown46b9ac02010-04-22 18:58:52 -07001028static bool checkInputManagerUnitialized(JNIEnv* env) {
Jeff Brown9c3cda02010-06-15 01:31:58 -07001029 if (gNativeInputManager == NULL) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07001030 LOGE("Input manager not initialized.");
1031 jniThrowRuntimeException(env, "Input manager not initialized.");
1032 return true;
1033 }
1034 return false;
1035}
1036
1037static void android_server_InputManager_nativeInit(JNIEnv* env, jclass clazz,
1038 jobject callbacks) {
Jeff Brown9c3cda02010-06-15 01:31:58 -07001039 if (gNativeInputManager == NULL) {
1040 gNativeInputManager = new NativeInputManager(callbacks);
1041 } else {
1042 LOGE("Input manager already initialized.");
1043 jniThrowRuntimeException(env, "Input manager already initialized.");
Jeff Brown46b9ac02010-04-22 18:58:52 -07001044 }
1045}
1046
1047static void android_server_InputManager_nativeStart(JNIEnv* env, jclass clazz) {
1048 if (checkInputManagerUnitialized(env)) {
1049 return;
1050 }
1051
Jeff Brown9c3cda02010-06-15 01:31:58 -07001052 status_t result = gNativeInputManager->getInputManager()->start();
Jeff Brown46b9ac02010-04-22 18:58:52 -07001053 if (result) {
1054 jniThrowRuntimeException(env, "Input manager could not be started.");
1055 }
1056}
1057
1058static void android_server_InputManager_nativeSetDisplaySize(JNIEnv* env, jclass clazz,
1059 jint displayId, jint width, jint height) {
1060 if (checkInputManagerUnitialized(env)) {
1061 return;
1062 }
1063
1064 // XXX we could get this from the SurfaceFlinger directly instead of requiring it
1065 // to be passed in like this, not sure which is better but leaving it like this
1066 // keeps the window manager in direct control of when display transitions propagate down
1067 // to the input dispatcher
Jeff Brown9c3cda02010-06-15 01:31:58 -07001068 gNativeInputManager->setDisplaySize(displayId, width, height);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001069}
1070
1071static void android_server_InputManager_nativeSetDisplayOrientation(JNIEnv* env, jclass clazz,
1072 jint displayId, jint orientation) {
1073 if (checkInputManagerUnitialized(env)) {
1074 return;
1075 }
1076
Jeff Brown9c3cda02010-06-15 01:31:58 -07001077 gNativeInputManager->setDisplayOrientation(displayId, orientation);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001078}
1079
1080static jint android_server_InputManager_nativeGetScanCodeState(JNIEnv* env, jclass clazz,
Jeff Brown6d0fec22010-07-23 21:28:06 -07001081 jint deviceId, jint sourceMask, jint scanCode) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07001082 if (checkInputManagerUnitialized(env)) {
Jeff Brownc5ed5912010-07-14 18:48:53 -07001083 return AKEY_STATE_UNKNOWN;
Jeff Brown46b9ac02010-04-22 18:58:52 -07001084 }
1085
Jeff Brownb88102f2010-09-08 11:49:43 -07001086 return gNativeInputManager->getInputManager()->getReader()->getScanCodeState(
Jeff Brown6d0fec22010-07-23 21:28:06 -07001087 deviceId, uint32_t(sourceMask), scanCode);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001088}
1089
1090static jint android_server_InputManager_nativeGetKeyCodeState(JNIEnv* env, jclass clazz,
Jeff Brown6d0fec22010-07-23 21:28:06 -07001091 jint deviceId, jint sourceMask, jint keyCode) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07001092 if (checkInputManagerUnitialized(env)) {
Jeff Brownc5ed5912010-07-14 18:48:53 -07001093 return AKEY_STATE_UNKNOWN;
Jeff Brown46b9ac02010-04-22 18:58:52 -07001094 }
1095
Jeff Brownb88102f2010-09-08 11:49:43 -07001096 return gNativeInputManager->getInputManager()->getReader()->getKeyCodeState(
Jeff Brown6d0fec22010-07-23 21:28:06 -07001097 deviceId, uint32_t(sourceMask), keyCode);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001098}
1099
1100static jint android_server_InputManager_nativeGetSwitchState(JNIEnv* env, jclass clazz,
Jeff Brown6d0fec22010-07-23 21:28:06 -07001101 jint deviceId, jint sourceMask, jint sw) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07001102 if (checkInputManagerUnitialized(env)) {
Jeff Brownc5ed5912010-07-14 18:48:53 -07001103 return AKEY_STATE_UNKNOWN;
Jeff Brown46b9ac02010-04-22 18:58:52 -07001104 }
1105
Jeff Brownb88102f2010-09-08 11:49:43 -07001106 return gNativeInputManager->getInputManager()->getReader()->getSwitchState(
Jeff Brown6d0fec22010-07-23 21:28:06 -07001107 deviceId, uint32_t(sourceMask), sw);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001108}
1109
1110static jboolean android_server_InputManager_nativeHasKeys(JNIEnv* env, jclass clazz,
Jeff Brown6d0fec22010-07-23 21:28:06 -07001111 jint deviceId, jint sourceMask, jintArray keyCodes, jbooleanArray outFlags) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07001112 if (checkInputManagerUnitialized(env)) {
1113 return JNI_FALSE;
1114 }
1115
1116 int32_t* codes = env->GetIntArrayElements(keyCodes, NULL);
1117 uint8_t* flags = env->GetBooleanArrayElements(outFlags, NULL);
1118 jsize numCodes = env->GetArrayLength(keyCodes);
1119 jboolean result;
Jeff Brown6d0fec22010-07-23 21:28:06 -07001120 if (numCodes == env->GetArrayLength(keyCodes)) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001121 result = gNativeInputManager->getInputManager()->getReader()->hasKeys(
Jeff Brown6d0fec22010-07-23 21:28:06 -07001122 deviceId, uint32_t(sourceMask), numCodes, codes, flags);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001123 } else {
1124 result = JNI_FALSE;
1125 }
1126
1127 env->ReleaseBooleanArrayElements(outFlags, flags, 0);
1128 env->ReleaseIntArrayElements(keyCodes, codes, 0);
1129 return result;
1130}
1131
1132static void throwInputChannelNotInitialized(JNIEnv* env) {
1133 jniThrowException(env, "java/lang/IllegalStateException",
1134 "inputChannel is not initialized");
1135}
1136
1137static void android_server_InputManager_handleInputChannelDisposed(JNIEnv* env,
1138 jobject inputChannelObj, const sp<InputChannel>& inputChannel, void* data) {
1139 LOGW("Input channel object '%s' was disposed without first being unregistered with "
1140 "the input manager!", inputChannel->getName().string());
1141
Jeff Brown9c3cda02010-06-15 01:31:58 -07001142 if (gNativeInputManager != NULL) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07001143 gNativeInputManager->unregisterInputChannel(env, inputChannel);
Jeff Brown9c3cda02010-06-15 01:31:58 -07001144 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07001145}
1146
1147static void android_server_InputManager_nativeRegisterInputChannel(JNIEnv* env, jclass clazz,
Jeff Browna41ca772010-08-11 14:46:32 -07001148 jobject inputChannelObj, jboolean monitor) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07001149 if (checkInputManagerUnitialized(env)) {
1150 return;
1151 }
1152
1153 sp<InputChannel> inputChannel = android_view_InputChannel_getInputChannel(env,
1154 inputChannelObj);
1155 if (inputChannel == NULL) {
1156 throwInputChannelNotInitialized(env);
1157 return;
1158 }
1159
Jeff Brown7fbdc842010-06-17 20:52:56 -07001160
1161 status_t status = gNativeInputManager->registerInputChannel(
Jeff Browna41ca772010-08-11 14:46:32 -07001162 env, inputChannel, inputChannelObj, monitor);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001163 if (status) {
1164 jniThrowRuntimeException(env, "Failed to register input channel. "
1165 "Check logs for details.");
1166 return;
1167 }
1168
Jeff Browna41ca772010-08-11 14:46:32 -07001169 if (! monitor) {
1170 android_view_InputChannel_setDisposeCallback(env, inputChannelObj,
1171 android_server_InputManager_handleInputChannelDisposed, NULL);
1172 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07001173}
1174
1175static void android_server_InputManager_nativeUnregisterInputChannel(JNIEnv* env, jclass clazz,
1176 jobject inputChannelObj) {
1177 if (checkInputManagerUnitialized(env)) {
1178 return;
1179 }
1180
1181 sp<InputChannel> inputChannel = android_view_InputChannel_getInputChannel(env,
1182 inputChannelObj);
1183 if (inputChannel == NULL) {
1184 throwInputChannelNotInitialized(env);
1185 return;
1186 }
1187
1188 android_view_InputChannel_setDisposeCallback(env, inputChannelObj, NULL, NULL);
1189
Jeff Brown7fbdc842010-06-17 20:52:56 -07001190 status_t status = gNativeInputManager->unregisterInputChannel(env, inputChannel);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001191 if (status) {
1192 jniThrowRuntimeException(env, "Failed to unregister input channel. "
1193 "Check logs for details.");
1194 }
1195}
1196
Jeff Brown6ec402b2010-07-28 15:48:59 -07001197static jint android_server_InputManager_nativeInjectInputEvent(JNIEnv* env, jclass clazz,
1198 jobject inputEventObj, jint injectorPid, jint injectorUid,
1199 jint syncMode, jint timeoutMillis) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07001200 if (checkInputManagerUnitialized(env)) {
1201 return INPUT_EVENT_INJECTION_FAILED;
1202 }
1203
Jeff Brown6ec402b2010-07-28 15:48:59 -07001204 if (env->IsInstanceOf(inputEventObj, gKeyEventClassInfo.clazz)) {
1205 KeyEvent keyEvent;
1206 android_view_KeyEvent_toNative(env, inputEventObj, & keyEvent);
Jeff Brown7fbdc842010-06-17 20:52:56 -07001207
Jeff Brownb88102f2010-09-08 11:49:43 -07001208 return gNativeInputManager->getInputManager()->getDispatcher()->injectInputEvent(
1209 & keyEvent, injectorPid, injectorUid, syncMode, timeoutMillis);
Jeff Brown6ec402b2010-07-28 15:48:59 -07001210 } else if (env->IsInstanceOf(inputEventObj, gMotionEventClassInfo.clazz)) {
1211 MotionEvent motionEvent;
1212 android_view_MotionEvent_toNative(env, inputEventObj, & motionEvent);
Jeff Brown7fbdc842010-06-17 20:52:56 -07001213
Jeff Brownb88102f2010-09-08 11:49:43 -07001214 return gNativeInputManager->getInputManager()->getDispatcher()->injectInputEvent(
1215 & motionEvent, injectorPid, injectorUid, syncMode, timeoutMillis);
Jeff Brown6ec402b2010-07-28 15:48:59 -07001216 } else {
1217 jniThrowRuntimeException(env, "Invalid input event type.");
Jeff Brown7fbdc842010-06-17 20:52:56 -07001218 return INPUT_EVENT_INJECTION_FAILED;
1219 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07001220}
1221
Jeff Brown349703e2010-06-22 01:27:15 -07001222static void android_server_InputManager_nativeSetInputWindows(JNIEnv* env, jclass clazz,
1223 jobjectArray windowObjArray) {
1224 if (checkInputManagerUnitialized(env)) {
1225 return;
1226 }
1227
1228 gNativeInputManager->setInputWindows(env, windowObjArray);
1229}
1230
1231static void android_server_InputManager_nativeSetFocusedApplication(JNIEnv* env, jclass clazz,
1232 jobject applicationObj) {
1233 if (checkInputManagerUnitialized(env)) {
1234 return;
1235 }
1236
1237 gNativeInputManager->setFocusedApplication(env, applicationObj);
1238}
1239
1240static void android_server_InputManager_nativeSetInputDispatchMode(JNIEnv* env,
1241 jclass clazz, jboolean enabled, jboolean frozen) {
1242 if (checkInputManagerUnitialized(env)) {
1243 return;
1244 }
1245
1246 gNativeInputManager->setInputDispatchMode(enabled, frozen);
1247}
1248
1249static void android_server_InputManager_nativePreemptInputDispatch(JNIEnv* env,
1250 jclass clazz) {
1251 if (checkInputManagerUnitialized(env)) {
1252 return;
1253 }
1254
1255 gNativeInputManager->preemptInputDispatch();
1256}
1257
Jeff Brown8d608662010-08-30 03:02:23 -07001258static jobject android_server_InputManager_nativeGetInputDevice(JNIEnv* env,
1259 jclass clazz, jint deviceId) {
1260 if (checkInputManagerUnitialized(env)) {
1261 return NULL;
1262 }
1263
1264 InputDeviceInfo deviceInfo;
Jeff Brownb88102f2010-09-08 11:49:43 -07001265 status_t status = gNativeInputManager->getInputManager()->getReader()->getInputDeviceInfo(
Jeff Brown8d608662010-08-30 03:02:23 -07001266 deviceId, & deviceInfo);
1267 if (status) {
1268 return NULL;
1269 }
1270
1271 jobject deviceObj = env->NewObject(gInputDeviceClassInfo.clazz, gInputDeviceClassInfo.ctor);
1272 if (! deviceObj) {
1273 return NULL;
1274 }
1275
1276 jstring deviceNameObj = env->NewStringUTF(deviceInfo.getName().string());
1277 if (! deviceNameObj) {
1278 return NULL;
1279 }
1280
1281 env->SetIntField(deviceObj, gInputDeviceClassInfo.mId, deviceInfo.getId());
1282 env->SetObjectField(deviceObj, gInputDeviceClassInfo.mName, deviceNameObj);
1283 env->SetIntField(deviceObj, gInputDeviceClassInfo.mSources, deviceInfo.getSources());
1284 env->SetIntField(deviceObj, gInputDeviceClassInfo.mKeyboardType, deviceInfo.getKeyboardType());
1285
1286 const KeyedVector<int, InputDeviceInfo::MotionRange>& ranges = deviceInfo.getMotionRanges();
1287 for (size_t i = 0; i < ranges.size(); i++) {
1288 int rangeType = ranges.keyAt(i);
1289 const InputDeviceInfo::MotionRange& range = ranges.valueAt(i);
1290 env->CallVoidMethod(deviceObj, gInputDeviceClassInfo.addMotionRange,
1291 rangeType, range.min, range.max, range.flat, range.fuzz);
1292 if (env->ExceptionCheck()) {
1293 return NULL;
1294 }
1295 }
1296
1297 return deviceObj;
1298}
1299
1300static jintArray android_server_InputManager_nativeGetInputDeviceIds(JNIEnv* env,
1301 jclass clazz) {
1302 if (checkInputManagerUnitialized(env)) {
1303 return NULL;
1304 }
1305
1306 Vector<int> deviceIds;
Jeff Brownb88102f2010-09-08 11:49:43 -07001307 gNativeInputManager->getInputManager()->getReader()->getInputDeviceIds(deviceIds);
Jeff Brown8d608662010-08-30 03:02:23 -07001308
1309 jintArray deviceIdsObj = env->NewIntArray(deviceIds.size());
1310 if (! deviceIdsObj) {
1311 return NULL;
1312 }
1313
1314 env->SetIntArrayRegion(deviceIdsObj, 0, deviceIds.size(), deviceIds.array());
1315 return deviceIdsObj;
1316}
1317
Jeff Browne33348b2010-07-15 23:54:05 -07001318static jstring android_server_InputManager_nativeDump(JNIEnv* env, jclass clazz) {
1319 if (checkInputManagerUnitialized(env)) {
1320 return NULL;
1321 }
1322
Jeff Brownb88102f2010-09-08 11:49:43 -07001323 String8 dump;
1324 gNativeInputManager->dump(dump);
Jeff Browne33348b2010-07-15 23:54:05 -07001325 return env->NewStringUTF(dump.string());
1326}
1327
Jeff Brown9c3cda02010-06-15 01:31:58 -07001328// ----------------------------------------------------------------------------
1329
Jeff Brown46b9ac02010-04-22 18:58:52 -07001330static JNINativeMethod gInputManagerMethods[] = {
1331 /* name, signature, funcPtr */
1332 { "nativeInit", "(Lcom/android/server/InputManager$Callbacks;)V",
1333 (void*) android_server_InputManager_nativeInit },
1334 { "nativeStart", "()V",
1335 (void*) android_server_InputManager_nativeStart },
1336 { "nativeSetDisplaySize", "(III)V",
1337 (void*) android_server_InputManager_nativeSetDisplaySize },
1338 { "nativeSetDisplayOrientation", "(II)V",
1339 (void*) android_server_InputManager_nativeSetDisplayOrientation },
1340 { "nativeGetScanCodeState", "(III)I",
1341 (void*) android_server_InputManager_nativeGetScanCodeState },
1342 { "nativeGetKeyCodeState", "(III)I",
1343 (void*) android_server_InputManager_nativeGetKeyCodeState },
1344 { "nativeGetSwitchState", "(III)I",
1345 (void*) android_server_InputManager_nativeGetSwitchState },
Jeff Brown6d0fec22010-07-23 21:28:06 -07001346 { "nativeHasKeys", "(II[I[Z)Z",
Jeff Brown46b9ac02010-04-22 18:58:52 -07001347 (void*) android_server_InputManager_nativeHasKeys },
Jeff Browna41ca772010-08-11 14:46:32 -07001348 { "nativeRegisterInputChannel", "(Landroid/view/InputChannel;Z)V",
Jeff Brown46b9ac02010-04-22 18:58:52 -07001349 (void*) android_server_InputManager_nativeRegisterInputChannel },
1350 { "nativeUnregisterInputChannel", "(Landroid/view/InputChannel;)V",
Jeff Brown7fbdc842010-06-17 20:52:56 -07001351 (void*) android_server_InputManager_nativeUnregisterInputChannel },
Jeff Brown6ec402b2010-07-28 15:48:59 -07001352 { "nativeInjectInputEvent", "(Landroid/view/InputEvent;IIII)I",
1353 (void*) android_server_InputManager_nativeInjectInputEvent },
Jeff Brown349703e2010-06-22 01:27:15 -07001354 { "nativeSetInputWindows", "([Lcom/android/server/InputWindow;)V",
1355 (void*) android_server_InputManager_nativeSetInputWindows },
1356 { "nativeSetFocusedApplication", "(Lcom/android/server/InputApplication;)V",
1357 (void*) android_server_InputManager_nativeSetFocusedApplication },
1358 { "nativeSetInputDispatchMode", "(ZZ)V",
1359 (void*) android_server_InputManager_nativeSetInputDispatchMode },
1360 { "nativePreemptInputDispatch", "()V",
Jeff Browne33348b2010-07-15 23:54:05 -07001361 (void*) android_server_InputManager_nativePreemptInputDispatch },
Jeff Brown8d608662010-08-30 03:02:23 -07001362 { "nativeGetInputDevice", "(I)Landroid/view/InputDevice;",
1363 (void*) android_server_InputManager_nativeGetInputDevice },
1364 { "nativeGetInputDeviceIds", "()[I",
1365 (void*) android_server_InputManager_nativeGetInputDeviceIds },
Jeff Browne33348b2010-07-15 23:54:05 -07001366 { "nativeDump", "()Ljava/lang/String;",
1367 (void*) android_server_InputManager_nativeDump },
Jeff Brown46b9ac02010-04-22 18:58:52 -07001368};
1369
1370#define FIND_CLASS(var, className) \
1371 var = env->FindClass(className); \
1372 LOG_FATAL_IF(! var, "Unable to find class " className); \
1373 var = jclass(env->NewGlobalRef(var));
1374
1375#define GET_METHOD_ID(var, clazz, methodName, methodDescriptor) \
1376 var = env->GetMethodID(clazz, methodName, methodDescriptor); \
1377 LOG_FATAL_IF(! var, "Unable to find method " methodName);
1378
1379#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \
1380 var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \
1381 LOG_FATAL_IF(! var, "Unable to find field " fieldName);
1382
1383int register_android_server_InputManager(JNIEnv* env) {
1384 int res = jniRegisterNativeMethods(env, "com/android/server/InputManager",
1385 gInputManagerMethods, NELEM(gInputManagerMethods));
1386 LOG_FATAL_IF(res < 0, "Unable to register native methods.");
1387
Jeff Brown9c3cda02010-06-15 01:31:58 -07001388 // Callbacks
Jeff Brown46b9ac02010-04-22 18:58:52 -07001389
1390 FIND_CLASS(gCallbacksClassInfo.clazz, "com/android/server/InputManager$Callbacks");
1391
Jeff Brown46b9ac02010-04-22 18:58:52 -07001392 GET_METHOD_ID(gCallbacksClassInfo.notifyConfigurationChanged, gCallbacksClassInfo.clazz,
1393 "notifyConfigurationChanged", "(JIII)V");
1394
1395 GET_METHOD_ID(gCallbacksClassInfo.notifyLidSwitchChanged, gCallbacksClassInfo.clazz,
1396 "notifyLidSwitchChanged", "(JZ)V");
1397
Jeff Brown7fbdc842010-06-17 20:52:56 -07001398 GET_METHOD_ID(gCallbacksClassInfo.notifyInputChannelBroken, gCallbacksClassInfo.clazz,
1399 "notifyInputChannelBroken", "(Landroid/view/InputChannel;)V");
1400
1401 GET_METHOD_ID(gCallbacksClassInfo.notifyInputChannelANR, gCallbacksClassInfo.clazz,
1402 "notifyInputChannelANR", "(Landroid/view/InputChannel;)J");
1403
1404 GET_METHOD_ID(gCallbacksClassInfo.notifyInputChannelRecoveredFromANR, gCallbacksClassInfo.clazz,
1405 "notifyInputChannelRecoveredFromANR", "(Landroid/view/InputChannel;)V");
1406
Jeff Brown349703e2010-06-22 01:27:15 -07001407 GET_METHOD_ID(gCallbacksClassInfo.notifyANR, gCallbacksClassInfo.clazz,
1408 "notifyANR", "(Ljava/lang/Object;)J");
1409
Jeff Brown00fa7bd2010-07-02 15:37:36 -07001410 GET_METHOD_ID(gCallbacksClassInfo.virtualKeyDownFeedback, gCallbacksClassInfo.clazz,
1411 "virtualKeyDownFeedback", "()V");
Jeff Brown46b9ac02010-04-22 18:58:52 -07001412
Jeff Brown349703e2010-06-22 01:27:15 -07001413 GET_METHOD_ID(gCallbacksClassInfo.interceptKeyBeforeQueueing, gCallbacksClassInfo.clazz,
Jeff Brown00fa7bd2010-07-02 15:37:36 -07001414 "interceptKeyBeforeQueueing", "(JIZIZ)I");
Jeff Brown349703e2010-06-22 01:27:15 -07001415
1416 GET_METHOD_ID(gCallbacksClassInfo.interceptKeyBeforeDispatching, gCallbacksClassInfo.clazz,
Jeff Brown00fa7bd2010-07-02 15:37:36 -07001417 "interceptKeyBeforeDispatching", "(Landroid/view/InputChannel;IIIIII)Z");
Jeff Brown349703e2010-06-22 01:27:15 -07001418
1419 GET_METHOD_ID(gCallbacksClassInfo.checkInjectEventsPermission, gCallbacksClassInfo.clazz,
1420 "checkInjectEventsPermission", "(II)Z");
Jeff Brown46b9ac02010-04-22 18:58:52 -07001421
Jeff Brown46b9ac02010-04-22 18:58:52 -07001422 GET_METHOD_ID(gCallbacksClassInfo.filterTouchEvents, gCallbacksClassInfo.clazz,
1423 "filterTouchEvents", "()Z");
1424
1425 GET_METHOD_ID(gCallbacksClassInfo.filterJumpyTouchEvents, gCallbacksClassInfo.clazz,
1426 "filterJumpyTouchEvents", "()Z");
1427
1428 GET_METHOD_ID(gCallbacksClassInfo.getVirtualKeyDefinitions, gCallbacksClassInfo.clazz,
1429 "getVirtualKeyDefinitions",
1430 "(Ljava/lang/String;)[Lcom/android/server/InputManager$VirtualKeyDefinition;");
1431
Jeff Brown8d608662010-08-30 03:02:23 -07001432 GET_METHOD_ID(gCallbacksClassInfo.getInputDeviceCalibration, gCallbacksClassInfo.clazz,
1433 "getInputDeviceCalibration",
1434 "(Ljava/lang/String;)Lcom/android/server/InputManager$InputDeviceCalibration;");
1435
Jeff Brown46b9ac02010-04-22 18:58:52 -07001436 GET_METHOD_ID(gCallbacksClassInfo.getExcludedDeviceNames, gCallbacksClassInfo.clazz,
1437 "getExcludedDeviceNames", "()[Ljava/lang/String;");
1438
Jeff Brownae9fc032010-08-18 15:51:08 -07001439 GET_METHOD_ID(gCallbacksClassInfo.getMaxEventsPerSecond, gCallbacksClassInfo.clazz,
1440 "getMaxEventsPerSecond", "()I");
1441
Jeff Brown46b9ac02010-04-22 18:58:52 -07001442 // VirtualKeyDefinition
1443
1444 FIND_CLASS(gVirtualKeyDefinitionClassInfo.clazz,
1445 "com/android/server/InputManager$VirtualKeyDefinition");
1446
1447 GET_FIELD_ID(gVirtualKeyDefinitionClassInfo.scanCode, gVirtualKeyDefinitionClassInfo.clazz,
1448 "scanCode", "I");
1449
1450 GET_FIELD_ID(gVirtualKeyDefinitionClassInfo.centerX, gVirtualKeyDefinitionClassInfo.clazz,
1451 "centerX", "I");
1452
1453 GET_FIELD_ID(gVirtualKeyDefinitionClassInfo.centerY, gVirtualKeyDefinitionClassInfo.clazz,
1454 "centerY", "I");
1455
1456 GET_FIELD_ID(gVirtualKeyDefinitionClassInfo.width, gVirtualKeyDefinitionClassInfo.clazz,
1457 "width", "I");
1458
1459 GET_FIELD_ID(gVirtualKeyDefinitionClassInfo.height, gVirtualKeyDefinitionClassInfo.clazz,
1460 "height", "I");
1461
Jeff Brown8d608662010-08-30 03:02:23 -07001462 // InputDeviceCalibration
1463
1464 FIND_CLASS(gInputDeviceCalibrationClassInfo.clazz,
1465 "com/android/server/InputManager$InputDeviceCalibration");
1466
1467 GET_FIELD_ID(gInputDeviceCalibrationClassInfo.keys, gInputDeviceCalibrationClassInfo.clazz,
1468 "keys", "[Ljava/lang/String;");
1469
1470 GET_FIELD_ID(gInputDeviceCalibrationClassInfo.values, gInputDeviceCalibrationClassInfo.clazz,
1471 "values", "[Ljava/lang/String;");
1472
Jeff Brown349703e2010-06-22 01:27:15 -07001473 // InputWindow
Jeff Brown7fbdc842010-06-17 20:52:56 -07001474
Jeff Brown349703e2010-06-22 01:27:15 -07001475 FIND_CLASS(gInputWindowClassInfo.clazz, "com/android/server/InputWindow");
Jeff Brown7fbdc842010-06-17 20:52:56 -07001476
Jeff Brown349703e2010-06-22 01:27:15 -07001477 GET_FIELD_ID(gInputWindowClassInfo.inputChannel, gInputWindowClassInfo.clazz,
1478 "inputChannel", "Landroid/view/InputChannel;");
Jeff Brown7fbdc842010-06-17 20:52:56 -07001479
Jeff Brown349703e2010-06-22 01:27:15 -07001480 GET_FIELD_ID(gInputWindowClassInfo.layoutParamsFlags, gInputWindowClassInfo.clazz,
1481 "layoutParamsFlags", "I");
1482
1483 GET_FIELD_ID(gInputWindowClassInfo.layoutParamsType, gInputWindowClassInfo.clazz,
1484 "layoutParamsType", "I");
1485
1486 GET_FIELD_ID(gInputWindowClassInfo.dispatchingTimeoutNanos, gInputWindowClassInfo.clazz,
1487 "dispatchingTimeoutNanos", "J");
1488
1489 GET_FIELD_ID(gInputWindowClassInfo.frameLeft, gInputWindowClassInfo.clazz,
1490 "frameLeft", "I");
1491
1492 GET_FIELD_ID(gInputWindowClassInfo.frameTop, gInputWindowClassInfo.clazz,
1493 "frameTop", "I");
1494
Jeff Brown85a31762010-09-01 17:01:00 -07001495 GET_FIELD_ID(gInputWindowClassInfo.frameRight, gInputWindowClassInfo.clazz,
1496 "frameRight", "I");
1497
1498 GET_FIELD_ID(gInputWindowClassInfo.frameBottom, gInputWindowClassInfo.clazz,
1499 "frameBottom", "I");
1500
1501 GET_FIELD_ID(gInputWindowClassInfo.visibleFrameLeft, gInputWindowClassInfo.clazz,
1502 "visibleFrameLeft", "I");
1503
1504 GET_FIELD_ID(gInputWindowClassInfo.visibleFrameTop, gInputWindowClassInfo.clazz,
1505 "visibleFrameTop", "I");
1506
1507 GET_FIELD_ID(gInputWindowClassInfo.visibleFrameRight, gInputWindowClassInfo.clazz,
1508 "visibleFrameRight", "I");
1509
1510 GET_FIELD_ID(gInputWindowClassInfo.visibleFrameBottom, gInputWindowClassInfo.clazz,
1511 "visibleFrameBottom", "I");
1512
Jeff Brown349703e2010-06-22 01:27:15 -07001513 GET_FIELD_ID(gInputWindowClassInfo.touchableAreaLeft, gInputWindowClassInfo.clazz,
1514 "touchableAreaLeft", "I");
1515
1516 GET_FIELD_ID(gInputWindowClassInfo.touchableAreaTop, gInputWindowClassInfo.clazz,
1517 "touchableAreaTop", "I");
1518
1519 GET_FIELD_ID(gInputWindowClassInfo.touchableAreaRight, gInputWindowClassInfo.clazz,
1520 "touchableAreaRight", "I");
1521
1522 GET_FIELD_ID(gInputWindowClassInfo.touchableAreaBottom, gInputWindowClassInfo.clazz,
1523 "touchableAreaBottom", "I");
1524
1525 GET_FIELD_ID(gInputWindowClassInfo.visible, gInputWindowClassInfo.clazz,
1526 "visible", "Z");
1527
1528 GET_FIELD_ID(gInputWindowClassInfo.hasFocus, gInputWindowClassInfo.clazz,
1529 "hasFocus", "Z");
1530
1531 GET_FIELD_ID(gInputWindowClassInfo.hasWallpaper, gInputWindowClassInfo.clazz,
1532 "hasWallpaper", "Z");
1533
1534 GET_FIELD_ID(gInputWindowClassInfo.paused, gInputWindowClassInfo.clazz,
1535 "paused", "Z");
1536
1537 GET_FIELD_ID(gInputWindowClassInfo.ownerPid, gInputWindowClassInfo.clazz,
1538 "ownerPid", "I");
1539
1540 GET_FIELD_ID(gInputWindowClassInfo.ownerUid, gInputWindowClassInfo.clazz,
1541 "ownerUid", "I");
1542
1543 // InputApplication
1544
1545 FIND_CLASS(gInputApplicationClassInfo.clazz, "com/android/server/InputApplication");
1546
1547 GET_FIELD_ID(gInputApplicationClassInfo.name, gInputApplicationClassInfo.clazz,
1548 "name", "Ljava/lang/String;");
1549
1550 GET_FIELD_ID(gInputApplicationClassInfo.dispatchingTimeoutNanos,
1551 gInputApplicationClassInfo.clazz,
1552 "dispatchingTimeoutNanos", "J");
1553
1554 GET_FIELD_ID(gInputApplicationClassInfo.token, gInputApplicationClassInfo.clazz,
1555 "token", "Ljava/lang/Object;");
Jeff Brown7fbdc842010-06-17 20:52:56 -07001556
Jeff Brown6ec402b2010-07-28 15:48:59 -07001557 // KeyEvent
1558
1559 FIND_CLASS(gKeyEventClassInfo.clazz, "android/view/KeyEvent");
1560
Jeff Brown8d608662010-08-30 03:02:23 -07001561 // MotionEvent
Jeff Brown6ec402b2010-07-28 15:48:59 -07001562
1563 FIND_CLASS(gMotionEventClassInfo.clazz, "android/view/MotionEvent");
1564
Jeff Brown8d608662010-08-30 03:02:23 -07001565 // InputDevice
1566
1567 FIND_CLASS(gInputDeviceClassInfo.clazz, "android/view/InputDevice");
1568
1569 GET_METHOD_ID(gInputDeviceClassInfo.ctor, gInputDeviceClassInfo.clazz,
1570 "<init>", "()V");
1571
1572 GET_METHOD_ID(gInputDeviceClassInfo.addMotionRange, gInputDeviceClassInfo.clazz,
1573 "addMotionRange", "(IFFFF)V");
1574
1575 GET_FIELD_ID(gInputDeviceClassInfo.mId, gInputDeviceClassInfo.clazz,
1576 "mId", "I");
1577
1578 GET_FIELD_ID(gInputDeviceClassInfo.mName, gInputDeviceClassInfo.clazz,
1579 "mName", "Ljava/lang/String;");
1580
1581 GET_FIELD_ID(gInputDeviceClassInfo.mSources, gInputDeviceClassInfo.clazz,
1582 "mSources", "I");
1583
1584 GET_FIELD_ID(gInputDeviceClassInfo.mKeyboardType, gInputDeviceClassInfo.clazz,
1585 "mKeyboardType", "I");
1586
1587 GET_FIELD_ID(gInputDeviceClassInfo.mMotionRanges, gInputDeviceClassInfo.clazz,
1588 "mMotionRanges", "[Landroid/view/InputDevice$MotionRange;");
1589
Jeff Brown46b9ac02010-04-22 18:58:52 -07001590 return 0;
1591}
1592
Jeff Brown46b9ac02010-04-22 18:58:52 -07001593} /* namespace android */