blob: 426197a97289fbbd68810289570b7905c0b0b35c [file] [log] [blame]
Jeff Brown46b9ac0a2010-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
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070028#include "JNIHelp.h"
29#include "jni.h"
Jeff Brown349703e2010-06-22 01:27:15 -070030#include <limits.h>
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070031#include <android_runtime/AndroidRuntime.h>
Jeff Brownb4ff35d2011-01-02 16:37:43 -080032
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070033#include <utils/Log.h>
Jeff Brown05dc66a2011-03-02 14:41:58 -080034#include <utils/Looper.h>
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070035#include <utils/threads.h>
Jeff Brown83c09682010-12-23 17:50:18 -080036
Jeff Brownb4ff35d2011-01-02 16:37:43 -080037#include <input/InputManager.h>
38#include <input/PointerController.h>
39
Jeff Brown05dc66a2011-03-02 14:41:58 -080040#include <android_os_MessageQueue.h>
Jeff Brownb4ff35d2011-01-02 16:37:43 -080041#include <android_view_KeyEvent.h>
42#include <android_view_MotionEvent.h>
43#include <android_view_InputChannel.h>
44#include <android/graphics/GraphicsJNI.h>
45
Jeff Brown00fa7bd2010-07-02 15:37:36 -070046#include "com_android_server_PowerManagerService.h"
Jeff Brown928e0542011-01-10 11:17:36 -080047#include "com_android_server_InputApplication.h"
48#include "com_android_server_InputApplicationHandle.h"
49#include "com_android_server_InputWindow.h"
50#include "com_android_server_InputWindowHandle.h"
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070051
52namespace android {
53
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070054static struct {
55 jclass clazz;
56
Jeff Brown46b9ac0a2010-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;
Jeff Brown56194eb2011-03-02 19:23:13 -080062 jmethodID interceptMotionBeforeQueueingWhenScreenOff;
Jeff Brown349703e2010-06-22 01:27:15 -070063 jmethodID interceptKeyBeforeDispatching;
Jeff Brown3915bb82010-11-05 15:02:16 -070064 jmethodID dispatchUnhandledKey;
Jeff Brown349703e2010-06-22 01:27:15 -070065 jmethodID checkInjectEventsPermission;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070066 jmethodID filterTouchEvents;
67 jmethodID filterJumpyTouchEvents;
Jeff Brownfe508922011-01-18 15:10:10 -080068 jmethodID getVirtualKeyQuietTimeMillis;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070069 jmethodID getExcludedDeviceNames;
Jeff Browna4547672011-03-02 21:38:11 -080070 jmethodID getKeyRepeatTimeout;
71 jmethodID getKeyRepeatDelay;
Jeff Brownae9fc032010-08-18 15:51:08 -070072 jmethodID getMaxEventsPerSecond;
Jeff Brown83c09682010-12-23 17:50:18 -080073 jmethodID getPointerLayer;
Jeff Brownb4ff35d2011-01-02 16:37:43 -080074 jmethodID getPointerIcon;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070075} gCallbacksClassInfo;
76
77static struct {
78 jclass clazz;
Jeff Brown6ec402b2010-07-28 15:48:59 -070079} gKeyEventClassInfo;
80
81static struct {
82 jclass clazz;
83} gMotionEventClassInfo;
84
Jeff Brown8d608662010-08-30 03:02:23 -070085static struct {
86 jclass clazz;
87
88 jmethodID ctor;
89 jmethodID addMotionRange;
90
91 jfieldID mId;
92 jfieldID mName;
93 jfieldID mSources;
94 jfieldID mKeyboardType;
Jeff Brown8d608662010-08-30 03:02:23 -070095} gInputDeviceClassInfo;
96
Jeff Brown57c59372010-09-21 18:22:55 -070097static struct {
98 jclass clazz;
99
100 jfieldID touchscreen;
101 jfieldID keyboard;
102 jfieldID navigation;
103} gConfigurationClassInfo;
104
Jeff Brownb4ff35d2011-01-02 16:37:43 -0800105static struct {
106 jclass clazz;
Jeff Brown349703e2010-06-22 01:27:15 -0700107
Jeff Brownb4ff35d2011-01-02 16:37:43 -0800108 jfieldID bitmap;
109 jfieldID hotSpotX;
110 jfieldID hotSpotY;
111} gPointerIconClassInfo;
Jeff Brown83c09682010-12-23 17:50:18 -0800112
Jeff Brown928e0542011-01-10 11:17:36 -0800113
114// --- Global functions ---
115
116static jobject getInputApplicationHandleObjLocalRef(JNIEnv* env,
117 const sp<InputApplicationHandle>& inputApplicationHandle) {
118 if (inputApplicationHandle == NULL) {
119 return NULL;
120 }
121 return static_cast<NativeInputApplicationHandle*>(inputApplicationHandle.get())->
122 getInputApplicationHandleObjLocalRef(env);
123}
124
125static jobject getInputWindowHandleObjLocalRef(JNIEnv* env,
126 const sp<InputWindowHandle>& inputWindowHandle) {
127 if (inputWindowHandle == NULL) {
128 return NULL;
129 }
130 return static_cast<NativeInputWindowHandle*>(inputWindowHandle.get())->
131 getInputWindowHandleObjLocalRef(env);
132}
133
134
135// --- NativeInputManager ---
Jeff Brown83c09682010-12-23 17:50:18 -0800136
Jeff Brown9c3cda02010-06-15 01:31:58 -0700137class NativeInputManager : public virtual RefBase,
138 public virtual InputReaderPolicyInterface,
139 public virtual InputDispatcherPolicyInterface {
140protected:
141 virtual ~NativeInputManager();
142
143public:
Jeff Brown05dc66a2011-03-02 14:41:58 -0800144 NativeInputManager(jobject callbacksObj, const sp<Looper>& looper);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700145
146 inline sp<InputManager> getInputManager() const { return mInputManager; }
147
Jeff Brownb88102f2010-09-08 11:49:43 -0700148 void dump(String8& dump);
Jeff Browne33348b2010-07-15 23:54:05 -0700149
Jeff Brown9c3cda02010-06-15 01:31:58 -0700150 void setDisplaySize(int32_t displayId, int32_t width, int32_t height);
151 void setDisplayOrientation(int32_t displayId, int32_t orientation);
152
Jeff Brown7fbdc842010-06-17 20:52:56 -0700153 status_t registerInputChannel(JNIEnv* env, const sp<InputChannel>& inputChannel,
Jeff Brown928e0542011-01-10 11:17:36 -0800154 const sp<InputWindowHandle>& inputWindowHandle, bool monitor);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700155 status_t unregisterInputChannel(JNIEnv* env, const sp<InputChannel>& inputChannel);
156
Jeff Brown349703e2010-06-22 01:27:15 -0700157 void setInputWindows(JNIEnv* env, jobjectArray windowObjArray);
158 void setFocusedApplication(JNIEnv* env, jobject applicationObj);
159 void setInputDispatchMode(bool enabled, bool frozen);
Jeff Brown05dc66a2011-03-02 14:41:58 -0800160 void setSystemUiVisibility(int32_t visibility);
Jeff Brown349703e2010-06-22 01:27:15 -0700161
Jeff Brown9c3cda02010-06-15 01:31:58 -0700162 /* --- InputReaderPolicyInterface implementation --- */
163
164 virtual bool getDisplayInfo(int32_t displayId,
165 int32_t* width, int32_t* height, int32_t* orientation);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700166 virtual bool filterTouchEvents();
167 virtual bool filterJumpyTouchEvents();
Jeff Brownfe508922011-01-18 15:10:10 -0800168 virtual nsecs_t getVirtualKeyQuietTime();
Jeff Brown9c3cda02010-06-15 01:31:58 -0700169 virtual void getExcludedDeviceNames(Vector<String8>& outExcludedDeviceNames);
Jeff Brown83c09682010-12-23 17:50:18 -0800170 virtual sp<PointerControllerInterface> obtainPointerController(int32_t deviceId);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700171
172 /* --- InputDispatcherPolicyInterface implementation --- */
173
Jeff Browne20c9e02010-10-11 14:20:19 -0700174 virtual void notifySwitch(nsecs_t when, int32_t switchCode, int32_t switchValue,
175 uint32_t policyFlags);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700176 virtual void notifyConfigurationChanged(nsecs_t when);
Jeff Brown519e0242010-09-15 15:18:56 -0700177 virtual nsecs_t notifyANR(const sp<InputApplicationHandle>& inputApplicationHandle,
Jeff Brown928e0542011-01-10 11:17:36 -0800178 const sp<InputWindowHandle>& inputWindowHandle);
179 virtual void notifyInputChannelBroken(const sp<InputWindowHandle>& inputWindowHandle);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700180 virtual nsecs_t getKeyRepeatTimeout();
Jeff Brownb21fb102010-09-07 10:44:57 -0700181 virtual nsecs_t getKeyRepeatDelay();
Jeff Brownae9fc032010-08-18 15:51:08 -0700182 virtual int32_t getMaxEventsPerSecond();
Jeff Brown1f245102010-11-18 20:53:46 -0800183 virtual void interceptKeyBeforeQueueing(const KeyEvent* keyEvent, uint32_t& policyFlags);
Jeff Brown56194eb2011-03-02 19:23:13 -0800184 virtual void interceptMotionBeforeQueueing(nsecs_t when, uint32_t& policyFlags);
Jeff Brown928e0542011-01-10 11:17:36 -0800185 virtual bool interceptKeyBeforeDispatching(const sp<InputWindowHandle>& inputWindowHandle,
Jeff Brownb88102f2010-09-08 11:49:43 -0700186 const KeyEvent* keyEvent, uint32_t policyFlags);
Jeff Brown928e0542011-01-10 11:17:36 -0800187 virtual bool dispatchUnhandledKey(const sp<InputWindowHandle>& inputWindowHandle,
Jeff Brown49ed71d2010-12-06 17:13:33 -0800188 const KeyEvent* keyEvent, uint32_t policyFlags, KeyEvent* outFallbackKeyEvent);
Jeff Brown01ce2e92010-09-26 22:20:12 -0700189 virtual void pokeUserActivity(nsecs_t eventTime, int32_t eventType);
Jeff Brownb88102f2010-09-08 11:49:43 -0700190 virtual bool checkInjectEventsPermissionNonReentrant(
191 int32_t injectorPid, int32_t injectorUid);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700192
193private:
194 sp<InputManager> mInputManager;
195
196 jobject mCallbacksObj;
Jeff Brown05dc66a2011-03-02 14:41:58 -0800197 sp<Looper> mLooper;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700198
199 // Cached filtering policies.
200 int32_t mFilterTouchEvents;
201 int32_t mFilterJumpyTouchEvents;
Jeff Brownfe508922011-01-18 15:10:10 -0800202 nsecs_t mVirtualKeyQuietTime;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700203
Jeff Browna4547672011-03-02 21:38:11 -0800204 // Cached key repeat policy.
205 nsecs_t mKeyRepeatTimeout;
206 nsecs_t mKeyRepeatDelay;
207
Jeff Brownae9fc032010-08-18 15:51:08 -0700208 // Cached throttling policy.
209 int32_t mMaxEventsPerSecond;
210
Jeff Brown83c09682010-12-23 17:50:18 -0800211 Mutex mLock;
212 struct Locked {
213 // Display size information.
214 int32_t displayWidth, displayHeight; // -1 when initialized
215 int32_t displayOrientation;
216
Jeff Brown05dc66a2011-03-02 14:41:58 -0800217 // System UI visibility.
218 int32_t systemUiVisibility;
219
Jeff Brown83c09682010-12-23 17:50:18 -0800220 // Pointer controller singleton, created and destroyed as needed.
221 wp<PointerController> pointerController;
Jeff Brown83c09682010-12-23 17:50:18 -0800222 } mLocked;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700223
Jeff Brown05dc66a2011-03-02 14:41:58 -0800224 void updateInactivityFadeDelayLocked(const sp<PointerController>& controller);
Jeff Brown56194eb2011-03-02 19:23:13 -0800225 void handleInterceptActions(jint wmActions, nsecs_t when, uint32_t& policyFlags);
Jeff Brown05dc66a2011-03-02 14:41:58 -0800226
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700227 // Power manager interactions.
Jeff Brown9c3cda02010-06-15 01:31:58 -0700228 bool isScreenOn();
229 bool isScreenBright();
230
Jeff Brownb88102f2010-09-08 11:49:43 -0700231 static bool checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName);
Jeff Browna41ca772010-08-11 14:46:32 -0700232
Jeff Brown9c3cda02010-06-15 01:31:58 -0700233 static inline JNIEnv* jniEnv() {
234 return AndroidRuntime::getJNIEnv();
235 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700236};
237
Jeff Brown928e0542011-01-10 11:17:36 -0800238
Jeff Brown9c3cda02010-06-15 01:31:58 -0700239
Jeff Brown05dc66a2011-03-02 14:41:58 -0800240NativeInputManager::NativeInputManager(jobject callbacksObj, const sp<Looper>& looper) :
241 mLooper(looper),
242 mFilterTouchEvents(-1), mFilterJumpyTouchEvents(-1), mVirtualKeyQuietTime(-1),
Jeff Browna4547672011-03-02 21:38:11 -0800243 mKeyRepeatTimeout(-1), mKeyRepeatDelay(-1),
Jeff Brown05dc66a2011-03-02 14:41:58 -0800244 mMaxEventsPerSecond(-1) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700245 JNIEnv* env = jniEnv();
246
247 mCallbacksObj = env->NewGlobalRef(callbacksObj);
248
Jeff Brown83c09682010-12-23 17:50:18 -0800249 {
250 AutoMutex _l(mLock);
251 mLocked.displayWidth = -1;
252 mLocked.displayHeight = -1;
253 mLocked.displayOrientation = ROTATION_0;
Jeff Brown05dc66a2011-03-02 14:41:58 -0800254
255 mLocked.systemUiVisibility = ASYSTEM_UI_VISIBILITY_STATUS_BAR_VISIBLE;
Jeff Brown83c09682010-12-23 17:50:18 -0800256 }
257
Jeff Brown9c3cda02010-06-15 01:31:58 -0700258 sp<EventHub> eventHub = new EventHub();
259 mInputManager = new InputManager(eventHub, this, this);
260}
261
262NativeInputManager::~NativeInputManager() {
263 JNIEnv* env = jniEnv();
264
265 env->DeleteGlobalRef(mCallbacksObj);
266}
267
Jeff Brownb88102f2010-09-08 11:49:43 -0700268void NativeInputManager::dump(String8& dump) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700269 mInputManager->getReader()->dump(dump);
270 dump.append("\n");
Jeff Brown6d0fec22010-07-23 21:28:06 -0700271
Jeff Brownb88102f2010-09-08 11:49:43 -0700272 mInputManager->getDispatcher()->dump(dump);
273 dump.append("\n");
Jeff Brown9c3cda02010-06-15 01:31:58 -0700274}
275
Jeff Brown7fbdc842010-06-17 20:52:56 -0700276bool NativeInputManager::checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700277 if (env->ExceptionCheck()) {
278 LOGE("An exception was thrown by callback '%s'.", methodName);
279 LOGE_EX(env);
280 env->ExceptionClear();
281 return true;
282 }
283 return false;
284}
285
286void NativeInputManager::setDisplaySize(int32_t displayId, int32_t width, int32_t height) {
287 if (displayId == 0) {
Jeff Brown83c09682010-12-23 17:50:18 -0800288 AutoMutex _l(mLock);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700289
Jeff Brown83c09682010-12-23 17:50:18 -0800290 if (mLocked.displayWidth != width || mLocked.displayHeight != height) {
291 mLocked.displayWidth = width;
292 mLocked.displayHeight = height;
293
294 sp<PointerController> controller = mLocked.pointerController.promote();
295 if (controller != NULL) {
296 controller->setDisplaySize(width, height);
297 }
298 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700299 }
300}
301
302void NativeInputManager::setDisplayOrientation(int32_t displayId, int32_t orientation) {
303 if (displayId == 0) {
Jeff Brown83c09682010-12-23 17:50:18 -0800304 AutoMutex _l(mLock);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700305
Jeff Brown83c09682010-12-23 17:50:18 -0800306 if (mLocked.displayOrientation != orientation) {
307 mLocked.displayOrientation = orientation;
308
309 sp<PointerController> controller = mLocked.pointerController.promote();
310 if (controller != NULL) {
311 controller->setDisplayOrientation(orientation);
312 }
313 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700314 }
315}
316
Jeff Brown7fbdc842010-06-17 20:52:56 -0700317status_t NativeInputManager::registerInputChannel(JNIEnv* env,
Jeff Brown928e0542011-01-10 11:17:36 -0800318 const sp<InputChannel>& inputChannel,
319 const sp<InputWindowHandle>& inputWindowHandle, bool monitor) {
320 return mInputManager->getDispatcher()->registerInputChannel(
321 inputChannel, inputWindowHandle, monitor);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700322}
323
324status_t NativeInputManager::unregisterInputChannel(JNIEnv* env,
325 const sp<InputChannel>& inputChannel) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700326 return mInputManager->getDispatcher()->unregisterInputChannel(inputChannel);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700327}
328
Jeff Brown9c3cda02010-06-15 01:31:58 -0700329bool NativeInputManager::getDisplayInfo(int32_t displayId,
330 int32_t* width, int32_t* height, int32_t* orientation) {
331 bool result = false;
332 if (displayId == 0) {
Jeff Brown83c09682010-12-23 17:50:18 -0800333 AutoMutex _l(mLock);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700334
Jeff Brown83c09682010-12-23 17:50:18 -0800335 if (mLocked.displayWidth > 0 && mLocked.displayHeight > 0) {
Jeff Brown6d0fec22010-07-23 21:28:06 -0700336 if (width) {
Jeff Brown83c09682010-12-23 17:50:18 -0800337 *width = mLocked.displayWidth;
Jeff Brown6d0fec22010-07-23 21:28:06 -0700338 }
339 if (height) {
Jeff Brown83c09682010-12-23 17:50:18 -0800340 *height = mLocked.displayHeight;
Jeff Brown6d0fec22010-07-23 21:28:06 -0700341 }
342 if (orientation) {
Jeff Brown83c09682010-12-23 17:50:18 -0800343 *orientation = mLocked.displayOrientation;
Jeff Brown6d0fec22010-07-23 21:28:06 -0700344 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700345 result = true;
346 }
347 }
348 return result;
349}
350
Jeff Brown9c3cda02010-06-15 01:31:58 -0700351bool NativeInputManager::filterTouchEvents() {
352 if (mFilterTouchEvents < 0) {
353 JNIEnv* env = jniEnv();
354
355 jboolean result = env->CallBooleanMethod(mCallbacksObj,
356 gCallbacksClassInfo.filterTouchEvents);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700357 if (checkAndClearExceptionFromCallback(env, "filterTouchEvents")) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700358 result = false;
359 }
360
361 mFilterTouchEvents = result ? 1 : 0;
362 }
363 return mFilterTouchEvents;
364}
365
366bool NativeInputManager::filterJumpyTouchEvents() {
367 if (mFilterJumpyTouchEvents < 0) {
368 JNIEnv* env = jniEnv();
369
370 jboolean result = env->CallBooleanMethod(mCallbacksObj,
371 gCallbacksClassInfo.filterJumpyTouchEvents);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700372 if (checkAndClearExceptionFromCallback(env, "filterJumpyTouchEvents")) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700373 result = false;
374 }
375
376 mFilterJumpyTouchEvents = result ? 1 : 0;
377 }
378 return mFilterJumpyTouchEvents;
379}
380
Jeff Brownfe508922011-01-18 15:10:10 -0800381nsecs_t NativeInputManager::getVirtualKeyQuietTime() {
382 if (mVirtualKeyQuietTime < 0) {
383 JNIEnv* env = jniEnv();
384
385 jint result = env->CallIntMethod(mCallbacksObj,
386 gCallbacksClassInfo.getVirtualKeyQuietTimeMillis);
387 if (checkAndClearExceptionFromCallback(env, "getVirtualKeyQuietTimeMillis")) {
388 result = 0;
389 }
390 if (result < 0) {
391 result = 0;
392 }
393
394 mVirtualKeyQuietTime = milliseconds_to_nanoseconds(result);
395 }
396 return mVirtualKeyQuietTime;
397}
398
Jeff Brown9c3cda02010-06-15 01:31:58 -0700399void NativeInputManager::getExcludedDeviceNames(Vector<String8>& outExcludedDeviceNames) {
Jeff Brown8d608662010-08-30 03:02:23 -0700400 outExcludedDeviceNames.clear();
401
Jeff Brown9c3cda02010-06-15 01:31:58 -0700402 JNIEnv* env = jniEnv();
403
404 jobjectArray result = jobjectArray(env->CallObjectMethod(mCallbacksObj,
405 gCallbacksClassInfo.getExcludedDeviceNames));
Jeff Brown7fbdc842010-06-17 20:52:56 -0700406 if (! checkAndClearExceptionFromCallback(env, "getExcludedDeviceNames") && result) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700407 jsize length = env->GetArrayLength(result);
408 for (jsize i = 0; i < length; i++) {
409 jstring item = jstring(env->GetObjectArrayElement(result, i));
410
411 const char* deviceNameChars = env->GetStringUTFChars(item, NULL);
412 outExcludedDeviceNames.add(String8(deviceNameChars));
413 env->ReleaseStringUTFChars(item, deviceNameChars);
414
415 env->DeleteLocalRef(item);
416 }
417 env->DeleteLocalRef(result);
418 }
419}
420
Jeff Brown83c09682010-12-23 17:50:18 -0800421sp<PointerControllerInterface> NativeInputManager::obtainPointerController(int32_t deviceId) {
422 AutoMutex _l(mLock);
423
424 sp<PointerController> controller = mLocked.pointerController.promote();
425 if (controller == NULL) {
426 JNIEnv* env = jniEnv();
427 jint layer = env->CallIntMethod(mCallbacksObj, gCallbacksClassInfo.getPointerLayer);
Jeff Brownb4ff35d2011-01-02 16:37:43 -0800428 if (checkAndClearExceptionFromCallback(env, "getPointerLayer")) {
429 layer = -1;
430 }
Jeff Brown83c09682010-12-23 17:50:18 -0800431
Jeff Brown05dc66a2011-03-02 14:41:58 -0800432 controller = new PointerController(mLooper, layer);
Jeff Brown83c09682010-12-23 17:50:18 -0800433 mLocked.pointerController = controller;
434
435 controller->setDisplaySize(mLocked.displayWidth, mLocked.displayHeight);
436 controller->setDisplayOrientation(mLocked.displayOrientation);
Jeff Brownb4ff35d2011-01-02 16:37:43 -0800437
438 jobject iconObj = env->CallObjectMethod(mCallbacksObj, gCallbacksClassInfo.getPointerIcon);
439 if (!checkAndClearExceptionFromCallback(env, "getPointerIcon") && iconObj) {
440 jfloat iconHotSpotX = env->GetFloatField(iconObj, gPointerIconClassInfo.hotSpotX);
441 jfloat iconHotSpotY = env->GetFloatField(iconObj, gPointerIconClassInfo.hotSpotY);
442 jobject iconBitmapObj = env->GetObjectField(iconObj, gPointerIconClassInfo.bitmap);
443 if (iconBitmapObj) {
444 SkBitmap* iconBitmap = GraphicsJNI::getNativeBitmap(env, iconBitmapObj);
445 if (iconBitmap) {
446 controller->setPointerIcon(iconBitmap, iconHotSpotX, iconHotSpotY);
447 }
448 env->DeleteLocalRef(iconBitmapObj);
449 }
450 env->DeleteLocalRef(iconObj);
451 }
Jeff Brown05dc66a2011-03-02 14:41:58 -0800452
453 updateInactivityFadeDelayLocked(controller);
Jeff Brown83c09682010-12-23 17:50:18 -0800454 }
455 return controller;
456}
457
Jeff Browne20c9e02010-10-11 14:20:19 -0700458void NativeInputManager::notifySwitch(nsecs_t when, int32_t switchCode,
459 int32_t switchValue, uint32_t policyFlags) {
460#if DEBUG_INPUT_DISPATCHER_POLICY
461 LOGD("notifySwitch - when=%lld, switchCode=%d, switchValue=%d, policyFlags=0x%x",
462 when, switchCode, switchValue, policyFlags);
463#endif
464
465 JNIEnv* env = jniEnv();
466
467 switch (switchCode) {
468 case SW_LID:
469 env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyLidSwitchChanged,
470 when, switchValue == 0);
471 checkAndClearExceptionFromCallback(env, "notifyLidSwitchChanged");
472 break;
473 }
474}
475
Jeff Brown9c3cda02010-06-15 01:31:58 -0700476void NativeInputManager::notifyConfigurationChanged(nsecs_t when) {
477#if DEBUG_INPUT_DISPATCHER_POLICY
478 LOGD("notifyConfigurationChanged - when=%lld", when);
479#endif
480
481 JNIEnv* env = jniEnv();
482
Jeff Brown57c59372010-09-21 18:22:55 -0700483 env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyConfigurationChanged, when);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700484 checkAndClearExceptionFromCallback(env, "notifyConfigurationChanged");
Jeff Brown9c3cda02010-06-15 01:31:58 -0700485}
486
Jeff Brown519e0242010-09-15 15:18:56 -0700487nsecs_t NativeInputManager::notifyANR(const sp<InputApplicationHandle>& inputApplicationHandle,
Jeff Brown928e0542011-01-10 11:17:36 -0800488 const sp<InputWindowHandle>& inputWindowHandle) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700489#if DEBUG_INPUT_DISPATCHER_POLICY
490 LOGD("notifyANR");
491#endif
492
493 JNIEnv* env = jniEnv();
494
Jeff Brown928e0542011-01-10 11:17:36 -0800495 jobject inputApplicationHandleObj =
496 getInputApplicationHandleObjLocalRef(env, inputApplicationHandle);
497 jobject inputWindowHandleObj =
498 getInputWindowHandleObjLocalRef(env, inputWindowHandle);
Jeff Brownb88102f2010-09-08 11:49:43 -0700499
Jeff Brown519e0242010-09-15 15:18:56 -0700500 jlong newTimeout = env->CallLongMethod(mCallbacksObj,
Jeff Brown928e0542011-01-10 11:17:36 -0800501 gCallbacksClassInfo.notifyANR, inputApplicationHandleObj, inputWindowHandleObj);
Jeff Brown519e0242010-09-15 15:18:56 -0700502 if (checkAndClearExceptionFromCallback(env, "notifyANR")) {
503 newTimeout = 0; // abort dispatch
504 } else {
505 assert(newTimeout >= 0);
506 }
507
Jeff Brown928e0542011-01-10 11:17:36 -0800508 env->DeleteLocalRef(inputWindowHandleObj);
509 env->DeleteLocalRef(inputApplicationHandleObj);
Jeff Brownb88102f2010-09-08 11:49:43 -0700510 return newTimeout;
511}
512
Jeff Brown928e0542011-01-10 11:17:36 -0800513void NativeInputManager::notifyInputChannelBroken(const sp<InputWindowHandle>& inputWindowHandle) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700514#if DEBUG_INPUT_DISPATCHER_POLICY
Jeff Brown928e0542011-01-10 11:17:36 -0800515 LOGD("notifyInputChannelBroken");
Jeff Brown9c3cda02010-06-15 01:31:58 -0700516#endif
517
Jeff Brown7fbdc842010-06-17 20:52:56 -0700518 JNIEnv* env = jniEnv();
519
Jeff Brown928e0542011-01-10 11:17:36 -0800520 jobject inputWindowHandleObj =
521 getInputWindowHandleObjLocalRef(env, inputWindowHandle);
522 if (inputWindowHandleObj) {
Jeff Brown7fbdc842010-06-17 20:52:56 -0700523 env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyInputChannelBroken,
Jeff Brown928e0542011-01-10 11:17:36 -0800524 inputWindowHandleObj);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700525 checkAndClearExceptionFromCallback(env, "notifyInputChannelBroken");
526
Jeff Brown928e0542011-01-10 11:17:36 -0800527 env->DeleteLocalRef(inputWindowHandleObj);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700528 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700529}
530
Jeff Brown9c3cda02010-06-15 01:31:58 -0700531nsecs_t NativeInputManager::getKeyRepeatTimeout() {
532 if (! isScreenOn()) {
533 // Disable key repeat when the screen is off.
534 return -1;
535 } else {
Jeff Browna4547672011-03-02 21:38:11 -0800536 if (mKeyRepeatTimeout < 0) {
537 JNIEnv* env = jniEnv();
538
539 jint result = env->CallIntMethod(mCallbacksObj,
540 gCallbacksClassInfo.getKeyRepeatTimeout);
541 if (checkAndClearExceptionFromCallback(env, "getKeyRepeatTimeout")) {
542 result = 500;
543 }
544
545 mKeyRepeatTimeout = milliseconds_to_nanoseconds(result);
546 }
547 return mKeyRepeatTimeout;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700548 }
549}
550
Jeff Brownb21fb102010-09-07 10:44:57 -0700551nsecs_t NativeInputManager::getKeyRepeatDelay() {
Jeff Browna4547672011-03-02 21:38:11 -0800552 if (mKeyRepeatDelay < 0) {
553 JNIEnv* env = jniEnv();
554
555 jint result = env->CallIntMethod(mCallbacksObj,
556 gCallbacksClassInfo.getKeyRepeatDelay);
557 if (checkAndClearExceptionFromCallback(env, "getKeyRepeatDelay")) {
558 result = 50;
559 }
560
561 mKeyRepeatDelay = milliseconds_to_nanoseconds(result);
562 }
563 return mKeyRepeatDelay;
Jeff Brownb21fb102010-09-07 10:44:57 -0700564}
565
Jeff Brownae9fc032010-08-18 15:51:08 -0700566int32_t NativeInputManager::getMaxEventsPerSecond() {
567 if (mMaxEventsPerSecond < 0) {
568 JNIEnv* env = jniEnv();
569
570 jint result = env->CallIntMethod(mCallbacksObj,
571 gCallbacksClassInfo.getMaxEventsPerSecond);
572 if (checkAndClearExceptionFromCallback(env, "getMaxEventsPerSecond")) {
Jeff Brown3d8c9bd2010-08-18 17:48:53 -0700573 result = 60;
Jeff Brownae9fc032010-08-18 15:51:08 -0700574 }
575
576 mMaxEventsPerSecond = result;
577 }
578 return mMaxEventsPerSecond;
579}
580
Jeff Brown349703e2010-06-22 01:27:15 -0700581void NativeInputManager::setInputWindows(JNIEnv* env, jobjectArray windowObjArray) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700582 Vector<InputWindow> windows;
Jeff Brown349703e2010-06-22 01:27:15 -0700583
Jeff Brownb88102f2010-09-08 11:49:43 -0700584 jsize length = env->GetArrayLength(windowObjArray);
585 for (jsize i = 0; i < length; i++) {
Jeff Brown928e0542011-01-10 11:17:36 -0800586 jobject windowObj = env->GetObjectArrayElement(windowObjArray, i);
587 if (! windowObj) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700588 break; // found null element indicating end of used portion of the array
Jeff Brown349703e2010-06-22 01:27:15 -0700589 }
590
Jeff Brownb88102f2010-09-08 11:49:43 -0700591 windows.push();
592 InputWindow& window = windows.editTop();
Jeff Brown928e0542011-01-10 11:17:36 -0800593 android_server_InputWindow_toNative(env, windowObj, &window);
594 if (window.inputChannel == NULL) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700595 windows.pop();
Jeff Brown349703e2010-06-22 01:27:15 -0700596 }
Jeff Brown928e0542011-01-10 11:17:36 -0800597 env->DeleteLocalRef(windowObj);
Jeff Brownb88102f2010-09-08 11:49:43 -0700598 }
Jeff Brown349703e2010-06-22 01:27:15 -0700599
Jeff Brownb88102f2010-09-08 11:49:43 -0700600 mInputManager->getDispatcher()->setInputWindows(windows);
Jeff Brown349703e2010-06-22 01:27:15 -0700601}
602
Jeff Brown349703e2010-06-22 01:27:15 -0700603void NativeInputManager::setFocusedApplication(JNIEnv* env, jobject applicationObj) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700604 if (applicationObj) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700605 InputApplication application;
Jeff Brown928e0542011-01-10 11:17:36 -0800606 android_server_InputApplication_toNative(env, applicationObj, &application);
607 if (application.inputApplicationHandle != NULL) {
608 mInputManager->getDispatcher()->setFocusedApplication(&application);
Jeff Brown22d789d2011-03-25 11:58:46 -0700609 return;
Jeff Brown928e0542011-01-10 11:17:36 -0800610 }
Jeff Brown349703e2010-06-22 01:27:15 -0700611 }
Jeff Brown928e0542011-01-10 11:17:36 -0800612 mInputManager->getDispatcher()->setFocusedApplication(NULL);
Jeff Brown349703e2010-06-22 01:27:15 -0700613}
614
615void NativeInputManager::setInputDispatchMode(bool enabled, bool frozen) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700616 mInputManager->getDispatcher()->setInputDispatchMode(enabled, frozen);
Jeff Brown349703e2010-06-22 01:27:15 -0700617}
618
Jeff Brown05dc66a2011-03-02 14:41:58 -0800619void NativeInputManager::setSystemUiVisibility(int32_t visibility) {
620 AutoMutex _l(mLock);
621
622 if (mLocked.systemUiVisibility != visibility) {
623 mLocked.systemUiVisibility = visibility;
624
625 sp<PointerController> controller = mLocked.pointerController.promote();
626 if (controller != NULL) {
627 updateInactivityFadeDelayLocked(controller);
628 }
629 }
630}
631
632void NativeInputManager::updateInactivityFadeDelayLocked(const sp<PointerController>& controller) {
633 bool lightsOut = mLocked.systemUiVisibility & ASYSTEM_UI_VISIBILITY_STATUS_BAR_HIDDEN;
634 controller->setInactivityFadeDelay(lightsOut
635 ? PointerController::INACTIVITY_FADE_DELAY_SHORT
636 : PointerController::INACTIVITY_FADE_DELAY_NORMAL);
637}
638
Jeff Browne20c9e02010-10-11 14:20:19 -0700639bool NativeInputManager::isScreenOn() {
640 return android_server_PowerManagerService_isScreenOn();
641}
642
643bool NativeInputManager::isScreenBright() {
644 return android_server_PowerManagerService_isScreenBright();
645}
646
Jeff Brown1f245102010-11-18 20:53:46 -0800647void NativeInputManager::interceptKeyBeforeQueueing(const KeyEvent* keyEvent,
648 uint32_t& policyFlags) {
Jeff Brown3122e442010-10-11 23:32:49 -0700649 // Policy:
650 // - Ignore untrusted events and pass them along.
651 // - Ask the window manager what to do with normal events and trusted injected events.
652 // - For normal events wake and brighten the screen if currently off or dim.
653 if ((policyFlags & POLICY_FLAG_TRUSTED)) {
Jeff Brown1f245102010-11-18 20:53:46 -0800654 nsecs_t when = keyEvent->getEventTime();
Jeff Brown3122e442010-10-11 23:32:49 -0700655 bool isScreenOn = this->isScreenOn();
656 bool isScreenBright = this->isScreenBright();
Jeff Browne20c9e02010-10-11 14:20:19 -0700657
Jeff Brown3122e442010-10-11 23:32:49 -0700658 JNIEnv* env = jniEnv();
Jeff Brown1f245102010-11-18 20:53:46 -0800659 jobject keyEventObj = android_view_KeyEvent_fromNative(env, keyEvent);
660 jint wmActions;
661 if (keyEventObj) {
662 wmActions = env->CallIntMethod(mCallbacksObj,
663 gCallbacksClassInfo.interceptKeyBeforeQueueing,
664 keyEventObj, policyFlags, isScreenOn);
665 if (checkAndClearExceptionFromCallback(env, "interceptKeyBeforeQueueing")) {
666 wmActions = 0;
667 }
668 android_view_KeyEvent_recycle(env, keyEventObj);
669 env->DeleteLocalRef(keyEventObj);
670 } else {
671 LOGE("Failed to obtain key event object for interceptKeyBeforeQueueing.");
Jeff Brown3122e442010-10-11 23:32:49 -0700672 wmActions = 0;
Jeff Browne20c9e02010-10-11 14:20:19 -0700673 }
674
Jeff Brown1f245102010-11-18 20:53:46 -0800675 if (!(policyFlags & POLICY_FLAG_INJECTED)) {
Jeff Brown3122e442010-10-11 23:32:49 -0700676 if (!isScreenOn) {
677 policyFlags |= POLICY_FLAG_WOKE_HERE;
Jeff Brown3122e442010-10-11 23:32:49 -0700678 }
679
680 if (!isScreenBright) {
681 policyFlags |= POLICY_FLAG_BRIGHT_HERE;
682 }
Jeff Browne20c9e02010-10-11 14:20:19 -0700683 }
684
Jeff Brown56194eb2011-03-02 19:23:13 -0800685 handleInterceptActions(wmActions, when, /*byref*/ policyFlags);
Jeff Brown3122e442010-10-11 23:32:49 -0700686 } else {
Jeff Browne20c9e02010-10-11 14:20:19 -0700687 policyFlags |= POLICY_FLAG_PASS_TO_USER;
688 }
689}
690
Jeff Brown56194eb2011-03-02 19:23:13 -0800691void NativeInputManager::interceptMotionBeforeQueueing(nsecs_t when, uint32_t& policyFlags) {
Jeff Brown3122e442010-10-11 23:32:49 -0700692 // Policy:
693 // - Ignore untrusted events and pass them along.
694 // - No special filtering for injected events required at this time.
695 // - Filter normal events based on screen state.
696 // - For normal events brighten (but do not wake) the screen if currently dim.
697 if ((policyFlags & POLICY_FLAG_TRUSTED) && !(policyFlags & POLICY_FLAG_INJECTED)) {
698 if (isScreenOn()) {
699 policyFlags |= POLICY_FLAG_PASS_TO_USER;
Jeff Browne20c9e02010-10-11 14:20:19 -0700700
Jeff Brown3122e442010-10-11 23:32:49 -0700701 if (!isScreenBright()) {
702 policyFlags |= POLICY_FLAG_BRIGHT_HERE;
703 }
Jeff Brown56194eb2011-03-02 19:23:13 -0800704 } else {
705 JNIEnv* env = jniEnv();
706 jint wmActions = env->CallIntMethod(mCallbacksObj,
707 gCallbacksClassInfo.interceptMotionBeforeQueueingWhenScreenOff,
708 policyFlags);
709 if (checkAndClearExceptionFromCallback(env,
710 "interceptMotionBeforeQueueingWhenScreenOff")) {
711 wmActions = 0;
712 }
713
714 policyFlags |= POLICY_FLAG_WOKE_HERE | POLICY_FLAG_BRIGHT_HERE;
715 handleInterceptActions(wmActions, when, /*byref*/ policyFlags);
Jeff Browne20c9e02010-10-11 14:20:19 -0700716 }
Jeff Brown3122e442010-10-11 23:32:49 -0700717 } else {
718 policyFlags |= POLICY_FLAG_PASS_TO_USER;
Jeff Browne20c9e02010-10-11 14:20:19 -0700719 }
720}
721
Jeff Brown56194eb2011-03-02 19:23:13 -0800722void NativeInputManager::handleInterceptActions(jint wmActions, nsecs_t when,
723 uint32_t& policyFlags) {
724 enum {
725 WM_ACTION_PASS_TO_USER = 1,
726 WM_ACTION_POKE_USER_ACTIVITY = 2,
727 WM_ACTION_GO_TO_SLEEP = 4,
728 };
729
730 if (wmActions & WM_ACTION_GO_TO_SLEEP) {
Jeff Brownb23bdf52011-03-07 20:11:22 -0800731#if DEBUG_INPUT_DISPATCHER_POLICY
Jeff Brown56194eb2011-03-02 19:23:13 -0800732 LOGD("handleInterceptActions: Going to sleep.");
733#endif
734 android_server_PowerManagerService_goToSleep(when);
735 }
736
737 if (wmActions & WM_ACTION_POKE_USER_ACTIVITY) {
Jeff Brownb23bdf52011-03-07 20:11:22 -0800738#if DEBUG_INPUT_DISPATCHER_POLICY
Jeff Brown56194eb2011-03-02 19:23:13 -0800739 LOGD("handleInterceptActions: Poking user activity.");
740#endif
741 android_server_PowerManagerService_userActivity(when, POWER_MANAGER_BUTTON_EVENT);
742 }
743
744 if (wmActions & WM_ACTION_PASS_TO_USER) {
745 policyFlags |= POLICY_FLAG_PASS_TO_USER;
746 } else {
Jeff Brownb23bdf52011-03-07 20:11:22 -0800747#if DEBUG_INPUT_DISPATCHER_POLICY
Jeff Brown56194eb2011-03-02 19:23:13 -0800748 LOGD("handleInterceptActions: Not passing key to user.");
749#endif
750 }
751}
752
Jeff Brown928e0542011-01-10 11:17:36 -0800753bool NativeInputManager::interceptKeyBeforeDispatching(
754 const sp<InputWindowHandle>& inputWindowHandle,
Jeff Browne20c9e02010-10-11 14:20:19 -0700755 const KeyEvent* keyEvent, uint32_t policyFlags) {
Jeff Brown3122e442010-10-11 23:32:49 -0700756 // Policy:
757 // - Ignore untrusted events and pass them along.
758 // - Filter normal events and trusted injected events through the window manager policy to
759 // handle the HOME key and the like.
Jeff Brown49ed71d2010-12-06 17:13:33 -0800760 bool result = false;
Jeff Brown3122e442010-10-11 23:32:49 -0700761 if (policyFlags & POLICY_FLAG_TRUSTED) {
762 JNIEnv* env = jniEnv();
Jeff Brownd0097872010-06-30 14:41:59 -0700763
Jeff Brown928e0542011-01-10 11:17:36 -0800764 // Note: inputWindowHandle may be null.
765 jobject inputWindowHandleObj = getInputWindowHandleObjLocalRef(env, inputWindowHandle);
Jeff Brown1f245102010-11-18 20:53:46 -0800766 jobject keyEventObj = android_view_KeyEvent_fromNative(env, keyEvent);
767 if (keyEventObj) {
768 jboolean consumed = env->CallBooleanMethod(mCallbacksObj,
769 gCallbacksClassInfo.interceptKeyBeforeDispatching,
Jeff Brown928e0542011-01-10 11:17:36 -0800770 inputWindowHandleObj, keyEventObj, policyFlags);
Jeff Brown1f245102010-11-18 20:53:46 -0800771 bool error = checkAndClearExceptionFromCallback(env, "interceptKeyBeforeDispatching");
772 android_view_KeyEvent_recycle(env, keyEventObj);
773 env->DeleteLocalRef(keyEventObj);
774 result = consumed && !error;
775 } else {
776 LOGE("Failed to obtain key event object for interceptKeyBeforeDispatching.");
Jeff Brown1f245102010-11-18 20:53:46 -0800777 }
Jeff Brown928e0542011-01-10 11:17:36 -0800778 env->DeleteLocalRef(inputWindowHandleObj);
Jeff Brown3122e442010-10-11 23:32:49 -0700779 }
Jeff Brown1f245102010-11-18 20:53:46 -0800780 return result;
Jeff Brownd0097872010-06-30 14:41:59 -0700781}
782
Jeff Brown928e0542011-01-10 11:17:36 -0800783bool NativeInputManager::dispatchUnhandledKey(const sp<InputWindowHandle>& inputWindowHandle,
Jeff Brown49ed71d2010-12-06 17:13:33 -0800784 const KeyEvent* keyEvent, uint32_t policyFlags, KeyEvent* outFallbackKeyEvent) {
Jeff Brown3915bb82010-11-05 15:02:16 -0700785 // Policy:
786 // - Ignore untrusted events and do not perform default handling.
Jeff Brown49ed71d2010-12-06 17:13:33 -0800787 bool result = false;
Jeff Brown3915bb82010-11-05 15:02:16 -0700788 if (policyFlags & POLICY_FLAG_TRUSTED) {
789 JNIEnv* env = jniEnv();
790
Jeff Brown928e0542011-01-10 11:17:36 -0800791 // Note: inputWindowHandle may be null.
792 jobject inputWindowHandleObj = getInputWindowHandleObjLocalRef(env, inputWindowHandle);
Jeff Brown1f245102010-11-18 20:53:46 -0800793 jobject keyEventObj = android_view_KeyEvent_fromNative(env, keyEvent);
794 if (keyEventObj) {
Jeff Brown49ed71d2010-12-06 17:13:33 -0800795 jobject fallbackKeyEventObj = env->CallObjectMethod(mCallbacksObj,
Jeff Brown1f245102010-11-18 20:53:46 -0800796 gCallbacksClassInfo.dispatchUnhandledKey,
Jeff Brown928e0542011-01-10 11:17:36 -0800797 inputWindowHandleObj, keyEventObj, policyFlags);
Jeff Brown524ee642011-03-29 15:11:34 -0700798 if (checkAndClearExceptionFromCallback(env, "dispatchUnhandledKey")) {
799 fallbackKeyEventObj = NULL;
800 }
Jeff Brown1f245102010-11-18 20:53:46 -0800801 android_view_KeyEvent_recycle(env, keyEventObj);
802 env->DeleteLocalRef(keyEventObj);
Jeff Brown49ed71d2010-12-06 17:13:33 -0800803
804 if (fallbackKeyEventObj) {
805 // Note: outFallbackKeyEvent may be the same object as keyEvent.
806 if (!android_view_KeyEvent_toNative(env, fallbackKeyEventObj,
807 outFallbackKeyEvent)) {
808 result = true;
809 }
810 android_view_KeyEvent_recycle(env, fallbackKeyEventObj);
811 env->DeleteLocalRef(fallbackKeyEventObj);
812 }
Jeff Brown1f245102010-11-18 20:53:46 -0800813 } else {
814 LOGE("Failed to obtain key event object for dispatchUnhandledKey.");
Jeff Brown1f245102010-11-18 20:53:46 -0800815 }
Jeff Brown928e0542011-01-10 11:17:36 -0800816 env->DeleteLocalRef(inputWindowHandleObj);
Jeff Brown3915bb82010-11-05 15:02:16 -0700817 }
Jeff Brown1f245102010-11-18 20:53:46 -0800818 return result;
Jeff Brown3915bb82010-11-05 15:02:16 -0700819}
820
Jeff Brown01ce2e92010-09-26 22:20:12 -0700821void NativeInputManager::pokeUserActivity(nsecs_t eventTime, int32_t eventType) {
822 android_server_PowerManagerService_userActivity(eventTime, eventType);
Jeff Brown349703e2010-06-22 01:27:15 -0700823}
824
Jeff Brown349703e2010-06-22 01:27:15 -0700825
Jeff Brownb88102f2010-09-08 11:49:43 -0700826bool NativeInputManager::checkInjectEventsPermissionNonReentrant(
827 int32_t injectorPid, int32_t injectorUid) {
828 JNIEnv* env = jniEnv();
829 jboolean result = env->CallBooleanMethod(mCallbacksObj,
830 gCallbacksClassInfo.checkInjectEventsPermission, injectorPid, injectorUid);
Jeff Brown524ee642011-03-29 15:11:34 -0700831 if (checkAndClearExceptionFromCallback(env, "checkInjectEventsPermission")) {
832 result = false;
833 }
Jeff Brown349703e2010-06-22 01:27:15 -0700834 return result;
835}
836
Jeff Brown83c09682010-12-23 17:50:18 -0800837
Jeff Brown9c3cda02010-06-15 01:31:58 -0700838// ----------------------------------------------------------------------------
839
840static sp<NativeInputManager> gNativeInputManager;
841
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700842static bool checkInputManagerUnitialized(JNIEnv* env) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700843 if (gNativeInputManager == NULL) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700844 LOGE("Input manager not initialized.");
845 jniThrowRuntimeException(env, "Input manager not initialized.");
846 return true;
847 }
848 return false;
849}
850
851static void android_server_InputManager_nativeInit(JNIEnv* env, jclass clazz,
Jeff Brown05dc66a2011-03-02 14:41:58 -0800852 jobject callbacks, jobject messageQueueObj) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700853 if (gNativeInputManager == NULL) {
Jeff Brown05dc66a2011-03-02 14:41:58 -0800854 sp<Looper> looper = android_os_MessageQueue_getLooper(env, messageQueueObj);
855 gNativeInputManager = new NativeInputManager(callbacks, looper);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700856 } else {
857 LOGE("Input manager already initialized.");
858 jniThrowRuntimeException(env, "Input manager already initialized.");
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700859 }
860}
861
862static void android_server_InputManager_nativeStart(JNIEnv* env, jclass clazz) {
863 if (checkInputManagerUnitialized(env)) {
864 return;
865 }
866
Jeff Brown9c3cda02010-06-15 01:31:58 -0700867 status_t result = gNativeInputManager->getInputManager()->start();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700868 if (result) {
869 jniThrowRuntimeException(env, "Input manager could not be started.");
870 }
871}
872
873static void android_server_InputManager_nativeSetDisplaySize(JNIEnv* env, jclass clazz,
874 jint displayId, jint width, jint height) {
875 if (checkInputManagerUnitialized(env)) {
876 return;
877 }
878
879 // XXX we could get this from the SurfaceFlinger directly instead of requiring it
880 // to be passed in like this, not sure which is better but leaving it like this
881 // keeps the window manager in direct control of when display transitions propagate down
882 // to the input dispatcher
Jeff Brown9c3cda02010-06-15 01:31:58 -0700883 gNativeInputManager->setDisplaySize(displayId, width, height);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700884}
885
886static void android_server_InputManager_nativeSetDisplayOrientation(JNIEnv* env, jclass clazz,
887 jint displayId, jint orientation) {
888 if (checkInputManagerUnitialized(env)) {
889 return;
890 }
891
Jeff Brown9c3cda02010-06-15 01:31:58 -0700892 gNativeInputManager->setDisplayOrientation(displayId, orientation);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700893}
894
895static jint android_server_InputManager_nativeGetScanCodeState(JNIEnv* env, jclass clazz,
Jeff Brown6d0fec22010-07-23 21:28:06 -0700896 jint deviceId, jint sourceMask, jint scanCode) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700897 if (checkInputManagerUnitialized(env)) {
Jeff Brownc5ed5912010-07-14 18:48:53 -0700898 return AKEY_STATE_UNKNOWN;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700899 }
900
Jeff Brownb88102f2010-09-08 11:49:43 -0700901 return gNativeInputManager->getInputManager()->getReader()->getScanCodeState(
Jeff Brown6d0fec22010-07-23 21:28:06 -0700902 deviceId, uint32_t(sourceMask), scanCode);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700903}
904
905static jint android_server_InputManager_nativeGetKeyCodeState(JNIEnv* env, jclass clazz,
Jeff Brown6d0fec22010-07-23 21:28:06 -0700906 jint deviceId, jint sourceMask, jint keyCode) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700907 if (checkInputManagerUnitialized(env)) {
Jeff Brownc5ed5912010-07-14 18:48:53 -0700908 return AKEY_STATE_UNKNOWN;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700909 }
910
Jeff Brownb88102f2010-09-08 11:49:43 -0700911 return gNativeInputManager->getInputManager()->getReader()->getKeyCodeState(
Jeff Brown6d0fec22010-07-23 21:28:06 -0700912 deviceId, uint32_t(sourceMask), keyCode);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700913}
914
915static jint android_server_InputManager_nativeGetSwitchState(JNIEnv* env, jclass clazz,
Jeff Brown6d0fec22010-07-23 21:28:06 -0700916 jint deviceId, jint sourceMask, jint sw) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700917 if (checkInputManagerUnitialized(env)) {
Jeff Brownc5ed5912010-07-14 18:48:53 -0700918 return AKEY_STATE_UNKNOWN;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700919 }
920
Jeff Brownb88102f2010-09-08 11:49:43 -0700921 return gNativeInputManager->getInputManager()->getReader()->getSwitchState(
Jeff Brown6d0fec22010-07-23 21:28:06 -0700922 deviceId, uint32_t(sourceMask), sw);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700923}
924
925static jboolean android_server_InputManager_nativeHasKeys(JNIEnv* env, jclass clazz,
Jeff Brown6d0fec22010-07-23 21:28:06 -0700926 jint deviceId, jint sourceMask, jintArray keyCodes, jbooleanArray outFlags) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700927 if (checkInputManagerUnitialized(env)) {
928 return JNI_FALSE;
929 }
930
931 int32_t* codes = env->GetIntArrayElements(keyCodes, NULL);
932 uint8_t* flags = env->GetBooleanArrayElements(outFlags, NULL);
933 jsize numCodes = env->GetArrayLength(keyCodes);
934 jboolean result;
Jeff Brown6d0fec22010-07-23 21:28:06 -0700935 if (numCodes == env->GetArrayLength(keyCodes)) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700936 result = gNativeInputManager->getInputManager()->getReader()->hasKeys(
Jeff Brown6d0fec22010-07-23 21:28:06 -0700937 deviceId, uint32_t(sourceMask), numCodes, codes, flags);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700938 } else {
939 result = JNI_FALSE;
940 }
941
942 env->ReleaseBooleanArrayElements(outFlags, flags, 0);
943 env->ReleaseIntArrayElements(keyCodes, codes, 0);
944 return result;
945}
946
947static void throwInputChannelNotInitialized(JNIEnv* env) {
948 jniThrowException(env, "java/lang/IllegalStateException",
949 "inputChannel is not initialized");
950}
951
952static void android_server_InputManager_handleInputChannelDisposed(JNIEnv* env,
953 jobject inputChannelObj, const sp<InputChannel>& inputChannel, void* data) {
954 LOGW("Input channel object '%s' was disposed without first being unregistered with "
955 "the input manager!", inputChannel->getName().string());
956
Jeff Brown9c3cda02010-06-15 01:31:58 -0700957 if (gNativeInputManager != NULL) {
Jeff Brown7fbdc842010-06-17 20:52:56 -0700958 gNativeInputManager->unregisterInputChannel(env, inputChannel);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700959 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700960}
961
962static void android_server_InputManager_nativeRegisterInputChannel(JNIEnv* env, jclass clazz,
Jeff Brown928e0542011-01-10 11:17:36 -0800963 jobject inputChannelObj, jobject inputWindowHandleObj, jboolean monitor) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700964 if (checkInputManagerUnitialized(env)) {
965 return;
966 }
967
968 sp<InputChannel> inputChannel = android_view_InputChannel_getInputChannel(env,
969 inputChannelObj);
970 if (inputChannel == NULL) {
971 throwInputChannelNotInitialized(env);
972 return;
973 }
974
Jeff Brown928e0542011-01-10 11:17:36 -0800975 sp<InputWindowHandle> inputWindowHandle =
976 android_server_InputWindowHandle_getHandle(env, inputWindowHandleObj);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700977
978 status_t status = gNativeInputManager->registerInputChannel(
Jeff Brown928e0542011-01-10 11:17:36 -0800979 env, inputChannel, inputWindowHandle, monitor);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700980 if (status) {
981 jniThrowRuntimeException(env, "Failed to register input channel. "
982 "Check logs for details.");
983 return;
984 }
985
Jeff Browna41ca772010-08-11 14:46:32 -0700986 if (! monitor) {
987 android_view_InputChannel_setDisposeCallback(env, inputChannelObj,
988 android_server_InputManager_handleInputChannelDisposed, NULL);
989 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700990}
991
992static void android_server_InputManager_nativeUnregisterInputChannel(JNIEnv* env, jclass clazz,
993 jobject inputChannelObj) {
994 if (checkInputManagerUnitialized(env)) {
995 return;
996 }
997
998 sp<InputChannel> inputChannel = android_view_InputChannel_getInputChannel(env,
999 inputChannelObj);
1000 if (inputChannel == NULL) {
1001 throwInputChannelNotInitialized(env);
1002 return;
1003 }
1004
1005 android_view_InputChannel_setDisposeCallback(env, inputChannelObj, NULL, NULL);
1006
Jeff Brown7fbdc842010-06-17 20:52:56 -07001007 status_t status = gNativeInputManager->unregisterInputChannel(env, inputChannel);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001008 if (status) {
1009 jniThrowRuntimeException(env, "Failed to unregister input channel. "
1010 "Check logs for details.");
1011 }
1012}
1013
Jeff Brown6ec402b2010-07-28 15:48:59 -07001014static jint android_server_InputManager_nativeInjectInputEvent(JNIEnv* env, jclass clazz,
1015 jobject inputEventObj, jint injectorPid, jint injectorUid,
1016 jint syncMode, jint timeoutMillis) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07001017 if (checkInputManagerUnitialized(env)) {
1018 return INPUT_EVENT_INJECTION_FAILED;
1019 }
1020
Jeff Brown6ec402b2010-07-28 15:48:59 -07001021 if (env->IsInstanceOf(inputEventObj, gKeyEventClassInfo.clazz)) {
1022 KeyEvent keyEvent;
Jeff Brown1f245102010-11-18 20:53:46 -08001023 status_t status = android_view_KeyEvent_toNative(env, inputEventObj, & keyEvent);
1024 if (status) {
1025 jniThrowRuntimeException(env, "Could not read contents of KeyEvent object.");
1026 return INPUT_EVENT_INJECTION_FAILED;
1027 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07001028
Jeff Brownb88102f2010-09-08 11:49:43 -07001029 return gNativeInputManager->getInputManager()->getDispatcher()->injectInputEvent(
1030 & keyEvent, injectorPid, injectorUid, syncMode, timeoutMillis);
Jeff Brown6ec402b2010-07-28 15:48:59 -07001031 } else if (env->IsInstanceOf(inputEventObj, gMotionEventClassInfo.clazz)) {
Jeff Brown5b2b4d92011-03-14 19:39:54 -07001032 const MotionEvent* motionEvent = android_view_MotionEvent_getNativePtr(env, inputEventObj);
1033 if (!motionEvent) {
Jeff Brown1f245102010-11-18 20:53:46 -08001034 jniThrowRuntimeException(env, "Could not read contents of MotionEvent object.");
1035 return INPUT_EVENT_INJECTION_FAILED;
1036 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07001037
Jeff Brownb88102f2010-09-08 11:49:43 -07001038 return gNativeInputManager->getInputManager()->getDispatcher()->injectInputEvent(
Jeff Brown5b2b4d92011-03-14 19:39:54 -07001039 motionEvent, injectorPid, injectorUid, syncMode, timeoutMillis);
Jeff Brown6ec402b2010-07-28 15:48:59 -07001040 } else {
1041 jniThrowRuntimeException(env, "Invalid input event type.");
Jeff Brown7fbdc842010-06-17 20:52:56 -07001042 return INPUT_EVENT_INJECTION_FAILED;
1043 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07001044}
1045
Jeff Brown349703e2010-06-22 01:27:15 -07001046static void android_server_InputManager_nativeSetInputWindows(JNIEnv* env, jclass clazz,
1047 jobjectArray windowObjArray) {
1048 if (checkInputManagerUnitialized(env)) {
1049 return;
1050 }
1051
1052 gNativeInputManager->setInputWindows(env, windowObjArray);
1053}
1054
1055static void android_server_InputManager_nativeSetFocusedApplication(JNIEnv* env, jclass clazz,
1056 jobject applicationObj) {
1057 if (checkInputManagerUnitialized(env)) {
1058 return;
1059 }
1060
1061 gNativeInputManager->setFocusedApplication(env, applicationObj);
1062}
1063
1064static void android_server_InputManager_nativeSetInputDispatchMode(JNIEnv* env,
1065 jclass clazz, jboolean enabled, jboolean frozen) {
1066 if (checkInputManagerUnitialized(env)) {
1067 return;
1068 }
1069
1070 gNativeInputManager->setInputDispatchMode(enabled, frozen);
1071}
1072
Jeff Brown05dc66a2011-03-02 14:41:58 -08001073static void android_server_InputManager_nativeSetSystemUiVisibility(JNIEnv* env,
1074 jclass clazz, jint visibility) {
1075 if (checkInputManagerUnitialized(env)) {
1076 return;
1077 }
1078
1079 gNativeInputManager->setSystemUiVisibility(visibility);
1080}
1081
Jeff Brown8d608662010-08-30 03:02:23 -07001082static jobject android_server_InputManager_nativeGetInputDevice(JNIEnv* env,
1083 jclass clazz, jint deviceId) {
1084 if (checkInputManagerUnitialized(env)) {
1085 return NULL;
1086 }
1087
1088 InputDeviceInfo deviceInfo;
Jeff Brownb88102f2010-09-08 11:49:43 -07001089 status_t status = gNativeInputManager->getInputManager()->getReader()->getInputDeviceInfo(
Jeff Brown8d608662010-08-30 03:02:23 -07001090 deviceId, & deviceInfo);
1091 if (status) {
1092 return NULL;
1093 }
1094
1095 jobject deviceObj = env->NewObject(gInputDeviceClassInfo.clazz, gInputDeviceClassInfo.ctor);
1096 if (! deviceObj) {
1097 return NULL;
1098 }
1099
1100 jstring deviceNameObj = env->NewStringUTF(deviceInfo.getName().string());
1101 if (! deviceNameObj) {
1102 return NULL;
1103 }
1104
1105 env->SetIntField(deviceObj, gInputDeviceClassInfo.mId, deviceInfo.getId());
1106 env->SetObjectField(deviceObj, gInputDeviceClassInfo.mName, deviceNameObj);
1107 env->SetIntField(deviceObj, gInputDeviceClassInfo.mSources, deviceInfo.getSources());
1108 env->SetIntField(deviceObj, gInputDeviceClassInfo.mKeyboardType, deviceInfo.getKeyboardType());
1109
Jeff Brownefd32662011-03-08 15:13:06 -08001110 const Vector<InputDeviceInfo::MotionRange>& ranges = deviceInfo.getMotionRanges();
Jeff Brown8d608662010-08-30 03:02:23 -07001111 for (size_t i = 0; i < ranges.size(); i++) {
Jeff Brownefd32662011-03-08 15:13:06 -08001112 const InputDeviceInfo::MotionRange& range = ranges.itemAt(i);
Jeff Brown8d608662010-08-30 03:02:23 -07001113 env->CallVoidMethod(deviceObj, gInputDeviceClassInfo.addMotionRange,
Jeff Brownefd32662011-03-08 15:13:06 -08001114 range.axis, range.source, range.min, range.max, range.flat, range.fuzz);
Jeff Brown8d608662010-08-30 03:02:23 -07001115 if (env->ExceptionCheck()) {
1116 return NULL;
1117 }
1118 }
1119
1120 return deviceObj;
1121}
1122
1123static jintArray android_server_InputManager_nativeGetInputDeviceIds(JNIEnv* env,
1124 jclass clazz) {
1125 if (checkInputManagerUnitialized(env)) {
1126 return NULL;
1127 }
1128
1129 Vector<int> deviceIds;
Jeff Brownb88102f2010-09-08 11:49:43 -07001130 gNativeInputManager->getInputManager()->getReader()->getInputDeviceIds(deviceIds);
Jeff Brown8d608662010-08-30 03:02:23 -07001131
1132 jintArray deviceIdsObj = env->NewIntArray(deviceIds.size());
1133 if (! deviceIdsObj) {
1134 return NULL;
1135 }
1136
1137 env->SetIntArrayRegion(deviceIdsObj, 0, deviceIds.size(), deviceIds.array());
1138 return deviceIdsObj;
1139}
1140
Jeff Brown57c59372010-09-21 18:22:55 -07001141static void android_server_InputManager_nativeGetInputConfiguration(JNIEnv* env,
1142 jclass clazz, jobject configObj) {
1143 if (checkInputManagerUnitialized(env)) {
1144 return;
1145 }
1146
1147 InputConfiguration config;
1148 gNativeInputManager->getInputManager()->getReader()->getInputConfiguration(& config);
1149
1150 env->SetIntField(configObj, gConfigurationClassInfo.touchscreen, config.touchScreen);
1151 env->SetIntField(configObj, gConfigurationClassInfo.keyboard, config.keyboard);
1152 env->SetIntField(configObj, gConfigurationClassInfo.navigation, config.navigation);
1153}
1154
Jeff Browne6504122010-09-27 14:52:15 -07001155static jboolean android_server_InputManager_nativeTransferTouchFocus(JNIEnv* env,
1156 jclass clazz, jobject fromChannelObj, jobject toChannelObj) {
1157 if (checkInputManagerUnitialized(env)) {
1158 return false;
1159 }
1160
1161 sp<InputChannel> fromChannel =
1162 android_view_InputChannel_getInputChannel(env, fromChannelObj);
1163 sp<InputChannel> toChannel =
1164 android_view_InputChannel_getInputChannel(env, toChannelObj);
1165
1166 if (fromChannel == NULL || toChannel == NULL) {
1167 return false;
1168 }
1169
1170 return gNativeInputManager->getInputManager()->getDispatcher()->
1171 transferTouchFocus(fromChannel, toChannel);
1172}
1173
Jeff Browne33348b2010-07-15 23:54:05 -07001174static jstring android_server_InputManager_nativeDump(JNIEnv* env, jclass clazz) {
1175 if (checkInputManagerUnitialized(env)) {
1176 return NULL;
1177 }
1178
Jeff Brownb88102f2010-09-08 11:49:43 -07001179 String8 dump;
1180 gNativeInputManager->dump(dump);
Jeff Browne33348b2010-07-15 23:54:05 -07001181 return env->NewStringUTF(dump.string());
1182}
1183
Jeff Brown9c3cda02010-06-15 01:31:58 -07001184// ----------------------------------------------------------------------------
1185
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001186static JNINativeMethod gInputManagerMethods[] = {
1187 /* name, signature, funcPtr */
Jeff Brown05dc66a2011-03-02 14:41:58 -08001188 { "nativeInit", "(Lcom/android/server/wm/InputManager$Callbacks;Landroid/os/MessageQueue;)V",
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001189 (void*) android_server_InputManager_nativeInit },
1190 { "nativeStart", "()V",
1191 (void*) android_server_InputManager_nativeStart },
1192 { "nativeSetDisplaySize", "(III)V",
1193 (void*) android_server_InputManager_nativeSetDisplaySize },
1194 { "nativeSetDisplayOrientation", "(II)V",
1195 (void*) android_server_InputManager_nativeSetDisplayOrientation },
1196 { "nativeGetScanCodeState", "(III)I",
1197 (void*) android_server_InputManager_nativeGetScanCodeState },
1198 { "nativeGetKeyCodeState", "(III)I",
1199 (void*) android_server_InputManager_nativeGetKeyCodeState },
1200 { "nativeGetSwitchState", "(III)I",
1201 (void*) android_server_InputManager_nativeGetSwitchState },
Jeff Brown6d0fec22010-07-23 21:28:06 -07001202 { "nativeHasKeys", "(II[I[Z)Z",
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001203 (void*) android_server_InputManager_nativeHasKeys },
Jeff Brown928e0542011-01-10 11:17:36 -08001204 { "nativeRegisterInputChannel",
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001205 "(Landroid/view/InputChannel;Lcom/android/server/wm/InputWindowHandle;Z)V",
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001206 (void*) android_server_InputManager_nativeRegisterInputChannel },
1207 { "nativeUnregisterInputChannel", "(Landroid/view/InputChannel;)V",
Jeff Brown7fbdc842010-06-17 20:52:56 -07001208 (void*) android_server_InputManager_nativeUnregisterInputChannel },
Jeff Brown6ec402b2010-07-28 15:48:59 -07001209 { "nativeInjectInputEvent", "(Landroid/view/InputEvent;IIII)I",
1210 (void*) android_server_InputManager_nativeInjectInputEvent },
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001211 { "nativeSetInputWindows", "([Lcom/android/server/wm/InputWindow;)V",
Jeff Brown349703e2010-06-22 01:27:15 -07001212 (void*) android_server_InputManager_nativeSetInputWindows },
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001213 { "nativeSetFocusedApplication", "(Lcom/android/server/wm/InputApplication;)V",
Jeff Brown349703e2010-06-22 01:27:15 -07001214 (void*) android_server_InputManager_nativeSetFocusedApplication },
1215 { "nativeSetInputDispatchMode", "(ZZ)V",
1216 (void*) android_server_InputManager_nativeSetInputDispatchMode },
Jeff Brown05dc66a2011-03-02 14:41:58 -08001217 { "nativeSetSystemUiVisibility", "(I)V",
1218 (void*) android_server_InputManager_nativeSetSystemUiVisibility },
Jeff Brown8d608662010-08-30 03:02:23 -07001219 { "nativeGetInputDevice", "(I)Landroid/view/InputDevice;",
1220 (void*) android_server_InputManager_nativeGetInputDevice },
1221 { "nativeGetInputDeviceIds", "()[I",
1222 (void*) android_server_InputManager_nativeGetInputDeviceIds },
Jeff Brown57c59372010-09-21 18:22:55 -07001223 { "nativeGetInputConfiguration", "(Landroid/content/res/Configuration;)V",
1224 (void*) android_server_InputManager_nativeGetInputConfiguration },
Jeff Browne6504122010-09-27 14:52:15 -07001225 { "nativeTransferTouchFocus", "(Landroid/view/InputChannel;Landroid/view/InputChannel;)Z",
1226 (void*) android_server_InputManager_nativeTransferTouchFocus },
Jeff Browne33348b2010-07-15 23:54:05 -07001227 { "nativeDump", "()Ljava/lang/String;",
1228 (void*) android_server_InputManager_nativeDump },
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001229};
1230
1231#define FIND_CLASS(var, className) \
1232 var = env->FindClass(className); \
1233 LOG_FATAL_IF(! var, "Unable to find class " className); \
1234 var = jclass(env->NewGlobalRef(var));
1235
1236#define GET_METHOD_ID(var, clazz, methodName, methodDescriptor) \
1237 var = env->GetMethodID(clazz, methodName, methodDescriptor); \
1238 LOG_FATAL_IF(! var, "Unable to find method " methodName);
1239
1240#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \
1241 var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \
1242 LOG_FATAL_IF(! var, "Unable to find field " fieldName);
1243
1244int register_android_server_InputManager(JNIEnv* env) {
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001245 int res = jniRegisterNativeMethods(env, "com/android/server/wm/InputManager",
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001246 gInputManagerMethods, NELEM(gInputManagerMethods));
1247 LOG_FATAL_IF(res < 0, "Unable to register native methods.");
1248
Jeff Brown9c3cda02010-06-15 01:31:58 -07001249 // Callbacks
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001250
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001251 FIND_CLASS(gCallbacksClassInfo.clazz, "com/android/server/wm/InputManager$Callbacks");
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001252
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001253 GET_METHOD_ID(gCallbacksClassInfo.notifyConfigurationChanged, gCallbacksClassInfo.clazz,
Jeff Brown57c59372010-09-21 18:22:55 -07001254 "notifyConfigurationChanged", "(J)V");
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001255
1256 GET_METHOD_ID(gCallbacksClassInfo.notifyLidSwitchChanged, gCallbacksClassInfo.clazz,
1257 "notifyLidSwitchChanged", "(JZ)V");
1258
Jeff Brown7fbdc842010-06-17 20:52:56 -07001259 GET_METHOD_ID(gCallbacksClassInfo.notifyInputChannelBroken, gCallbacksClassInfo.clazz,
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001260 "notifyInputChannelBroken", "(Lcom/android/server/wm/InputWindowHandle;)V");
Jeff Brown7fbdc842010-06-17 20:52:56 -07001261
Jeff Brown349703e2010-06-22 01:27:15 -07001262 GET_METHOD_ID(gCallbacksClassInfo.notifyANR, gCallbacksClassInfo.clazz,
Jeff Brown928e0542011-01-10 11:17:36 -08001263 "notifyANR",
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001264 "(Lcom/android/server/wm/InputApplicationHandle;Lcom/android/server/wm/InputWindowHandle;)J");
Jeff Brown349703e2010-06-22 01:27:15 -07001265
Jeff Brown349703e2010-06-22 01:27:15 -07001266 GET_METHOD_ID(gCallbacksClassInfo.interceptKeyBeforeQueueing, gCallbacksClassInfo.clazz,
Jeff Brown1f245102010-11-18 20:53:46 -08001267 "interceptKeyBeforeQueueing", "(Landroid/view/KeyEvent;IZ)I");
Jeff Brown349703e2010-06-22 01:27:15 -07001268
Jeff Brown56194eb2011-03-02 19:23:13 -08001269 GET_METHOD_ID(gCallbacksClassInfo.interceptMotionBeforeQueueingWhenScreenOff,
1270 gCallbacksClassInfo.clazz,
1271 "interceptMotionBeforeQueueingWhenScreenOff", "(I)I");
1272
Jeff Brown349703e2010-06-22 01:27:15 -07001273 GET_METHOD_ID(gCallbacksClassInfo.interceptKeyBeforeDispatching, gCallbacksClassInfo.clazz,
Jeff Brown1f245102010-11-18 20:53:46 -08001274 "interceptKeyBeforeDispatching",
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001275 "(Lcom/android/server/wm/InputWindowHandle;Landroid/view/KeyEvent;I)Z");
Jeff Brown349703e2010-06-22 01:27:15 -07001276
Jeff Brown3915bb82010-11-05 15:02:16 -07001277 GET_METHOD_ID(gCallbacksClassInfo.dispatchUnhandledKey, gCallbacksClassInfo.clazz,
Jeff Brown49ed71d2010-12-06 17:13:33 -08001278 "dispatchUnhandledKey",
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001279 "(Lcom/android/server/wm/InputWindowHandle;Landroid/view/KeyEvent;I)Landroid/view/KeyEvent;");
Jeff Brown3915bb82010-11-05 15:02:16 -07001280
Jeff Brown349703e2010-06-22 01:27:15 -07001281 GET_METHOD_ID(gCallbacksClassInfo.checkInjectEventsPermission, gCallbacksClassInfo.clazz,
1282 "checkInjectEventsPermission", "(II)Z");
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001283
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001284 GET_METHOD_ID(gCallbacksClassInfo.filterTouchEvents, gCallbacksClassInfo.clazz,
1285 "filterTouchEvents", "()Z");
1286
1287 GET_METHOD_ID(gCallbacksClassInfo.filterJumpyTouchEvents, gCallbacksClassInfo.clazz,
1288 "filterJumpyTouchEvents", "()Z");
1289
Jeff Brownfe508922011-01-18 15:10:10 -08001290 GET_METHOD_ID(gCallbacksClassInfo.getVirtualKeyQuietTimeMillis, gCallbacksClassInfo.clazz,
1291 "getVirtualKeyQuietTimeMillis", "()I");
1292
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001293 GET_METHOD_ID(gCallbacksClassInfo.getExcludedDeviceNames, gCallbacksClassInfo.clazz,
1294 "getExcludedDeviceNames", "()[Ljava/lang/String;");
1295
Jeff Browna4547672011-03-02 21:38:11 -08001296 GET_METHOD_ID(gCallbacksClassInfo.getKeyRepeatTimeout, gCallbacksClassInfo.clazz,
1297 "getKeyRepeatTimeout", "()I");
1298
1299 GET_METHOD_ID(gCallbacksClassInfo.getKeyRepeatDelay, gCallbacksClassInfo.clazz,
1300 "getKeyRepeatDelay", "()I");
1301
Jeff Brownae9fc032010-08-18 15:51:08 -07001302 GET_METHOD_ID(gCallbacksClassInfo.getMaxEventsPerSecond, gCallbacksClassInfo.clazz,
1303 "getMaxEventsPerSecond", "()I");
1304
Jeff Brown83c09682010-12-23 17:50:18 -08001305 GET_METHOD_ID(gCallbacksClassInfo.getPointerLayer, gCallbacksClassInfo.clazz,
1306 "getPointerLayer", "()I");
1307
Jeff Brownb4ff35d2011-01-02 16:37:43 -08001308 GET_METHOD_ID(gCallbacksClassInfo.getPointerIcon, gCallbacksClassInfo.clazz,
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001309 "getPointerIcon", "()Lcom/android/server/wm/InputManager$PointerIcon;");
Jeff Brownb4ff35d2011-01-02 16:37:43 -08001310
Jeff Brown6ec402b2010-07-28 15:48:59 -07001311 // KeyEvent
1312
1313 FIND_CLASS(gKeyEventClassInfo.clazz, "android/view/KeyEvent");
1314
Jeff Brown8d608662010-08-30 03:02:23 -07001315 // MotionEvent
Jeff Brown6ec402b2010-07-28 15:48:59 -07001316
1317 FIND_CLASS(gMotionEventClassInfo.clazz, "android/view/MotionEvent");
1318
Jeff Brown8d608662010-08-30 03:02:23 -07001319 // InputDevice
1320
1321 FIND_CLASS(gInputDeviceClassInfo.clazz, "android/view/InputDevice");
1322
1323 GET_METHOD_ID(gInputDeviceClassInfo.ctor, gInputDeviceClassInfo.clazz,
1324 "<init>", "()V");
1325
1326 GET_METHOD_ID(gInputDeviceClassInfo.addMotionRange, gInputDeviceClassInfo.clazz,
Jeff Brownefd32662011-03-08 15:13:06 -08001327 "addMotionRange", "(IIFFFF)V");
Jeff Brown8d608662010-08-30 03:02:23 -07001328
1329 GET_FIELD_ID(gInputDeviceClassInfo.mId, gInputDeviceClassInfo.clazz,
1330 "mId", "I");
1331
1332 GET_FIELD_ID(gInputDeviceClassInfo.mName, gInputDeviceClassInfo.clazz,
1333 "mName", "Ljava/lang/String;");
1334
1335 GET_FIELD_ID(gInputDeviceClassInfo.mSources, gInputDeviceClassInfo.clazz,
1336 "mSources", "I");
1337
1338 GET_FIELD_ID(gInputDeviceClassInfo.mKeyboardType, gInputDeviceClassInfo.clazz,
1339 "mKeyboardType", "I");
1340
Jeff Brown57c59372010-09-21 18:22:55 -07001341 // Configuration
1342
1343 FIND_CLASS(gConfigurationClassInfo.clazz, "android/content/res/Configuration");
1344
1345 GET_FIELD_ID(gConfigurationClassInfo.touchscreen, gConfigurationClassInfo.clazz,
1346 "touchscreen", "I");
1347
1348 GET_FIELD_ID(gConfigurationClassInfo.keyboard, gConfigurationClassInfo.clazz,
1349 "keyboard", "I");
1350
1351 GET_FIELD_ID(gConfigurationClassInfo.navigation, gConfigurationClassInfo.clazz,
1352 "navigation", "I");
1353
Jeff Brownb4ff35d2011-01-02 16:37:43 -08001354 // PointerIcon
1355
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001356 FIND_CLASS(gPointerIconClassInfo.clazz, "com/android/server/wm/InputManager$PointerIcon");
Jeff Brownb4ff35d2011-01-02 16:37:43 -08001357
1358 GET_FIELD_ID(gPointerIconClassInfo.bitmap, gPointerIconClassInfo.clazz,
1359 "bitmap", "Landroid/graphics/Bitmap;");
1360
1361 GET_FIELD_ID(gPointerIconClassInfo.hotSpotX, gPointerIconClassInfo.clazz,
1362 "hotSpotX", "F");
1363
1364 GET_FIELD_ID(gPointerIconClassInfo.hotSpotY, gPointerIconClassInfo.clazz,
1365 "hotSpotY", "F");
1366
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001367 return 0;
1368}
1369
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001370} /* namespace android */