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 },