summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeff Brown <jeffbrown@google.com>2012-04-05 18:57:33 -0700
committerJeff Brown <jeffbrown@google.com>2012-04-05 19:33:11 -0700
commitac14351e16e1258f1cb54e2bf772b8be004eb2b8 (patch)
tree55c22fe8e19d35764f00a6ffad899e4fd2c4ccd0
parent030711c39b6093024d784c1c3d7566bd5a3e3489 (diff)
downloadframeworks_base-ac14351e16e1258f1cb54e2bf772b8be004eb2b8.zip
frameworks_base-ac14351e16e1258f1cb54e2bf772b8be004eb2b8.tar.gz
frameworks_base-ac14351e16e1258f1cb54e2bf772b8be004eb2b8.tar.bz2
Move some APIs from window manager to input manager.
Simplified input injection API down to just one call. Removed all input state reading API. It was only used by the window manager policy and required a permission that applications could not obtain. READ_INPUT_STATE is now unused and deprecated. Change-Id: I41278141586ddee9468cae0fb59ff0dced6cbc00
-rw-r--r--api/current.txt2
-rwxr-xr-xcmds/input/src/com/android/commands/input/Input.java39
-rw-r--r--core/java/android/app/ContextImpl.java7
-rw-r--r--core/java/android/app/Instrumentation.java43
-rw-r--r--core/java/android/hardware/input/IInputManager.aidl16
-rwxr-xr-xcore/java/android/hardware/input/InputManager.java213
-rw-r--r--core/java/android/view/IWindowManager.aidl34
-rwxr-xr-xcore/java/android/view/InputDevice.java18
-rw-r--r--core/java/android/view/KeyCharacterMap.java17
-rw-r--r--core/java/android/view/WindowManagerPolicy.java18
-rw-r--r--core/res/AndroidManifest.xml3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java12
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java8
-rwxr-xr-xpolicy/src/com/android/internal/policy/impl/PhoneWindowManager.java65
-rw-r--r--services/java/com/android/server/input/InputManagerService.java135
-rw-r--r--services/java/com/android/server/wm/WindowManagerService.java290
-rw-r--r--tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java101
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowManager.java117
18 files changed, 435 insertions, 703 deletions
diff --git a/api/current.txt b/api/current.txt
index f00911b..d7290317 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -80,7 +80,7 @@ package android {
field public static final java.lang.String READ_EXTERNAL_STORAGE = "android.permission.READ_EXTERNAL_STORAGE";
field public static final java.lang.String READ_FRAME_BUFFER = "android.permission.READ_FRAME_BUFFER";
field public static final java.lang.String READ_HISTORY_BOOKMARKS = "com.android.browser.permission.READ_HISTORY_BOOKMARKS";
- field public static final java.lang.String READ_INPUT_STATE = "android.permission.READ_INPUT_STATE";
+ field public static final deprecated java.lang.String READ_INPUT_STATE = "android.permission.READ_INPUT_STATE";
field public static final java.lang.String READ_LOGS = "android.permission.READ_LOGS";
field public static final java.lang.String READ_PHONE_STATE = "android.permission.READ_PHONE_STATE";
field public static final java.lang.String READ_PROFILE = "android.permission.READ_PROFILE";
diff --git a/cmds/input/src/com/android/commands/input/Input.java b/cmds/input/src/com/android/commands/input/Input.java
index c4c3b8a..3037881 100755
--- a/cmds/input/src/com/android/commands/input/Input.java
+++ b/cmds/input/src/com/android/commands/input/Input.java
@@ -16,11 +16,12 @@
package com.android.commands.input;
+import android.hardware.input.InputManager;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemClock;
import android.util.Log;
-import android.view.IWindowManager;
+import android.view.InputDevice;
import android.view.KeyCharacterMap;
import android.view.KeyEvent;
import android.view.MotionEvent;
@@ -33,8 +34,6 @@ import android.view.MotionEvent;
public class Input {
private static final String TAG = "Input";
- private IWindowManager mWindowManager;
-
/**
* Command-line entry point.
*
@@ -44,13 +43,6 @@ public class Input {
(new Input()).run(args);
}
- private IWindowManager getWindowManager() {
- if (mWindowManager == null) {
- mWindowManager = (IWindowManager.Stub.asInterface(ServiceManager.getService("window")));
- }
- return mWindowManager;
- }
-
private void run(String[] args) {
if (args.length < 1) {
showUsage();
@@ -127,8 +119,10 @@ public class Input {
private void sendKeyEvent(int keyCode) {
long now = SystemClock.uptimeMillis();
- injectKeyEvent(new KeyEvent(now, now, KeyEvent.ACTION_DOWN, keyCode, 0));
- injectKeyEvent(new KeyEvent(now, now, KeyEvent.ACTION_UP, keyCode, 0));
+ injectKeyEvent(new KeyEvent(now, now, KeyEvent.ACTION_DOWN, keyCode, 0, 0,
+ KeyCharacterMap.VIRTUAL_KEYBOARD, 0, 0, InputDevice.SOURCE_KEYBOARD));
+ injectKeyEvent(new KeyEvent(now, now, KeyEvent.ACTION_UP, keyCode, 0, 0,
+ KeyCharacterMap.VIRTUAL_KEYBOARD, 0, 0, InputDevice.SOURCE_KEYBOARD));
}
private void sendTap(float x, float y) {
@@ -150,23 +144,14 @@ public class Input {
}
private void injectKeyEvent(KeyEvent event) {
- try {
- Log.i(TAG, "InjectKeyEvent: " + event);
- getWindowManager().injectKeyEvent(event, true);
- } catch (RemoteException ex) {
- Log.i(TAG, "RemoteException", ex);
- }
+ Log.i(TAG, "InjectKeyEvent: " + event);
+ InputManager.injectInputEvent(event, InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH);
}
private void injectPointerEvent(MotionEvent event) {
- try {
- Log.i("Input", "InjectPointerEvent: " + event);
- getWindowManager().injectPointerEvent(event, true);
- } catch (RemoteException ex) {
- Log.i(TAG, "RemoteException", ex);
- } finally {
- event.recycle();
- }
+ event.setSource(InputDevice.SOURCE_TOUCHSCREEN);
+ Log.i("Input", "InjectPointerEvent: " + event);
+ InputManager.injectInputEvent(event, InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH);
}
private static final float lerp(float a, float b, float alpha) {
@@ -174,7 +159,7 @@ public class Input {
}
private void showUsage() {
- System.err.println("usage: input [text|keyevent]");
+ System.err.println("usage: input ...");
System.err.println(" input text <string>");
System.err.println(" input keyevent <key code>");
System.err.println(" input tap <x> <y>");
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 9dde51c..c5d7b91 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -45,6 +45,7 @@ import android.graphics.drawable.Drawable;
import android.hardware.ISerialManager;
import android.hardware.SensorManager;
import android.hardware.SerialManager;
+import android.hardware.input.IInputManager;
import android.hardware.input.InputManager;
import android.hardware.usb.IUsbManager;
import android.hardware.usb.UsbManager;
@@ -325,9 +326,9 @@ class ContextImpl extends Context {
}});
registerService(INPUT_SERVICE, new ServiceFetcher() {
- public Object createService(ContextImpl ctx) {
- return new InputManager(ctx);
- }});
+ public Object createService(ContextImpl ctx) {
+ return new InputManager(ctx);
+ }});
registerService(INPUT_METHOD_SERVICE, new ServiceFetcher() {
public Object createService(ContextImpl ctx) {
diff --git a/core/java/android/app/Instrumentation.java b/core/java/android/app/Instrumentation.java
index e4f7950..f955713 100644
--- a/core/java/android/app/Instrumentation.java
+++ b/core/java/android/app/Instrumentation.java
@@ -23,6 +23,7 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
+import android.hardware.input.InputManager;
import android.os.Bundle;
import android.os.Debug;
import android.os.IBinder;
@@ -35,6 +36,7 @@ import android.os.SystemClock;
import android.util.AndroidRuntimeException;
import android.util.Log;
import android.view.IWindowManager;
+import android.view.InputDevice;
import android.view.KeyCharacterMap;
import android.view.KeyEvent;
import android.view.MotionEvent;
@@ -859,11 +861,30 @@ public class Instrumentation {
*/
public void sendKeySync(KeyEvent event) {
validateNotAppThread();
- try {
- (IWindowManager.Stub.asInterface(ServiceManager.getService("window")))
- .injectKeyEvent(event, true);
- } catch (RemoteException e) {
+
+ long downTime = event.getDownTime();
+ long eventTime = event.getEventTime();
+ int action = event.getAction();
+ int code = event.getKeyCode();
+ int repeatCount = event.getRepeatCount();
+ int metaState = event.getMetaState();
+ int deviceId = event.getDeviceId();
+ int scancode = event.getScanCode();
+ int source = event.getSource();
+ int flags = event.getFlags();
+ if (source == InputDevice.SOURCE_UNKNOWN) {
+ source = InputDevice.SOURCE_KEYBOARD;
+ }
+ if (eventTime == 0) {
+ eventTime = SystemClock.uptimeMillis();
+ }
+ if (downTime == 0) {
+ downTime = eventTime;
}
+ KeyEvent newEvent = new KeyEvent(downTime, eventTime, action, code, repeatCount, metaState,
+ deviceId, scancode, flags | KeyEvent.FLAG_FROM_SYSTEM, source);
+ InputManager.injectInputEvent(newEvent,
+ InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH);
}
/**
@@ -902,11 +923,10 @@ public class Instrumentation {
*/
public void sendPointerSync(MotionEvent event) {
validateNotAppThread();
- try {
- (IWindowManager.Stub.asInterface(ServiceManager.getService("window")))
- .injectPointerEvent(event, true);
- } catch (RemoteException e) {
+ if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) == 0) {
+ event.setSource(InputDevice.SOURCE_TOUCHSCREEN);
}
+ InputManager.injectInputEvent(event, InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH);
}
/**
@@ -922,11 +942,10 @@ public class Instrumentation {
*/
public void sendTrackballEventSync(MotionEvent event) {
validateNotAppThread();
- try {
- (IWindowManager.Stub.asInterface(ServiceManager.getService("window")))
- .injectTrackballEvent(event, true);
- } catch (RemoteException e) {
+ if ((event.getSource() & InputDevice.SOURCE_CLASS_TRACKBALL) == 0) {
+ event.setSource(InputDevice.SOURCE_TRACKBALL);
}
+ InputManager.injectInputEvent(event, InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH);
}
/**
diff --git a/core/java/android/hardware/input/IInputManager.aidl b/core/java/android/hardware/input/IInputManager.aidl
index 85061bb..c2abce5 100644
--- a/core/java/android/hardware/input/IInputManager.aidl
+++ b/core/java/android/hardware/input/IInputManager.aidl
@@ -16,6 +16,22 @@
package android.hardware.input;
+import android.view.InputDevice;
+import android.view.InputEvent;
+
/** @hide */
interface IInputManager {
+ // Gets input device information.
+ InputDevice getInputDevice(int deviceId);
+ int[] getInputDeviceIds();
+
+ // Reports whether the hardware supports the given keys; returns true if successful
+ boolean hasKeys(int deviceId, int sourceMask, in int[] keyCodes, out boolean[] keyExists);
+
+ // Temporarily changes the pointer speed.
+ void tryPointerSpeed(int speed);
+
+ // Injects an input event into the system. To inject into windows owned by other
+ // applications, the caller must have the INJECT_EVENTS permission.
+ boolean injectInputEvent(in InputEvent ev, int mode);
}
diff --git a/core/java/android/hardware/input/InputManager.java b/core/java/android/hardware/input/InputManager.java
index 6093404..ba64035 100755
--- a/core/java/android/hardware/input/InputManager.java
+++ b/core/java/android/hardware/input/InputManager.java
@@ -31,10 +31,20 @@ import android.content.res.Resources;
import android.content.res.TypedArray;
import android.content.res.XmlResourceParser;
import android.os.Bundle;
+import android.os.IBinder;
import android.os.Parcel;
import android.os.Parcelable;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.provider.Settings;
+import android.provider.Settings.SettingNotFoundException;
import android.util.Log;
+import android.view.Display;
+import android.view.IWindowManager;
+import android.view.InputDevice;
+import android.view.InputEvent;
import android.view.KeyCharacterMap;
+import android.view.WindowManagerPolicy;
import android.view.KeyCharacterMap.UnavailableException;
import java.util.ArrayList;
@@ -53,6 +63,8 @@ import java.util.List;
public final class InputManager {
private static final String TAG = "InputManager";
+ private static final IInputManager sIm;
+
private final Context mContext;
// Used to simulate a persistent data store.
@@ -118,6 +130,53 @@ public final class InputManager {
public static final String META_DATA_KEYBOARD_LAYOUTS =
"android.hardware.input.metadata.KEYBOARD_LAYOUTS";
+ /**
+ * Pointer Speed: The minimum (slowest) pointer speed (-7).
+ * @hide
+ */
+ public static final int MIN_POINTER_SPEED = -7;
+
+ /**
+ * Pointer Speed: The maximum (fastest) pointer speed (7).
+ * @hide
+ */
+ public static final int MAX_POINTER_SPEED = 7;
+
+ /**
+ * Pointer Speed: The default pointer speed (0).
+ * @hide
+ */
+ public static final int DEFAULT_POINTER_SPEED = 0;
+
+ /**
+ * Input Event Injection Synchronization Mode: None.
+ * Never blocks. Injection is asynchronous and is assumed always to be successful.
+ * @hide
+ */
+ public static final int INJECT_INPUT_EVENT_MODE_ASYNC = 0; // see InputDispatcher.h
+
+ /**
+ * Input Event Injection Synchronization Mode: Wait for result.
+ * Waits for previous events to be dispatched so that the input dispatcher can
+ * determine whether input event injection will be permitted based on the current
+ * input focus. Does not wait for the input event to finish being handled
+ * by the application.
+ * @hide
+ */
+ public static final int INJECT_INPUT_EVENT_MODE_WAIT_FOR_RESULT = 1; // see InputDispatcher.h
+
+ /**
+ * Input Event Injection Synchronization Mode: Wait for finish.
+ * Waits for the event to be delivered to the application and handled.
+ * @hide
+ */
+ public static final int INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH = 2; // see InputDispatcher.h
+
+ static {
+ IBinder b = ServiceManager.getService(Context.INPUT_SERVICE);
+ sIm = IInputManager.Stub.asInterface(b);
+ }
+
/** @hide */
public InputManager(Context context) {
mContext = context;
@@ -296,6 +355,160 @@ public final class InputManager {
return null;
}
+ /**
+ * Gets the mouse pointer speed.
+ * <p>
+ * Only returns the permanent mouse pointer speed. Ignores any temporary pointer
+ * speed set by {@link #tryPointerSpeed}.
+ * </p>
+ *
+ * @return The pointer speed as a value between {@link #MIN_POINTER_SPEED} and
+ * {@link #MAX_POINTER_SPEED}, or the default value {@link #DEFAULT_POINTER_SPEED}.
+ *
+ * @hide
+ */
+ public int getPointerSpeed() {
+ int speed = DEFAULT_POINTER_SPEED;
+ try {
+ speed = Settings.System.getInt(mContext.getContentResolver(),
+ Settings.System.POINTER_SPEED);
+ } catch (SettingNotFoundException snfe) {
+ }
+ return speed;
+ }
+
+ /**
+ * Sets the mouse pointer speed.
+ * <p>
+ * Requires {@link android.Manifest.permissions.WRITE_SETTINGS}.
+ * </p>
+ *
+ * @param speed The pointer speed as a value between {@link #MIN_POINTER_SPEED} and
+ * {@link #MAX_POINTER_SPEED}, or the default value {@link #DEFAULT_POINTER_SPEED}.
+ *
+ * @hide
+ */
+ public void setPointerSpeed(int speed) {
+ if (speed < MIN_POINTER_SPEED || speed > MAX_POINTER_SPEED) {
+ throw new IllegalArgumentException("speed out of range");
+ }
+
+ Settings.System.putInt(mContext.getContentResolver(),
+ Settings.System.POINTER_SPEED, speed);
+ }
+
+ /**
+ * Changes the mouse pointer speed temporarily, but does not save the setting.
+ * <p>
+ * Requires {@link android.Manifest.permission.SET_POINTER_SPEED}.
+ * </p>
+ *
+ * @param speed The pointer speed as a value between {@link #MIN_POINTER_SPEED} and
+ * {@link #MAX_POINTER_SPEED}, or the default value {@link #DEFAULT_POINTER_SPEED}.
+ *
+ * @hide
+ */
+ public void tryPointerSpeed(int speed) {
+ if (speed < MIN_POINTER_SPEED || speed > MAX_POINTER_SPEED) {
+ throw new IllegalArgumentException("speed out of range");
+ }
+
+ try {
+ sIm.tryPointerSpeed(speed);
+ } catch (RemoteException ex) {
+ Log.w(TAG, "Could not set temporary pointer speed.", ex);
+ }
+ }
+
+ /**
+ * Gets information about the input device with the specified id.
+ * @param id The device id.
+ * @return The input device or null if not found.
+ *
+ * @hide
+ */
+ public static InputDevice getInputDevice(int id) {
+ try {
+ return sIm.getInputDevice(id);
+ } catch (RemoteException ex) {
+ throw new RuntimeException("Could not get input device information.", ex);
+ }
+ }
+
+ /**
+ * Gets the ids of all input devices in the system.
+ * @return The input device ids.
+ *
+ * @hide
+ */
+ public static int[] getInputDeviceIds() {
+ try {
+ return sIm.getInputDeviceIds();
+ } catch (RemoteException ex) {
+ throw new RuntimeException("Could not get input device ids.", ex);
+ }
+ }
+
+ /**
+ * Queries the framework about whether any physical keys exist on the
+ * any keyboard attached to the device that are capable of producing the given
+ * array of key codes.
+ *
+ * @param keyCodes The array of key codes to query.
+ * @return A new array of the same size as the key codes array whose elements
+ * are set to true if at least one attached keyboard supports the corresponding key code
+ * at the same index in the key codes array.
+ *
+ * @hide
+ */
+ public static boolean[] deviceHasKeys(int[] keyCodes) {
+ boolean[] ret = new boolean[keyCodes.length];
+ try {
+ sIm.hasKeys(-1, InputDevice.SOURCE_ANY, keyCodes, ret);
+ } catch (RemoteException e) {
+ // no fallback; just return the empty array
+ }
+ return ret;
+ }
+
+ /**
+ * Injects an input event into the event system on behalf of an application.
+ * The synchronization mode determines whether the method blocks while waiting for
+ * input injection to proceed.
+ * <p>
+ * Requires {@link android.Manifest.permission.INJECT_EVENTS} to inject into
+ * windows that are owned by other applications.
+ * </p><p>
+ * Make sure you correctly set the event time and input source of the event
+ * before calling this method.
+ * </p>
+ *
+ * @param event The event to inject.
+ * @param mode The synchronization mode. One of:
+ * {@link #INJECT_INPUT_EVENT_MODE_ASYNC},
+ * {@link #INJECT_INPUT_EVENT_MODE_WAIT_FOR_RESULT}, or
+ * {@link #INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH}.
+ * @return True if input event injection succeeded.
+ *
+ * @hide
+ */
+ public static boolean injectInputEvent(InputEvent event, int mode) {
+ if (event == null) {
+ throw new IllegalArgumentException("event must not be null");
+ }
+ if (mode != INJECT_INPUT_EVENT_MODE_ASYNC
+ && mode != INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH
+ && mode != INJECT_INPUT_EVENT_MODE_WAIT_FOR_RESULT) {
+ throw new IllegalArgumentException("mode is invalid");
+ }
+
+ try {
+ return sIm.injectInputEvent(event, mode);
+ } catch (RemoteException ex) {
+ return false;
+ }
+ }
+
private static String makeKeyboardLayoutDescriptor(String packageName,
String receiverName, String keyboardName) {
return packageName + "/" + receiverName + "/" + keyboardName;
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index eb030de..8fe8e40 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -65,15 +65,6 @@ interface IWindowManager
// Is the device configured to have a full system bar for larger screens?
boolean hasSystemNavBar();
- // These can only be called when injecting events to your own window,
- // or by holding the INJECT_EVENTS permission. These methods may block
- // until pending input events are finished being dispatched even when 'sync' is false.
- // Avoid calling these methods on your UI thread or use the 'NoWait' version instead.
- boolean injectKeyEvent(in KeyEvent ev, boolean sync);
- boolean injectPointerEvent(in MotionEvent ev, boolean sync);
- boolean injectTrackballEvent(in MotionEvent ev, boolean sync);
- boolean injectInputEventNoWait(in InputEvent ev);
-
// These can only be called when holding the MANAGE_APP_TOKENS permission.
void pauseKeyDispatching(IBinder token);
void resumeKeyDispatching(IBinder token);
@@ -128,26 +119,6 @@ interface IWindowManager
void setAnimationScale(int which, float scale);
void setAnimationScales(in float[] scales);
- // These require the READ_INPUT_STATE permission.
- int getSwitchState(int sw);
- int getSwitchStateForDevice(int devid, int sw);
- int getScancodeState(int sw);
- int getScancodeStateForDevice(int devid, int sw);
- int getTrackballScancodeState(int sw);
- int getDPadScancodeState(int sw);
- int getKeycodeState(int sw);
- int getKeycodeStateForDevice(int devid, int sw);
- int getTrackballKeycodeState(int sw);
- int getDPadKeycodeState(int sw);
- InputChannel monitorInput(String inputChannelName);
-
- // Report whether the hardware supports the given keys; returns true if successful
- boolean hasKeys(in int[] keycodes, inout boolean[] keyExists);
-
- // Get input device information.
- InputDevice getInputDevice(int deviceId);
- int[] getInputDeviceIds();
-
// For testing
void setInTouchMode(boolean showFocus);
@@ -220,11 +191,6 @@ interface IWindowManager
void statusBarVisibilityChanged(int visibility);
/**
- * Called by the settings application to temporarily set the pointer speed.
- */
- void setPointerSpeed(int speed);
-
- /**
* Block until the given window has been drawn to the screen.
*/
void waitForWindowDrawn(IBinder token, in IRemoteCallback callback);
diff --git a/core/java/android/view/InputDevice.java b/core/java/android/view/InputDevice.java
index 91e47e6..93a0185 100755
--- a/core/java/android/view/InputDevice.java
+++ b/core/java/android/view/InputDevice.java
@@ -16,9 +16,9 @@
package android.view;
+import android.hardware.input.InputManager;
import android.os.Parcel;
import android.os.Parcelable;
-import android.os.RemoteException;
import java.util.ArrayList;
import java.util.List;
@@ -301,13 +301,7 @@ public final class InputDevice implements Parcelable {
* @return The input device or null if not found.
*/
public static InputDevice getDevice(int id) {
- IWindowManager wm = Display.getWindowManager();
- try {
- return wm.getInputDevice(id);
- } catch (RemoteException ex) {
- throw new RuntimeException(
- "Could not get input device information from Window Manager.", ex);
- }
+ return InputManager.getInputDevice(id);
}
/**
@@ -315,13 +309,7 @@ public final class InputDevice implements Parcelable {
* @return The input device ids.
*/
public static int[] getDeviceIds() {
- IWindowManager wm = Display.getWindowManager();
- try {
- return wm.getInputDeviceIds();
- } catch (RemoteException ex) {
- throw new RuntimeException(
- "Could not get input device ids from Window Manager.", ex);
- }
+ return InputManager.getInputDeviceIds();
}
/**
diff --git a/core/java/android/view/KeyCharacterMap.java b/core/java/android/view/KeyCharacterMap.java
index 98cce5e..b03f086 100644
--- a/core/java/android/view/KeyCharacterMap.java
+++ b/core/java/android/view/KeyCharacterMap.java
@@ -19,10 +19,9 @@ package android.view;
import android.text.method.MetaKeyKeyListener;
import android.util.AndroidRuntimeException;
import android.util.SparseIntArray;
-import android.os.RemoteException;
+import android.hardware.input.InputManager;
import android.util.SparseArray;
-import java.io.Reader;
import java.lang.Character;
/**
@@ -528,10 +527,7 @@ public class KeyCharacterMap {
* @return True if at least one attached keyboard supports the specified key code.
*/
public static boolean deviceHasKey(int keyCode) {
- int[] codeArray = new int[1];
- codeArray[0] = keyCode;
- boolean[] ret = deviceHasKeys(codeArray);
- return ret[0];
+ return InputManager.deviceHasKeys(new int[] { keyCode })[0];
}
/**
@@ -545,14 +541,7 @@ public class KeyCharacterMap {
* at the same index in the key codes array.
*/
public static boolean[] deviceHasKeys(int[] keyCodes) {
- boolean[] ret = new boolean[keyCodes.length];
- IWindowManager wm = Display.getWindowManager();
- try {
- wm.hasKeys(keyCodes, ret);
- } catch (RemoteException e) {
- // no fallback; just return the empty array
- }
- return ret;
+ return InputManager.deviceHasKeys(keyCodes);
}
/**
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index cf9cafc..491cd67 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -349,6 +349,10 @@ public interface WindowManagerPolicy {
* between it and the policy.
*/
public interface WindowManagerFuncs {
+ public static final int LID_ABSENT = -1;
+ public static final int LID_CLOSED = 0;
+ public static final int LID_OPEN = 1;
+
/**
* Ask the window manager to re-evaluate the system UI flags.
*/
@@ -362,6 +366,16 @@ public interface WindowManagerPolicy {
InputEventReceiver.Factory inputEventReceiverFactory,
String name, int windowType, int layoutParamsFlags, boolean canReceiveKeys,
boolean hasFocus, boolean touchFullscreen);
+
+ /**
+ * Returns a code that describes the current state of the lid switch.
+ */
+ public int getLidState();
+
+ /**
+ * Creates an input channel that will receive all input from the input dispatcher.
+ */
+ public InputChannel monitorInput(String name);
}
/**
@@ -943,10 +957,10 @@ public interface WindowManagerPolicy {
public void setRotationLw(int rotation);
/**
- * Called when the system is mostly done booting to determine whether
+ * Called when the system is mostly done booting to set whether
* the system should go into safe mode.
*/
- public boolean detectSafeMode();
+ public void setSafeMode(boolean safeMode);
/**
* Called when the system is mostly done booting.
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 5ae12b6..00faa41 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1200,7 +1200,8 @@
android:protectionLevel="signature|system" />
<!-- Allows an application to retrieve the current state of keys and
- switches. This is only for use by the system.-->
+ switches. This is only for use by the system.
+ @deprecated The API that used this permission has been removed. -->
<permission android:name="android.permission.READ_INPUT_STATE"
android:label="@string/permlab_readInputState"
android:description="@string/permdesc_readInputState"
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
index cc07240..0c8208f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
@@ -23,6 +23,7 @@ import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.graphics.Canvas;
import android.graphics.RectF;
+import android.hardware.input.InputManager;
import android.os.RemoteException;
import android.os.SystemClock;
import android.os.ServiceManager;
@@ -47,7 +48,6 @@ public class KeyButtonView extends ImageView {
final float GLOW_MAX_SCALE_FACTOR = 1.8f;
final float BUTTON_QUIESCENT_ALPHA = 0.6f;
- IWindowManager mWindowManager;
long mDownTime;
int mCode;
int mTouchSlop;
@@ -93,9 +93,6 @@ public class KeyButtonView extends ImageView {
a.recycle();
- mWindowManager = IWindowManager.Stub.asInterface(
- ServiceManager.getService(Context.WINDOW_SERVICE));
-
setClickable(true);
mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
}
@@ -276,12 +273,7 @@ public class KeyButtonView extends ImageView {
0, KeyCharacterMap.VIRTUAL_KEYBOARD, 0,
flags | KeyEvent.FLAG_FROM_SYSTEM | KeyEvent.FLAG_VIRTUAL_HARD_KEY,
InputDevice.SOURCE_KEYBOARD);
- try {
- //Slog.d(TAG, "injecting event " + ev);
- mWindowManager.injectInputEventNoWait(ev);
- } catch (RemoteException ex) {
- // System process is dead
- }
+ InputManager.injectInputEvent(ev, InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
index 49b1a14..09283f4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
@@ -1322,14 +1322,6 @@ public class TabletStatusBar extends BaseStatusBar implements
}
}
- private void sendKey(KeyEvent key) {
- try {
- if (DEBUG) Slog.d(TAG, "injecting key event: " + key);
- mWindowManager.injectInputEventNoWait(key);
- } catch (RemoteException ex) {
- }
- }
-
private View.OnClickListener mOnClickListener = new View.OnClickListener() {
public void onClick(View v) {
if (v == mRecentButton) {
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index ded190b..1be5bd7 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -132,6 +132,9 @@ import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
import static android.view.WindowManager.LayoutParams.TYPE_BOOT_PROGRESS;
import android.view.WindowManagerImpl;
import android.view.WindowManagerPolicy;
+import static android.view.WindowManagerPolicy.WindowManagerFuncs.LID_ABSENT;
+import static android.view.WindowManagerPolicy.WindowManagerFuncs.LID_OPEN;
+import static android.view.WindowManagerPolicy.WindowManagerFuncs.LID_CLOSED;
import android.view.KeyCharacterMap.FallbackAction;
import android.view.accessibility.AccessibilityEvent;
import android.view.animation.Animation;
@@ -237,8 +240,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
static final int SYSTEM_UI_CHANGING_LAYOUT =
View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN;
- // Useful scan codes.
- private static final int SW_LID = 0x00;
private static final int BTN_MOUSE = 0x110;
/* Table of Application Launch keys. Maps from key codes to intent categories.
@@ -322,10 +323,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
RecentApplicationsDialog mRecentAppsDialog;
int mRecentAppsDialogHeldModifiers;
- private static final int LID_ABSENT = -1;
- private static final int LID_CLOSED = 0;
- private static final int LID_OPEN = 1;
-
int mLidOpen = LID_ABSENT;
boolean mSystemReady;
@@ -1120,16 +1117,11 @@ public class PhoneWindowManager implements WindowManagerPolicy {
lp.inputFeatures |= WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL;
wm.addView(mPointerLocationView, lp);
- try {
- mPointerLocationInputChannel =
- mWindowManager.monitorInput("PointerLocationView");
- mPointerLocationInputEventReceiver =
- new PointerLocationInputEventReceiver(mPointerLocationInputChannel,
- Looper.myLooper(), mPointerLocationView);
- } catch (RemoteException ex) {
- Slog.e(TAG, "Could not set up input monitoring channel for PointerLocation.",
- ex);
- }
+ mPointerLocationInputChannel =
+ mWindowManagerFuncs.monitorInput("PointerLocationView");
+ mPointerLocationInputEventReceiver =
+ new PointerLocationInputEventReceiver(mPointerLocationInputChannel,
+ Looper.myLooper(), mPointerLocationView);
}
}
@@ -1223,18 +1215,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
void readLidState() {
- try {
- int sw = mWindowManager.getSwitchState(SW_LID);
- if (sw > 0) {
- mLidOpen = LID_OPEN;
- } else if (sw == 0) {
- mLidOpen = LID_CLOSED;
- } else {
- mLidOpen = LID_ABSENT;
- }
- } catch (RemoteException e) {
- // Ignore
- }
+ mLidOpen = mWindowManagerFuncs.getLidState();
}
private int determineHiddenState(int mode, int hiddenValue, int visibleValue) {
@@ -3648,29 +3629,11 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
}
- public boolean detectSafeMode() {
- try {
- int menuState = mWindowManager.getKeycodeState(KeyEvent.KEYCODE_MENU);
- int sState = mWindowManager.getKeycodeState(KeyEvent.KEYCODE_S);
- int dpadState = mWindowManager.getDPadKeycodeState(KeyEvent.KEYCODE_DPAD_CENTER);
- int trackballState = mWindowManager.getTrackballScancodeState(BTN_MOUSE);
- int volumeDownState = mWindowManager.getKeycodeState(KeyEvent.KEYCODE_VOLUME_DOWN);
- mSafeMode = menuState > 0 || sState > 0 || dpadState > 0 || trackballState > 0
- || volumeDownState > 0;
- performHapticFeedbackLw(null, mSafeMode
- ? HapticFeedbackConstants.SAFE_MODE_ENABLED
- : HapticFeedbackConstants.SAFE_MODE_DISABLED, true);
- if (mSafeMode) {
- Log.i(TAG, "SAFE MODE ENABLED (menu=" + menuState + " s=" + sState
- + " dpad=" + dpadState + " trackball=" + trackballState + ")");
- } else {
- Log.i(TAG, "SAFE MODE not enabled");
- }
- return mSafeMode;
- } catch (RemoteException e) {
- // Doom! (it's also local)
- throw new RuntimeException("window manager dead");
- }
+ public void setSafeMode(boolean safeMode) {
+ mSafeMode = safeMode;
+ performHapticFeedbackLw(null, safeMode
+ ? HapticFeedbackConstants.SAFE_MODE_ENABLED
+ : HapticFeedbackConstants.SAFE_MODE_DISABLED, true);
}
static long[] getLongIntArray(Resources r, int resid) {
diff --git a/services/java/com/android/server/input/InputManagerService.java b/services/java/com/android/server/input/InputManagerService.java
index 6a566ae..b8cc65e 100644
--- a/services/java/com/android/server/input/InputManagerService.java
+++ b/services/java/com/android/server/input/InputManagerService.java
@@ -28,11 +28,13 @@ import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.database.ContentObserver;
import android.hardware.input.IInputManager;
+import android.hardware.input.InputManager;
import android.os.Binder;
import android.os.Environment;
import android.os.Handler;
import android.os.Looper;
import android.os.MessageQueue;
+import android.os.Process;
import android.os.SystemProperties;
import android.provider.Settings;
import android.provider.Settings.SettingNotFoundException;
@@ -108,18 +110,16 @@ public class InputManagerService extends IInputManager.Stub implements Watchdog.
private static native void nativeSetShowTouches(int ptr, boolean enabled);
private static native String nativeDump(int ptr);
private static native void nativeMonitor(int ptr);
-
+
// Input event injection constants defined in InputDispatcher.h.
- public static final int INPUT_EVENT_INJECTION_SUCCEEDED = 0;
- public static final int INPUT_EVENT_INJECTION_PERMISSION_DENIED = 1;
- public static final int INPUT_EVENT_INJECTION_FAILED = 2;
- public static final int INPUT_EVENT_INJECTION_TIMED_OUT = 3;
-
- // Input event injection synchronization modes defined in InputDispatcher.h
- public static final int INPUT_EVENT_INJECTION_SYNC_NONE = 0;
- public static final int INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT = 1;
- public static final int INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISH = 2;
-
+ private static final int INPUT_EVENT_INJECTION_SUCCEEDED = 0;
+ private static final int INPUT_EVENT_INJECTION_PERMISSION_DENIED = 1;
+ private static final int INPUT_EVENT_INJECTION_FAILED = 2;
+ private static final int INPUT_EVENT_INJECTION_TIMED_OUT = 3;
+
+ // Maximum number of milliseconds to wait for input event injection.
+ private static final int INJECTION_TIMEOUT_MILLIS = 30 * 1000;
+
// Key states (may be returned by queries about the current state of a
// particular key code, scan code or switch).
@@ -194,7 +194,7 @@ public class InputManagerService extends IInputManager.Stub implements Watchdog.
nativeGetInputConfiguration(mPtr, config);
}
-
+
/**
* Gets the current state of a key or button by key code.
* @param deviceId The input device id, or -1 to consult all devices.
@@ -246,6 +246,7 @@ public class InputManagerService extends IInputManager.Stub implements Watchdog.
* key codes.
* @return True if the lookup was successful, false otherwise.
*/
+ @Override
public boolean hasKeys(int deviceId, int sourceMask, int[] keyCodes, boolean[] keyExists) {
if (keyCodes == null) {
throw new IllegalArgumentException("keyCodes must not be null.");
@@ -336,43 +337,42 @@ public class InputManagerService extends IInputManager.Stub implements Watchdog.
}
}
- /**
- * Injects an input event into the event system on behalf of an application.
- * The synchronization mode determines whether the method blocks while waiting for
- * input injection to proceed.
- *
- * {@link #INPUT_EVENT_INJECTION_SYNC_NONE} never blocks. Injection is asynchronous and
- * is assumed always to be successful.
- *
- * {@link #INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT} waits for previous events to be
- * dispatched so that the input dispatcher can determine whether input event injection will
- * be permitted based on the current input focus. Does not wait for the input event to
- * finish processing.
- *
- * {@link #INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISH} waits for the input event to
- * be completely processed.
- *
- * @param event The event to inject.
- * @param injectorPid The pid of the injecting application.
- * @param injectorUid The uid of the injecting application.
- * @param syncMode The synchronization mode.
- * @param timeoutMillis The injection timeout in milliseconds.
- * @return One of the INPUT_EVENT_INJECTION_XXX constants.
- */
- public int injectInputEvent(InputEvent event, int injectorPid, int injectorUid,
- int syncMode, int timeoutMillis) {
+ @Override
+ public boolean injectInputEvent(InputEvent event, int mode) {
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");
+ if (mode != InputManager.INJECT_INPUT_EVENT_MODE_ASYNC
+ && mode != InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH
+ && mode != InputManager.INJECT_INPUT_EVENT_MODE_WAIT_FOR_RESULT) {
+ throw new IllegalArgumentException("mode is invalid");
}
- return nativeInjectInputEvent(mPtr, event, injectorPid, injectorUid, syncMode,
- timeoutMillis, WindowManagerPolicy.FLAG_DISABLE_KEY_REPEAT);
+ final int pid = Binder.getCallingPid();
+ final int uid = Binder.getCallingUid();
+ final long ident = Binder.clearCallingIdentity();
+ final int result;
+ try {
+ result = nativeInjectInputEvent(mPtr, event, pid, uid, mode,
+ INJECTION_TIMEOUT_MILLIS, WindowManagerPolicy.FLAG_DISABLE_KEY_REPEAT);
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ switch (result) {
+ case INPUT_EVENT_INJECTION_PERMISSION_DENIED:
+ Slog.w(TAG, "Input event injection from pid " + pid + " permission denied.");
+ throw new SecurityException(
+ "Injecting to another application requires INJECT_EVENTS permission");
+ case INPUT_EVENT_INJECTION_SUCCEEDED:
+ return true;
+ case INPUT_EVENT_INJECTION_TIMED_OUT:
+ Slog.w(TAG, "Input event injection from pid " + pid + " timed out.");
+ return false;
+ case INPUT_EVENT_INJECTION_FAILED:
+ default:
+ Slog.w(TAG, "Input event injection from pid " + pid + " failed.");
+ return false;
+ }
}
/**
@@ -380,6 +380,7 @@ public class InputManagerService extends IInputManager.Stub implements Watchdog.
* @param id The device id.
* @return The input device or null if not found.
*/
+ @Override
public InputDevice getInputDevice(int deviceId) {
return nativeGetInputDevice(mPtr, deviceId);
}
@@ -388,6 +389,7 @@ public class InputManagerService extends IInputManager.Stub implements Watchdog.
* Gets the ids of all input devices in the system.
* @return The input device ids.
*/
+ @Override
public int[] getInputDeviceIds() {
return nativeGetInputDeviceIds(mPtr);
}
@@ -436,14 +438,25 @@ public class InputManagerService extends IInputManager.Stub implements Watchdog.
* @param speed The pointer speed as a value between -7 (slowest) and 7 (fastest)
* where 0 is the default speed.
*/
- public void setPointerSpeed(int speed) {
- speed = Math.min(Math.max(speed, -7), 7);
- nativeSetPointerSpeed(mPtr, speed);
+ @Override
+ public void tryPointerSpeed(int speed) {
+ if (!checkCallingPermission(android.Manifest.permission.SET_POINTER_SPEED,
+ "tryPointerSpeed()")) {
+ throw new SecurityException("Requires SET_POINTER_SPEED permission");
+ }
+
+ setPointerSpeedUnchecked(speed);
}
public void updatePointerSpeedFromSettings() {
- int speed = getPointerSpeedSetting(0);
- setPointerSpeed(speed);
+ int speed = getPointerSpeedSetting();
+ setPointerSpeedUnchecked(speed);
+ }
+
+ private void setPointerSpeedUnchecked(int speed) {
+ speed = Math.min(Math.max(speed, InputManager.MIN_POINTER_SPEED),
+ InputManager.MAX_POINTER_SPEED);
+ nativeSetPointerSpeed(mPtr, speed);
}
private void registerPointerSpeedSettingObserver() {
@@ -457,8 +470,8 @@ public class InputManagerService extends IInputManager.Stub implements Watchdog.
});
}
- private int getPointerSpeedSetting(int defaultValue) {
- int speed = defaultValue;
+ private int getPointerSpeedSetting() {
+ int speed = InputManager.DEFAULT_POINTER_SPEED;
try {
speed = Settings.System.getInt(mContext.getContentResolver(),
Settings.System.POINTER_SPEED);
@@ -510,6 +523,23 @@ public class InputManagerService extends IInputManager.Stub implements Watchdog.
}
}
+ private boolean checkCallingPermission(String permission, String func) {
+ // Quick check: if the calling permission is me, it's all okay.
+ if (Binder.getCallingPid() == Process.myPid()) {
+ return true;
+ }
+
+ if (mContext.checkCallingPermission(permission) == PackageManager.PERMISSION_GRANTED) {
+ return true;
+ }
+ String msg = "Permission Denial: " + func + " from pid="
+ + Binder.getCallingPid()
+ + ", uid=" + Binder.getCallingUid()
+ + " requires " + permission;
+ Slog.w(TAG, msg);
+ return false;
+ }
+
// Called by the heartbeat to ensure locks are not held indefinitely (for deadlock detection).
public void monitor() {
synchronized (mInputFilterLock) { }
@@ -703,7 +733,8 @@ public class InputManagerService extends IInputManager.Stub implements Watchdog.
synchronized (mInputFilterLock) {
if (!mDisconnected) {
- nativeInjectInputEvent(mPtr, event, 0, 0, INPUT_EVENT_INJECTION_SYNC_NONE, 0,
+ nativeInjectInputEvent(mPtr, event, 0, 0,
+ InputManager.INJECT_INPUT_EVENT_MODE_ASYNC, 0,
policyFlags | WindowManagerPolicy.FLAG_FILTERED);
}
}
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index 8ea00c1..3e74486 100644
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -245,10 +245,6 @@ public class WindowManagerService extends IWindowManager.Stub
*/
static final boolean CUSTOM_SCREEN_ROTATION = true;
- // Maximum number of milliseconds to wait for input event injection.
- // FIXME is this value reasonable?
- private static final int INJECTION_TIMEOUT_MILLIS = 30 * 1000;
-
// Maximum number of milliseconds to wait for input devices to be enumerated before
// proceding with safe mode detection.
private static final int INPUT_DEVICES_READY_FOR_SAFE_MODE_DETECTION_TIMEOUT_MILLIS = 1000;
@@ -4855,90 +4851,22 @@ public class WindowManagerService extends IWindowManager.Stub
mAnimatorDurationScale };
}
- public int getSwitchState(int sw) {
- if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
- "getSwitchState()")) {
- throw new SecurityException("Requires READ_INPUT_STATE permission");
- }
- return mInputManager.getSwitchState(-1, InputDevice.SOURCE_ANY, sw);
- }
-
- public int getSwitchStateForDevice(int devid, int sw) {
- if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
- "getSwitchStateForDevice()")) {
- throw new SecurityException("Requires READ_INPUT_STATE permission");
- }
- return mInputManager.getSwitchState(devid, InputDevice.SOURCE_ANY, sw);
- }
-
- public int getScancodeState(int sw) {
- if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
- "getScancodeState()")) {
- throw new SecurityException("Requires READ_INPUT_STATE permission");
- }
- return mInputManager.getScanCodeState(-1, InputDevice.SOURCE_ANY, sw);
- }
-
- public int getScancodeStateForDevice(int devid, int sw) {
- if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
- "getScancodeStateForDevice()")) {
- throw new SecurityException("Requires READ_INPUT_STATE permission");
- }
- return mInputManager.getScanCodeState(devid, InputDevice.SOURCE_ANY, sw);
- }
-
- public int getTrackballScancodeState(int sw) {
- if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
- "getTrackballScancodeState()")) {
- throw new SecurityException("Requires READ_INPUT_STATE permission");
- }
- return mInputManager.getScanCodeState(-1, InputDevice.SOURCE_TRACKBALL, sw);
- }
-
- public int getDPadScancodeState(int sw) {
- if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
- "getDPadScancodeState()")) {
- throw new SecurityException("Requires READ_INPUT_STATE permission");
- }
- return mInputManager.getScanCodeState(-1, InputDevice.SOURCE_DPAD, sw);
- }
-
- public int getKeycodeState(int sw) {
- if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
- "getKeycodeState()")) {
- throw new SecurityException("Requires READ_INPUT_STATE permission");
- }
- return mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_ANY, sw);
- }
-
- public int getKeycodeStateForDevice(int devid, int sw) {
- if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
- "getKeycodeStateForDevice()")) {
- throw new SecurityException("Requires READ_INPUT_STATE permission");
- }
- return mInputManager.getKeyCodeState(devid, InputDevice.SOURCE_ANY, sw);
- }
-
- public int getTrackballKeycodeState(int sw) {
- if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
- "getTrackballKeycodeState()")) {
- throw new SecurityException("Requires READ_INPUT_STATE permission");
- }
- return mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_TRACKBALL, sw);
- }
-
- public int getDPadKeycodeState(int sw) {
- if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
- "getDPadKeycodeState()")) {
- throw new SecurityException("Requires READ_INPUT_STATE permission");
+ // Called by window manager policy. Not exposed externally.
+ @Override
+ public int getLidState() {
+ final int SW_LID = 0x00;
+ int sw = mInputManager.getSwitchState(-1, InputDevice.SOURCE_ANY, SW_LID);
+ if (sw > 0) {
+ return LID_OPEN;
+ } else if (sw == 0) {
+ return LID_CLOSED;
+ } else {
+ return LID_ABSENT;
}
- return mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_DPAD, sw);
- }
-
- public boolean hasKeys(int[] keycodes, boolean[] keyExists) {
- return mInputManager.hasKeys(-1, InputDevice.SOURCE_ANY, keycodes, keyExists);
}
+ // Called by window manager policy. Not exposed externally.
+ @Override
public InputChannel monitorInput(String inputChannelName) {
if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
"monitorInput()")) {
@@ -4951,14 +4879,6 @@ public class WindowManagerService extends IWindowManager.Stub
mInputManager.setInputFilter(filter);
}
- public InputDevice getInputDevice(int deviceId) {
- return mInputManager.getInputDevice(deviceId);
- }
-
- public int[] getInputDeviceIds() {
- return mInputManager.getInputDeviceIds();
- }
-
public void enableScreenAfterBoot() {
synchronized(mWindowMap) {
if (DEBUG_BOOT) {
@@ -6444,164 +6364,6 @@ public class WindowManagerService extends IWindowManager.Stub
sendScreenStatusToClients();
}
- /**
- * Injects a keystroke event into the UI.
- * Even when sync is false, this method may block while waiting for current
- * input events to be dispatched.
- *
- * @param ev A motion event describing the keystroke action. (Be sure to use
- * {@link SystemClock#uptimeMillis()} as the timebase.)
- * @param sync If true, wait for the event to be completed before returning to the caller.
- * @return Returns true if event was dispatched, false if it was dropped for any reason
- */
- public boolean injectKeyEvent(KeyEvent ev, boolean sync) {
- long downTime = ev.getDownTime();
- long eventTime = ev.getEventTime();
-
- int action = ev.getAction();
- int code = ev.getKeyCode();
- int repeatCount = ev.getRepeatCount();
- int metaState = ev.getMetaState();
- int deviceId = ev.getDeviceId();
- int scancode = ev.getScanCode();
- int source = ev.getSource();
- int flags = ev.getFlags();
-
- if (source == InputDevice.SOURCE_UNKNOWN) {
- source = InputDevice.SOURCE_KEYBOARD;
- }
-
- if (eventTime == 0) eventTime = SystemClock.uptimeMillis();
- if (downTime == 0) downTime = eventTime;
-
- KeyEvent newEvent = new KeyEvent(downTime, eventTime, action, code, repeatCount, metaState,
- deviceId, scancode, flags | KeyEvent.FLAG_FROM_SYSTEM, source);
-
- final int pid = Binder.getCallingPid();
- final int uid = Binder.getCallingUid();
- final long ident = Binder.clearCallingIdentity();
-
- final int result = mInputManager.injectInputEvent(newEvent, pid, uid,
- sync ? InputManagerService.INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISH
- : InputManagerService.INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT,
- INJECTION_TIMEOUT_MILLIS);
-
- Binder.restoreCallingIdentity(ident);
- return reportInjectionResult(result, pid);
- }
-
- /**
- * Inject a pointer (touch) event into the UI.
- * Even when sync is false, this method may block while waiting for current
- * input events to be dispatched.
- *
- * @param ev A motion event describing the pointer (touch) action. (As noted in
- * {@link MotionEvent#obtain(long, long, int, float, float, int)}, be sure to use
- * {@link SystemClock#uptimeMillis()} as the timebase.)
- * @param sync If true, wait for the event to be completed before returning to the caller.
- * @return Returns true if event was dispatched, false if it was dropped for any reason
- */
- public boolean injectPointerEvent(MotionEvent ev, boolean sync) {
- final int pid = Binder.getCallingPid();
- final int uid = Binder.getCallingUid();
- final long ident = Binder.clearCallingIdentity();
-
- MotionEvent newEvent = MotionEvent.obtain(ev);
- if ((newEvent.getSource() & InputDevice.SOURCE_CLASS_POINTER) == 0) {
- newEvent.setSource(InputDevice.SOURCE_TOUCHSCREEN);
- }
-
- final int result = mInputManager.injectInputEvent(newEvent, pid, uid,
- sync ? InputManagerService.INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISH
- : InputManagerService.INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT,
- INJECTION_TIMEOUT_MILLIS);
-
- Binder.restoreCallingIdentity(ident);
- return reportInjectionResult(result, pid);
- }
-
- /**
- * Inject a trackball (navigation device) event into the UI.
- * Even when sync is false, this method may block while waiting for current
- * input events to be dispatched.
- *
- * @param ev A motion event describing the trackball action. (As noted in
- * {@link MotionEvent#obtain(long, long, int, float, float, int)}, be sure to use
- * {@link SystemClock#uptimeMillis()} as the timebase.)
- * @param sync If true, wait for the event to be completed before returning to the caller.
- * @return Returns true if event was dispatched, false if it was dropped for any reason
- */
- public boolean injectTrackballEvent(MotionEvent ev, boolean sync) {
- final int pid = Binder.getCallingPid();
- final int uid = Binder.getCallingUid();
- final long ident = Binder.clearCallingIdentity();
-
- MotionEvent newEvent = MotionEvent.obtain(ev);
- if ((newEvent.getSource() & InputDevice.SOURCE_CLASS_TRACKBALL) == 0) {
- newEvent.setSource(InputDevice.SOURCE_TRACKBALL);
- }
-
- final int result = mInputManager.injectInputEvent(newEvent, pid, uid,
- sync ? InputManagerService.INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISH
- : InputManagerService.INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT,
- INJECTION_TIMEOUT_MILLIS);
-
- Binder.restoreCallingIdentity(ident);
- return reportInjectionResult(result, pid);
- }
-
- /**
- * Inject an input event into the UI without waiting for dispatch to commence.
- * This variant is useful for fire-and-forget input event injection. It does not
- * block any longer than it takes to enqueue the input event.
- *
- * @param ev An input event. (Be sure to set the input source correctly.)
- * @return Returns true if event was dispatched, false if it was dropped for any reason
- */
- public boolean injectInputEventNoWait(InputEvent ev) {
- final int pid = Binder.getCallingPid();
- final int uid = Binder.getCallingUid();
- final long ident = Binder.clearCallingIdentity();
-
- final int result = mInputManager.injectInputEvent(ev, pid, uid,
- InputManagerService.INPUT_EVENT_INJECTION_SYNC_NONE,
- INJECTION_TIMEOUT_MILLIS);
-
- Binder.restoreCallingIdentity(ident);
- return reportInjectionResult(result, pid);
- }
-
- private boolean reportInjectionResult(int result, int pid) {
- switch (result) {
- case InputManagerService.INPUT_EVENT_INJECTION_PERMISSION_DENIED:
- Slog.w(TAG, "Input event injection from pid " + pid + " permission denied.");
- throw new SecurityException(
- "Injecting to another application requires INJECT_EVENTS permission");
- case InputManagerService.INPUT_EVENT_INJECTION_SUCCEEDED:
- return true;
- case InputManagerService.INPUT_EVENT_INJECTION_TIMED_OUT:
- Slog.w(TAG, "Input event injection from pid " + pid + " timed out.");
- return false;
- case InputManagerService.INPUT_EVENT_INJECTION_FAILED:
- default:
- Slog.w(TAG, "Input event injection from pid " + pid + " failed.");
- return false;
- }
- }
-
- /**
- * Temporarily set the pointer speed. Does not save the new setting.
- * Used by the settings application.
- */
- public void setPointerSpeed(int speed) {
- if (!checkCallingPermission(android.Manifest.permission.SET_POINTER_SPEED,
- "setPointerSpeed()")) {
- throw new SecurityException("Requires SET_POINTER_SPEED permission");
- }
-
- mInputManager.setPointerSpeed(speed);
- }
-
private WindowState getFocusedWindow() {
synchronized (mWindowMap) {
return getFocusedWindowLocked();
@@ -6616,11 +6378,29 @@ public class WindowManagerService extends IWindowManager.Stub
if (!mInputMonitor.waitForInputDevicesReady(
INPUT_DEVICES_READY_FOR_SAFE_MODE_DETECTION_TIMEOUT_MILLIS)) {
Slog.w(TAG, "Devices still not ready after waiting "
- + INPUT_DEVICES_READY_FOR_SAFE_MODE_DETECTION_TIMEOUT_MILLIS
- + " milliseconds before attempting to detect safe mode.");
+ + INPUT_DEVICES_READY_FOR_SAFE_MODE_DETECTION_TIMEOUT_MILLIS
+ + " milliseconds before attempting to detect safe mode.");
+ }
+
+ final int BTN_MOUSE = 0x110;
+ int menuState = mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_ANY,
+ KeyEvent.KEYCODE_MENU);
+ int sState = mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_ANY, KeyEvent.KEYCODE_S);
+ int dpadState = mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_DPAD,
+ KeyEvent.KEYCODE_DPAD_CENTER);
+ int trackballState = mInputManager.getScanCodeState(-1, InputDevice.SOURCE_TRACKBALL,
+ BTN_MOUSE);
+ int volumeDownState = mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_ANY,
+ KeyEvent.KEYCODE_VOLUME_DOWN);
+ mSafeMode = menuState > 0 || sState > 0 || dpadState > 0 || trackballState > 0
+ || volumeDownState > 0;
+ if (mSafeMode) {
+ Log.i(TAG, "SAFE MODE ENABLED (menu=" + menuState + " s=" + sState
+ + " dpad=" + dpadState + " trackball=" + trackballState + ")");
+ } else {
+ Log.i(TAG, "SAFE MODE not enabled");
}
-
- mSafeMode = mPolicy.detectSafeMode();
+ mPolicy.setSafeMode(mSafeMode);
return mSafeMode;
}
diff --git a/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java b/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java
index 58f65be..1f6279c 100644
--- a/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java
+++ b/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java
@@ -255,41 +255,6 @@ public class WindowManagerPermissionTests extends TestCase {
}
@SmallTest
- public void testINJECT_EVENTS() {
- try {
- mWm.injectKeyEvent(new KeyEvent(0, 0), false);
- fail("IWindowManager.injectKeyEvent did not throw SecurityException as"
- + " expected");
- } catch (SecurityException e) {
- // expected
- } catch (RemoteException e) {
- fail("Unexpected remote exception");
- }
-
- try {
- mWm.injectPointerEvent(MotionEvent.obtain(0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0), false);
- fail("IWindowManager.injectPointerEvent did not throw SecurityException as"
- + " expected");
- } catch (SecurityException e) {
- // expected
- } catch (RemoteException e) {
- fail("Unexpected remote exception");
- }
-
- try {
- mWm.injectTrackballEvent(MotionEvent.obtain(0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0), false);
- fail("IWindowManager.injectTrackballEvent did not throw SecurityException as"
- + " expected");
- } catch (SecurityException e) {
- // expected
- } catch (RemoteException e) {
- fail("Unexpected remote exception");
- }
- }
-
- @SmallTest
public void testDISABLE_KEYGUARD() {
Binder token = new Binder();
try {
@@ -347,73 +312,9 @@ public class WindowManagerPermissionTests extends TestCase {
}
@SmallTest
- public void testREAD_INPUT_STATE() {
- try {
- mWm.getSwitchState(0);
- fail("IWindowManager.getSwitchState did not throw SecurityException as"
- + " expected");
- } catch (SecurityException e) {
- // expected
- } catch (RemoteException e) {
- fail("Unexpected remote exception");
- }
-
- try {
- mWm.getSwitchStateForDevice(0, 0);
- fail("IWindowManager.getSwitchStateForDevice did not throw SecurityException as"
- + " expected");
- } catch (SecurityException e) {
- // expected
- } catch (RemoteException e) {
- fail("Unexpected remote exception");
- }
-
- try {
- mWm.getScancodeState(0);
- fail("IWindowManager.getScancodeState did not throw SecurityException as"
- + " expected");
- } catch (SecurityException e) {
- // expected
- } catch (RemoteException e) {
- fail("Unexpected remote exception");
- }
-
- try {
- mWm.getScancodeStateForDevice(0, 0);
- fail("IWindowManager.getScancodeStateForDevice did not throw SecurityException as"
- + " expected");
- } catch (SecurityException e) {
- // expected
- } catch (RemoteException e) {
- fail("Unexpected remote exception");
- }
-
- try {
- mWm.getKeycodeState(0);
- fail("IWindowManager.getKeycodeState did not throw SecurityException as"
- + " expected");
- } catch (SecurityException e) {
- // expected
- } catch (RemoteException e) {
- fail("Unexpected remote exception");
- }
-
- try {
- mWm.getKeycodeStateForDevice(0, 0);
- fail("IWindowManager.getKeycodeStateForDevice did not throw SecurityException as"
- + " expected");
- } catch (SecurityException e) {
- // expected
- } catch (RemoteException e) {
- fail("Unexpected remote exception");
- }
- }
-
- @SmallTest
public void testSET_ORIENTATION() {
try {
mWm.updateRotation(true, false);
- mWm.getSwitchState(0);
fail("IWindowManager.updateRotation did not throw SecurityException as"
+ " expected");
} catch (SecurityException e) {
@@ -424,7 +325,6 @@ public class WindowManagerPermissionTests extends TestCase {
try {
mWm.freezeRotation(-1);
- mWm.getSwitchState(0);
fail("IWindowManager.freezeRotation did not throw SecurityException as"
+ " expected");
} catch (SecurityException e) {
@@ -435,7 +335,6 @@ public class WindowManagerPermissionTests extends TestCase {
try {
mWm.thawRotation();
- mWm.getSwitchState(0);
fail("IWindowManager.thawRotation did not throw SecurityException as"
+ " expected");
} catch (SecurityException e) {
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowManager.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowManager.java
index 0755670..e6c9351 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowManager.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowManager.java
@@ -161,92 +161,11 @@ public class BridgeWindowManager implements IWindowManager {
}
@Override
- public int getDPadKeycodeState(int arg0) throws RemoteException {
- // TODO Auto-generated method stub
- return 0;
- }
-
- @Override
- public int getDPadScancodeState(int arg0) throws RemoteException {
- // TODO Auto-generated method stub
- return 0;
- }
-
-
- @Override
- public InputDevice getInputDevice(int arg0) throws RemoteException {
- // TODO Auto-generated method stub
- return null;
- }
-
- @Override
- public int[] getInputDeviceIds() throws RemoteException {
- // TODO Auto-generated method stub
- return null;
- }
-
- @Override
- public int getKeycodeState(int arg0) throws RemoteException {
- // TODO Auto-generated method stub
- return 0;
- }
-
- @Override
- public int getKeycodeStateForDevice(int arg0, int arg1) throws RemoteException {
- // TODO Auto-generated method stub
- return 0;
- }
-
-
- @Override
public int getPendingAppTransition() throws RemoteException {
// TODO Auto-generated method stub
return 0;
}
-
- @Override
- public int getScancodeState(int arg0) throws RemoteException {
- // TODO Auto-generated method stub
- return 0;
- }
-
- @Override
- public int getScancodeStateForDevice(int arg0, int arg1) throws RemoteException {
- // TODO Auto-generated method stub
- return 0;
- }
-
- @Override
- public int getSwitchState(int arg0) throws RemoteException {
- // TODO Auto-generated method stub
- return 0;
- }
-
- @Override
- public int getSwitchStateForDevice(int arg0, int arg1) throws RemoteException {
- // TODO Auto-generated method stub
- return 0;
- }
-
- @Override
- public int getTrackballKeycodeState(int arg0) throws RemoteException {
- // TODO Auto-generated method stub
- return 0;
- }
-
- @Override
- public int getTrackballScancodeState(int arg0) throws RemoteException {
- // TODO Auto-generated method stub
- return 0;
- }
-
- @Override
- public boolean hasKeys(int[] arg0, boolean[] arg1) throws RemoteException {
- // TODO Auto-generated method stub
- return false;
- }
-
@Override
public boolean inKeyguardRestrictedInputMode() throws RemoteException {
// TODO Auto-generated method stub
@@ -254,30 +173,6 @@ public class BridgeWindowManager implements IWindowManager {
}
@Override
- public boolean injectInputEventNoWait(InputEvent arg0) throws RemoteException {
- // TODO Auto-generated method stub
- return false;
- }
-
- @Override
- public boolean injectKeyEvent(KeyEvent arg0, boolean arg1) throws RemoteException {
- // TODO Auto-generated method stub
- return false;
- }
-
- @Override
- public boolean injectPointerEvent(MotionEvent arg0, boolean arg1) throws RemoteException {
- // TODO Auto-generated method stub
- return false;
- }
-
- @Override
- public boolean injectTrackballEvent(MotionEvent arg0, boolean arg1) throws RemoteException {
- // TODO Auto-generated method stub
- return false;
- }
-
- @Override
public boolean inputMethodClientHasFocus(IInputMethodClient arg0) throws RemoteException {
// TODO Auto-generated method stub
return false;
@@ -302,12 +197,6 @@ public class BridgeWindowManager implements IWindowManager {
}
@Override
- public InputChannel monitorInput(String arg0) throws RemoteException {
- // TODO Auto-generated method stub
- return null;
- }
-
- @Override
public void moveAppToken(int arg0, IBinder arg1) throws RemoteException {
// TODO Auto-generated method stub
@@ -462,12 +351,6 @@ public class BridgeWindowManager implements IWindowManager {
}
@Override
- public void setPointerSpeed(int arg0) throws RemoteException {
- // TODO Auto-generated method stub
-
- }
-
- @Override
public void updateRotation(boolean arg0, boolean arg1) throws RemoteException {
// TODO Auto-generated method stub
}