diff --git a/api/current.txt b/api/current.txt
index 690fec7fdbb2b..f7651168205d7 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -41649,9 +41649,11 @@ package android.view {
}
public final class KeyboardShortcutInfo implements android.os.Parcelable {
+ ctor public KeyboardShortcutInfo(java.lang.CharSequence, int, int);
ctor public KeyboardShortcutInfo(java.lang.CharSequence, char, int);
method public int describeContents();
method public char getBaseCharacter();
+ method public int getKeycode();
method public java.lang.CharSequence getLabel();
method public int getModifiers();
method public void writeToParcel(android.os.Parcel, int);
diff --git a/api/system-current.txt b/api/system-current.txt
index f06e545628679..96c4ba1148f3d 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -44375,9 +44375,11 @@ package android.view {
}
public final class KeyboardShortcutInfo implements android.os.Parcelable {
+ ctor public KeyboardShortcutInfo(java.lang.CharSequence, int, int);
ctor public KeyboardShortcutInfo(java.lang.CharSequence, char, int);
method public int describeContents();
method public char getBaseCharacter();
+ method public int getKeycode();
method public java.lang.CharSequence getLabel();
method public int getModifiers();
method public void writeToParcel(android.os.Parcel, int);
diff --git a/api/test-current.txt b/api/test-current.txt
index 4afda9cfe65e2..6e8236002181d 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -41722,9 +41722,11 @@ package android.view {
}
public final class KeyboardShortcutInfo implements android.os.Parcelable {
+ ctor public KeyboardShortcutInfo(java.lang.CharSequence, int, int);
ctor public KeyboardShortcutInfo(java.lang.CharSequence, char, int);
method public int describeContents();
method public char getBaseCharacter();
+ method public int getKeycode();
method public java.lang.CharSequence getLabel();
method public int getModifiers();
method public void writeToParcel(android.os.Parcel, int);
diff --git a/core/java/android/view/KeyboardShortcutInfo.java b/core/java/android/view/KeyboardShortcutInfo.java
index 2c9006deb1899..c2bd347687a6c 100644
--- a/core/java/android/view/KeyboardShortcutInfo.java
+++ b/core/java/android/view/KeyboardShortcutInfo.java
@@ -30,31 +30,46 @@ public final class KeyboardShortcutInfo implements Parcelable {
private final CharSequence mLabel;
private final Icon mIcon;
private final char mBaseCharacter;
+ private final int mKeycode;
private final int mModifiers;
/**
* @param label The label that identifies the action performed by this shortcut.
* @param icon An icon that identifies the action performed by this shortcut.
- * @param baseCharacter The character that triggers the shortcut.
+ * @param keycode The keycode that triggers the shortcut. This should be a valid constant
+ * defined in {@link KeyEvent}.
* @param modifiers The set of modifiers that, combined with the key, trigger the shortcut.
* These should be a combination of {@link KeyEvent#META_CTRL_ON},
- * {@link KeyEvent#META_SHIFT_ON}, {@link KeyEvent#META_META_ON} and
- * {@link KeyEvent#META_ALT_ON}.
+ * {@link KeyEvent#META_SHIFT_ON}, {@link KeyEvent#META_META_ON},
+ * {@link KeyEvent#META_ALT_ON}, {@link KeyEvent#META_FUNCTION_ON} and
+ * {@link KeyEvent#META_SYM_ON}.
*
* @hide
*/
public KeyboardShortcutInfo(
- @Nullable CharSequence label, @Nullable Icon icon, char baseCharacter, int modifiers) {
+ @Nullable CharSequence label, @Nullable Icon icon, int keycode, int modifiers) {
mLabel = label;
mIcon = icon;
- checkArgument(baseCharacter != MIN_VALUE);
- mBaseCharacter = baseCharacter;
+ mBaseCharacter = MIN_VALUE;
+ checkArgument(keycode > KeyEvent.KEYCODE_UNKNOWN && keycode <= KeyEvent.getMaxKeyCode());
+ mKeycode = keycode;
mModifiers = modifiers;
}
/**
- * Convenience constructor for shortcuts with a label and no icon.
- *
+ * @param label The label that identifies the action performed by this shortcut.
+ * @param keycode The keycode that triggers the shortcut. This should be a valid constant
+ * defined in {@link KeyEvent}.
+ * @param modifiers The set of modifiers that, combined with the key, trigger the shortcut.
+ * These should be a combination of {@link KeyEvent#META_CTRL_ON},
+ * {@link KeyEvent#META_SHIFT_ON}, {@link KeyEvent#META_META_ON} and
+ * {@link KeyEvent#META_ALT_ON}.
+ */
+ public KeyboardShortcutInfo(CharSequence label, int keycode, int modifiers) {
+ this(label, null, keycode, modifiers);
+ }
+
+ /**
* @param label The label that identifies the action performed by this shortcut.
* @param baseCharacter The character that triggers the shortcut.
* @param modifiers The set of modifiers that, combined with the key, trigger the shortcut.
@@ -66,14 +81,16 @@ public final class KeyboardShortcutInfo implements Parcelable {
mLabel = label;
checkArgument(baseCharacter != MIN_VALUE);
mBaseCharacter = baseCharacter;
+ mKeycode = KeyEvent.KEYCODE_UNKNOWN;
mModifiers = modifiers;
mIcon = null;
}
private KeyboardShortcutInfo(Parcel source) {
mLabel = source.readCharSequence();
- mIcon = (Icon) source.readParcelable(null);
+ mIcon = source.readParcelable(null);
mBaseCharacter = (char) source.readInt();
+ mKeycode = source.readInt();
mModifiers = source.readInt();
}
@@ -96,7 +113,16 @@ public final class KeyboardShortcutInfo implements Parcelable {
}
/**
- * Returns the base character that, combined with the modifiers, triggers this shortcut.
+ * Returns the base keycode that, combined with the modifiers, triggers this shortcut. If the
+ * base character was set instead, returns {@link KeyEvent#KEYCODE_UNKNOWN}.
+ */
+ public int getKeycode() {
+ return mKeycode;
+ }
+
+ /**
+ * Returns the base character that, combined with the modifiers, triggers this shortcut. If the
+ * keycode was set instead, returns {@link Character#MIN_VALUE}.
*/
public char getBaseCharacter() {
return mBaseCharacter;
@@ -119,6 +145,7 @@ public final class KeyboardShortcutInfo implements Parcelable {
dest.writeCharSequence(mLabel);
dest.writeParcelable(mIcon, 0);
dest.writeInt(mBaseCharacter);
+ dest.writeInt(mKeycode);
dest.writeInt(mModifiers);
}
diff --git a/core/java/com/android/internal/statusbar/IStatusBar.aidl b/core/java/com/android/internal/statusbar/IStatusBar.aidl
index 64c5b8de46a9c..b243cac291822 100644
--- a/core/java/com/android/internal/statusbar/IStatusBar.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBar.aidl
@@ -65,7 +65,7 @@ oneway interface IStatusBar
void cancelPreloadRecentApps();
void showScreenPinningRequest();
- void toggleKeyboardShortcutsMenu();
+ void toggleKeyboardShortcutsMenu(int deviceId);
/**
* Notifies the status bar that an app transition is pending to delay applying some flags with
diff --git a/core/java/com/android/internal/statusbar/IStatusBarService.aidl b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
index 8acf5d3070d39..ee3f9379b03ef 100644
--- a/core/java/com/android/internal/statusbar/IStatusBarService.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
@@ -71,7 +71,7 @@ interface IStatusBarService
void preloadRecentApps();
void cancelPreloadRecentApps();
- void toggleKeyboardShortcutsMenu();
+ void toggleKeyboardShortcutsMenu(int deviceId);
/**
* Notifies the status bar that an app transition is pending to delay applying some flags with
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index c9aa714e1fe29..6f0f30d26f2e8 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -1327,6 +1327,59 @@
Reduces performance and background data
+
+ Button %1$s
+
+ Home
+
+ Back
+
+ Up
+
+ Down
+
+ Left
+
+ Right
+
+ Center
+
+ Tab
+
+ Space
+
+ Enter
+
+ Backspace
+
+ Play/Pause
+
+ Stop
+
+ Next
+
+ Previous
+
+ Rewind
+
+ Fast Forward
+
+ Page Up
+
+ Page Down
+
+ Delete
+
+ Home
+
+ End
+
+ Insert
+
+ Num Lock
+
+ Numpad %1$s
+
System
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index ec56727bc040f..35f6db213adb3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -1210,10 +1210,10 @@ public abstract class BaseStatusBar extends SystemUI implements
}
@Override
- public void toggleKeyboardShortcutsMenu() {
+ public void toggleKeyboardShortcutsMenu(int deviceId) {
int msg = MSG_TOGGLE_KEYBOARD_SHORTCUTS_MENU;
mHandler.removeMessages(msg);
- mHandler.sendEmptyMessage(msg);
+ mHandler.obtainMessage(msg, deviceId, 0).sendToTarget();
}
/** Jumps to the next affiliated task in the group. */
@@ -1299,8 +1299,8 @@ public abstract class BaseStatusBar extends SystemUI implements
}
}
- protected void toggleKeyboardShortcuts() {
- getKeyboardShortcuts().toggleKeyboardShortcuts();
+ protected void toggleKeyboardShortcuts(int deviceId) {
+ getKeyboardShortcuts().toggleKeyboardShortcuts(deviceId);
}
protected void cancelPreloadingRecents() {
@@ -1473,7 +1473,7 @@ public abstract class BaseStatusBar extends SystemUI implements
showRecentsPreviousAffiliatedTask();
break;
case MSG_TOGGLE_KEYBOARD_SHORTCUTS_MENU:
- toggleKeyboardShortcuts();
+ toggleKeyboardShortcuts(m.arg1);
break;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
index 6a984887931df..0ffab5b7a141e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
@@ -107,7 +107,7 @@ public class CommandQueue extends IStatusBar.Stub {
public void toggleRecentApps();
public void toggleSplitScreen();
public void preloadRecentApps();
- public void toggleKeyboardShortcutsMenu();
+ public void toggleKeyboardShortcutsMenu(int deviceId);
public void cancelPreloadRecentApps();
public void setWindowState(int window, int state);
public void buzzBeepBlinked();
@@ -254,10 +254,10 @@ public class CommandQueue extends IStatusBar.Stub {
}
@Override
- public void toggleKeyboardShortcutsMenu() {
+ public void toggleKeyboardShortcutsMenu(int deviceId) {
synchronized (mLock) {
mHandler.removeMessages(MSG_TOGGLE_KEYBOARD_SHORTCUTS);
- mHandler.obtainMessage(MSG_TOGGLE_KEYBOARD_SHORTCUTS).sendToTarget();
+ mHandler.obtainMessage(MSG_TOGGLE_KEYBOARD_SHORTCUTS, deviceId, 0).sendToTarget();
}
}
@@ -425,7 +425,7 @@ public class CommandQueue extends IStatusBar.Stub {
mCallbacks.cancelPreloadRecentApps();
break;
case MSG_TOGGLE_KEYBOARD_SHORTCUTS:
- mCallbacks.toggleKeyboardShortcutsMenu();
+ mCallbacks.toggleKeyboardShortcutsMenu(msg.arg1);
break;
case MSG_SET_WINDOW_STATE:
mCallbacks.setWindowState(msg.arg1, msg.arg2);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcuts.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcuts.java
index 60c2fa61830c4..dc015c69799ef 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcuts.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcuts.java
@@ -21,9 +21,14 @@ import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
+import android.hardware.input.InputManager;
import android.os.Handler;
import android.os.Looper;
+import android.util.Log;
+import android.util.SparseArray;
import android.view.ContextThemeWrapper;
+import android.view.InputDevice;
+import android.view.KeyCharacterMap;
import android.view.KeyEvent;
import android.view.KeyboardShortcutGroup;
import android.view.KeyboardShortcutInfo;
@@ -42,16 +47,155 @@ import java.util.ArrayList;
import java.util.List;
import static android.content.Context.LAYOUT_INFLATER_SERVICE;
-import static android.view.Gravity.TOP;
import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG;
/**
* Contains functionality for handling keyboard shortcuts.
*/
public class KeyboardShortcuts {
- private static final char SYSTEM_HOME_BASE_CHARACTER = '\u2386';
- private static final char SYSTEM_BACK_BASE_CHARACTER = '\u007F';
- private static final char SYSTEM_RECENTS_BASE_CHARACTER = '\u0009';
+ private static final String TAG = KeyboardShortcuts.class.getSimpleName();
+
+ private static final SparseArray SPECIAL_CHARACTER_NAMES = new SparseArray<>();
+
+ private static void loadSpecialCharacterNames(Context context) {
+ SPECIAL_CHARACTER_NAMES.put(
+ KeyEvent.KEYCODE_HOME, context.getString(R.string.keyboard_key_home));
+ SPECIAL_CHARACTER_NAMES.put(
+ KeyEvent.KEYCODE_BACK, context.getString(R.string.keyboard_key_back));
+ SPECIAL_CHARACTER_NAMES.put(
+ KeyEvent.KEYCODE_DPAD_UP, context.getString(R.string.keyboard_key_dpad_up));
+ SPECIAL_CHARACTER_NAMES.put(
+ KeyEvent.KEYCODE_DPAD_DOWN, context.getString(R.string.keyboard_key_dpad_down));
+ SPECIAL_CHARACTER_NAMES.put(
+ KeyEvent.KEYCODE_DPAD_LEFT, context.getString(R.string.keyboard_key_dpad_left));
+ SPECIAL_CHARACTER_NAMES.put(
+ KeyEvent.KEYCODE_DPAD_RIGHT, context.getString(R.string.keyboard_key_dpad_right));
+ SPECIAL_CHARACTER_NAMES.put(
+ KeyEvent.KEYCODE_DPAD_CENTER, context.getString(R.string.keyboard_key_dpad_center));
+ SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_PERIOD, ".");
+ SPECIAL_CHARACTER_NAMES.put(
+ KeyEvent.KEYCODE_TAB, context.getString(R.string.keyboard_key_tab));
+ SPECIAL_CHARACTER_NAMES.put(
+ KeyEvent.KEYCODE_SPACE, context.getString(R.string.keyboard_key_space));
+ SPECIAL_CHARACTER_NAMES.put(
+ KeyEvent.KEYCODE_ENTER, context.getString(R.string.keyboard_key_enter));
+ SPECIAL_CHARACTER_NAMES.put(
+ KeyEvent.KEYCODE_DEL, context.getString(R.string.keyboard_key_backspace));
+ SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE,
+ context.getString(R.string.keyboard_key_media_play_pause));
+ SPECIAL_CHARACTER_NAMES.put(
+ KeyEvent.KEYCODE_MEDIA_STOP, context.getString(R.string.keyboard_key_media_stop));
+ SPECIAL_CHARACTER_NAMES.put(
+ KeyEvent.KEYCODE_MEDIA_NEXT, context.getString(R.string.keyboard_key_media_next));
+ SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_MEDIA_PREVIOUS,
+ context.getString(R.string.keyboard_key_media_previous));
+ SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_MEDIA_REWIND,
+ context.getString(R.string.keyboard_key_media_rewind));
+ SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_MEDIA_FAST_FORWARD,
+ context.getString(R.string.keyboard_key_media_fast_forward));
+ SPECIAL_CHARACTER_NAMES.put(
+ KeyEvent.KEYCODE_PAGE_UP, context.getString(R.string.keyboard_key_page_up));
+ SPECIAL_CHARACTER_NAMES.put(
+ KeyEvent.KEYCODE_PAGE_DOWN, context.getString(R.string.keyboard_key_page_down));
+ SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_BUTTON_A,
+ context.getString(R.string.keyboard_key_button_template, "A"));
+ SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_BUTTON_B,
+ context.getString(R.string.keyboard_key_button_template, "B"));
+ SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_BUTTON_C,
+ context.getString(R.string.keyboard_key_button_template, "C"));
+ SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_BUTTON_X,
+ context.getString(R.string.keyboard_key_button_template, "X"));
+ SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_BUTTON_Y,
+ context.getString(R.string.keyboard_key_button_template, "Y"));
+ SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_BUTTON_Z,
+ context.getString(R.string.keyboard_key_button_template, "Z"));
+ SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_BUTTON_L1,
+ context.getString(R.string.keyboard_key_button_template, "L1"));
+ SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_BUTTON_R1,
+ context.getString(R.string.keyboard_key_button_template, "R1"));
+ SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_BUTTON_L2,
+ context.getString(R.string.keyboard_key_button_template, "L2"));
+ SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_BUTTON_R2,
+ context.getString(R.string.keyboard_key_button_template, "R2"));
+ SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_BUTTON_START,
+ context.getString(R.string.keyboard_key_button_template, "Start"));
+ SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_BUTTON_SELECT,
+ context.getString(R.string.keyboard_key_button_template, "Select"));
+ SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_BUTTON_MODE,
+ context.getString(R.string.keyboard_key_button_template, "Mode"));
+ SPECIAL_CHARACTER_NAMES.put(
+ KeyEvent.KEYCODE_FORWARD_DEL, context.getString(R.string.keyboard_key_forward_del));
+ SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_ESCAPE, "Esc");
+ SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_SYSRQ, "SysRq");
+ SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_BREAK, "Break");
+ SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_SCROLL_LOCK, "Scroll Lock");
+ SPECIAL_CHARACTER_NAMES.put(
+ KeyEvent.KEYCODE_MOVE_HOME, context.getString(R.string.keyboard_key_move_home));
+ SPECIAL_CHARACTER_NAMES.put(
+ KeyEvent.KEYCODE_MOVE_END, context.getString(R.string.keyboard_key_move_end));
+ SPECIAL_CHARACTER_NAMES.put(
+ KeyEvent.KEYCODE_INSERT, context.getString(R.string.keyboard_key_insert));
+ SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_F1, "F1");
+ SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_F2, "F2");
+ SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_F3, "F3");
+ SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_F4, "F4");
+ SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_F5, "F5");
+ SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_F6, "F6");
+ SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_F7, "F7");
+ SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_F8, "F8");
+ SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_F9, "F9");
+ SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_F10, "F10");
+ SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_F11, "F11");
+ SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_F12, "F12");
+ SPECIAL_CHARACTER_NAMES.put(
+ KeyEvent.KEYCODE_NUM_LOCK, context.getString(R.string.keyboard_key_num_lock));
+ SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_NUMPAD_0,
+ context.getString(R.string.keyboard_key_numpad_template, "0"));
+ SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_NUMPAD_1,
+ context.getString(R.string.keyboard_key_numpad_template, "1"));
+ SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_NUMPAD_2,
+ context.getString(R.string.keyboard_key_numpad_template, "2"));
+ SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_NUMPAD_3,
+ context.getString(R.string.keyboard_key_numpad_template, "3"));
+ SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_NUMPAD_4,
+ context.getString(R.string.keyboard_key_numpad_template, "4"));
+ SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_NUMPAD_5,
+ context.getString(R.string.keyboard_key_numpad_template, "5"));
+ SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_NUMPAD_6,
+ context.getString(R.string.keyboard_key_numpad_template, "6"));
+ SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_NUMPAD_7,
+ context.getString(R.string.keyboard_key_numpad_template, "7"));
+ SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_NUMPAD_8,
+ context.getString(R.string.keyboard_key_numpad_template, "8"));
+ SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_NUMPAD_9,
+ context.getString(R.string.keyboard_key_numpad_template, "9"));
+ SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_NUMPAD_DIVIDE,
+ context.getString(R.string.keyboard_key_numpad_template, "/"));
+ SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_NUMPAD_MULTIPLY,
+ context.getString(R.string.keyboard_key_numpad_template, "*"));
+ SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_NUMPAD_SUBTRACT,
+ context.getString(R.string.keyboard_key_numpad_template, "-"));
+ SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_NUMPAD_ADD,
+ context.getString(R.string.keyboard_key_numpad_template, "+"));
+ SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_NUMPAD_DOT,
+ context.getString(R.string.keyboard_key_numpad_template, "."));
+ SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_NUMPAD_COMMA,
+ context.getString(R.string.keyboard_key_numpad_template, ","));
+ SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_NUMPAD_ENTER,
+ context.getString(R.string.keyboard_key_numpad_template,
+ context.getString(R.string.keyboard_key_enter)));
+ SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_NUMPAD_EQUALS,
+ context.getString(R.string.keyboard_key_numpad_template, "="));
+ SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_NUMPAD_LEFT_PAREN,
+ context.getString(R.string.keyboard_key_numpad_template, "("));
+ SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_NUMPAD_RIGHT_PAREN,
+ context.getString(R.string.keyboard_key_numpad_template, ")"));
+ SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_ZENKAKU_HANKAKU, "半角/全角");
+ SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_EISU, "英数");
+ SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_MUHENKAN, "無変換");
+ SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_HENKAN, "変換");
+ SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_KATAKANA_HIRAGANA, "かな");
+ }
private final Handler mHandler = new Handler(Looper.getMainLooper());
private final Context mContext;
@@ -62,12 +206,20 @@ public class KeyboardShortcuts {
};
private Dialog mKeyboardShortcutsDialog;
+ private KeyCharacterMap mKeyCharacterMap;
public KeyboardShortcuts(Context context) {
this.mContext = new ContextThemeWrapper(context, android.R.style.Theme_Material_Light);
+ if (SPECIAL_CHARACTER_NAMES.size() == 0) {
+ loadSpecialCharacterNames(context);
+ }
}
- public void toggleKeyboardShortcuts() {
+ public void toggleKeyboardShortcuts(int deviceId) {
+ InputDevice inputDevice = InputManager.getInstance().getInputDevice(deviceId);
+ if (inputDevice != null) {
+ mKeyCharacterMap = inputDevice.getKeyCharacterMap();
+ }
if (mKeyboardShortcutsDialog == null) {
Recents.getSystemServices().requestKeyboardShortcuts(mContext,
new KeyboardShortcutsReceiver() {
@@ -78,13 +230,13 @@ public class KeyboardShortcuts {
mContext.getString(R.string.keyboard_shortcut_group_system), true);
systemGroup.addItem(new KeyboardShortcutInfo(
mContext.getString(R.string.keyboard_shortcut_group_system_home),
- SYSTEM_HOME_BASE_CHARACTER, KeyEvent.META_META_ON));
+ KeyEvent.KEYCODE_ENTER, KeyEvent.META_META_ON));
systemGroup.addItem(new KeyboardShortcutInfo(
mContext.getString(R.string.keyboard_shortcut_group_system_back),
- SYSTEM_BACK_BASE_CHARACTER, KeyEvent.META_META_ON));
+ KeyEvent.KEYCODE_DEL, KeyEvent.META_META_ON));
systemGroup.addItem(new KeyboardShortcutInfo(
mContext.getString(R.string.keyboard_shortcut_group_system_recents),
- SYSTEM_RECENTS_BASE_CHARACTER, KeyEvent.META_ALT_ON));
+ KeyEvent.KEYCODE_TAB, KeyEvent.META_ALT_ON));
result.add(systemGroup);
showKeyboardShortcutsDialog(result);
}
@@ -148,6 +300,18 @@ public class KeyboardShortcuts {
final int itemsSize = group.getItems().size();
for (int j = 0; j < itemsSize; j++) {
KeyboardShortcutInfo info = group.getItems().get(j);
+ if (info.getKeycode() != KeyEvent.KEYCODE_UNKNOWN
+ && !KeyCharacterMap.deviceHasKey(info.getKeycode())) {
+ // The user can't achieve this shortcut, so skipping.
+ Log.w(TAG, "Keyboard Shortcut contains key not on device, skipping.");
+ continue;
+ }
+ List shortcutKeys = getHumanReadableShortcutKeys(info);
+ if (shortcutKeys == null) {
+ // Ignore shortcuts we can't display keys for.
+ Log.w(TAG, "Keyboard Shortcut contains unsupported keys, skipping.");
+ continue;
+ }
View shortcutView = inflater.inflate(R.layout.keyboard_shortcut_app_item,
shortcutContainer, false);
TextView textView = (TextView) shortcutView
@@ -156,7 +320,6 @@ public class KeyboardShortcuts {
ViewGroup shortcutItemsContainer = (ViewGroup) shortcutView
.findViewById(R.id.keyboard_shortcuts_item_container);
- List shortcutKeys = getHumanReadableShortcutKeys(info);
final int shortcutKeysSize = shortcutKeys.size();
for (int k = 0; k < shortcutKeysSize; k++) {
String shortcutKey = shortcutKeys.get(k);
@@ -179,10 +342,25 @@ public class KeyboardShortcuts {
private List getHumanReadableShortcutKeys(KeyboardShortcutInfo info) {
// TODO: fix the shortcuts. Find or build an util which can produce human readable
- // names of the baseCharacter and the modifiers.
+ // names of the modifiers.
List shortcutKeys = new ArrayList<>();
shortcutKeys.add(KeyEvent.metaStateToString(info.getModifiers()).toUpperCase());
- shortcutKeys.add(Character.getName(info.getBaseCharacter()).toUpperCase());
+ String displayLabelString;
+ if (info.getKeycode() == KeyEvent.KEYCODE_UNKNOWN) {
+ displayLabelString = String.valueOf(info.getBaseCharacter());
+ } else if (SPECIAL_CHARACTER_NAMES.get(info.getKeycode()) != null) {
+ displayLabelString = SPECIAL_CHARACTER_NAMES.get(info.getKeycode());
+ } else {
+ // TODO: Have a generic map for when we don't have the device's.
+ char displayLabel = mKeyCharacterMap == null
+ ? 0 : mKeyCharacterMap.getDisplayLabel(info.getKeycode());
+ if (displayLabel != 0) {
+ displayLabelString = String.valueOf(displayLabel);
+ } else {
+ return null;
+ }
+ }
+ shortcutKeys.add(displayLabelString.toUpperCase());
return shortcutKeys;
}
}
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 0115a08cefe55..d92d942d2b910 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -3101,7 +3101,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
} else if (keyCode == KeyEvent.KEYCODE_SLASH && event.isMetaPressed()) {
if (down) {
if (repeatCount == 0) {
- toggleKeyboardShortcutsMenu();
+ toggleKeyboardShortcutsMenu(event.getDeviceId());
}
}
} else if (keyCode == KeyEvent.KEYCODE_ASSIST) {
@@ -3576,11 +3576,11 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
}
- private void toggleKeyboardShortcutsMenu() {
+ private void toggleKeyboardShortcutsMenu(int deviceId) {
try {
IStatusBarService statusbar = getStatusBarService();
if (statusbar != null) {
- statusbar.toggleKeyboardShortcutsMenu();
+ statusbar.toggleKeyboardShortcutsMenu(deviceId);
}
} catch (RemoteException e) {
Slog.e(TAG, "RemoteException when showing keyboard shortcuts menu", e);
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
index d24e1af3f382b..403a4c608061a 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
@@ -564,10 +564,10 @@ public class StatusBarManagerService extends IStatusBarService.Stub {
}
@Override
- public void toggleKeyboardShortcutsMenu() {
+ public void toggleKeyboardShortcutsMenu(int deviceId) {
if (mBar != null) {
try {
- mBar.toggleKeyboardShortcutsMenu();
+ mBar.toggleKeyboardShortcutsMenu(deviceId);
} catch (RemoteException ex) {}
}
}