blob: c757ada3f0dbaa4aa38beacc49ca62540efb2d0f [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 Brown83c09682010-12-23 17:50:18 -080027// Log debug messages about PointerController
28#define DEBUG_POINTER_CONTROLLER 1
29
30
Jeff Brown46b9ac02010-04-22 18:58:52 -070031#include "JNIHelp.h"
32#include "jni.h"
Jeff Brown349703e2010-06-22 01:27:15 -070033#include <limits.h>
Jeff Brown46b9ac02010-04-22 18:58:52 -070034#include <android_runtime/AndroidRuntime.h>
Jeff Brown9c3cda02010-06-15 01:31:58 -070035#include <ui/InputReader.h>
36#include <ui/InputDispatcher.h>
Jeff Brown46b9ac02010-04-22 18:58:52 -070037#include <ui/InputManager.h>
38#include <ui/InputTransport.h>
39#include <utils/Log.h>
40#include <utils/threads.h>
Jeff Brown83c09682010-12-23 17:50:18 -080041#include <surfaceflinger/Surface.h>
42#include <surfaceflinger/SurfaceComposerClient.h>
43#include <surfaceflinger/ISurfaceComposer.h>
44
Jeff Brown46b9ac02010-04-22 18:58:52 -070045#include "../../core/jni/android_view_KeyEvent.h"
46#include "../../core/jni/android_view_MotionEvent.h"
47#include "../../core/jni/android_view_InputChannel.h"
Jeff Brown00fa7bd2010-07-02 15:37:36 -070048#include "com_android_server_PowerManagerService.h"
Jeff Brown46b9ac02010-04-22 18:58:52 -070049
50namespace android {
51
Jeff Brown9c3cda02010-06-15 01:31:58 -070052// ----------------------------------------------------------------------------
Jeff Brown46b9ac02010-04-22 18:58:52 -070053
54static struct {
55 jclass clazz;
56
Jeff Brown46b9ac02010-04-22 18:58:52 -070057 jmethodID notifyConfigurationChanged;
58 jmethodID notifyLidSwitchChanged;
Jeff Brown7fbdc842010-06-17 20:52:56 -070059 jmethodID notifyInputChannelBroken;
Jeff Brown349703e2010-06-22 01:27:15 -070060 jmethodID notifyANR;
Jeff Brown349703e2010-06-22 01:27:15 -070061 jmethodID interceptKeyBeforeQueueing;
62 jmethodID interceptKeyBeforeDispatching;
Jeff Brown3915bb82010-11-05 15:02:16 -070063 jmethodID dispatchUnhandledKey;
Jeff Brown349703e2010-06-22 01:27:15 -070064 jmethodID checkInjectEventsPermission;
Jeff Brown46b9ac02010-04-22 18:58:52 -070065 jmethodID filterTouchEvents;
66 jmethodID filterJumpyTouchEvents;
Jeff Brown46b9ac02010-04-22 18:58:52 -070067 jmethodID getExcludedDeviceNames;
Jeff Brownae9fc032010-08-18 15:51:08 -070068 jmethodID getMaxEventsPerSecond;
Jeff Brown83c09682010-12-23 17:50:18 -080069 jmethodID getPointerLayer;
Jeff Brown46b9ac02010-04-22 18:58:52 -070070} gCallbacksClassInfo;
71
72static struct {
73 jclass clazz;
74
Jeff Brown349703e2010-06-22 01:27:15 -070075 jfieldID inputChannel;
Jeff Brown519e0242010-09-15 15:18:56 -070076 jfieldID name;
Jeff Brown349703e2010-06-22 01:27:15 -070077 jfieldID layoutParamsFlags;
78 jfieldID layoutParamsType;
79 jfieldID dispatchingTimeoutNanos;
80 jfieldID frameLeft;
81 jfieldID frameTop;
Jeff Brown85a31762010-09-01 17:01:00 -070082 jfieldID frameRight;
83 jfieldID frameBottom;
84 jfieldID visibleFrameLeft;
85 jfieldID visibleFrameTop;
86 jfieldID visibleFrameRight;
87 jfieldID visibleFrameBottom;
Jeff Brown349703e2010-06-22 01:27:15 -070088 jfieldID touchableAreaLeft;
89 jfieldID touchableAreaTop;
90 jfieldID touchableAreaRight;
91 jfieldID touchableAreaBottom;
92 jfieldID visible;
Jeff Brown519e0242010-09-15 15:18:56 -070093 jfieldID canReceiveKeys;
Jeff Brown349703e2010-06-22 01:27:15 -070094 jfieldID hasFocus;
95 jfieldID hasWallpaper;
96 jfieldID paused;
Jeff Brown519e0242010-09-15 15:18:56 -070097 jfieldID layer;
Jeff Brown349703e2010-06-22 01:27:15 -070098 jfieldID ownerPid;
99 jfieldID ownerUid;
100} gInputWindowClassInfo;
101
102static struct {
103 jclass clazz;
104
105 jfieldID name;
106 jfieldID dispatchingTimeoutNanos;
107 jfieldID token;
108} gInputApplicationClassInfo;
109
Jeff Brown6ec402b2010-07-28 15:48:59 -0700110static struct {
111 jclass clazz;
112} gKeyEventClassInfo;
113
114static struct {
115 jclass clazz;
116} gMotionEventClassInfo;
117
Jeff Brown8d608662010-08-30 03:02:23 -0700118static struct {
119 jclass clazz;
120
121 jmethodID ctor;
122 jmethodID addMotionRange;
123
124 jfieldID mId;
125 jfieldID mName;
126 jfieldID mSources;
127 jfieldID mKeyboardType;
128 jfieldID mMotionRanges;
129} gInputDeviceClassInfo;
130
Jeff Brown57c59372010-09-21 18:22:55 -0700131static struct {
132 jclass clazz;
133
134 jfieldID touchscreen;
135 jfieldID keyboard;
136 jfieldID navigation;
137} gConfigurationClassInfo;
138
Jeff Brown349703e2010-06-22 01:27:15 -0700139// ----------------------------------------------------------------------------
140
141static inline nsecs_t now() {
142 return systemTime(SYSTEM_TIME_MONOTONIC);
143}
Jeff Brown7fbdc842010-06-17 20:52:56 -0700144
Jeff Brown9c3cda02010-06-15 01:31:58 -0700145// ----------------------------------------------------------------------------
146
Jeff Brown83c09682010-12-23 17:50:18 -0800147class PointerController : public PointerControllerInterface {
148protected:
149 virtual ~PointerController();
150
151public:
152 PointerController(int32_t pointerLayer);
153
154 virtual bool getBounds(float* outMinX, float* outMinY,
155 float* outMaxX, float* outMaxY) const;
156 virtual void move(float deltaX, float deltaY);
157 virtual void setButtonState(uint32_t buttonState);
158 virtual uint32_t getButtonState() const;
159 virtual void setPosition(float x, float y);
160 virtual void getPosition(float* outX, float* outY) const;
161
162 void setDisplaySize(int32_t width, int32_t height);
163 void setDisplayOrientation(int32_t orientation);
164
165private:
166 mutable Mutex mLock;
167
168 int32_t mPointerLayer;
169 sp<SurfaceComposerClient> mSurfaceComposerClient;
170 sp<SurfaceControl> mSurfaceControl;
171
172 struct Locked {
173 int32_t displayWidth;
174 int32_t displayHeight;
175 int32_t displayOrientation;
176
177 float pointerX;
178 float pointerY;
179 uint32_t buttonState;
180
181 bool wantVisible;
182 bool visible;
183 bool drawn;
184 } mLocked;
185
186 bool getBoundsLocked(float* outMinX, float* outMinY, float* outMaxX, float* outMaxY) const;
187 void setPositionLocked(float x, float y);
188 void updateLocked();
189};
190
191// ----------------------------------------------------------------------------
192
Jeff Brown9c3cda02010-06-15 01:31:58 -0700193class NativeInputManager : public virtual RefBase,
194 public virtual InputReaderPolicyInterface,
195 public virtual InputDispatcherPolicyInterface {
196protected:
197 virtual ~NativeInputManager();
198
199public:
200 NativeInputManager(jobject callbacksObj);
201
202 inline sp<InputManager> getInputManager() const { return mInputManager; }
203
Jeff Brownb88102f2010-09-08 11:49:43 -0700204 void dump(String8& dump);
Jeff Browne33348b2010-07-15 23:54:05 -0700205
Jeff Brown9c3cda02010-06-15 01:31:58 -0700206 void setDisplaySize(int32_t displayId, int32_t width, int32_t height);
207 void setDisplayOrientation(int32_t displayId, int32_t orientation);
208
Jeff Brown7fbdc842010-06-17 20:52:56 -0700209 status_t registerInputChannel(JNIEnv* env, const sp<InputChannel>& inputChannel,
Jeff Browna41ca772010-08-11 14:46:32 -0700210 jweak inputChannelObjWeak, bool monitor);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700211 status_t unregisterInputChannel(JNIEnv* env, const sp<InputChannel>& inputChannel);
212
Jeff Brown349703e2010-06-22 01:27:15 -0700213 void setInputWindows(JNIEnv* env, jobjectArray windowObjArray);
214 void setFocusedApplication(JNIEnv* env, jobject applicationObj);
215 void setInputDispatchMode(bool enabled, bool frozen);
Jeff Brown349703e2010-06-22 01:27:15 -0700216
Jeff Brown9c3cda02010-06-15 01:31:58 -0700217 /* --- InputReaderPolicyInterface implementation --- */
218
219 virtual bool getDisplayInfo(int32_t displayId,
220 int32_t* width, int32_t* height, int32_t* orientation);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700221 virtual bool filterTouchEvents();
222 virtual bool filterJumpyTouchEvents();
Jeff Brown9c3cda02010-06-15 01:31:58 -0700223 virtual void getExcludedDeviceNames(Vector<String8>& outExcludedDeviceNames);
Jeff Brown83c09682010-12-23 17:50:18 -0800224 virtual sp<PointerControllerInterface> obtainPointerController(int32_t deviceId);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700225
226 /* --- InputDispatcherPolicyInterface implementation --- */
227
Jeff Browne20c9e02010-10-11 14:20:19 -0700228 virtual void notifySwitch(nsecs_t when, int32_t switchCode, int32_t switchValue,
229 uint32_t policyFlags);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700230 virtual void notifyConfigurationChanged(nsecs_t when);
Jeff Brown519e0242010-09-15 15:18:56 -0700231 virtual nsecs_t notifyANR(const sp<InputApplicationHandle>& inputApplicationHandle,
232 const sp<InputChannel>& inputChannel);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700233 virtual void notifyInputChannelBroken(const sp<InputChannel>& inputChannel);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700234 virtual nsecs_t getKeyRepeatTimeout();
Jeff Brownb21fb102010-09-07 10:44:57 -0700235 virtual nsecs_t getKeyRepeatDelay();
Jeff Brownae9fc032010-08-18 15:51:08 -0700236 virtual int32_t getMaxEventsPerSecond();
Jeff Brown1f245102010-11-18 20:53:46 -0800237 virtual void interceptKeyBeforeQueueing(const KeyEvent* keyEvent, uint32_t& policyFlags);
Jeff Brownb6997262010-10-08 22:31:17 -0700238 virtual void interceptGenericBeforeQueueing(nsecs_t when, uint32_t& policyFlags);
Jeff Brownb88102f2010-09-08 11:49:43 -0700239 virtual bool interceptKeyBeforeDispatching(const sp<InputChannel>& inputChannel,
240 const KeyEvent* keyEvent, uint32_t policyFlags);
Jeff Brown3915bb82010-11-05 15:02:16 -0700241 virtual bool dispatchUnhandledKey(const sp<InputChannel>& inputChannel,
Jeff Brown49ed71d2010-12-06 17:13:33 -0800242 const KeyEvent* keyEvent, uint32_t policyFlags, KeyEvent* outFallbackKeyEvent);
Jeff Brown01ce2e92010-09-26 22:20:12 -0700243 virtual void pokeUserActivity(nsecs_t eventTime, int32_t eventType);
Jeff Brownb88102f2010-09-08 11:49:43 -0700244 virtual bool checkInjectEventsPermissionNonReentrant(
245 int32_t injectorPid, int32_t injectorUid);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700246
247private:
Jeff Brownb88102f2010-09-08 11:49:43 -0700248 class ApplicationToken : public InputApplicationHandle {
249 jweak mTokenObjWeak;
Jeff Brown349703e2010-06-22 01:27:15 -0700250
251 public:
Jeff Brownb88102f2010-09-08 11:49:43 -0700252 ApplicationToken(jweak tokenObjWeak) :
253 mTokenObjWeak(tokenObjWeak) { }
Jeff Brown349703e2010-06-22 01:27:15 -0700254
Jeff Brownb88102f2010-09-08 11:49:43 -0700255 virtual ~ApplicationToken() {
256 JNIEnv* env = NativeInputManager::jniEnv();
257 env->DeleteWeakGlobalRef(mTokenObjWeak);
258 }
Jeff Brown349703e2010-06-22 01:27:15 -0700259
Jeff Brownb88102f2010-09-08 11:49:43 -0700260 inline jweak getTokenObj() { return mTokenObjWeak; }
Jeff Brown349703e2010-06-22 01:27:15 -0700261 };
262
Jeff Brown9c3cda02010-06-15 01:31:58 -0700263 sp<InputManager> mInputManager;
264
265 jobject mCallbacksObj;
266
267 // Cached filtering policies.
268 int32_t mFilterTouchEvents;
269 int32_t mFilterJumpyTouchEvents;
270
Jeff Brownae9fc032010-08-18 15:51:08 -0700271 // Cached throttling policy.
272 int32_t mMaxEventsPerSecond;
273
Jeff Brown83c09682010-12-23 17:50:18 -0800274 Mutex mLock;
275 struct Locked {
276 // Display size information.
277 int32_t displayWidth, displayHeight; // -1 when initialized
278 int32_t displayOrientation;
279
280 // Pointer controller singleton, created and destroyed as needed.
281 wp<PointerController> pointerController;
282
283 // Weak references to all currently registered input channels by connection pointer.
284 KeyedVector<InputChannel*, jweak> inputChannelObjWeakTable;
285 } mLocked;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700286
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700287 // Power manager interactions.
Jeff Brown9c3cda02010-06-15 01:31:58 -0700288 bool isScreenOn();
289 bool isScreenBright();
290
Jeff Brown7fbdc842010-06-17 20:52:56 -0700291 jobject getInputChannelObjLocal(JNIEnv* env, const sp<InputChannel>& inputChannel);
292
Jeff Brown349703e2010-06-22 01:27:15 -0700293 static bool populateWindow(JNIEnv* env, jobject windowObj, InputWindow& outWindow);
Jeff Brown349703e2010-06-22 01:27:15 -0700294
Jeff Brownb88102f2010-09-08 11:49:43 -0700295 static bool checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName);
Jeff Browna41ca772010-08-11 14:46:32 -0700296
Jeff Brown9c3cda02010-06-15 01:31:58 -0700297 static inline JNIEnv* jniEnv() {
298 return AndroidRuntime::getJNIEnv();
299 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700300};
301
302// ----------------------------------------------------------------------------
303
304NativeInputManager::NativeInputManager(jobject callbacksObj) :
305 mFilterTouchEvents(-1), mFilterJumpyTouchEvents(-1),
Jeff Brown83c09682010-12-23 17:50:18 -0800306 mMaxEventsPerSecond(-1) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700307 JNIEnv* env = jniEnv();
308
309 mCallbacksObj = env->NewGlobalRef(callbacksObj);
310
Jeff Brown83c09682010-12-23 17:50:18 -0800311 {
312 AutoMutex _l(mLock);
313 mLocked.displayWidth = -1;
314 mLocked.displayHeight = -1;
315 mLocked.displayOrientation = ROTATION_0;
316 }
317
Jeff Brown9c3cda02010-06-15 01:31:58 -0700318 sp<EventHub> eventHub = new EventHub();
319 mInputManager = new InputManager(eventHub, this, this);
320}
321
322NativeInputManager::~NativeInputManager() {
323 JNIEnv* env = jniEnv();
324
325 env->DeleteGlobalRef(mCallbacksObj);
326}
327
Jeff Brownb88102f2010-09-08 11:49:43 -0700328void NativeInputManager::dump(String8& dump) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700329 mInputManager->getReader()->dump(dump);
330 dump.append("\n");
Jeff Brown6d0fec22010-07-23 21:28:06 -0700331
Jeff Brownb88102f2010-09-08 11:49:43 -0700332 mInputManager->getDispatcher()->dump(dump);
333 dump.append("\n");
Jeff Brown9c3cda02010-06-15 01:31:58 -0700334}
335
Jeff Brown7fbdc842010-06-17 20:52:56 -0700336bool NativeInputManager::checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700337 if (env->ExceptionCheck()) {
338 LOGE("An exception was thrown by callback '%s'.", methodName);
339 LOGE_EX(env);
340 env->ExceptionClear();
341 return true;
342 }
343 return false;
344}
345
346void NativeInputManager::setDisplaySize(int32_t displayId, int32_t width, int32_t height) {
347 if (displayId == 0) {
Jeff Brown83c09682010-12-23 17:50:18 -0800348 AutoMutex _l(mLock);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700349
Jeff Brown83c09682010-12-23 17:50:18 -0800350 if (mLocked.displayWidth != width || mLocked.displayHeight != height) {
351 mLocked.displayWidth = width;
352 mLocked.displayHeight = height;
353
354 sp<PointerController> controller = mLocked.pointerController.promote();
355 if (controller != NULL) {
356 controller->setDisplaySize(width, height);
357 }
358 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700359 }
360}
361
362void NativeInputManager::setDisplayOrientation(int32_t displayId, int32_t orientation) {
363 if (displayId == 0) {
Jeff Brown83c09682010-12-23 17:50:18 -0800364 AutoMutex _l(mLock);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700365
Jeff Brown83c09682010-12-23 17:50:18 -0800366 if (mLocked.displayOrientation != orientation) {
367 mLocked.displayOrientation = orientation;
368
369 sp<PointerController> controller = mLocked.pointerController.promote();
370 if (controller != NULL) {
371 controller->setDisplayOrientation(orientation);
372 }
373 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700374 }
375}
376
Jeff Brown7fbdc842010-06-17 20:52:56 -0700377status_t NativeInputManager::registerInputChannel(JNIEnv* env,
Jeff Browna41ca772010-08-11 14:46:32 -0700378 const sp<InputChannel>& inputChannel, jobject inputChannelObj, bool monitor) {
Jeff Brown7fbdc842010-06-17 20:52:56 -0700379 jweak inputChannelObjWeak = env->NewWeakGlobalRef(inputChannelObj);
380 if (! inputChannelObjWeak) {
381 LOGE("Could not create weak reference for input channel.");
382 LOGE_EX(env);
383 return NO_MEMORY;
384 }
385
386 status_t status;
387 {
Jeff Brown83c09682010-12-23 17:50:18 -0800388 AutoMutex _l(mLock);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700389
Jeff Brown83c09682010-12-23 17:50:18 -0800390 ssize_t index = mLocked.inputChannelObjWeakTable.indexOfKey(inputChannel.get());
Jeff Brown7fbdc842010-06-17 20:52:56 -0700391 if (index >= 0) {
392 LOGE("Input channel object '%s' has already been registered",
393 inputChannel->getName().string());
394 status = INVALID_OPERATION;
395 goto DeleteWeakRef;
396 }
397
Jeff Brown83c09682010-12-23 17:50:18 -0800398 mLocked.inputChannelObjWeakTable.add(inputChannel.get(), inputChannelObjWeak);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700399 }
400
Jeff Brownb88102f2010-09-08 11:49:43 -0700401 status = mInputManager->getDispatcher()->registerInputChannel(inputChannel, monitor);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700402 if (! status) {
Jeff Browna41ca772010-08-11 14:46:32 -0700403 // Success.
Jeff Brown7fbdc842010-06-17 20:52:56 -0700404 return OK;
405 }
406
Jeff Browna41ca772010-08-11 14:46:32 -0700407 // Failed!
Jeff Brown7fbdc842010-06-17 20:52:56 -0700408 {
Jeff Brown83c09682010-12-23 17:50:18 -0800409 AutoMutex _l(mLock);
410 mLocked.inputChannelObjWeakTable.removeItem(inputChannel.get());
Jeff Brown7fbdc842010-06-17 20:52:56 -0700411 }
412
413DeleteWeakRef:
414 env->DeleteWeakGlobalRef(inputChannelObjWeak);
415 return status;
416}
417
418status_t NativeInputManager::unregisterInputChannel(JNIEnv* env,
419 const sp<InputChannel>& inputChannel) {
420 jweak inputChannelObjWeak;
421 {
Jeff Brown83c09682010-12-23 17:50:18 -0800422 AutoMutex _l(mLock);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700423
Jeff Brown83c09682010-12-23 17:50:18 -0800424 ssize_t index = mLocked.inputChannelObjWeakTable.indexOfKey(inputChannel.get());
Jeff Brown7fbdc842010-06-17 20:52:56 -0700425 if (index < 0) {
426 LOGE("Input channel object '%s' is not currently registered",
427 inputChannel->getName().string());
428 return INVALID_OPERATION;
429 }
430
Jeff Brown83c09682010-12-23 17:50:18 -0800431 inputChannelObjWeak = mLocked.inputChannelObjWeakTable.valueAt(index);
432 mLocked.inputChannelObjWeakTable.removeItemsAt(index);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700433 }
434
435 env->DeleteWeakGlobalRef(inputChannelObjWeak);
436
Jeff Brownb88102f2010-09-08 11:49:43 -0700437 return mInputManager->getDispatcher()->unregisterInputChannel(inputChannel);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700438}
439
440jobject NativeInputManager::getInputChannelObjLocal(JNIEnv* env,
441 const sp<InputChannel>& inputChannel) {
Jeff Brown54a18252010-09-16 14:07:33 -0700442 InputChannel* inputChannelPtr = inputChannel.get();
443 if (! inputChannelPtr) {
444 return NULL;
445 }
446
Jeff Brown7fbdc842010-06-17 20:52:56 -0700447 {
Jeff Brown83c09682010-12-23 17:50:18 -0800448 AutoMutex _l(mLock);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700449
Jeff Brown83c09682010-12-23 17:50:18 -0800450 ssize_t index = mLocked.inputChannelObjWeakTable.indexOfKey(inputChannelPtr);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700451 if (index < 0) {
452 return NULL;
453 }
454
Jeff Brown83c09682010-12-23 17:50:18 -0800455 jweak inputChannelObjWeak = mLocked.inputChannelObjWeakTable.valueAt(index);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700456 return env->NewLocalRef(inputChannelObjWeak);
457 }
458}
459
Jeff Brown9c3cda02010-06-15 01:31:58 -0700460bool NativeInputManager::getDisplayInfo(int32_t displayId,
461 int32_t* width, int32_t* height, int32_t* orientation) {
462 bool result = false;
463 if (displayId == 0) {
Jeff Brown83c09682010-12-23 17:50:18 -0800464 AutoMutex _l(mLock);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700465
Jeff Brown83c09682010-12-23 17:50:18 -0800466 if (mLocked.displayWidth > 0 && mLocked.displayHeight > 0) {
Jeff Brown6d0fec22010-07-23 21:28:06 -0700467 if (width) {
Jeff Brown83c09682010-12-23 17:50:18 -0800468 *width = mLocked.displayWidth;
Jeff Brown6d0fec22010-07-23 21:28:06 -0700469 }
470 if (height) {
Jeff Brown83c09682010-12-23 17:50:18 -0800471 *height = mLocked.displayHeight;
Jeff Brown6d0fec22010-07-23 21:28:06 -0700472 }
473 if (orientation) {
Jeff Brown83c09682010-12-23 17:50:18 -0800474 *orientation = mLocked.displayOrientation;
Jeff Brown6d0fec22010-07-23 21:28:06 -0700475 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700476 result = true;
477 }
478 }
479 return result;
480}
481
Jeff Brown9c3cda02010-06-15 01:31:58 -0700482bool NativeInputManager::filterTouchEvents() {
483 if (mFilterTouchEvents < 0) {
484 JNIEnv* env = jniEnv();
485
486 jboolean result = env->CallBooleanMethod(mCallbacksObj,
487 gCallbacksClassInfo.filterTouchEvents);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700488 if (checkAndClearExceptionFromCallback(env, "filterTouchEvents")) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700489 result = false;
490 }
491
492 mFilterTouchEvents = result ? 1 : 0;
493 }
494 return mFilterTouchEvents;
495}
496
497bool NativeInputManager::filterJumpyTouchEvents() {
498 if (mFilterJumpyTouchEvents < 0) {
499 JNIEnv* env = jniEnv();
500
501 jboolean result = env->CallBooleanMethod(mCallbacksObj,
502 gCallbacksClassInfo.filterJumpyTouchEvents);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700503 if (checkAndClearExceptionFromCallback(env, "filterJumpyTouchEvents")) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700504 result = false;
505 }
506
507 mFilterJumpyTouchEvents = result ? 1 : 0;
508 }
509 return mFilterJumpyTouchEvents;
510}
511
Jeff Brown9c3cda02010-06-15 01:31:58 -0700512void NativeInputManager::getExcludedDeviceNames(Vector<String8>& outExcludedDeviceNames) {
Jeff Brown8d608662010-08-30 03:02:23 -0700513 outExcludedDeviceNames.clear();
514
Jeff Brown9c3cda02010-06-15 01:31:58 -0700515 JNIEnv* env = jniEnv();
516
517 jobjectArray result = jobjectArray(env->CallObjectMethod(mCallbacksObj,
518 gCallbacksClassInfo.getExcludedDeviceNames));
Jeff Brown7fbdc842010-06-17 20:52:56 -0700519 if (! checkAndClearExceptionFromCallback(env, "getExcludedDeviceNames") && result) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700520 jsize length = env->GetArrayLength(result);
521 for (jsize i = 0; i < length; i++) {
522 jstring item = jstring(env->GetObjectArrayElement(result, i));
523
524 const char* deviceNameChars = env->GetStringUTFChars(item, NULL);
525 outExcludedDeviceNames.add(String8(deviceNameChars));
526 env->ReleaseStringUTFChars(item, deviceNameChars);
527
528 env->DeleteLocalRef(item);
529 }
530 env->DeleteLocalRef(result);
531 }
532}
533
Jeff Brown83c09682010-12-23 17:50:18 -0800534sp<PointerControllerInterface> NativeInputManager::obtainPointerController(int32_t deviceId) {
535 AutoMutex _l(mLock);
536
537 sp<PointerController> controller = mLocked.pointerController.promote();
538 if (controller == NULL) {
539 JNIEnv* env = jniEnv();
540 jint layer = env->CallIntMethod(mCallbacksObj, gCallbacksClassInfo.getPointerLayer);
541 checkAndClearExceptionFromCallback(env, "getPointerLayer");
542
543 controller = new PointerController(layer);
544 mLocked.pointerController = controller;
545
546 controller->setDisplaySize(mLocked.displayWidth, mLocked.displayHeight);
547 controller->setDisplayOrientation(mLocked.displayOrientation);
548 }
549 return controller;
550}
551
Jeff Browne20c9e02010-10-11 14:20:19 -0700552void NativeInputManager::notifySwitch(nsecs_t when, int32_t switchCode,
553 int32_t switchValue, uint32_t policyFlags) {
554#if DEBUG_INPUT_DISPATCHER_POLICY
555 LOGD("notifySwitch - when=%lld, switchCode=%d, switchValue=%d, policyFlags=0x%x",
556 when, switchCode, switchValue, policyFlags);
557#endif
558
559 JNIEnv* env = jniEnv();
560
561 switch (switchCode) {
562 case SW_LID:
563 env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyLidSwitchChanged,
564 when, switchValue == 0);
565 checkAndClearExceptionFromCallback(env, "notifyLidSwitchChanged");
566 break;
567 }
568}
569
Jeff Brown9c3cda02010-06-15 01:31:58 -0700570void NativeInputManager::notifyConfigurationChanged(nsecs_t when) {
571#if DEBUG_INPUT_DISPATCHER_POLICY
572 LOGD("notifyConfigurationChanged - when=%lld", when);
573#endif
574
575 JNIEnv* env = jniEnv();
576
Jeff Brown57c59372010-09-21 18:22:55 -0700577 env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyConfigurationChanged, when);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700578 checkAndClearExceptionFromCallback(env, "notifyConfigurationChanged");
Jeff Brown9c3cda02010-06-15 01:31:58 -0700579}
580
Jeff Brown519e0242010-09-15 15:18:56 -0700581nsecs_t NativeInputManager::notifyANR(const sp<InputApplicationHandle>& inputApplicationHandle,
582 const sp<InputChannel>& inputChannel) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700583#if DEBUG_INPUT_DISPATCHER_POLICY
584 LOGD("notifyANR");
585#endif
586
587 JNIEnv* env = jniEnv();
588
Jeff Brown519e0242010-09-15 15:18:56 -0700589 jobject tokenObjLocal;
590 if (inputApplicationHandle.get()) {
591 ApplicationToken* token = static_cast<ApplicationToken*>(inputApplicationHandle.get());
592 jweak tokenObjWeak = token->getTokenObj();
593 tokenObjLocal = env->NewLocalRef(tokenObjWeak);
Jeff Brownb88102f2010-09-08 11:49:43 -0700594 } else {
Jeff Brown519e0242010-09-15 15:18:56 -0700595 tokenObjLocal = NULL;
Jeff Brownb88102f2010-09-08 11:49:43 -0700596 }
597
Jeff Brown54a18252010-09-16 14:07:33 -0700598 jobject inputChannelObjLocal = getInputChannelObjLocal(env, inputChannel);
Jeff Brown519e0242010-09-15 15:18:56 -0700599 jlong newTimeout = env->CallLongMethod(mCallbacksObj,
600 gCallbacksClassInfo.notifyANR, tokenObjLocal, inputChannelObjLocal);
601 if (checkAndClearExceptionFromCallback(env, "notifyANR")) {
602 newTimeout = 0; // abort dispatch
603 } else {
604 assert(newTimeout >= 0);
605 }
606
607 env->DeleteLocalRef(tokenObjLocal);
608 env->DeleteLocalRef(inputChannelObjLocal);
Jeff Brownb88102f2010-09-08 11:49:43 -0700609 return newTimeout;
610}
611
Jeff Brown9c3cda02010-06-15 01:31:58 -0700612void NativeInputManager::notifyInputChannelBroken(const sp<InputChannel>& inputChannel) {
613#if DEBUG_INPUT_DISPATCHER_POLICY
614 LOGD("notifyInputChannelBroken - inputChannel='%s'", inputChannel->getName().string());
615#endif
616
Jeff Brown7fbdc842010-06-17 20:52:56 -0700617 JNIEnv* env = jniEnv();
618
619 jobject inputChannelObjLocal = getInputChannelObjLocal(env, inputChannel);
620 if (inputChannelObjLocal) {
621 env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyInputChannelBroken,
622 inputChannelObjLocal);
623 checkAndClearExceptionFromCallback(env, "notifyInputChannelBroken");
624
625 env->DeleteLocalRef(inputChannelObjLocal);
626 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700627}
628
Jeff Brown9c3cda02010-06-15 01:31:58 -0700629nsecs_t NativeInputManager::getKeyRepeatTimeout() {
630 if (! isScreenOn()) {
631 // Disable key repeat when the screen is off.
632 return -1;
633 } else {
634 // TODO use ViewConfiguration.getLongPressTimeout()
635 return milliseconds_to_nanoseconds(500);
636 }
637}
638
Jeff Brownb21fb102010-09-07 10:44:57 -0700639nsecs_t NativeInputManager::getKeyRepeatDelay() {
640 return milliseconds_to_nanoseconds(50);
641}
642
Jeff Brownae9fc032010-08-18 15:51:08 -0700643int32_t NativeInputManager::getMaxEventsPerSecond() {
644 if (mMaxEventsPerSecond < 0) {
645 JNIEnv* env = jniEnv();
646
647 jint result = env->CallIntMethod(mCallbacksObj,
648 gCallbacksClassInfo.getMaxEventsPerSecond);
649 if (checkAndClearExceptionFromCallback(env, "getMaxEventsPerSecond")) {
Jeff Brown3d8c9bd2010-08-18 17:48:53 -0700650 result = 60;
Jeff Brownae9fc032010-08-18 15:51:08 -0700651 }
652
653 mMaxEventsPerSecond = result;
654 }
655 return mMaxEventsPerSecond;
656}
657
Jeff Brown349703e2010-06-22 01:27:15 -0700658void NativeInputManager::setInputWindows(JNIEnv* env, jobjectArray windowObjArray) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700659 Vector<InputWindow> windows;
Jeff Brown349703e2010-06-22 01:27:15 -0700660
Jeff Brownb88102f2010-09-08 11:49:43 -0700661 jsize length = env->GetArrayLength(windowObjArray);
662 for (jsize i = 0; i < length; i++) {
663 jobject inputTargetObj = env->GetObjectArrayElement(windowObjArray, i);
664 if (! inputTargetObj) {
665 break; // found null element indicating end of used portion of the array
Jeff Brown349703e2010-06-22 01:27:15 -0700666 }
667
Jeff Brownb88102f2010-09-08 11:49:43 -0700668 windows.push();
669 InputWindow& window = windows.editTop();
670 bool valid = populateWindow(env, inputTargetObj, window);
671 if (! valid) {
672 windows.pop();
Jeff Brown349703e2010-06-22 01:27:15 -0700673 }
674
Jeff Brownb88102f2010-09-08 11:49:43 -0700675 env->DeleteLocalRef(inputTargetObj);
676 }
Jeff Brown349703e2010-06-22 01:27:15 -0700677
Jeff Brownb88102f2010-09-08 11:49:43 -0700678 mInputManager->getDispatcher()->setInputWindows(windows);
Jeff Brown349703e2010-06-22 01:27:15 -0700679}
680
681bool NativeInputManager::populateWindow(JNIEnv* env, jobject windowObj,
682 InputWindow& outWindow) {
683 bool valid = false;
684
685 jobject inputChannelObj = env->GetObjectField(windowObj,
686 gInputWindowClassInfo.inputChannel);
687 if (inputChannelObj) {
688 sp<InputChannel> inputChannel =
689 android_view_InputChannel_getInputChannel(env, inputChannelObj);
690 if (inputChannel != NULL) {
Jeff Brown519e0242010-09-15 15:18:56 -0700691 jstring name = jstring(env->GetObjectField(windowObj,
692 gInputWindowClassInfo.name));
Jeff Brown349703e2010-06-22 01:27:15 -0700693 jint layoutParamsFlags = env->GetIntField(windowObj,
694 gInputWindowClassInfo.layoutParamsFlags);
695 jint layoutParamsType = env->GetIntField(windowObj,
696 gInputWindowClassInfo.layoutParamsType);
697 jlong dispatchingTimeoutNanos = env->GetLongField(windowObj,
698 gInputWindowClassInfo.dispatchingTimeoutNanos);
699 jint frameLeft = env->GetIntField(windowObj,
700 gInputWindowClassInfo.frameLeft);
701 jint frameTop = env->GetIntField(windowObj,
702 gInputWindowClassInfo.frameTop);
Jeff Brown85a31762010-09-01 17:01:00 -0700703 jint frameRight = env->GetIntField(windowObj,
704 gInputWindowClassInfo.frameRight);
705 jint frameBottom = env->GetIntField(windowObj,
706 gInputWindowClassInfo.frameBottom);
707 jint visibleFrameLeft = env->GetIntField(windowObj,
708 gInputWindowClassInfo.visibleFrameLeft);
709 jint visibleFrameTop = env->GetIntField(windowObj,
710 gInputWindowClassInfo.visibleFrameTop);
711 jint visibleFrameRight = env->GetIntField(windowObj,
712 gInputWindowClassInfo.visibleFrameRight);
713 jint visibleFrameBottom = env->GetIntField(windowObj,
714 gInputWindowClassInfo.visibleFrameBottom);
Jeff Brown349703e2010-06-22 01:27:15 -0700715 jint touchableAreaLeft = env->GetIntField(windowObj,
716 gInputWindowClassInfo.touchableAreaLeft);
717 jint touchableAreaTop = env->GetIntField(windowObj,
718 gInputWindowClassInfo.touchableAreaTop);
719 jint touchableAreaRight = env->GetIntField(windowObj,
720 gInputWindowClassInfo.touchableAreaRight);
721 jint touchableAreaBottom = env->GetIntField(windowObj,
722 gInputWindowClassInfo.touchableAreaBottom);
723 jboolean visible = env->GetBooleanField(windowObj,
724 gInputWindowClassInfo.visible);
Jeff Brown519e0242010-09-15 15:18:56 -0700725 jboolean canReceiveKeys = env->GetBooleanField(windowObj,
726 gInputWindowClassInfo.canReceiveKeys);
Jeff Brown349703e2010-06-22 01:27:15 -0700727 jboolean hasFocus = env->GetBooleanField(windowObj,
728 gInputWindowClassInfo.hasFocus);
729 jboolean hasWallpaper = env->GetBooleanField(windowObj,
730 gInputWindowClassInfo.hasWallpaper);
731 jboolean paused = env->GetBooleanField(windowObj,
732 gInputWindowClassInfo.paused);
Jeff Brown519e0242010-09-15 15:18:56 -0700733 jint layer = env->GetIntField(windowObj,
734 gInputWindowClassInfo.layer);
Jeff Brown349703e2010-06-22 01:27:15 -0700735 jint ownerPid = env->GetIntField(windowObj,
736 gInputWindowClassInfo.ownerPid);
737 jint ownerUid = env->GetIntField(windowObj,
738 gInputWindowClassInfo.ownerUid);
739
Jeff Brown519e0242010-09-15 15:18:56 -0700740 const char* nameStr = env->GetStringUTFChars(name, NULL);
741
Jeff Brown349703e2010-06-22 01:27:15 -0700742 outWindow.inputChannel = inputChannel;
Jeff Brown519e0242010-09-15 15:18:56 -0700743 outWindow.name.setTo(nameStr);
Jeff Brown349703e2010-06-22 01:27:15 -0700744 outWindow.layoutParamsFlags = layoutParamsFlags;
745 outWindow.layoutParamsType = layoutParamsType;
746 outWindow.dispatchingTimeout = dispatchingTimeoutNanos;
747 outWindow.frameLeft = frameLeft;
748 outWindow.frameTop = frameTop;
Jeff Brown85a31762010-09-01 17:01:00 -0700749 outWindow.frameRight = frameRight;
750 outWindow.frameBottom = frameBottom;
751 outWindow.visibleFrameLeft = visibleFrameLeft;
752 outWindow.visibleFrameTop = visibleFrameTop;
753 outWindow.visibleFrameRight = visibleFrameRight;
754 outWindow.visibleFrameBottom = visibleFrameBottom;
Jeff Brown349703e2010-06-22 01:27:15 -0700755 outWindow.touchableAreaLeft = touchableAreaLeft;
756 outWindow.touchableAreaTop = touchableAreaTop;
757 outWindow.touchableAreaRight = touchableAreaRight;
758 outWindow.touchableAreaBottom = touchableAreaBottom;
759 outWindow.visible = visible;
Jeff Brown519e0242010-09-15 15:18:56 -0700760 outWindow.canReceiveKeys = canReceiveKeys;
Jeff Brown349703e2010-06-22 01:27:15 -0700761 outWindow.hasFocus = hasFocus;
762 outWindow.hasWallpaper = hasWallpaper;
763 outWindow.paused = paused;
Jeff Brown519e0242010-09-15 15:18:56 -0700764 outWindow.layer = layer;
Jeff Brown349703e2010-06-22 01:27:15 -0700765 outWindow.ownerPid = ownerPid;
766 outWindow.ownerUid = ownerUid;
Jeff Brown519e0242010-09-15 15:18:56 -0700767
768 env->ReleaseStringUTFChars(name, nameStr);
Jeff Brown1f245102010-11-18 20:53:46 -0800769 env->DeleteLocalRef(name);
Jeff Brown349703e2010-06-22 01:27:15 -0700770 valid = true;
771 } else {
772 LOGW("Dropping input target because its input channel is not initialized.");
773 }
774
775 env->DeleteLocalRef(inputChannelObj);
776 } else {
777 LOGW("Dropping input target because the input channel object was null.");
778 }
779 return valid;
780}
781
782void NativeInputManager::setFocusedApplication(JNIEnv* env, jobject applicationObj) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700783 if (applicationObj) {
784 jstring nameObj = jstring(env->GetObjectField(applicationObj,
785 gInputApplicationClassInfo.name));
786 jlong dispatchingTimeoutNanos = env->GetLongField(applicationObj,
787 gInputApplicationClassInfo.dispatchingTimeoutNanos);
788 jobject tokenObj = env->GetObjectField(applicationObj,
789 gInputApplicationClassInfo.token);
790 jweak tokenObjWeak = env->NewWeakGlobalRef(tokenObj);
791 if (! tokenObjWeak) {
792 LOGE("Could not create weak reference for application token.");
793 LOGE_EX(env);
794 env->ExceptionClear();
795 }
796 env->DeleteLocalRef(tokenObj);
Jeff Brown349703e2010-06-22 01:27:15 -0700797
Jeff Brownb88102f2010-09-08 11:49:43 -0700798 String8 name;
799 if (nameObj) {
800 const char* nameStr = env->GetStringUTFChars(nameObj, NULL);
801 name.setTo(nameStr);
802 env->ReleaseStringUTFChars(nameObj, nameStr);
803 env->DeleteLocalRef(nameObj);
804 } else {
805 LOGE("InputApplication.name should not be null.");
806 name.setTo("unknown");
Jeff Brown349703e2010-06-22 01:27:15 -0700807 }
808
Jeff Brownb88102f2010-09-08 11:49:43 -0700809 InputApplication application;
810 application.name = name;
811 application.dispatchingTimeout = dispatchingTimeoutNanos;
812 application.handle = new ApplicationToken(tokenObjWeak);
813 mInputManager->getDispatcher()->setFocusedApplication(& application);
814 } else {
815 mInputManager->getDispatcher()->setFocusedApplication(NULL);
Jeff Brown349703e2010-06-22 01:27:15 -0700816 }
817}
818
819void NativeInputManager::setInputDispatchMode(bool enabled, bool frozen) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700820 mInputManager->getDispatcher()->setInputDispatchMode(enabled, frozen);
Jeff Brown349703e2010-06-22 01:27:15 -0700821}
822
Jeff Browne20c9e02010-10-11 14:20:19 -0700823bool NativeInputManager::isScreenOn() {
824 return android_server_PowerManagerService_isScreenOn();
825}
826
827bool NativeInputManager::isScreenBright() {
828 return android_server_PowerManagerService_isScreenBright();
829}
830
Jeff Brown1f245102010-11-18 20:53:46 -0800831void NativeInputManager::interceptKeyBeforeQueueing(const KeyEvent* keyEvent,
832 uint32_t& policyFlags) {
Jeff Brown3122e442010-10-11 23:32:49 -0700833 // Policy:
834 // - Ignore untrusted events and pass them along.
835 // - Ask the window manager what to do with normal events and trusted injected events.
836 // - For normal events wake and brighten the screen if currently off or dim.
837 if ((policyFlags & POLICY_FLAG_TRUSTED)) {
838 const int32_t WM_ACTION_PASS_TO_USER = 1;
839 const int32_t WM_ACTION_POKE_USER_ACTIVITY = 2;
840 const int32_t WM_ACTION_GO_TO_SLEEP = 4;
Jeff Browne20c9e02010-10-11 14:20:19 -0700841
Jeff Brown1f245102010-11-18 20:53:46 -0800842 nsecs_t when = keyEvent->getEventTime();
Jeff Brown3122e442010-10-11 23:32:49 -0700843 bool isScreenOn = this->isScreenOn();
844 bool isScreenBright = this->isScreenBright();
Jeff Browne20c9e02010-10-11 14:20:19 -0700845
Jeff Brown3122e442010-10-11 23:32:49 -0700846 JNIEnv* env = jniEnv();
Jeff Brown1f245102010-11-18 20:53:46 -0800847 jobject keyEventObj = android_view_KeyEvent_fromNative(env, keyEvent);
848 jint wmActions;
849 if (keyEventObj) {
850 wmActions = env->CallIntMethod(mCallbacksObj,
851 gCallbacksClassInfo.interceptKeyBeforeQueueing,
852 keyEventObj, policyFlags, isScreenOn);
853 if (checkAndClearExceptionFromCallback(env, "interceptKeyBeforeQueueing")) {
854 wmActions = 0;
855 }
856 android_view_KeyEvent_recycle(env, keyEventObj);
857 env->DeleteLocalRef(keyEventObj);
858 } else {
859 LOGE("Failed to obtain key event object for interceptKeyBeforeQueueing.");
Jeff Brown3122e442010-10-11 23:32:49 -0700860 wmActions = 0;
Jeff Browne20c9e02010-10-11 14:20:19 -0700861 }
862
Jeff Brown1f245102010-11-18 20:53:46 -0800863 if (!(policyFlags & POLICY_FLAG_INJECTED)) {
Jeff Brown3122e442010-10-11 23:32:49 -0700864 if (!isScreenOn) {
865 policyFlags |= POLICY_FLAG_WOKE_HERE;
Jeff Brown3122e442010-10-11 23:32:49 -0700866 }
867
868 if (!isScreenBright) {
869 policyFlags |= POLICY_FLAG_BRIGHT_HERE;
870 }
Jeff Browne20c9e02010-10-11 14:20:19 -0700871 }
872
873 if (wmActions & WM_ACTION_GO_TO_SLEEP) {
874 android_server_PowerManagerService_goToSleep(when);
875 }
876
877 if (wmActions & WM_ACTION_POKE_USER_ACTIVITY) {
878 android_server_PowerManagerService_userActivity(when, POWER_MANAGER_BUTTON_EVENT);
879 }
Jeff Browne20c9e02010-10-11 14:20:19 -0700880
Jeff Brown3122e442010-10-11 23:32:49 -0700881 if (wmActions & WM_ACTION_PASS_TO_USER) {
882 policyFlags |= POLICY_FLAG_PASS_TO_USER;
883 }
884 } else {
Jeff Browne20c9e02010-10-11 14:20:19 -0700885 policyFlags |= POLICY_FLAG_PASS_TO_USER;
886 }
887}
888
889void NativeInputManager::interceptGenericBeforeQueueing(nsecs_t when, uint32_t& policyFlags) {
Jeff Brown3122e442010-10-11 23:32:49 -0700890 // Policy:
891 // - Ignore untrusted events and pass them along.
892 // - No special filtering for injected events required at this time.
893 // - Filter normal events based on screen state.
894 // - For normal events brighten (but do not wake) the screen if currently dim.
895 if ((policyFlags & POLICY_FLAG_TRUSTED) && !(policyFlags & POLICY_FLAG_INJECTED)) {
896 if (isScreenOn()) {
897 policyFlags |= POLICY_FLAG_PASS_TO_USER;
Jeff Browne20c9e02010-10-11 14:20:19 -0700898
Jeff Brown3122e442010-10-11 23:32:49 -0700899 if (!isScreenBright()) {
900 policyFlags |= POLICY_FLAG_BRIGHT_HERE;
901 }
Jeff Browne20c9e02010-10-11 14:20:19 -0700902 }
Jeff Brown3122e442010-10-11 23:32:49 -0700903 } else {
904 policyFlags |= POLICY_FLAG_PASS_TO_USER;
Jeff Browne20c9e02010-10-11 14:20:19 -0700905 }
906}
907
908bool NativeInputManager::interceptKeyBeforeDispatching(const sp<InputChannel>& inputChannel,
909 const KeyEvent* keyEvent, uint32_t policyFlags) {
Jeff Brown3122e442010-10-11 23:32:49 -0700910 // Policy:
911 // - Ignore untrusted events and pass them along.
912 // - Filter normal events and trusted injected events through the window manager policy to
913 // handle the HOME key and the like.
Jeff Brown49ed71d2010-12-06 17:13:33 -0800914 bool result = false;
Jeff Brown3122e442010-10-11 23:32:49 -0700915 if (policyFlags & POLICY_FLAG_TRUSTED) {
916 JNIEnv* env = jniEnv();
Jeff Brownd0097872010-06-30 14:41:59 -0700917
Jeff Brown3122e442010-10-11 23:32:49 -0700918 // Note: inputChannel may be null.
919 jobject inputChannelObj = getInputChannelObjLocal(env, inputChannel);
Jeff Brown1f245102010-11-18 20:53:46 -0800920 jobject keyEventObj = android_view_KeyEvent_fromNative(env, keyEvent);
921 if (keyEventObj) {
922 jboolean consumed = env->CallBooleanMethod(mCallbacksObj,
923 gCallbacksClassInfo.interceptKeyBeforeDispatching,
924 inputChannelObj, keyEventObj, policyFlags);
925 bool error = checkAndClearExceptionFromCallback(env, "interceptKeyBeforeDispatching");
926 android_view_KeyEvent_recycle(env, keyEventObj);
927 env->DeleteLocalRef(keyEventObj);
928 result = consumed && !error;
929 } else {
930 LOGE("Failed to obtain key event object for interceptKeyBeforeDispatching.");
Jeff Brown1f245102010-11-18 20:53:46 -0800931 }
Jeff Brown3122e442010-10-11 23:32:49 -0700932 env->DeleteLocalRef(inputChannelObj);
Jeff Brown3122e442010-10-11 23:32:49 -0700933 }
Jeff Brown1f245102010-11-18 20:53:46 -0800934 return result;
Jeff Brownd0097872010-06-30 14:41:59 -0700935}
936
Jeff Brown3915bb82010-11-05 15:02:16 -0700937bool NativeInputManager::dispatchUnhandledKey(const sp<InputChannel>& inputChannel,
Jeff Brown49ed71d2010-12-06 17:13:33 -0800938 const KeyEvent* keyEvent, uint32_t policyFlags, KeyEvent* outFallbackKeyEvent) {
Jeff Brown3915bb82010-11-05 15:02:16 -0700939 // Policy:
940 // - Ignore untrusted events and do not perform default handling.
Jeff Brown49ed71d2010-12-06 17:13:33 -0800941 bool result = false;
Jeff Brown3915bb82010-11-05 15:02:16 -0700942 if (policyFlags & POLICY_FLAG_TRUSTED) {
943 JNIEnv* env = jniEnv();
944
945 // Note: inputChannel may be null.
946 jobject inputChannelObj = getInputChannelObjLocal(env, inputChannel);
Jeff Brown1f245102010-11-18 20:53:46 -0800947 jobject keyEventObj = android_view_KeyEvent_fromNative(env, keyEvent);
948 if (keyEventObj) {
Jeff Brown49ed71d2010-12-06 17:13:33 -0800949 jobject fallbackKeyEventObj = env->CallObjectMethod(mCallbacksObj,
Jeff Brown1f245102010-11-18 20:53:46 -0800950 gCallbacksClassInfo.dispatchUnhandledKey,
951 inputChannelObj, keyEventObj, policyFlags);
Jeff Brown49ed71d2010-12-06 17:13:33 -0800952 checkAndClearExceptionFromCallback(env, "dispatchUnhandledKey");
Jeff Brown1f245102010-11-18 20:53:46 -0800953 android_view_KeyEvent_recycle(env, keyEventObj);
954 env->DeleteLocalRef(keyEventObj);
Jeff Brown49ed71d2010-12-06 17:13:33 -0800955
956 if (fallbackKeyEventObj) {
957 // Note: outFallbackKeyEvent may be the same object as keyEvent.
958 if (!android_view_KeyEvent_toNative(env, fallbackKeyEventObj,
959 outFallbackKeyEvent)) {
960 result = true;
961 }
962 android_view_KeyEvent_recycle(env, fallbackKeyEventObj);
963 env->DeleteLocalRef(fallbackKeyEventObj);
964 }
Jeff Brown1f245102010-11-18 20:53:46 -0800965 } else {
966 LOGE("Failed to obtain key event object for dispatchUnhandledKey.");
Jeff Brown1f245102010-11-18 20:53:46 -0800967 }
Jeff Brown3915bb82010-11-05 15:02:16 -0700968 env->DeleteLocalRef(inputChannelObj);
Jeff Brown3915bb82010-11-05 15:02:16 -0700969 }
Jeff Brown1f245102010-11-18 20:53:46 -0800970 return result;
Jeff Brown3915bb82010-11-05 15:02:16 -0700971}
972
Jeff Brown01ce2e92010-09-26 22:20:12 -0700973void NativeInputManager::pokeUserActivity(nsecs_t eventTime, int32_t eventType) {
974 android_server_PowerManagerService_userActivity(eventTime, eventType);
Jeff Brown349703e2010-06-22 01:27:15 -0700975}
976
Jeff Brown349703e2010-06-22 01:27:15 -0700977
Jeff Brownb88102f2010-09-08 11:49:43 -0700978bool NativeInputManager::checkInjectEventsPermissionNonReentrant(
979 int32_t injectorPid, int32_t injectorUid) {
980 JNIEnv* env = jniEnv();
981 jboolean result = env->CallBooleanMethod(mCallbacksObj,
982 gCallbacksClassInfo.checkInjectEventsPermission, injectorPid, injectorUid);
983 checkAndClearExceptionFromCallback(env, "checkInjectEventsPermission");
Jeff Brown349703e2010-06-22 01:27:15 -0700984 return result;
985}
986
Jeff Brown83c09682010-12-23 17:50:18 -0800987// --- PointerController ---
988
989PointerController::PointerController(int32_t pointerLayer) :
990 mPointerLayer(pointerLayer) {
991 AutoMutex _l(mLock);
992
993 mLocked.displayWidth = -1;
994 mLocked.displayHeight = -1;
995 mLocked.displayOrientation = InputReaderPolicyInterface::ROTATION_0;
996
997 mLocked.pointerX = 0;
998 mLocked.pointerY = 0;
999 mLocked.buttonState = 0;
1000
1001 mLocked.wantVisible = false;
1002 mLocked.visible = false;
1003 mLocked.drawn = false;
1004}
1005
1006PointerController::~PointerController() {
1007 mSurfaceControl.clear();
1008 mSurfaceComposerClient.clear();
1009}
1010
1011bool PointerController::getBounds(float* outMinX, float* outMinY,
1012 float* outMaxX, float* outMaxY) const {
1013 AutoMutex _l(mLock);
1014
1015 return getBoundsLocked(outMinX, outMinY, outMaxX, outMaxY);
1016}
1017
1018bool PointerController::getBoundsLocked(float* outMinX, float* outMinY,
1019 float* outMaxX, float* outMaxY) const {
1020 if (mLocked.displayWidth <= 0 || mLocked.displayHeight <= 0) {
1021 return false;
1022 }
1023
1024 *outMinX = 0;
1025 *outMinY = 0;
1026 switch (mLocked.displayOrientation) {
1027 case InputReaderPolicyInterface::ROTATION_90:
1028 case InputReaderPolicyInterface::ROTATION_270:
1029 *outMaxX = mLocked.displayHeight;
1030 *outMaxY = mLocked.displayWidth;
1031 break;
1032 default:
1033 *outMaxX = mLocked.displayWidth;
1034 *outMaxY = mLocked.displayHeight;
1035 break;
1036 }
1037 return true;
1038}
1039
1040void PointerController::move(float deltaX, float deltaY) {
1041#if DEBUG_POINTER_CONTROLLER
1042 LOGD("Move pointer by deltaX=%0.3f, deltaY=%0.3f", deltaX, deltaY);
1043#endif
1044 if (deltaX == 0.0f && deltaY == 0.0f) {
1045 return;
1046 }
1047
1048 AutoMutex _l(mLock);
1049
1050 setPositionLocked(mLocked.pointerX + deltaX, mLocked.pointerY + deltaY);
1051}
1052
1053void PointerController::setButtonState(uint32_t buttonState) {
1054 AutoMutex _l(mLock);
1055
1056 if (mLocked.buttonState != buttonState) {
1057 mLocked.buttonState = buttonState;
1058 mLocked.wantVisible = true;
1059 updateLocked();
1060 }
1061}
1062
1063uint32_t PointerController::getButtonState() const {
1064 AutoMutex _l(mLock);
1065
1066 return mLocked.buttonState;
1067}
1068
1069void PointerController::setPosition(float x, float y) {
1070 AutoMutex _l(mLock);
1071
1072 setPositionLocked(x, y);
1073}
1074
1075void PointerController::setPositionLocked(float x, float y) {
1076 float minX, minY, maxX, maxY;
1077 if (getBoundsLocked(&minX, &minY, &maxX, &maxY)) {
1078 if (x <= minX) {
1079 mLocked.pointerX = minX;
1080 } else if (x >= maxX) {
1081 mLocked.pointerX = maxX;
1082 } else {
1083 mLocked.pointerX = x;
1084 }
1085 if (y <= minY) {
1086 mLocked.pointerY = minY;
1087 } else if (y >= maxY) {
1088 mLocked.pointerY = maxY;
1089 } else {
1090 mLocked.pointerY = y;
1091 }
1092 mLocked.wantVisible = true;
1093 updateLocked();
1094 }
1095}
1096
1097void PointerController::getPosition(float* outX, float* outY) const {
1098 AutoMutex _l(mLock);
1099
1100 *outX = mLocked.pointerX;
1101 *outY = mLocked.pointerY;
1102}
1103
1104void PointerController::updateLocked() {
1105#if DEBUG_POINTER_CONTROLLER
1106 LOGD("Pointer at (%f, %f).", mLocked.pointerX, mLocked.pointerY);
1107#endif
1108
1109 if (!mLocked.wantVisible && !mLocked.visible) {
1110 return;
1111 }
1112
1113 if (mSurfaceComposerClient == NULL) {
1114 mSurfaceComposerClient = new SurfaceComposerClient();
1115 }
1116
1117 if (mSurfaceControl == NULL) {
1118 mSurfaceControl = mSurfaceComposerClient->createSurface(getpid(),
1119 String8("Pointer"), 0, 16, 16, PIXEL_FORMAT_RGBA_8888);
1120 if (mSurfaceControl == NULL) {
1121 LOGE("Error creating pointer surface.");
1122 return;
1123 }
1124 }
1125
1126 status_t status = mSurfaceComposerClient->openTransaction();
1127 if (status) {
1128 LOGE("Error opening surface transaction to update pointer surface.");
1129 return;
1130 }
1131
1132 if (mLocked.wantVisible) {
1133 if (!mLocked.drawn) {
1134 mLocked.drawn = true;
1135
1136 sp<Surface> surface = mSurfaceControl->getSurface();
1137 Surface::SurfaceInfo surfaceInfo;
1138 status = surface->lock(&surfaceInfo);
1139 if (status) {
1140 LOGE("Error %d locking pointer surface before drawing.", status);
1141 goto CloseTransaction;
1142 }
1143
1144 // TODO: Load pointers from assets and allow them to be set.
1145 char* bitmap = (char*)surfaceInfo.bits;
1146 ssize_t bpr = surfaceInfo.s * 4;
1147 for (int y = 0; y < surfaceInfo.h; y++) {
1148 for (int x = 0; x < surfaceInfo.w; x++) {
1149 bitmap[y * bpr + x * 4] = 128;
1150 bitmap[y * bpr + x * 4 + 1] = 255;
1151 bitmap[y * bpr + x * 4 + 2] = 128;
1152 bitmap[y * bpr + x * 4 + 3] = 255;
1153 }
1154 }
1155
1156 status = surface->unlockAndPost();
1157 if (status) {
1158 LOGE("Error %d unlocking pointer surface after drawing.", status);
1159 goto CloseTransaction;
1160 }
1161 }
1162
1163 status = mSurfaceControl->setPosition(mLocked.pointerX, mLocked.pointerY);
1164 if (status) {
1165 LOGE("Error %d moving pointer surface.", status);
1166 goto CloseTransaction;
1167 }
1168
1169 if (!mLocked.visible) {
1170 mLocked.visible = true;
1171
1172 mSurfaceControl->setLayer(mPointerLayer);
1173
1174 LOGD("XXX Show");
1175 status = mSurfaceControl->show(mPointerLayer);
1176 if (status) {
1177 LOGE("Error %d showing pointer surface.", status);
1178 goto CloseTransaction;
1179 }
1180 }
1181 } else {
1182 if (mLocked.visible) {
1183 mLocked.visible = false;
1184
1185 if (mSurfaceControl != NULL) {
1186 status = mSurfaceControl->hide();
1187 if (status) {
1188 LOGE("Error %d hiding pointer surface.", status);
1189 goto CloseTransaction;
1190 }
1191 }
1192 }
1193 }
1194
1195CloseTransaction:
1196 status = mSurfaceComposerClient->closeTransaction();
1197 if (status) {
1198 LOGE("Error closing surface transaction to update pointer surface.");
1199 }
1200}
1201
1202void PointerController::setDisplaySize(int32_t width, int32_t height) {
1203 AutoMutex _l(mLock);
1204
1205 if (mLocked.displayWidth != width || mLocked.displayHeight != height) {
1206 mLocked.displayWidth = width;
1207 mLocked.displayHeight = height;
1208
1209 float minX, minY, maxX, maxY;
1210 if (getBoundsLocked(&minX, &minY, &maxX, &maxY)) {
1211 mLocked.pointerX = (minX + maxX) * 0.5f;
1212 mLocked.pointerY = (minY + maxY) * 0.5f;
1213 } else {
1214 mLocked.pointerX = 0;
1215 mLocked.pointerY = 0;
1216 }
1217
1218 updateLocked();
1219 }
1220}
1221
1222void PointerController::setDisplayOrientation(int32_t orientation) {
1223 AutoMutex _l(mLock);
1224
1225 if (mLocked.displayOrientation != orientation) {
1226 float absoluteX, absoluteY;
1227
1228 // Map from oriented display coordinates to absolute display coordinates.
1229 switch (mLocked.displayOrientation) {
1230 case InputReaderPolicyInterface::ROTATION_90:
1231 absoluteX = mLocked.displayWidth - mLocked.pointerY;
1232 absoluteY = mLocked.pointerX;
1233 break;
1234 case InputReaderPolicyInterface::ROTATION_180:
1235 absoluteX = mLocked.displayWidth - mLocked.pointerX;
1236 absoluteY = mLocked.displayHeight - mLocked.pointerY;
1237 break;
1238 case InputReaderPolicyInterface::ROTATION_270:
1239 absoluteX = mLocked.pointerY;
1240 absoluteY = mLocked.displayHeight - mLocked.pointerX;
1241 break;
1242 default:
1243 absoluteX = mLocked.pointerX;
1244 absoluteY = mLocked.pointerY;
1245 break;
1246 }
1247
1248 // Map from absolute display coordinates to oriented display coordinates.
1249 switch (orientation) {
1250 case InputReaderPolicyInterface::ROTATION_90:
1251 mLocked.pointerX = absoluteY;
1252 mLocked.pointerY = mLocked.displayWidth - absoluteX;
1253 break;
1254 case InputReaderPolicyInterface::ROTATION_180:
1255 mLocked.pointerX = mLocked.displayWidth - absoluteX;
1256 mLocked.pointerY = mLocked.displayHeight - absoluteY;
1257 break;
1258 case InputReaderPolicyInterface::ROTATION_270:
1259 mLocked.pointerX = mLocked.displayHeight - absoluteY;
1260 mLocked.pointerY = absoluteX;
1261 break;
1262 default:
1263 mLocked.pointerX = absoluteX;
1264 mLocked.pointerY = absoluteY;
1265 break;
1266 }
1267
1268 mLocked.displayOrientation = orientation;
1269
1270 updateLocked();
1271 }
1272}
1273
1274
Jeff Brown9c3cda02010-06-15 01:31:58 -07001275// ----------------------------------------------------------------------------
1276
1277static sp<NativeInputManager> gNativeInputManager;
1278
Jeff Brown46b9ac02010-04-22 18:58:52 -07001279static bool checkInputManagerUnitialized(JNIEnv* env) {
Jeff Brown9c3cda02010-06-15 01:31:58 -07001280 if (gNativeInputManager == NULL) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07001281 LOGE("Input manager not initialized.");
1282 jniThrowRuntimeException(env, "Input manager not initialized.");
1283 return true;
1284 }
1285 return false;
1286}
1287
1288static void android_server_InputManager_nativeInit(JNIEnv* env, jclass clazz,
1289 jobject callbacks) {
Jeff Brown9c3cda02010-06-15 01:31:58 -07001290 if (gNativeInputManager == NULL) {
1291 gNativeInputManager = new NativeInputManager(callbacks);
1292 } else {
1293 LOGE("Input manager already initialized.");
1294 jniThrowRuntimeException(env, "Input manager already initialized.");
Jeff Brown46b9ac02010-04-22 18:58:52 -07001295 }
1296}
1297
1298static void android_server_InputManager_nativeStart(JNIEnv* env, jclass clazz) {
1299 if (checkInputManagerUnitialized(env)) {
1300 return;
1301 }
1302
Jeff Brown9c3cda02010-06-15 01:31:58 -07001303 status_t result = gNativeInputManager->getInputManager()->start();
Jeff Brown46b9ac02010-04-22 18:58:52 -07001304 if (result) {
1305 jniThrowRuntimeException(env, "Input manager could not be started.");
1306 }
1307}
1308
1309static void android_server_InputManager_nativeSetDisplaySize(JNIEnv* env, jclass clazz,
1310 jint displayId, jint width, jint height) {
1311 if (checkInputManagerUnitialized(env)) {
1312 return;
1313 }
1314
1315 // XXX we could get this from the SurfaceFlinger directly instead of requiring it
1316 // to be passed in like this, not sure which is better but leaving it like this
1317 // keeps the window manager in direct control of when display transitions propagate down
1318 // to the input dispatcher
Jeff Brown9c3cda02010-06-15 01:31:58 -07001319 gNativeInputManager->setDisplaySize(displayId, width, height);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001320}
1321
1322static void android_server_InputManager_nativeSetDisplayOrientation(JNIEnv* env, jclass clazz,
1323 jint displayId, jint orientation) {
1324 if (checkInputManagerUnitialized(env)) {
1325 return;
1326 }
1327
Jeff Brown9c3cda02010-06-15 01:31:58 -07001328 gNativeInputManager->setDisplayOrientation(displayId, orientation);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001329}
1330
1331static jint android_server_InputManager_nativeGetScanCodeState(JNIEnv* env, jclass clazz,
Jeff Brown6d0fec22010-07-23 21:28:06 -07001332 jint deviceId, jint sourceMask, jint scanCode) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07001333 if (checkInputManagerUnitialized(env)) {
Jeff Brownc5ed5912010-07-14 18:48:53 -07001334 return AKEY_STATE_UNKNOWN;
Jeff Brown46b9ac02010-04-22 18:58:52 -07001335 }
1336
Jeff Brownb88102f2010-09-08 11:49:43 -07001337 return gNativeInputManager->getInputManager()->getReader()->getScanCodeState(
Jeff Brown6d0fec22010-07-23 21:28:06 -07001338 deviceId, uint32_t(sourceMask), scanCode);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001339}
1340
1341static jint android_server_InputManager_nativeGetKeyCodeState(JNIEnv* env, jclass clazz,
Jeff Brown6d0fec22010-07-23 21:28:06 -07001342 jint deviceId, jint sourceMask, jint keyCode) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07001343 if (checkInputManagerUnitialized(env)) {
Jeff Brownc5ed5912010-07-14 18:48:53 -07001344 return AKEY_STATE_UNKNOWN;
Jeff Brown46b9ac02010-04-22 18:58:52 -07001345 }
1346
Jeff Brownb88102f2010-09-08 11:49:43 -07001347 return gNativeInputManager->getInputManager()->getReader()->getKeyCodeState(
Jeff Brown6d0fec22010-07-23 21:28:06 -07001348 deviceId, uint32_t(sourceMask), keyCode);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001349}
1350
1351static jint android_server_InputManager_nativeGetSwitchState(JNIEnv* env, jclass clazz,
Jeff Brown6d0fec22010-07-23 21:28:06 -07001352 jint deviceId, jint sourceMask, jint sw) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07001353 if (checkInputManagerUnitialized(env)) {
Jeff Brownc5ed5912010-07-14 18:48:53 -07001354 return AKEY_STATE_UNKNOWN;
Jeff Brown46b9ac02010-04-22 18:58:52 -07001355 }
1356
Jeff Brownb88102f2010-09-08 11:49:43 -07001357 return gNativeInputManager->getInputManager()->getReader()->getSwitchState(
Jeff Brown6d0fec22010-07-23 21:28:06 -07001358 deviceId, uint32_t(sourceMask), sw);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001359}
1360
1361static jboolean android_server_InputManager_nativeHasKeys(JNIEnv* env, jclass clazz,
Jeff Brown6d0fec22010-07-23 21:28:06 -07001362 jint deviceId, jint sourceMask, jintArray keyCodes, jbooleanArray outFlags) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07001363 if (checkInputManagerUnitialized(env)) {
1364 return JNI_FALSE;
1365 }
1366
1367 int32_t* codes = env->GetIntArrayElements(keyCodes, NULL);
1368 uint8_t* flags = env->GetBooleanArrayElements(outFlags, NULL);
1369 jsize numCodes = env->GetArrayLength(keyCodes);
1370 jboolean result;
Jeff Brown6d0fec22010-07-23 21:28:06 -07001371 if (numCodes == env->GetArrayLength(keyCodes)) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001372 result = gNativeInputManager->getInputManager()->getReader()->hasKeys(
Jeff Brown6d0fec22010-07-23 21:28:06 -07001373 deviceId, uint32_t(sourceMask), numCodes, codes, flags);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001374 } else {
1375 result = JNI_FALSE;
1376 }
1377
1378 env->ReleaseBooleanArrayElements(outFlags, flags, 0);
1379 env->ReleaseIntArrayElements(keyCodes, codes, 0);
1380 return result;
1381}
1382
1383static void throwInputChannelNotInitialized(JNIEnv* env) {
1384 jniThrowException(env, "java/lang/IllegalStateException",
1385 "inputChannel is not initialized");
1386}
1387
1388static void android_server_InputManager_handleInputChannelDisposed(JNIEnv* env,
1389 jobject inputChannelObj, const sp<InputChannel>& inputChannel, void* data) {
1390 LOGW("Input channel object '%s' was disposed without first being unregistered with "
1391 "the input manager!", inputChannel->getName().string());
1392
Jeff Brown9c3cda02010-06-15 01:31:58 -07001393 if (gNativeInputManager != NULL) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07001394 gNativeInputManager->unregisterInputChannel(env, inputChannel);
Jeff Brown9c3cda02010-06-15 01:31:58 -07001395 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07001396}
1397
1398static void android_server_InputManager_nativeRegisterInputChannel(JNIEnv* env, jclass clazz,
Jeff Browna41ca772010-08-11 14:46:32 -07001399 jobject inputChannelObj, jboolean monitor) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07001400 if (checkInputManagerUnitialized(env)) {
1401 return;
1402 }
1403
1404 sp<InputChannel> inputChannel = android_view_InputChannel_getInputChannel(env,
1405 inputChannelObj);
1406 if (inputChannel == NULL) {
1407 throwInputChannelNotInitialized(env);
1408 return;
1409 }
1410
Jeff Brown7fbdc842010-06-17 20:52:56 -07001411
1412 status_t status = gNativeInputManager->registerInputChannel(
Jeff Browna41ca772010-08-11 14:46:32 -07001413 env, inputChannel, inputChannelObj, monitor);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001414 if (status) {
1415 jniThrowRuntimeException(env, "Failed to register input channel. "
1416 "Check logs for details.");
1417 return;
1418 }
1419
Jeff Browna41ca772010-08-11 14:46:32 -07001420 if (! monitor) {
1421 android_view_InputChannel_setDisposeCallback(env, inputChannelObj,
1422 android_server_InputManager_handleInputChannelDisposed, NULL);
1423 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07001424}
1425
1426static void android_server_InputManager_nativeUnregisterInputChannel(JNIEnv* env, jclass clazz,
1427 jobject inputChannelObj) {
1428 if (checkInputManagerUnitialized(env)) {
1429 return;
1430 }
1431
1432 sp<InputChannel> inputChannel = android_view_InputChannel_getInputChannel(env,
1433 inputChannelObj);
1434 if (inputChannel == NULL) {
1435 throwInputChannelNotInitialized(env);
1436 return;
1437 }
1438
1439 android_view_InputChannel_setDisposeCallback(env, inputChannelObj, NULL, NULL);
1440
Jeff Brown7fbdc842010-06-17 20:52:56 -07001441 status_t status = gNativeInputManager->unregisterInputChannel(env, inputChannel);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001442 if (status) {
1443 jniThrowRuntimeException(env, "Failed to unregister input channel. "
1444 "Check logs for details.");
1445 }
1446}
1447
Jeff Brown6ec402b2010-07-28 15:48:59 -07001448static jint android_server_InputManager_nativeInjectInputEvent(JNIEnv* env, jclass clazz,
1449 jobject inputEventObj, jint injectorPid, jint injectorUid,
1450 jint syncMode, jint timeoutMillis) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07001451 if (checkInputManagerUnitialized(env)) {
1452 return INPUT_EVENT_INJECTION_FAILED;
1453 }
1454
Jeff Brown6ec402b2010-07-28 15:48:59 -07001455 if (env->IsInstanceOf(inputEventObj, gKeyEventClassInfo.clazz)) {
1456 KeyEvent keyEvent;
Jeff Brown1f245102010-11-18 20:53:46 -08001457 status_t status = android_view_KeyEvent_toNative(env, inputEventObj, & keyEvent);
1458 if (status) {
1459 jniThrowRuntimeException(env, "Could not read contents of KeyEvent object.");
1460 return INPUT_EVENT_INJECTION_FAILED;
1461 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07001462
Jeff Brownb88102f2010-09-08 11:49:43 -07001463 return gNativeInputManager->getInputManager()->getDispatcher()->injectInputEvent(
1464 & keyEvent, injectorPid, injectorUid, syncMode, timeoutMillis);
Jeff Brown6ec402b2010-07-28 15:48:59 -07001465 } else if (env->IsInstanceOf(inputEventObj, gMotionEventClassInfo.clazz)) {
1466 MotionEvent motionEvent;
Jeff Brown1f245102010-11-18 20:53:46 -08001467 status_t status = android_view_MotionEvent_toNative(env, inputEventObj, & motionEvent);
1468 if (status) {
1469 jniThrowRuntimeException(env, "Could not read contents of MotionEvent object.");
1470 return INPUT_EVENT_INJECTION_FAILED;
1471 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07001472
Jeff Brownb88102f2010-09-08 11:49:43 -07001473 return gNativeInputManager->getInputManager()->getDispatcher()->injectInputEvent(
1474 & motionEvent, injectorPid, injectorUid, syncMode, timeoutMillis);
Jeff Brown6ec402b2010-07-28 15:48:59 -07001475 } else {
1476 jniThrowRuntimeException(env, "Invalid input event type.");
Jeff Brown7fbdc842010-06-17 20:52:56 -07001477 return INPUT_EVENT_INJECTION_FAILED;
1478 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07001479}
1480
Jeff Brown349703e2010-06-22 01:27:15 -07001481static void android_server_InputManager_nativeSetInputWindows(JNIEnv* env, jclass clazz,
1482 jobjectArray windowObjArray) {
1483 if (checkInputManagerUnitialized(env)) {
1484 return;
1485 }
1486
1487 gNativeInputManager->setInputWindows(env, windowObjArray);
1488}
1489
1490static void android_server_InputManager_nativeSetFocusedApplication(JNIEnv* env, jclass clazz,
1491 jobject applicationObj) {
1492 if (checkInputManagerUnitialized(env)) {
1493 return;
1494 }
1495
1496 gNativeInputManager->setFocusedApplication(env, applicationObj);
1497}
1498
1499static void android_server_InputManager_nativeSetInputDispatchMode(JNIEnv* env,
1500 jclass clazz, jboolean enabled, jboolean frozen) {
1501 if (checkInputManagerUnitialized(env)) {
1502 return;
1503 }
1504
1505 gNativeInputManager->setInputDispatchMode(enabled, frozen);
1506}
1507
Jeff Brown8d608662010-08-30 03:02:23 -07001508static jobject android_server_InputManager_nativeGetInputDevice(JNIEnv* env,
1509 jclass clazz, jint deviceId) {
1510 if (checkInputManagerUnitialized(env)) {
1511 return NULL;
1512 }
1513
1514 InputDeviceInfo deviceInfo;
Jeff Brownb88102f2010-09-08 11:49:43 -07001515 status_t status = gNativeInputManager->getInputManager()->getReader()->getInputDeviceInfo(
Jeff Brown8d608662010-08-30 03:02:23 -07001516 deviceId, & deviceInfo);
1517 if (status) {
1518 return NULL;
1519 }
1520
1521 jobject deviceObj = env->NewObject(gInputDeviceClassInfo.clazz, gInputDeviceClassInfo.ctor);
1522 if (! deviceObj) {
1523 return NULL;
1524 }
1525
1526 jstring deviceNameObj = env->NewStringUTF(deviceInfo.getName().string());
1527 if (! deviceNameObj) {
1528 return NULL;
1529 }
1530
1531 env->SetIntField(deviceObj, gInputDeviceClassInfo.mId, deviceInfo.getId());
1532 env->SetObjectField(deviceObj, gInputDeviceClassInfo.mName, deviceNameObj);
1533 env->SetIntField(deviceObj, gInputDeviceClassInfo.mSources, deviceInfo.getSources());
1534 env->SetIntField(deviceObj, gInputDeviceClassInfo.mKeyboardType, deviceInfo.getKeyboardType());
1535
1536 const KeyedVector<int, InputDeviceInfo::MotionRange>& ranges = deviceInfo.getMotionRanges();
1537 for (size_t i = 0; i < ranges.size(); i++) {
1538 int rangeType = ranges.keyAt(i);
1539 const InputDeviceInfo::MotionRange& range = ranges.valueAt(i);
1540 env->CallVoidMethod(deviceObj, gInputDeviceClassInfo.addMotionRange,
1541 rangeType, range.min, range.max, range.flat, range.fuzz);
1542 if (env->ExceptionCheck()) {
1543 return NULL;
1544 }
1545 }
1546
1547 return deviceObj;
1548}
1549
1550static jintArray android_server_InputManager_nativeGetInputDeviceIds(JNIEnv* env,
1551 jclass clazz) {
1552 if (checkInputManagerUnitialized(env)) {
1553 return NULL;
1554 }
1555
1556 Vector<int> deviceIds;
Jeff Brownb88102f2010-09-08 11:49:43 -07001557 gNativeInputManager->getInputManager()->getReader()->getInputDeviceIds(deviceIds);
Jeff Brown8d608662010-08-30 03:02:23 -07001558
1559 jintArray deviceIdsObj = env->NewIntArray(deviceIds.size());
1560 if (! deviceIdsObj) {
1561 return NULL;
1562 }
1563
1564 env->SetIntArrayRegion(deviceIdsObj, 0, deviceIds.size(), deviceIds.array());
1565 return deviceIdsObj;
1566}
1567
Jeff Brown57c59372010-09-21 18:22:55 -07001568static void android_server_InputManager_nativeGetInputConfiguration(JNIEnv* env,
1569 jclass clazz, jobject configObj) {
1570 if (checkInputManagerUnitialized(env)) {
1571 return;
1572 }
1573
1574 InputConfiguration config;
1575 gNativeInputManager->getInputManager()->getReader()->getInputConfiguration(& config);
1576
1577 env->SetIntField(configObj, gConfigurationClassInfo.touchscreen, config.touchScreen);
1578 env->SetIntField(configObj, gConfigurationClassInfo.keyboard, config.keyboard);
1579 env->SetIntField(configObj, gConfigurationClassInfo.navigation, config.navigation);
1580}
1581
Jeff Browne6504122010-09-27 14:52:15 -07001582static jboolean android_server_InputManager_nativeTransferTouchFocus(JNIEnv* env,
1583 jclass clazz, jobject fromChannelObj, jobject toChannelObj) {
1584 if (checkInputManagerUnitialized(env)) {
1585 return false;
1586 }
1587
1588 sp<InputChannel> fromChannel =
1589 android_view_InputChannel_getInputChannel(env, fromChannelObj);
1590 sp<InputChannel> toChannel =
1591 android_view_InputChannel_getInputChannel(env, toChannelObj);
1592
1593 if (fromChannel == NULL || toChannel == NULL) {
1594 return false;
1595 }
1596
1597 return gNativeInputManager->getInputManager()->getDispatcher()->
1598 transferTouchFocus(fromChannel, toChannel);
1599}
1600
Jeff Browne33348b2010-07-15 23:54:05 -07001601static jstring android_server_InputManager_nativeDump(JNIEnv* env, jclass clazz) {
1602 if (checkInputManagerUnitialized(env)) {
1603 return NULL;
1604 }
1605
Jeff Brownb88102f2010-09-08 11:49:43 -07001606 String8 dump;
1607 gNativeInputManager->dump(dump);
Jeff Browne33348b2010-07-15 23:54:05 -07001608 return env->NewStringUTF(dump.string());
1609}
1610
Jeff Brown9c3cda02010-06-15 01:31:58 -07001611// ----------------------------------------------------------------------------
1612
Jeff Brown46b9ac02010-04-22 18:58:52 -07001613static JNINativeMethod gInputManagerMethods[] = {
1614 /* name, signature, funcPtr */
1615 { "nativeInit", "(Lcom/android/server/InputManager$Callbacks;)V",
1616 (void*) android_server_InputManager_nativeInit },
1617 { "nativeStart", "()V",
1618 (void*) android_server_InputManager_nativeStart },
1619 { "nativeSetDisplaySize", "(III)V",
1620 (void*) android_server_InputManager_nativeSetDisplaySize },
1621 { "nativeSetDisplayOrientation", "(II)V",
1622 (void*) android_server_InputManager_nativeSetDisplayOrientation },
1623 { "nativeGetScanCodeState", "(III)I",
1624 (void*) android_server_InputManager_nativeGetScanCodeState },
1625 { "nativeGetKeyCodeState", "(III)I",
1626 (void*) android_server_InputManager_nativeGetKeyCodeState },
1627 { "nativeGetSwitchState", "(III)I",
1628 (void*) android_server_InputManager_nativeGetSwitchState },
Jeff Brown6d0fec22010-07-23 21:28:06 -07001629 { "nativeHasKeys", "(II[I[Z)Z",
Jeff Brown46b9ac02010-04-22 18:58:52 -07001630 (void*) android_server_InputManager_nativeHasKeys },
Jeff Browna41ca772010-08-11 14:46:32 -07001631 { "nativeRegisterInputChannel", "(Landroid/view/InputChannel;Z)V",
Jeff Brown46b9ac02010-04-22 18:58:52 -07001632 (void*) android_server_InputManager_nativeRegisterInputChannel },
1633 { "nativeUnregisterInputChannel", "(Landroid/view/InputChannel;)V",
Jeff Brown7fbdc842010-06-17 20:52:56 -07001634 (void*) android_server_InputManager_nativeUnregisterInputChannel },
Jeff Brown6ec402b2010-07-28 15:48:59 -07001635 { "nativeInjectInputEvent", "(Landroid/view/InputEvent;IIII)I",
1636 (void*) android_server_InputManager_nativeInjectInputEvent },
Jeff Brown349703e2010-06-22 01:27:15 -07001637 { "nativeSetInputWindows", "([Lcom/android/server/InputWindow;)V",
1638 (void*) android_server_InputManager_nativeSetInputWindows },
1639 { "nativeSetFocusedApplication", "(Lcom/android/server/InputApplication;)V",
1640 (void*) android_server_InputManager_nativeSetFocusedApplication },
1641 { "nativeSetInputDispatchMode", "(ZZ)V",
1642 (void*) android_server_InputManager_nativeSetInputDispatchMode },
Jeff Brown8d608662010-08-30 03:02:23 -07001643 { "nativeGetInputDevice", "(I)Landroid/view/InputDevice;",
1644 (void*) android_server_InputManager_nativeGetInputDevice },
1645 { "nativeGetInputDeviceIds", "()[I",
1646 (void*) android_server_InputManager_nativeGetInputDeviceIds },
Jeff Brown57c59372010-09-21 18:22:55 -07001647 { "nativeGetInputConfiguration", "(Landroid/content/res/Configuration;)V",
1648 (void*) android_server_InputManager_nativeGetInputConfiguration },
Jeff Browne6504122010-09-27 14:52:15 -07001649 { "nativeTransferTouchFocus", "(Landroid/view/InputChannel;Landroid/view/InputChannel;)Z",
1650 (void*) android_server_InputManager_nativeTransferTouchFocus },
Jeff Browne33348b2010-07-15 23:54:05 -07001651 { "nativeDump", "()Ljava/lang/String;",
1652 (void*) android_server_InputManager_nativeDump },
Jeff Brown46b9ac02010-04-22 18:58:52 -07001653};
1654
1655#define FIND_CLASS(var, className) \
1656 var = env->FindClass(className); \
1657 LOG_FATAL_IF(! var, "Unable to find class " className); \
1658 var = jclass(env->NewGlobalRef(var));
1659
1660#define GET_METHOD_ID(var, clazz, methodName, methodDescriptor) \
1661 var = env->GetMethodID(clazz, methodName, methodDescriptor); \
1662 LOG_FATAL_IF(! var, "Unable to find method " methodName);
1663
1664#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \
1665 var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \
1666 LOG_FATAL_IF(! var, "Unable to find field " fieldName);
1667
1668int register_android_server_InputManager(JNIEnv* env) {
1669 int res = jniRegisterNativeMethods(env, "com/android/server/InputManager",
1670 gInputManagerMethods, NELEM(gInputManagerMethods));
1671 LOG_FATAL_IF(res < 0, "Unable to register native methods.");
1672
Jeff Brown9c3cda02010-06-15 01:31:58 -07001673 // Callbacks
Jeff Brown46b9ac02010-04-22 18:58:52 -07001674
1675 FIND_CLASS(gCallbacksClassInfo.clazz, "com/android/server/InputManager$Callbacks");
1676
Jeff Brown46b9ac02010-04-22 18:58:52 -07001677 GET_METHOD_ID(gCallbacksClassInfo.notifyConfigurationChanged, gCallbacksClassInfo.clazz,
Jeff Brown57c59372010-09-21 18:22:55 -07001678 "notifyConfigurationChanged", "(J)V");
Jeff Brown46b9ac02010-04-22 18:58:52 -07001679
1680 GET_METHOD_ID(gCallbacksClassInfo.notifyLidSwitchChanged, gCallbacksClassInfo.clazz,
1681 "notifyLidSwitchChanged", "(JZ)V");
1682
Jeff Brown7fbdc842010-06-17 20:52:56 -07001683 GET_METHOD_ID(gCallbacksClassInfo.notifyInputChannelBroken, gCallbacksClassInfo.clazz,
1684 "notifyInputChannelBroken", "(Landroid/view/InputChannel;)V");
1685
Jeff Brown349703e2010-06-22 01:27:15 -07001686 GET_METHOD_ID(gCallbacksClassInfo.notifyANR, gCallbacksClassInfo.clazz,
Jeff Brown519e0242010-09-15 15:18:56 -07001687 "notifyANR", "(Ljava/lang/Object;Landroid/view/InputChannel;)J");
Jeff Brown349703e2010-06-22 01:27:15 -07001688
Jeff Brown349703e2010-06-22 01:27:15 -07001689 GET_METHOD_ID(gCallbacksClassInfo.interceptKeyBeforeQueueing, gCallbacksClassInfo.clazz,
Jeff Brown1f245102010-11-18 20:53:46 -08001690 "interceptKeyBeforeQueueing", "(Landroid/view/KeyEvent;IZ)I");
Jeff Brown349703e2010-06-22 01:27:15 -07001691
1692 GET_METHOD_ID(gCallbacksClassInfo.interceptKeyBeforeDispatching, gCallbacksClassInfo.clazz,
Jeff Brown1f245102010-11-18 20:53:46 -08001693 "interceptKeyBeforeDispatching",
1694 "(Landroid/view/InputChannel;Landroid/view/KeyEvent;I)Z");
Jeff Brown349703e2010-06-22 01:27:15 -07001695
Jeff Brown3915bb82010-11-05 15:02:16 -07001696 GET_METHOD_ID(gCallbacksClassInfo.dispatchUnhandledKey, gCallbacksClassInfo.clazz,
Jeff Brown49ed71d2010-12-06 17:13:33 -08001697 "dispatchUnhandledKey",
1698 "(Landroid/view/InputChannel;Landroid/view/KeyEvent;I)Landroid/view/KeyEvent;");
Jeff Brown3915bb82010-11-05 15:02:16 -07001699
Jeff Brown349703e2010-06-22 01:27:15 -07001700 GET_METHOD_ID(gCallbacksClassInfo.checkInjectEventsPermission, gCallbacksClassInfo.clazz,
1701 "checkInjectEventsPermission", "(II)Z");
Jeff Brown46b9ac02010-04-22 18:58:52 -07001702
Jeff Brown46b9ac02010-04-22 18:58:52 -07001703 GET_METHOD_ID(gCallbacksClassInfo.filterTouchEvents, gCallbacksClassInfo.clazz,
1704 "filterTouchEvents", "()Z");
1705
1706 GET_METHOD_ID(gCallbacksClassInfo.filterJumpyTouchEvents, gCallbacksClassInfo.clazz,
1707 "filterJumpyTouchEvents", "()Z");
1708
Jeff Brown46b9ac02010-04-22 18:58:52 -07001709 GET_METHOD_ID(gCallbacksClassInfo.getExcludedDeviceNames, gCallbacksClassInfo.clazz,
1710 "getExcludedDeviceNames", "()[Ljava/lang/String;");
1711
Jeff Brownae9fc032010-08-18 15:51:08 -07001712 GET_METHOD_ID(gCallbacksClassInfo.getMaxEventsPerSecond, gCallbacksClassInfo.clazz,
1713 "getMaxEventsPerSecond", "()I");
1714
Jeff Brown83c09682010-12-23 17:50:18 -08001715 GET_METHOD_ID(gCallbacksClassInfo.getPointerLayer, gCallbacksClassInfo.clazz,
1716 "getPointerLayer", "()I");
1717
Jeff Brown349703e2010-06-22 01:27:15 -07001718 // InputWindow
Jeff Brown7fbdc842010-06-17 20:52:56 -07001719
Jeff Brown349703e2010-06-22 01:27:15 -07001720 FIND_CLASS(gInputWindowClassInfo.clazz, "com/android/server/InputWindow");
Jeff Brown7fbdc842010-06-17 20:52:56 -07001721
Jeff Brown349703e2010-06-22 01:27:15 -07001722 GET_FIELD_ID(gInputWindowClassInfo.inputChannel, gInputWindowClassInfo.clazz,
1723 "inputChannel", "Landroid/view/InputChannel;");
Jeff Brown7fbdc842010-06-17 20:52:56 -07001724
Jeff Brown519e0242010-09-15 15:18:56 -07001725 GET_FIELD_ID(gInputWindowClassInfo.name, gInputWindowClassInfo.clazz,
1726 "name", "Ljava/lang/String;");
1727
Jeff Brown349703e2010-06-22 01:27:15 -07001728 GET_FIELD_ID(gInputWindowClassInfo.layoutParamsFlags, gInputWindowClassInfo.clazz,
1729 "layoutParamsFlags", "I");
1730
1731 GET_FIELD_ID(gInputWindowClassInfo.layoutParamsType, gInputWindowClassInfo.clazz,
1732 "layoutParamsType", "I");
1733
1734 GET_FIELD_ID(gInputWindowClassInfo.dispatchingTimeoutNanos, gInputWindowClassInfo.clazz,
1735 "dispatchingTimeoutNanos", "J");
1736
1737 GET_FIELD_ID(gInputWindowClassInfo.frameLeft, gInputWindowClassInfo.clazz,
1738 "frameLeft", "I");
1739
1740 GET_FIELD_ID(gInputWindowClassInfo.frameTop, gInputWindowClassInfo.clazz,
1741 "frameTop", "I");
1742
Jeff Brown85a31762010-09-01 17:01:00 -07001743 GET_FIELD_ID(gInputWindowClassInfo.frameRight, gInputWindowClassInfo.clazz,
1744 "frameRight", "I");
1745
1746 GET_FIELD_ID(gInputWindowClassInfo.frameBottom, gInputWindowClassInfo.clazz,
1747 "frameBottom", "I");
1748
1749 GET_FIELD_ID(gInputWindowClassInfo.visibleFrameLeft, gInputWindowClassInfo.clazz,
1750 "visibleFrameLeft", "I");
1751
1752 GET_FIELD_ID(gInputWindowClassInfo.visibleFrameTop, gInputWindowClassInfo.clazz,
1753 "visibleFrameTop", "I");
1754
1755 GET_FIELD_ID(gInputWindowClassInfo.visibleFrameRight, gInputWindowClassInfo.clazz,
1756 "visibleFrameRight", "I");
1757
1758 GET_FIELD_ID(gInputWindowClassInfo.visibleFrameBottom, gInputWindowClassInfo.clazz,
1759 "visibleFrameBottom", "I");
1760
Jeff Brown349703e2010-06-22 01:27:15 -07001761 GET_FIELD_ID(gInputWindowClassInfo.touchableAreaLeft, gInputWindowClassInfo.clazz,
1762 "touchableAreaLeft", "I");
1763
1764 GET_FIELD_ID(gInputWindowClassInfo.touchableAreaTop, gInputWindowClassInfo.clazz,
1765 "touchableAreaTop", "I");
1766
1767 GET_FIELD_ID(gInputWindowClassInfo.touchableAreaRight, gInputWindowClassInfo.clazz,
1768 "touchableAreaRight", "I");
1769
1770 GET_FIELD_ID(gInputWindowClassInfo.touchableAreaBottom, gInputWindowClassInfo.clazz,
1771 "touchableAreaBottom", "I");
1772
1773 GET_FIELD_ID(gInputWindowClassInfo.visible, gInputWindowClassInfo.clazz,
1774 "visible", "Z");
1775
Jeff Brown519e0242010-09-15 15:18:56 -07001776 GET_FIELD_ID(gInputWindowClassInfo.canReceiveKeys, gInputWindowClassInfo.clazz,
1777 "canReceiveKeys", "Z");
1778
Jeff Brown349703e2010-06-22 01:27:15 -07001779 GET_FIELD_ID(gInputWindowClassInfo.hasFocus, gInputWindowClassInfo.clazz,
1780 "hasFocus", "Z");
1781
1782 GET_FIELD_ID(gInputWindowClassInfo.hasWallpaper, gInputWindowClassInfo.clazz,
1783 "hasWallpaper", "Z");
1784
1785 GET_FIELD_ID(gInputWindowClassInfo.paused, gInputWindowClassInfo.clazz,
1786 "paused", "Z");
1787
Jeff Brown519e0242010-09-15 15:18:56 -07001788 GET_FIELD_ID(gInputWindowClassInfo.layer, gInputWindowClassInfo.clazz,
1789 "layer", "I");
1790
Jeff Brown349703e2010-06-22 01:27:15 -07001791 GET_FIELD_ID(gInputWindowClassInfo.ownerPid, gInputWindowClassInfo.clazz,
1792 "ownerPid", "I");
1793
1794 GET_FIELD_ID(gInputWindowClassInfo.ownerUid, gInputWindowClassInfo.clazz,
1795 "ownerUid", "I");
1796
1797 // InputApplication
1798
1799 FIND_CLASS(gInputApplicationClassInfo.clazz, "com/android/server/InputApplication");
1800
1801 GET_FIELD_ID(gInputApplicationClassInfo.name, gInputApplicationClassInfo.clazz,
1802 "name", "Ljava/lang/String;");
1803
1804 GET_FIELD_ID(gInputApplicationClassInfo.dispatchingTimeoutNanos,
1805 gInputApplicationClassInfo.clazz,
1806 "dispatchingTimeoutNanos", "J");
1807
1808 GET_FIELD_ID(gInputApplicationClassInfo.token, gInputApplicationClassInfo.clazz,
1809 "token", "Ljava/lang/Object;");
Jeff Brown7fbdc842010-06-17 20:52:56 -07001810
Jeff Brown6ec402b2010-07-28 15:48:59 -07001811 // KeyEvent
1812
1813 FIND_CLASS(gKeyEventClassInfo.clazz, "android/view/KeyEvent");
1814
Jeff Brown8d608662010-08-30 03:02:23 -07001815 // MotionEvent
Jeff Brown6ec402b2010-07-28 15:48:59 -07001816
1817 FIND_CLASS(gMotionEventClassInfo.clazz, "android/view/MotionEvent");
1818
Jeff Brown8d608662010-08-30 03:02:23 -07001819 // InputDevice
1820
1821 FIND_CLASS(gInputDeviceClassInfo.clazz, "android/view/InputDevice");
1822
1823 GET_METHOD_ID(gInputDeviceClassInfo.ctor, gInputDeviceClassInfo.clazz,
1824 "<init>", "()V");
1825
1826 GET_METHOD_ID(gInputDeviceClassInfo.addMotionRange, gInputDeviceClassInfo.clazz,
1827 "addMotionRange", "(IFFFF)V");
1828
1829 GET_FIELD_ID(gInputDeviceClassInfo.mId, gInputDeviceClassInfo.clazz,
1830 "mId", "I");
1831
1832 GET_FIELD_ID(gInputDeviceClassInfo.mName, gInputDeviceClassInfo.clazz,
1833 "mName", "Ljava/lang/String;");
1834
1835 GET_FIELD_ID(gInputDeviceClassInfo.mSources, gInputDeviceClassInfo.clazz,
1836 "mSources", "I");
1837
1838 GET_FIELD_ID(gInputDeviceClassInfo.mKeyboardType, gInputDeviceClassInfo.clazz,
1839 "mKeyboardType", "I");
1840
1841 GET_FIELD_ID(gInputDeviceClassInfo.mMotionRanges, gInputDeviceClassInfo.clazz,
1842 "mMotionRanges", "[Landroid/view/InputDevice$MotionRange;");
1843
Jeff Brown57c59372010-09-21 18:22:55 -07001844 // Configuration
1845
1846 FIND_CLASS(gConfigurationClassInfo.clazz, "android/content/res/Configuration");
1847
1848 GET_FIELD_ID(gConfigurationClassInfo.touchscreen, gConfigurationClassInfo.clazz,
1849 "touchscreen", "I");
1850
1851 GET_FIELD_ID(gConfigurationClassInfo.keyboard, gConfigurationClassInfo.clazz,
1852 "keyboard", "I");
1853
1854 GET_FIELD_ID(gConfigurationClassInfo.navigation, gConfigurationClassInfo.clazz,
1855 "navigation", "I");
1856
Jeff Brown46b9ac02010-04-22 18:58:52 -07001857 return 0;
1858}
1859
Jeff Brown46b9ac02010-04-22 18:58:52 -07001860} /* namespace android */