diff options
author | Jeff Brown <jeffbrown@google.com> | 2010-06-17 20:52:56 -0700 |
---|---|---|
committer | Jeff Brown <jeffbrown@google.com> | 2010-06-21 13:59:34 -0700 |
commit | 7fbdc84e87dd3a0e196b9803bb04495d11e9cb8a (patch) | |
tree | 32691f639ef71365b602795db215f11f457397a5 /services/java/com/android/server/InputManager.java | |
parent | e47e3f3855a062ba0338a57eeda2f12a0f7a1fa8 (diff) |
More native input event dispatching.
Added ANRs handling.
Added event injection.
Fixed a NPE ActivityManagerServer writing ANRs to the drop box.
Fixed HOME key interception.
Fixed trackball reporting.
Fixed pointer rotation in landscape mode.
Change-Id: I50340f559f22899ab924e220a78119ffc79469b7
Diffstat (limited to 'services/java/com/android/server/InputManager.java')
-rw-r--r-- | services/java/com/android/server/InputManager.java | 114 |
1 files changed, 81 insertions, 33 deletions
diff --git a/services/java/com/android/server/InputManager.java b/services/java/com/android/server/InputManager.java index 72c4166f28c0..8d9bb2940ab2 100644 --- a/services/java/com/android/server/InputManager.java +++ b/services/java/com/android/server/InputManager.java @@ -81,6 +81,10 @@ public class InputManager { private static native boolean nativeHasKeys(int[] keyCodes, boolean[] keyExists); private static native void nativeRegisterInputChannel(InputChannel inputChannel); private static native void nativeUnregisterInputChannel(InputChannel inputChannel); + private static native int nativeInjectKeyEvent(KeyEvent event, int nature, + int injectorPid, int injectorUid, boolean sync, int timeoutMillis); + private static native int nativeInjectMotionEvent(MotionEvent event, int nature, + int injectorPid, int injectorUid, boolean sync, int timeoutMillis); // Device class as defined by EventHub. private static final int CLASS_KEYBOARD = 0x00000001; @@ -90,6 +94,12 @@ public class InputManager { private static final int CLASS_TOUCHSCREEN_MT = 0x00000010; private static final int CLASS_DPAD = 0x00000020; + // Input event injection constants defined in InputDispatcher.h. + static final int INPUT_EVENT_INJECTION_SUCCEEDED = 0; + static final int INPUT_EVENT_INJECTION_PERMISSION_DENIED = 1; + static final int INPUT_EVENT_INJECTION_FAILED = 2; + static final int INPUT_EVENT_INJECTION_TIMED_OUT = 3; + public InputManager(Context context, WindowManagerService windowManagerService, WindowManagerPolicy windowManagerPolicy, @@ -215,37 +225,63 @@ public class InputManager { nativeUnregisterInputChannel(inputChannel); } - // TBD where this really belongs, duplicate copy in WindowManagerService - static final int INJECT_FAILED = 0; - static final int INJECT_SUCCEEDED = 1; - static final int INJECT_NO_PERMISSION = -1; - /** * Injects a key event into the event system on behalf of an application. + * This method may block even if sync is false because it must wait for previous events + * to be dispatched before it can determine whether input event injection will be + * permitted based on the current input focus. * @param event The event to inject. * @param nature The nature of the event. + * @param injectorPid The pid of the injecting application. + * @param injectorUid The uid of the injecting application. * @param sync If true, waits for the event to be completed before returning. - * @param pid The pid of the injecting application. - * @param uid The uid of the injecting application. - * @return INJECT_SUCCEEDED, INJECT_FAILED or INJECT_NO_PERMISSION + * @param timeoutMillis The injection timeout in milliseconds. + * @return One of the INPUT_EVENT_INJECTION_XXX constants. */ - public int injectKeyEvent(KeyEvent event, int nature, boolean sync, int pid, int uid) { - // TODO - return INJECT_FAILED; + public int injectKeyEvent(KeyEvent event, int nature, int injectorPid, int injectorUid, + boolean sync, int timeoutMillis) { + if (event == null) { + throw new IllegalArgumentException("event must not be null"); + } + if (injectorPid < 0 || injectorUid < 0) { + throw new IllegalArgumentException("injectorPid and injectorUid must not be negative."); + } + if (timeoutMillis <= 0) { + throw new IllegalArgumentException("timeoutMillis must be positive"); + } + + return nativeInjectKeyEvent(event, nature, injectorPid, injectorUid, + sync, timeoutMillis); } /** * Injects a motion event into the event system on behalf of an application. + * This method may block even if sync is false because it must wait for previous events + * to be dispatched before it can determine whether input event injection will be + * permitted based on the current input focus. * @param event The event to inject. * @param nature The nature of the event. * @param sync If true, waits for the event to be completed before returning. - * @param pid The pid of the injecting application. - * @param uid The uid of the injecting application. - * @return INJECT_SUCCEEDED, INJECT_FAILED or INJECT_NO_PERMISSION + * @param injectorPid The pid of the injecting application. + * @param injectorUid The uid of the injecting application. + * @param sync If true, waits for the event to be completed before returning. + * @param timeoutMillis The injection timeout in milliseconds. + * @return One of the INPUT_EVENT_INJECTION_XXX constants. */ - public int injectMotionEvent(MotionEvent event, int nature, boolean sync, int pid, int uid) { - // TODO - return INJECT_FAILED; + public int injectMotionEvent(MotionEvent event, int nature, int injectorPid, int injectorUid, + boolean sync, int timeoutMillis) { + if (event == null) { + throw new IllegalArgumentException("event must not be null"); + } + if (injectorPid < 0 || injectorUid < 0) { + throw new IllegalArgumentException("injectorPid and injectorUid must not be negative."); + } + if (timeoutMillis <= 0) { + throw new IllegalArgumentException("timeoutMillis must be positive"); + } + + return nativeInjectMotionEvent(event, nature, injectorPid, injectorUid, + sync, timeoutMillis); } public void dump(PrintWriter pw) { @@ -271,8 +307,6 @@ public class InputManager { private static final boolean DEBUG_VIRTUAL_KEYS = false; private static final String EXCLUDED_DEVICES_PATH = "etc/excluded-input-devices.xml"; - private final InputTargetList mReusableInputTargetList = new InputTargetList(); - @SuppressWarnings("unused") public boolean isScreenOn() { return mPowerManagerService.isScreenOn(); @@ -309,6 +343,21 @@ public class InputManager { } @SuppressWarnings("unused") + public void notifyInputChannelBroken(InputChannel inputChannel) { + mWindowManagerService.notifyInputChannelBroken(inputChannel); + } + + @SuppressWarnings("unused") + public long notifyInputChannelANR(InputChannel inputChannel) { + return mWindowManagerService.notifyInputChannelANR(inputChannel); + } + + @SuppressWarnings("unused") + public void notifyInputChannelRecoveredFromANR(InputChannel inputChannel) { + mWindowManagerService.notifyInputChannelRecoveredFromANR(inputChannel); + } + + @SuppressWarnings("unused") public int hackInterceptKey(int deviceId, int type, int scanCode, int keyCode, int policyFlags, int value, long whenNanos, boolean isScreenOn) { RawInputEvent event = new RawInputEvent(); @@ -437,24 +486,23 @@ public class InputManager { return names.toArray(new String[names.size()]); } + // TODO All code related to target identification should be moved down into native. @SuppressWarnings("unused") - public InputTarget[] getKeyEventTargets(KeyEvent event, int nature, int policyFlags) { - mReusableInputTargetList.clear(); - - mWindowManagerService.getKeyEventTargets(mReusableInputTargetList, - event, nature, policyFlags); - - return mReusableInputTargetList.toNullTerminatedArray(); + public int getKeyEventTargets(InputTargetList inputTargets, + KeyEvent event, int nature, int policyFlags, + int injectorPid, int injectorUid) { + inputTargets.clear(); + return mWindowManagerService.getKeyEventTargetsTd( + inputTargets, event, nature, policyFlags, injectorPid, injectorUid); } @SuppressWarnings("unused") - public InputTarget[] getMotionEventTargets(MotionEvent event, int nature, int policyFlags) { - mReusableInputTargetList.clear(); - - mWindowManagerService.getMotionEventTargets(mReusableInputTargetList, - event, nature, policyFlags); - - return mReusableInputTargetList.toNullTerminatedArray(); + public int getMotionEventTargets(InputTargetList inputTargets, + MotionEvent event, int nature, int policyFlags, + int injectorPid, int injectorUid) { + inputTargets.clear(); + return mWindowManagerService.getMotionEventTargetsTd( + inputTargets, event, nature, policyFlags, injectorPid, injectorUid); } } } |