Loading core/res/res/values/attrs.xml +19 −11 Original line number Diff line number Diff line Loading @@ -10285,11 +10285,6 @@ </declare-styleable> <!-- @hide --> <declare-styleable name="HardwareDefinedShortcut"> <attr name="keycode" /> <!-- The values are taken from public constants for modifier state defined in {@see KeyEvent.java}. Here we allow multiple modifier flags as value, since this represents the modifier state --> <attr name="modifierState"> <flag name="META" value="0x10000" /> <flag name="CTRL" value="0x1000" /> Loading @@ -10301,6 +10296,14 @@ <flag name="NUM_LOCK" value="0x200000" /> <flag name="SCROLL_LOCK" value="0x400000" /> </attr> <!-- @hide --> <declare-styleable name="HardwareDefinedShortcut"> <attr name="keycode" /> <!-- The values are taken from public constants for modifier state defined in {@see KeyEvent.java}. Here we allow multiple modifier flags as value, since this represents the modifier state --> <attr name="modifierState" /> <attr name="outKeycode" /> </declare-styleable> Loading @@ -10309,6 +10312,11 @@ <attr name="keycode" /> </declare-styleable> <declare-styleable name="Bookmark"> <attr name="keycode" /> <attr name="modifierState" /> </declare-styleable> <declare-styleable name="MediaRouteButton"> <!-- This drawable is a state list where the "activated" state indicates active media routing. Non-activated indicates core/res/res/xml/bookmarks.xml +17 −9 Original line number Diff line number Diff line Loading @@ -31,29 +31,37 @@ 'u': Calculator 'y': YouTube --> <bookmarks> <bookmarks xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"> <bookmark role="android.app.role.BROWSER" shortcut="b" /> androidprv:keycode="KEYCODE_B" androidprv:modifierState="META" /> <bookmark category="android.intent.category.APP_CONTACTS" shortcut="c" /> androidprv:keycode="KEYCODE_C" androidprv:modifierState="META" /> <bookmark category="android.intent.category.APP_EMAIL" shortcut="e" /> androidprv:keycode="KEYCODE_E" androidprv:modifierState="META" /> <bookmark category="android.intent.category.APP_CALENDAR" shortcut="k" /> androidprv:keycode="KEYCODE_K" androidprv:modifierState="META" /> <bookmark category="android.intent.category.APP_MAPS" shortcut="m" /> androidprv:keycode="KEYCODE_M" androidprv:modifierState="META" /> <bookmark category="android.intent.category.APP_MUSIC" shortcut="p" /> androidprv:keycode="KEYCODE_P" androidprv:modifierState="META" /> <bookmark role="android.app.role.SMS" shortcut="s" /> androidprv:keycode="KEYCODE_S" androidprv:modifierState="META" /> <bookmark category="android.intent.category.APP_CALCULATOR" shortcut="u" /> androidprv:keycode="KEYCODE_U" androidprv:modifierState="META" /> </bookmarks> packages/SettingsProvider/res/xml/bookmarks.xml +3 −0 Original line number Diff line number Diff line Loading @@ -32,6 +32,9 @@ 'y': YouTube --> <bookmarks> <!-- TODO(b/358569822): Remove this from Settings DB This is legacy implementation to store bookmarks in Settings DB, which is deprecated and no longer used --> <bookmark role="android.app.role.BROWSER" shortcut="b" /> Loading services/core/java/com/android/server/input/AppLaunchShortcutManager.java +23 −11 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import android.annotation.SuppressLint; import android.app.role.RoleManager; import android.content.Context; import android.content.Intent; import android.content.res.TypedArray; import android.content.res.XmlResourceParser; import android.hardware.input.AppLaunchData; import android.hardware.input.InputGestureData; Loading Loading @@ -137,11 +138,19 @@ final class AppLaunchShortcutManager { String categoryName = parser.getAttributeValue(null, ATTRIBUTE_CATEGORY); String shiftName = parser.getAttributeValue(null, ATTRIBUTE_SHIFT); String roleName = parser.getAttributeValue(null, ATTRIBUTE_ROLE); // TODO(b/358569822): Shift bookmarks to use keycode instead of shortcutChar int keycode = KeyEvent.KEYCODE_UNKNOWN; String shortcut = parser.getAttributeValue(null, ATTRIBUTE_SHORTCUT); if (!TextUtils.isEmpty(shortcut)) { int keycode; int modifierState; TypedArray a = mContext.getResources().obtainAttributes(parser, R.styleable.Bookmark); try { keycode = a.getInt(R.styleable.Bookmark_keycode, KeyEvent.KEYCODE_UNKNOWN); modifierState = a.getInt(R.styleable.Bookmark_modifierState, 0); } finally { a.recycle(); } if (keycode == KeyEvent.KEYCODE_UNKNOWN && !TextUtils.isEmpty(shortcut)) { // Fetch keycode using shortcut char KeyEvent[] events = virtualKcm.getEvents(new char[]{shortcut.toLowerCase( Locale.ROOT).charAt(0)}); // Single key press can generate the character Loading @@ -153,12 +162,17 @@ final class AppLaunchShortcutManager { Log.w(TAG, "Keycode required for bookmark with category=" + categoryName + " packageName=" + packageName + " className=" + className + " role=" + roleName + " shiftName=" + shiftName + " shortcut=" + shortcut); + " shortcut=" + shortcut + " modifierState=" + modifierState); continue; } final boolean isShiftShortcut = (shiftName != null && shiftName.toLowerCase( Locale.ROOT).equals("true")); if (modifierState == 0) { // Fetch modifierState using shiftName boolean isShiftShortcut = shiftName != null && shiftName.toLowerCase( Locale.ROOT).equals("true"); modifierState = KeyEvent.META_META_ON | (isShiftShortcut ? KeyEvent.META_SHIFT_ON : 0); } AppLaunchData launchData = null; if (!TextUtils.isEmpty(packageName) && !TextUtils.isEmpty(className)) { launchData = AppLaunchData.createLaunchDataForComponent(packageName, className); Loading @@ -168,11 +182,9 @@ final class AppLaunchShortcutManager { launchData = AppLaunchData.createLaunchDataForRole(roleName); } if (launchData != null) { Log.d(TAG, "adding shortcut " + launchData + "shift=" + isShiftShortcut + " keycode=" + keycode); Log.d(TAG, "adding shortcut " + launchData + " modifierState=" + modifierState + " keycode=" + keycode); // All bookmarks are based on Action key int modifierState = KeyEvent.META_META_ON | (isShiftShortcut ? KeyEvent.META_SHIFT_ON : 0); InputGestureData bookmark = new InputGestureData.Builder() .setTrigger(InputGestureData.createKeyTrigger(keycode, modifierState)) .setKeyGestureType(KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_APPLICATION) Loading services/core/java/com/android/server/policy/ModifierShortcutManager.java +31 −3 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ import android.content.Context; import android.content.Intent; import android.content.pm.ActivityInfo; import android.content.pm.PackageManager; import android.content.res.TypedArray; import android.content.res.XmlResourceParser; import android.graphics.drawable.Icon; import android.hardware.input.AppLaunchData; Loading Loading @@ -65,6 +66,7 @@ import java.io.PrintWriter; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Objects; import java.util.Set; Loading @@ -84,6 +86,7 @@ public class ModifierShortcutManager { private static final String ATTRIBUTE_PACKAGE = "package"; private static final String ATTRIBUTE_CLASS = "class"; private static final String ATTRIBUTE_SHORTCUT = "shortcut"; private static final String ATTRIBUTE_KEYCODE = "keycode"; private static final String ATTRIBUTE_CATEGORY = "category"; private static final String ATTRIBUTE_SHIFT = "shift"; private static final String ATTRIBUTE_ROLE = "role"; Loading Loading @@ -167,6 +170,9 @@ public class ModifierShortcutManager { }, UserHandle.ALL); mCurrentUser = currentUser; mInputManagerInternal = LocalServices.getService(InputManagerInternal.class); } void onSystemReady() { loadShortcuts(); } Loading Loading @@ -335,6 +341,7 @@ public class ModifierShortcutManager { try { XmlResourceParser parser = mContext.getResources().getXml(R.xml.bookmarks); XmlUtils.beginDocument(parser, TAG_BOOKMARKS); KeyCharacterMap virtualKcm = KeyCharacterMap.load(KeyCharacterMap.VIRTUAL_KEYBOARD); while (true) { XmlUtils.nextElement(parser); Loading @@ -353,15 +360,36 @@ public class ModifierShortcutManager { String categoryName = parser.getAttributeValue(null, ATTRIBUTE_CATEGORY); String shiftName = parser.getAttributeValue(null, ATTRIBUTE_SHIFT); String roleName = parser.getAttributeValue(null, ATTRIBUTE_ROLE); final int keycode; final int modifierState; TypedArray a = mContext.getResources().obtainAttributes(parser, R.styleable.Bookmark); try { keycode = a.getInt(R.styleable.Bookmark_keycode, KeyEvent.KEYCODE_UNKNOWN); modifierState = a.getInt(R.styleable.Bookmark_modifierState, 0); } finally { a.recycle(); } if (TextUtils.isEmpty(shortcutName) && keycode != KeyEvent.KEYCODE_UNKNOWN) { // Try to find shortcutChar using keycode shortcutName = String.valueOf(virtualKcm.getDisplayLabel(keycode)).toLowerCase( Locale.ROOT); } if (TextUtils.isEmpty(shortcutName)) { Log.w(TAG, "Shortcut required for bookmark with category=" + categoryName + " packageName=" + packageName + " className=" + className + " role=" + roleName + "shiftName=" + shiftName); + " role=" + roleName + " shiftName=" + shiftName + " keycode= " + keycode + " modifierState= " + modifierState); continue; } final boolean isShiftShortcut = (shiftName != null && shiftName.equals("true")); final boolean isShiftShortcut; if (!TextUtils.isEmpty(shiftName)) { isShiftShortcut = shiftName.equals("true"); } else { isShiftShortcut = (modifierState & KeyEvent.META_SHIFT_ON) != 0; } if (modifierShortcutManagerRefactor()) { final char shortcutChar = shortcutName.charAt(0); Loading Loading
core/res/res/values/attrs.xml +19 −11 Original line number Diff line number Diff line Loading @@ -10285,11 +10285,6 @@ </declare-styleable> <!-- @hide --> <declare-styleable name="HardwareDefinedShortcut"> <attr name="keycode" /> <!-- The values are taken from public constants for modifier state defined in {@see KeyEvent.java}. Here we allow multiple modifier flags as value, since this represents the modifier state --> <attr name="modifierState"> <flag name="META" value="0x10000" /> <flag name="CTRL" value="0x1000" /> Loading @@ -10301,6 +10296,14 @@ <flag name="NUM_LOCK" value="0x200000" /> <flag name="SCROLL_LOCK" value="0x400000" /> </attr> <!-- @hide --> <declare-styleable name="HardwareDefinedShortcut"> <attr name="keycode" /> <!-- The values are taken from public constants for modifier state defined in {@see KeyEvent.java}. Here we allow multiple modifier flags as value, since this represents the modifier state --> <attr name="modifierState" /> <attr name="outKeycode" /> </declare-styleable> Loading @@ -10309,6 +10312,11 @@ <attr name="keycode" /> </declare-styleable> <declare-styleable name="Bookmark"> <attr name="keycode" /> <attr name="modifierState" /> </declare-styleable> <declare-styleable name="MediaRouteButton"> <!-- This drawable is a state list where the "activated" state indicates active media routing. Non-activated indicates
core/res/res/xml/bookmarks.xml +17 −9 Original line number Diff line number Diff line Loading @@ -31,29 +31,37 @@ 'u': Calculator 'y': YouTube --> <bookmarks> <bookmarks xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"> <bookmark role="android.app.role.BROWSER" shortcut="b" /> androidprv:keycode="KEYCODE_B" androidprv:modifierState="META" /> <bookmark category="android.intent.category.APP_CONTACTS" shortcut="c" /> androidprv:keycode="KEYCODE_C" androidprv:modifierState="META" /> <bookmark category="android.intent.category.APP_EMAIL" shortcut="e" /> androidprv:keycode="KEYCODE_E" androidprv:modifierState="META" /> <bookmark category="android.intent.category.APP_CALENDAR" shortcut="k" /> androidprv:keycode="KEYCODE_K" androidprv:modifierState="META" /> <bookmark category="android.intent.category.APP_MAPS" shortcut="m" /> androidprv:keycode="KEYCODE_M" androidprv:modifierState="META" /> <bookmark category="android.intent.category.APP_MUSIC" shortcut="p" /> androidprv:keycode="KEYCODE_P" androidprv:modifierState="META" /> <bookmark role="android.app.role.SMS" shortcut="s" /> androidprv:keycode="KEYCODE_S" androidprv:modifierState="META" /> <bookmark category="android.intent.category.APP_CALCULATOR" shortcut="u" /> androidprv:keycode="KEYCODE_U" androidprv:modifierState="META" /> </bookmarks>
packages/SettingsProvider/res/xml/bookmarks.xml +3 −0 Original line number Diff line number Diff line Loading @@ -32,6 +32,9 @@ 'y': YouTube --> <bookmarks> <!-- TODO(b/358569822): Remove this from Settings DB This is legacy implementation to store bookmarks in Settings DB, which is deprecated and no longer used --> <bookmark role="android.app.role.BROWSER" shortcut="b" /> Loading
services/core/java/com/android/server/input/AppLaunchShortcutManager.java +23 −11 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import android.annotation.SuppressLint; import android.app.role.RoleManager; import android.content.Context; import android.content.Intent; import android.content.res.TypedArray; import android.content.res.XmlResourceParser; import android.hardware.input.AppLaunchData; import android.hardware.input.InputGestureData; Loading Loading @@ -137,11 +138,19 @@ final class AppLaunchShortcutManager { String categoryName = parser.getAttributeValue(null, ATTRIBUTE_CATEGORY); String shiftName = parser.getAttributeValue(null, ATTRIBUTE_SHIFT); String roleName = parser.getAttributeValue(null, ATTRIBUTE_ROLE); // TODO(b/358569822): Shift bookmarks to use keycode instead of shortcutChar int keycode = KeyEvent.KEYCODE_UNKNOWN; String shortcut = parser.getAttributeValue(null, ATTRIBUTE_SHORTCUT); if (!TextUtils.isEmpty(shortcut)) { int keycode; int modifierState; TypedArray a = mContext.getResources().obtainAttributes(parser, R.styleable.Bookmark); try { keycode = a.getInt(R.styleable.Bookmark_keycode, KeyEvent.KEYCODE_UNKNOWN); modifierState = a.getInt(R.styleable.Bookmark_modifierState, 0); } finally { a.recycle(); } if (keycode == KeyEvent.KEYCODE_UNKNOWN && !TextUtils.isEmpty(shortcut)) { // Fetch keycode using shortcut char KeyEvent[] events = virtualKcm.getEvents(new char[]{shortcut.toLowerCase( Locale.ROOT).charAt(0)}); // Single key press can generate the character Loading @@ -153,12 +162,17 @@ final class AppLaunchShortcutManager { Log.w(TAG, "Keycode required for bookmark with category=" + categoryName + " packageName=" + packageName + " className=" + className + " role=" + roleName + " shiftName=" + shiftName + " shortcut=" + shortcut); + " shortcut=" + shortcut + " modifierState=" + modifierState); continue; } final boolean isShiftShortcut = (shiftName != null && shiftName.toLowerCase( Locale.ROOT).equals("true")); if (modifierState == 0) { // Fetch modifierState using shiftName boolean isShiftShortcut = shiftName != null && shiftName.toLowerCase( Locale.ROOT).equals("true"); modifierState = KeyEvent.META_META_ON | (isShiftShortcut ? KeyEvent.META_SHIFT_ON : 0); } AppLaunchData launchData = null; if (!TextUtils.isEmpty(packageName) && !TextUtils.isEmpty(className)) { launchData = AppLaunchData.createLaunchDataForComponent(packageName, className); Loading @@ -168,11 +182,9 @@ final class AppLaunchShortcutManager { launchData = AppLaunchData.createLaunchDataForRole(roleName); } if (launchData != null) { Log.d(TAG, "adding shortcut " + launchData + "shift=" + isShiftShortcut + " keycode=" + keycode); Log.d(TAG, "adding shortcut " + launchData + " modifierState=" + modifierState + " keycode=" + keycode); // All bookmarks are based on Action key int modifierState = KeyEvent.META_META_ON | (isShiftShortcut ? KeyEvent.META_SHIFT_ON : 0); InputGestureData bookmark = new InputGestureData.Builder() .setTrigger(InputGestureData.createKeyTrigger(keycode, modifierState)) .setKeyGestureType(KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_APPLICATION) Loading
services/core/java/com/android/server/policy/ModifierShortcutManager.java +31 −3 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ import android.content.Context; import android.content.Intent; import android.content.pm.ActivityInfo; import android.content.pm.PackageManager; import android.content.res.TypedArray; import android.content.res.XmlResourceParser; import android.graphics.drawable.Icon; import android.hardware.input.AppLaunchData; Loading Loading @@ -65,6 +66,7 @@ import java.io.PrintWriter; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Objects; import java.util.Set; Loading @@ -84,6 +86,7 @@ public class ModifierShortcutManager { private static final String ATTRIBUTE_PACKAGE = "package"; private static final String ATTRIBUTE_CLASS = "class"; private static final String ATTRIBUTE_SHORTCUT = "shortcut"; private static final String ATTRIBUTE_KEYCODE = "keycode"; private static final String ATTRIBUTE_CATEGORY = "category"; private static final String ATTRIBUTE_SHIFT = "shift"; private static final String ATTRIBUTE_ROLE = "role"; Loading Loading @@ -167,6 +170,9 @@ public class ModifierShortcutManager { }, UserHandle.ALL); mCurrentUser = currentUser; mInputManagerInternal = LocalServices.getService(InputManagerInternal.class); } void onSystemReady() { loadShortcuts(); } Loading Loading @@ -335,6 +341,7 @@ public class ModifierShortcutManager { try { XmlResourceParser parser = mContext.getResources().getXml(R.xml.bookmarks); XmlUtils.beginDocument(parser, TAG_BOOKMARKS); KeyCharacterMap virtualKcm = KeyCharacterMap.load(KeyCharacterMap.VIRTUAL_KEYBOARD); while (true) { XmlUtils.nextElement(parser); Loading @@ -353,15 +360,36 @@ public class ModifierShortcutManager { String categoryName = parser.getAttributeValue(null, ATTRIBUTE_CATEGORY); String shiftName = parser.getAttributeValue(null, ATTRIBUTE_SHIFT); String roleName = parser.getAttributeValue(null, ATTRIBUTE_ROLE); final int keycode; final int modifierState; TypedArray a = mContext.getResources().obtainAttributes(parser, R.styleable.Bookmark); try { keycode = a.getInt(R.styleable.Bookmark_keycode, KeyEvent.KEYCODE_UNKNOWN); modifierState = a.getInt(R.styleable.Bookmark_modifierState, 0); } finally { a.recycle(); } if (TextUtils.isEmpty(shortcutName) && keycode != KeyEvent.KEYCODE_UNKNOWN) { // Try to find shortcutChar using keycode shortcutName = String.valueOf(virtualKcm.getDisplayLabel(keycode)).toLowerCase( Locale.ROOT); } if (TextUtils.isEmpty(shortcutName)) { Log.w(TAG, "Shortcut required for bookmark with category=" + categoryName + " packageName=" + packageName + " className=" + className + " role=" + roleName + "shiftName=" + shiftName); + " role=" + roleName + " shiftName=" + shiftName + " keycode= " + keycode + " modifierState= " + modifierState); continue; } final boolean isShiftShortcut = (shiftName != null && shiftName.equals("true")); final boolean isShiftShortcut; if (!TextUtils.isEmpty(shiftName)) { isShiftShortcut = shiftName.equals("true"); } else { isShiftShortcut = (modifierState & KeyEvent.META_SHIFT_ON) != 0; } if (modifierShortcutManagerRefactor()) { final char shortcutChar = shortcutName.charAt(0); Loading