Merge "Caps Lock toggle with Meta + Alt (2/2)" into nyc-dev
diff --git a/core/java/android/hardware/input/InputManager.java b/core/java/android/hardware/input/InputManager.java
index fbac58c..47440de 100644
--- a/core/java/android/hardware/input/InputManager.java
+++ b/core/java/android/hardware/input/InputManager.java
@@ -16,9 +16,7 @@
package android.hardware.input;
-import com.android.internal.inputmethod.InputMethodSubtypeHandle;
import com.android.internal.os.SomeArgs;
-import com.android.internal.util.ArrayUtils;
import android.annotation.IntDef;
import android.annotation.SdkConstant;
diff --git a/core/java/android/hardware/input/InputManagerInternal.java b/core/java/android/hardware/input/InputManagerInternal.java
index 014e73f..10fc8e6 100644
--- a/core/java/android/hardware/input/InputManagerInternal.java
+++ b/core/java/android/hardware/input/InputManagerInternal.java
@@ -52,4 +52,11 @@
*/
public abstract void onInputMethodSubtypeChanged(int userId,
@Nullable InputMethodInfo inputMethodInfo, @Nullable InputMethodSubtype subtype);
+
+ /**
+ * Toggles Caps Lock state for input device with specific id.
+ *
+ * @param deviceId The id of input device.
+ */
+ public abstract void toggleCapsLock(int deviceId);
}
diff --git a/core/java/android/view/KeyEvent.java b/core/java/android/view/KeyEvent.java
index e0c6770..636384c 100644
--- a/core/java/android/view/KeyEvent.java
+++ b/core/java/android/view/KeyEvent.java
@@ -1870,6 +1870,11 @@
return keyCode == KeyEvent.KEYCODE_META_LEFT || keyCode == KeyEvent.KEYCODE_META_RIGHT;
}
+ /** @hide */
+ public static final boolean isAltKey(int keyCode) {
+ return keyCode == KeyEvent.KEYCODE_ALT_LEFT || keyCode == KeyEvent.KEYCODE_ALT_RIGHT;
+ }
+
/** {@inheritDoc} */
@Override
public final int getDeviceId() {
diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java
index e73beaa..c7c765bb 100644
--- a/services/core/java/com/android/server/input/InputManagerService.java
+++ b/services/core/java/com/android/server/input/InputManagerService.java
@@ -200,6 +200,7 @@
private static native int nativeInjectInputEvent(long ptr, InputEvent event, int displayId,
int injectorPid, int injectorUid, int syncMode, int timeoutMillis,
int policyFlags);
+ private static native void nativeToggleCapsLock(long ptr, int deviceId);
private static native void nativeSetInputWindows(long ptr, InputWindowHandle[] windowHandles);
private static native void nativeSetInputDispatchMode(long ptr, boolean enabled, boolean frozen);
private static native void nativeSetSystemUiVisibility(long ptr, int visibility);
@@ -2279,5 +2280,10 @@
mHandler.obtainMessage(MSG_INPUT_METHOD_SUBTYPE_CHANGED, userId, 0, someArgs)
.sendToTarget();
}
+
+ @Override
+ public void toggleCapsLock(int deviceId) {
+ nativeToggleCapsLock(mPtr, deviceId);
+ }
}
}
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 97c0cf1..fb56a0c 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -69,6 +69,7 @@
import android.hardware.hdmi.HdmiControlManager;
import android.hardware.hdmi.HdmiPlaybackClient;
import android.hardware.hdmi.HdmiPlaybackClient.OneTouchPlayCallback;
+import android.hardware.input.InputManagerInternal;
import android.media.AudioAttributes;
import android.media.AudioManager;
import android.media.AudioSystem;
@@ -305,6 +306,7 @@
WindowManagerInternal mWindowManagerInternal;
PowerManager mPowerManager;
ActivityManagerInternal mActivityManagerInternal;
+ InputManagerInternal mInputManagerInternal;
DreamManagerInternal mDreamManagerInternal;
PowerManagerInternal mPowerManagerInternal;
IStatusBarService mStatusBarService;
@@ -604,6 +606,9 @@
boolean mConsumeSearchKeyUp;
boolean mAssistKeyLongPressed;
boolean mPendingMetaAction;
+ boolean mPendingCapsLockToggle;
+ int mMetaState;
+ int mInitialMetaState;
boolean mForceShowSystemBars;
// support for activating the lock screen while the screen is on
@@ -1494,6 +1499,7 @@
mWindowManagerFuncs = windowManagerFuncs;
mWindowManagerInternal = LocalServices.getService(WindowManagerInternal.class);
mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
+ mInputManagerInternal = LocalServices.getService(InputManagerInternal.class);
mDreamManagerInternal = LocalServices.getService(DreamManagerInternal.class);
mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class);
mAppOpsManager = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE);
@@ -2968,6 +2974,10 @@
if (mPendingMetaAction && !KeyEvent.isMetaKey(keyCode)) {
mPendingMetaAction = false;
}
+ // Any key that is not Alt or Meta cancels Caps Lock combo tracking.
+ if (mPendingCapsLockToggle && !KeyEvent.isMetaKey(keyCode) && !KeyEvent.isAltKey(keyCode)) {
+ mPendingCapsLockToggle = false;
+ }
// First we always handle the home key here, so applications
// can never break it, although if keyguard is on, we do let
@@ -3216,6 +3226,38 @@
}
}
+ // Toggle Caps Lock on META-ALT.
+ boolean actionTriggered = false;
+ if (KeyEvent.isModifierKey(keyCode)) {
+ if (!mPendingCapsLockToggle) {
+ // Start tracking meta state for combo.
+ mInitialMetaState = mMetaState;
+ mPendingCapsLockToggle = true;
+ } else if (event.getAction() == KeyEvent.ACTION_UP) {
+ int altOnMask = mMetaState & KeyEvent.META_ALT_MASK;
+ int metaOnMask = mMetaState & KeyEvent.META_META_MASK;
+
+ // Check for Caps Lock toggle
+ if ((metaOnMask != 0) && (altOnMask != 0)) {
+ // Check if nothing else is pressed
+ if (mInitialMetaState == (mMetaState ^ (altOnMask | metaOnMask))) {
+ // Handle Caps Lock Toggle
+ mInputManagerInternal.toggleCapsLock(event.getDeviceId());
+ actionTriggered = true;
+ }
+ }
+
+ // Always stop tracking when key goes up.
+ mPendingCapsLockToggle = false;
+ }
+ }
+ // Store current meta state to be able to evaluate it later.
+ mMetaState = metaState;
+
+ if (actionTriggered) {
+ return -1;
+ }
+
if (KeyEvent.isMetaKey(keyCode)) {
if (down) {
mPendingMetaAction = true;
diff --git a/services/core/jni/com_android_server_input_InputManagerService.cpp b/services/core/jni/com_android_server_input_InputManagerService.cpp
index a5237ca..cd485c5 100644
--- a/services/core/jni/com_android_server_input_InputManagerService.cpp
+++ b/services/core/jni/com_android_server_input_InputManagerService.cpp
@@ -1312,6 +1312,12 @@
}
}
+static void nativeToggleCapsLock(JNIEnv* env, jclass /* clazz */,
+ jlong ptr, jint deviceId) {
+ NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+ im->getInputManager()->getReader()->toggleCapsLockState(deviceId);
+}
+
static void nativeSetInputWindows(JNIEnv* env, jclass /* clazz */,
jlong ptr, jobjectArray windowHandleObjArray) {
NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
@@ -1508,6 +1514,8 @@
(void*) nativeSetInputFilterEnabled },
{ "nativeInjectInputEvent", "(JLandroid/view/InputEvent;IIIIII)I",
(void*) nativeInjectInputEvent },
+ { "nativeToggleCapsLock", "(JI)V",
+ (void*) nativeToggleCapsLock },
{ "nativeSetInputWindows", "(J[Lcom/android/server/input/InputWindowHandle;)V",
(void*) nativeSetInputWindows },
{ "nativeSetFocusedApplication", "(JLcom/android/server/input/InputApplicationHandle;)V",