summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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
}