|
|
|
@@ -16,6 +16,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
package com.android.systemui.statusbar;
|
|
|
|
package com.android.systemui.statusbar;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import android.annotation.NonNull;
|
|
|
|
|
|
|
|
import android.annotation.Nullable;
|
|
|
|
import android.app.AlertDialog;
|
|
|
|
import android.app.AlertDialog;
|
|
|
|
import android.app.AppGlobals;
|
|
|
|
import android.app.AppGlobals;
|
|
|
|
import android.app.Dialog;
|
|
|
|
import android.app.Dialog;
|
|
|
|
@@ -45,9 +47,11 @@ import android.view.KeyboardShortcutGroup;
|
|
|
|
import android.view.KeyboardShortcutInfo;
|
|
|
|
import android.view.KeyboardShortcutInfo;
|
|
|
|
import android.view.LayoutInflater;
|
|
|
|
import android.view.LayoutInflater;
|
|
|
|
import android.view.View;
|
|
|
|
import android.view.View;
|
|
|
|
|
|
|
|
import android.view.View.AccessibilityDelegate;
|
|
|
|
import android.view.ViewGroup;
|
|
|
|
import android.view.ViewGroup;
|
|
|
|
import android.view.Window;
|
|
|
|
import android.view.Window;
|
|
|
|
import android.view.WindowManager.KeyboardShortcutsReceiver;
|
|
|
|
import android.view.WindowManager.KeyboardShortcutsReceiver;
|
|
|
|
|
|
|
|
import android.view.accessibility.AccessibilityNodeInfo;
|
|
|
|
import android.widget.ImageView;
|
|
|
|
import android.widget.ImageView;
|
|
|
|
import android.widget.LinearLayout;
|
|
|
|
import android.widget.LinearLayout;
|
|
|
|
import android.widget.RelativeLayout;
|
|
|
|
import android.widget.RelativeLayout;
|
|
|
|
@@ -63,6 +67,7 @@ import java.util.Comparator;
|
|
|
|
import java.util.List;
|
|
|
|
import java.util.List;
|
|
|
|
|
|
|
|
|
|
|
|
import static android.content.Context.LAYOUT_INFLATER_SERVICE;
|
|
|
|
import static android.content.Context.LAYOUT_INFLATER_SERVICE;
|
|
|
|
|
|
|
|
import static android.view.View.IMPORTANT_FOR_ACCESSIBILITY_YES;
|
|
|
|
import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG;
|
|
|
|
import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG;
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
@@ -591,7 +596,7 @@ public final class KeyboardShortcuts {
|
|
|
|
final int itemsSize = group.getItems().size();
|
|
|
|
final int itemsSize = group.getItems().size();
|
|
|
|
for (int j = 0; j < itemsSize; j++) {
|
|
|
|
for (int j = 0; j < itemsSize; j++) {
|
|
|
|
KeyboardShortcutInfo info = group.getItems().get(j);
|
|
|
|
KeyboardShortcutInfo info = group.getItems().get(j);
|
|
|
|
List<StringOrDrawable> shortcutKeys = getHumanReadableShortcutKeys(info);
|
|
|
|
List<StringDrawableContainer> shortcutKeys = getHumanReadableShortcutKeys(info);
|
|
|
|
if (shortcutKeys == null) {
|
|
|
|
if (shortcutKeys == null) {
|
|
|
|
// Ignore shortcuts we can't display keys for.
|
|
|
|
// Ignore shortcuts we can't display keys for.
|
|
|
|
Log.w(TAG, "Keyboard Shortcut contains unsupported keys, skipping.");
|
|
|
|
Log.w(TAG, "Keyboard Shortcut contains unsupported keys, skipping.");
|
|
|
|
@@ -621,25 +626,33 @@ public final class KeyboardShortcuts {
|
|
|
|
.findViewById(R.id.keyboard_shortcuts_item_container);
|
|
|
|
.findViewById(R.id.keyboard_shortcuts_item_container);
|
|
|
|
final int shortcutKeysSize = shortcutKeys.size();
|
|
|
|
final int shortcutKeysSize = shortcutKeys.size();
|
|
|
|
for (int k = 0; k < shortcutKeysSize; k++) {
|
|
|
|
for (int k = 0; k < shortcutKeysSize; k++) {
|
|
|
|
StringOrDrawable shortcutRepresentation = shortcutKeys.get(k);
|
|
|
|
StringDrawableContainer shortcutRepresentation = shortcutKeys.get(k);
|
|
|
|
if (shortcutRepresentation.drawable != null) {
|
|
|
|
if (shortcutRepresentation.mDrawable != null) {
|
|
|
|
ImageView shortcutKeyIconView = (ImageView) inflater.inflate(
|
|
|
|
ImageView shortcutKeyIconView = (ImageView) inflater.inflate(
|
|
|
|
R.layout.keyboard_shortcuts_key_icon_view, shortcutItemsContainer,
|
|
|
|
R.layout.keyboard_shortcuts_key_icon_view, shortcutItemsContainer,
|
|
|
|
false);
|
|
|
|
false);
|
|
|
|
Bitmap bitmap = Bitmap.createBitmap(shortcutKeyIconItemHeightWidth,
|
|
|
|
Bitmap bitmap = Bitmap.createBitmap(shortcutKeyIconItemHeightWidth,
|
|
|
|
shortcutKeyIconItemHeightWidth, Bitmap.Config.ARGB_8888);
|
|
|
|
shortcutKeyIconItemHeightWidth, Bitmap.Config.ARGB_8888);
|
|
|
|
Canvas canvas = new Canvas(bitmap);
|
|
|
|
Canvas canvas = new Canvas(bitmap);
|
|
|
|
shortcutRepresentation.drawable.setBounds(0, 0, canvas.getWidth(),
|
|
|
|
shortcutRepresentation.mDrawable.setBounds(0, 0, canvas.getWidth(),
|
|
|
|
canvas.getHeight());
|
|
|
|
canvas.getHeight());
|
|
|
|
shortcutRepresentation.drawable.draw(canvas);
|
|
|
|
shortcutRepresentation.mDrawable.draw(canvas);
|
|
|
|
shortcutKeyIconView.setImageBitmap(bitmap);
|
|
|
|
shortcutKeyIconView.setImageBitmap(bitmap);
|
|
|
|
|
|
|
|
shortcutKeyIconView.setImportantForAccessibility(
|
|
|
|
|
|
|
|
IMPORTANT_FOR_ACCESSIBILITY_YES);
|
|
|
|
|
|
|
|
shortcutKeyIconView.setAccessibilityDelegate(
|
|
|
|
|
|
|
|
new ShortcutKeyAccessibilityDelegate(
|
|
|
|
|
|
|
|
shortcutRepresentation.mString));
|
|
|
|
shortcutItemsContainer.addView(shortcutKeyIconView);
|
|
|
|
shortcutItemsContainer.addView(shortcutKeyIconView);
|
|
|
|
} else if (shortcutRepresentation.string != null) {
|
|
|
|
} else if (shortcutRepresentation.mString != null) {
|
|
|
|
TextView shortcutKeyTextView = (TextView) inflater.inflate(
|
|
|
|
TextView shortcutKeyTextView = (TextView) inflater.inflate(
|
|
|
|
R.layout.keyboard_shortcuts_key_view, shortcutItemsContainer,
|
|
|
|
R.layout.keyboard_shortcuts_key_view, shortcutItemsContainer,
|
|
|
|
false);
|
|
|
|
false);
|
|
|
|
shortcutKeyTextView.setMinimumWidth(shortcutKeyTextItemMinWidth);
|
|
|
|
shortcutKeyTextView.setMinimumWidth(shortcutKeyTextItemMinWidth);
|
|
|
|
shortcutKeyTextView.setText(shortcutRepresentation.string);
|
|
|
|
shortcutKeyTextView.setText(shortcutRepresentation.mString);
|
|
|
|
|
|
|
|
shortcutKeyTextView.setAccessibilityDelegate(
|
|
|
|
|
|
|
|
new ShortcutKeyAccessibilityDelegate(
|
|
|
|
|
|
|
|
shortcutRepresentation.mString));
|
|
|
|
shortcutItemsContainer.addView(shortcutKeyTextView);
|
|
|
|
shortcutItemsContainer.addView(shortcutKeyTextView);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@@ -655,19 +668,20 @@ public final class KeyboardShortcuts {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private List<StringOrDrawable> getHumanReadableShortcutKeys(KeyboardShortcutInfo info) {
|
|
|
|
private List<StringDrawableContainer> getHumanReadableShortcutKeys(KeyboardShortcutInfo info) {
|
|
|
|
List<StringOrDrawable> shortcutKeys = getHumanReadableModifiers(info);
|
|
|
|
List<StringDrawableContainer> shortcutKeys = getHumanReadableModifiers(info);
|
|
|
|
if (shortcutKeys == null) {
|
|
|
|
if (shortcutKeys == null) {
|
|
|
|
return null;
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
String displayLabelString = null;
|
|
|
|
String shortcutKeyString = null;
|
|
|
|
Drawable displayLabelDrawable = null;
|
|
|
|
Drawable shortcutKeyDrawable = null;
|
|
|
|
if (info.getBaseCharacter() > Character.MIN_VALUE) {
|
|
|
|
if (info.getBaseCharacter() > Character.MIN_VALUE) {
|
|
|
|
displayLabelString = String.valueOf(info.getBaseCharacter());
|
|
|
|
shortcutKeyString = String.valueOf(info.getBaseCharacter());
|
|
|
|
} else if (mSpecialCharacterDrawables.get(info.getKeycode()) != null) {
|
|
|
|
} else if (mSpecialCharacterDrawables.get(info.getKeycode()) != null) {
|
|
|
|
displayLabelDrawable = mSpecialCharacterDrawables.get(info.getKeycode());
|
|
|
|
shortcutKeyDrawable = mSpecialCharacterDrawables.get(info.getKeycode());
|
|
|
|
|
|
|
|
shortcutKeyString = mSpecialCharacterNames.get(info.getKeycode());
|
|
|
|
} else if (mSpecialCharacterNames.get(info.getKeycode()) != null) {
|
|
|
|
} else if (mSpecialCharacterNames.get(info.getKeycode()) != null) {
|
|
|
|
displayLabelString = mSpecialCharacterNames.get(info.getKeycode());
|
|
|
|
shortcutKeyString = mSpecialCharacterNames.get(info.getKeycode());
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
// Special case for shortcuts with no base key or keycode.
|
|
|
|
// Special case for shortcuts with no base key or keycode.
|
|
|
|
if (info.getKeycode() == KeyEvent.KEYCODE_UNKNOWN) {
|
|
|
|
if (info.getKeycode() == KeyEvent.KEYCODE_UNKNOWN) {
|
|
|
|
@@ -675,22 +689,23 @@ public final class KeyboardShortcuts {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
char displayLabel = mKeyCharacterMap.getDisplayLabel(info.getKeycode());
|
|
|
|
char displayLabel = mKeyCharacterMap.getDisplayLabel(info.getKeycode());
|
|
|
|
if (displayLabel != 0) {
|
|
|
|
if (displayLabel != 0) {
|
|
|
|
displayLabelString = String.valueOf(displayLabel);
|
|
|
|
shortcutKeyString = String.valueOf(displayLabel);
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
return null;
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (displayLabelDrawable != null) {
|
|
|
|
if (shortcutKeyString != null) {
|
|
|
|
shortcutKeys.add(new StringOrDrawable(displayLabelDrawable));
|
|
|
|
shortcutKeys.add(new StringDrawableContainer(shortcutKeyString, shortcutKeyDrawable));
|
|
|
|
} else if (displayLabelString != null) {
|
|
|
|
} else {
|
|
|
|
shortcutKeys.add(new StringOrDrawable(displayLabelString.toUpperCase()));
|
|
|
|
Log.w(TAG, "Keyboard Shortcut does not have a text representation, skipping.");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return shortcutKeys;
|
|
|
|
return shortcutKeys;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private List<StringOrDrawable> getHumanReadableModifiers(KeyboardShortcutInfo info) {
|
|
|
|
private List<StringDrawableContainer> getHumanReadableModifiers(KeyboardShortcutInfo info) {
|
|
|
|
final List<StringOrDrawable> shortcutKeys = new ArrayList<>();
|
|
|
|
final List<StringDrawableContainer> shortcutKeys = new ArrayList<>();
|
|
|
|
int modifiers = info.getModifiers();
|
|
|
|
int modifiers = info.getModifiers();
|
|
|
|
if (modifiers == 0) {
|
|
|
|
if (modifiers == 0) {
|
|
|
|
return shortcutKeys;
|
|
|
|
return shortcutKeys;
|
|
|
|
@@ -698,13 +713,9 @@ public final class KeyboardShortcuts {
|
|
|
|
for(int i = 0; i < mModifierNames.size(); ++i) {
|
|
|
|
for(int i = 0; i < mModifierNames.size(); ++i) {
|
|
|
|
final int supportedModifier = mModifierNames.keyAt(i);
|
|
|
|
final int supportedModifier = mModifierNames.keyAt(i);
|
|
|
|
if ((modifiers & supportedModifier) != 0) {
|
|
|
|
if ((modifiers & supportedModifier) != 0) {
|
|
|
|
if (mModifierDrawables.get(supportedModifier) != null) {
|
|
|
|
shortcutKeys.add(new StringDrawableContainer(
|
|
|
|
shortcutKeys.add(new StringOrDrawable(
|
|
|
|
mModifierNames.get(supportedModifier),
|
|
|
|
mModifierDrawables.get(supportedModifier)));
|
|
|
|
mModifierDrawables.get(supportedModifier)));
|
|
|
|
} else {
|
|
|
|
|
|
|
|
shortcutKeys.add(new StringOrDrawable(
|
|
|
|
|
|
|
|
mModifierNames.get(supportedModifier).toUpperCase()));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
modifiers &= ~supportedModifier;
|
|
|
|
modifiers &= ~supportedModifier;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@@ -715,16 +726,31 @@ public final class KeyboardShortcuts {
|
|
|
|
return shortcutKeys;
|
|
|
|
return shortcutKeys;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private static final class StringOrDrawable {
|
|
|
|
private final class ShortcutKeyAccessibilityDelegate extends AccessibilityDelegate {
|
|
|
|
public String string;
|
|
|
|
private String mContentDescription;
|
|
|
|
public Drawable drawable;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public StringOrDrawable(String string) {
|
|
|
|
ShortcutKeyAccessibilityDelegate(String contentDescription) {
|
|
|
|
this.string = string;
|
|
|
|
mContentDescription = contentDescription;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public StringOrDrawable(Drawable drawable) {
|
|
|
|
@Override
|
|
|
|
this.drawable = drawable;
|
|
|
|
public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) {
|
|
|
|
|
|
|
|
super.onInitializeAccessibilityNodeInfo(host, info);
|
|
|
|
|
|
|
|
if (mContentDescription != null) {
|
|
|
|
|
|
|
|
info.setContentDescription(mContentDescription.toLowerCase());
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private static final class StringDrawableContainer {
|
|
|
|
|
|
|
|
@NonNull
|
|
|
|
|
|
|
|
public String mString;
|
|
|
|
|
|
|
|
@Nullable
|
|
|
|
|
|
|
|
public Drawable mDrawable;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
StringDrawableContainer(String string, Drawable drawable) {
|
|
|
|
|
|
|
|
mString = string;
|
|
|
|
|
|
|
|
mDrawable = drawable;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|