From 6af0d50a8edb101d9da1306b6d85abf5dd3f9a30 Mon Sep 17 00:00:00 2001 From: Dianne Hackborn Date: Mon, 28 Sep 2009 13:25:46 -0700 Subject: [PATCH] Fix issue #2149145: Safe Mode does not work on Sholes device The APIs for checking whether keys are held down now also look at virtual keys. However it turns out there is less than a second between the time we start the input thread and check for safe mode, so there is not enough time to actually open all of the devices and get the data from them about the finger being down to determine if a virtual key is down. So now you can also hold DPAD center, trackball center, or s to enter safe mode. Also give some vibrator feedback. Change-Id: I55edce63bc0c375813bd3751766b8070beeb0153 --- .../android/view/HapticFeedbackConstants.java | 12 ++++ .../android/view/WindowManagerPolicy.java | 2 +- core/res/res/values/config.xml | 18 ++++++ .../com/android/server/KeyInputQueue.java | 56 +++++++++++++++++-- .../java/com/android/server/SystemServer.java | 11 +++- .../android/server/WindowManagerService.java | 8 +-- .../jni/com_android_server_KeyInputQueue.cpp | 8 +-- 7 files changed, 101 insertions(+), 14 deletions(-) diff --git a/core/java/android/view/HapticFeedbackConstants.java b/core/java/android/view/HapticFeedbackConstants.java index f936f65cef527..e1f2823989b62 100644 --- a/core/java/android/view/HapticFeedbackConstants.java +++ b/core/java/android/view/HapticFeedbackConstants.java @@ -35,6 +35,18 @@ public class HapticFeedbackConstants { */ public static final int VIRTUAL_KEY = 1; + /** + * This is a private constant. Feel free to renumber as desired. + * @hide + */ + public static final int SAFE_MODE_DISABLED = 10000; + + /** + * This is a private constant. Feel free to renumber as desired. + * @hide + */ + public static final int SAFE_MODE_ENABLED = 10001; + /** * Flag for {@link View#performHapticFeedback(int, int) * View.performHapticFeedback(int, int)}: Ignore the setting in the diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java index b3125b2077eb6..78999fa51bbab 100644 --- a/core/java/android/view/WindowManagerPolicy.java +++ b/core/java/android/view/WindowManagerPolicy.java @@ -813,7 +813,7 @@ public interface WindowManagerPolicy { boolean displayEnabled); /** - * Called when the system is mostly done booting to dentermine whether + * Called when the system is mostly done booting to determine whether * the system should go into safe mode. */ public boolean detectSafeMode(); diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index 907fd8f77cc0d..498b5cf1e90fe 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -124,6 +124,24 @@ 30 + + + 0 + 1 + 20 + 21 + + + + + 0 + 1 + 20 + 21 + 500 + 600 + + false diff --git a/services/java/com/android/server/KeyInputQueue.java b/services/java/com/android/server/KeyInputQueue.java index d9f4c9c7654b2..d7b8f57098d34 100644 --- a/services/java/com/android/server/KeyInputQueue.java +++ b/services/java/com/android/server/KeyInputQueue.java @@ -337,6 +337,54 @@ public abstract class KeyInputQueue { } } + public int getScancodeState(int code) { + synchronized (mFirst) { + VirtualKey vk = mPressedVirtualKey; + if (vk != null) { + if (vk.scancode == code) { + return 2; + } + } + return nativeGetScancodeState(code); + } + } + + public int getScancodeState(int deviceId, int code) { + synchronized (mFirst) { + VirtualKey vk = mPressedVirtualKey; + if (vk != null) { + if (vk.scancode == code) { + return 2; + } + } + return nativeGetScancodeState(deviceId, code); + } + } + + public int getKeycodeState(int code) { + synchronized (mFirst) { + VirtualKey vk = mPressedVirtualKey; + if (vk != null) { + if (vk.lastKeycode == code) { + return 2; + } + } + return nativeGetKeycodeState(code); + } + } + + public int getKeycodeState(int deviceId, int code) { + synchronized (mFirst) { + VirtualKey vk = mPressedVirtualKey; + if (vk != null) { + if (vk.lastKeycode == code) { + return 2; + } + } + return nativeGetKeycodeState(deviceId, code); + } + } + public static native String getDeviceName(int deviceId); public static native int getDeviceClasses(int deviceId); public static native void addExcludedDevice(String deviceName); @@ -344,10 +392,10 @@ public abstract class KeyInputQueue { InputDevice.AbsoluteInfo outInfo); public static native int getSwitchState(int sw); public static native int getSwitchState(int deviceId, int sw); - public static native int getScancodeState(int sw); - public static native int getScancodeState(int deviceId, int sw); - public static native int getKeycodeState(int sw); - public static native int getKeycodeState(int deviceId, int sw); + public static native int nativeGetScancodeState(int code); + public static native int nativeGetScancodeState(int deviceId, int code); + public static native int nativeGetKeycodeState(int code); + public static native int nativeGetKeycodeState(int deviceId, int code); public static native int scancodeToKeycode(int deviceId, int scancode); public static native boolean hasKeys(int[] keycodes, boolean[] keyExists); diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java index b3b50e56c86eb..65b3e3fea19d0 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -365,8 +365,17 @@ class ServerThread extends Thread { mContentResolver.registerContentObserver(Settings.Secure.getUriFor(Settings.Secure.ADB_ENABLED), false, new AdbSettingsObserver()); - // It is now time to start up the app processes... + // Before things start rolling, be sure we have decided whether + // we are in safe mode. final boolean safeMode = wm.detectSafeMode(); + if (safeMode) { + try { + ActivityManagerNative.getDefault().enterSafeMode(); + } catch (RemoteException e) { + } + } + + // It is now time to start up the app processes... if (notification != null) { notification.systemReady(); diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java index 228d25e15281b..30855b1cfab28 100644 --- a/services/java/com/android/server/WindowManagerService.java +++ b/services/java/com/android/server/WindowManagerService.java @@ -4108,7 +4108,7 @@ public class WindowManagerService extends IWindowManager.Stub "getScancodeState()")) { throw new SecurityException("Requires READ_INPUT_STATE permission"); } - return KeyInputQueue.getScancodeState(sw); + return mQueue.getScancodeState(sw); } public int getScancodeStateForDevice(int devid, int sw) { @@ -4116,7 +4116,7 @@ public class WindowManagerService extends IWindowManager.Stub "getScancodeStateForDevice()")) { throw new SecurityException("Requires READ_INPUT_STATE permission"); } - return KeyInputQueue.getScancodeState(devid, sw); + return mQueue.getScancodeState(devid, sw); } public int getKeycodeState(int sw) { @@ -4124,7 +4124,7 @@ public class WindowManagerService extends IWindowManager.Stub "getKeycodeState()")) { throw new SecurityException("Requires READ_INPUT_STATE permission"); } - return KeyInputQueue.getKeycodeState(sw); + return mQueue.getKeycodeState(sw); } public int getKeycodeStateForDevice(int devid, int sw) { @@ -4132,7 +4132,7 @@ public class WindowManagerService extends IWindowManager.Stub "getKeycodeStateForDevice()")) { throw new SecurityException("Requires READ_INPUT_STATE permission"); } - return KeyInputQueue.getKeycodeState(devid, sw); + return mQueue.getKeycodeState(devid, sw); } public boolean hasKeys(int[] keycodes, boolean[] keyExists) { diff --git a/services/jni/com_android_server_KeyInputQueue.cpp b/services/jni/com_android_server_KeyInputQueue.cpp index f27596c5c581a..c92f8df58c846 100644 --- a/services/jni/com_android_server_KeyInputQueue.cpp +++ b/services/jni/com_android_server_KeyInputQueue.cpp @@ -280,13 +280,13 @@ static JNINativeMethod gInputMethods[] = { (void*) android_server_KeyInputQueue_getSwitchState }, { "getSwitchState", "(II)I", (void*) android_server_KeyInputQueue_getSwitchStateDevice }, - { "getScancodeState", "(I)I", + { "nativeGetScancodeState", "(I)I", (void*) android_server_KeyInputQueue_getScancodeState }, - { "getScancodeState", "(II)I", + { "nativeGetScancodeState", "(II)I", (void*) android_server_KeyInputQueue_getScancodeStateDevice }, - { "getKeycodeState", "(I)I", + { "nativeGetKeycodeState", "(I)I", (void*) android_server_KeyInputQueue_getKeycodeState }, - { "getKeycodeState", "(II)I", + { "nativeGetKeycodeState", "(II)I", (void*) android_server_KeyInputQueue_getKeycodeStateDevice }, { "hasKeys", "([I[Z)Z", (void*) android_server_KeyInputQueue_hasKeys },