Shift to keycode and modifierState attrs in bookmarks.xml
Use keycodes and modifier state in bookmarks.xml instead of
legacy shortcutChar and shift xml params
Test: atest InputTests
Test: atest WmTests
Bug: 358569822
Flag: EXEMPT refactor
Change-Id: I15dcf179476a99e15f3bb3cbc9deef26a2da96d7
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index e6dedce..72467b3 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -10285,22 +10285,25 @@
</declare-styleable>
<!-- @hide -->
+ <attr name="modifierState">
+ <flag name="META" value="0x10000" />
+ <flag name="CTRL" value="0x1000" />
+ <flag name="ALT" value="0x02" />
+ <flag name="SHIFT" value="0x1" />
+ <flag name="SYM" value="0x4" />
+ <flag name="FUNCTION" value="0x8" />
+ <flag name="CAPS_LOCK" value="0x100000" />
+ <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">
- <flag name="META" value="0x10000" />
- <flag name="CTRL" value="0x1000" />
- <flag name="ALT" value="0x02" />
- <flag name="SHIFT" value="0x1" />
- <flag name="SYM" value="0x4" />
- <flag name="FUNCTION" value="0x8" />
- <flag name="CAPS_LOCK" value="0x100000" />
- <flag name="NUM_LOCK" value="0x200000" />
- <flag name="SCROLL_LOCK" value="0x400000" />
- </attr>
+ <attr name="modifierState" />
<attr name="outKeycode" />
</declare-styleable>
@@ -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
diff --git a/core/res/res/xml/bookmarks.xml b/core/res/res/xml/bookmarks.xml
index 22d0226..e735784 100644
--- a/core/res/res/xml/bookmarks.xml
+++ b/core/res/res/xml/bookmarks.xml
@@ -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>
diff --git a/packages/SettingsProvider/res/xml/bookmarks.xml b/packages/SettingsProvider/res/xml/bookmarks.xml
index 22d0226..645b275 100644
--- a/packages/SettingsProvider/res/xml/bookmarks.xml
+++ b/packages/SettingsProvider/res/xml/bookmarks.xml
@@ -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" />
diff --git a/services/core/java/com/android/server/input/AppLaunchShortcutManager.java b/services/core/java/com/android/server/input/AppLaunchShortcutManager.java
index aef207f..f3820e5 100644
--- a/services/core/java/com/android/server/input/AppLaunchShortcutManager.java
+++ b/services/core/java/com/android/server/input/AppLaunchShortcutManager.java
@@ -21,6 +21,7 @@
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;
@@ -137,11 +138,19 @@
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
@@ -153,12 +162,17 @@
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);
@@ -168,11 +182,9 @@
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)
diff --git a/services/core/java/com/android/server/policy/ModifierShortcutManager.java b/services/core/java/com/android/server/policy/ModifierShortcutManager.java
index 4f67318..c9f66eb 100644
--- a/services/core/java/com/android/server/policy/ModifierShortcutManager.java
+++ b/services/core/java/com/android/server/policy/ModifierShortcutManager.java
@@ -29,6 +29,7 @@
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;
@@ -65,6 +66,7 @@
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;
@@ -84,6 +86,7 @@
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";
@@ -167,6 +170,9 @@
}, UserHandle.ALL);
mCurrentUser = currentUser;
mInputManagerInternal = LocalServices.getService(InputManagerInternal.class);
+ }
+
+ void onSystemReady() {
loadShortcuts();
}
@@ -335,6 +341,7 @@
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);
@@ -353,15 +360,36 @@
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);
@@ -376,7 +404,7 @@
bookmark = new RoleBookmark(shortcutChar, isShiftShortcut, roleName);
}
if (bookmark != null) {
- Log.d(TAG, "adding shortcut " + bookmark + "shift="
+ Log.d(TAG, "adding shortcut " + bookmark + " shift="
+ isShiftShortcut + " char=" + shortcutChar);
mBookmarks.put(new Pair<>(shortcutChar, isShiftShortcut), bookmark);
}
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index dda5bcf..85e7cfe 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -6610,6 +6610,7 @@
// In normal flow, systemReady is called before other system services are ready.
// So it is better not to bind keyguard here.
mKeyguardDelegate.onSystemReady();
+ mModifierShortcutManager.onSystemReady();
mVrManagerInternal = LocalServices.getService(VrManagerInternal.class);
if (mVrManagerInternal != null) {
diff --git a/services/tests/wmtests/res/xml/bookmarks.xml b/services/tests/wmtests/res/xml/bookmarks.xml
index 197b366..787f4e8 100644
--- a/services/tests/wmtests/res/xml/bookmarks.xml
+++ b/services/tests/wmtests/res/xml/bookmarks.xml
@@ -13,60 +13,70 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<bookmarks>
+<bookmarks xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
<!-- the key combinations for the following shortcuts must be in sync
with the key combinations sent by the test in ModifierShortcutTests.java -->
<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" />
<bookmark
role="android.app.role.BROWSER"
- shortcut="b"
- shift="true" />
+ androidprv:keycode="KEYCODE_B"
+ androidprv:modifierState="META|SHIFT" />
<bookmark
category="android.intent.category.APP_CONTACTS"
- shortcut="c"
- shift="true" />
+ androidprv:keycode="KEYCODE_C"
+ androidprv:modifierState="META|SHIFT" />
<bookmark
package="com.test"
class="com.test.BookmarkTest"
- shortcut="j"
- shift="true" />
+ androidprv:keycode="KEYCODE_J"
+ androidprv:modifierState="META|SHIFT" />
<!-- The following shortcuts will not be invoked by tests but are here to
provide test coverage of parsing the different types of shortcut. -->
<bookmark
package="com.test"
class="com.test.BookmarkTest"
- shortcut="j" />
+ androidprv:keycode="KEYCODE_J"
+ androidprv:modifierState="META" />
<bookmark
package="com.test2"
class="com.test.BookmarkTest"
- shortcut="d" />
+ androidprv:keycode="KEYCODE_D"
+ androidprv:modifierState="META" />
<!-- It's intended that this package/class will NOT resolve so we test the resolution
@@ -74,6 +84,7 @@
<bookmark
package="com.test3"
class="com.test.BookmarkTest"
- shortcut="f" />
+ androidprv:keycode="KEYCODE_F"
+ androidprv:modifierState="META" />
</bookmarks>
diff --git a/services/tests/wmtests/src/com/android/server/policy/ModifierShortcutManagerTests.java b/services/tests/wmtests/src/com/android/server/policy/ModifierShortcutManagerTests.java
index 0575d98..82a5add 100644
--- a/services/tests/wmtests/src/com/android/server/policy/ModifierShortcutManagerTests.java
+++ b/services/tests/wmtests/src/com/android/server/policy/ModifierShortcutManagerTests.java
@@ -116,6 +116,7 @@
mModifierShortcutManager = new ModifierShortcutManager(
mContext, mHandler, UserHandle.SYSTEM);
+ mModifierShortcutManager.onSystemReady();
}
@Test
diff --git a/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java b/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java
index a51ce995..bc03c23 100644
--- a/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java
+++ b/services/tests/wmtests/src/com/android/server/policy/TestPhoneWindowManager.java
@@ -88,6 +88,7 @@
import android.telecom.TelecomManager;
import android.view.Display;
import android.view.InputEvent;
+import android.view.KeyCharacterMap;
import android.view.KeyEvent;
import android.view.accessibility.AccessibilityManager;
import android.view.autofill.AutofillManagerInternal;
@@ -270,11 +271,15 @@
// Return mocked services: LocalServices.getService
mMockitoSession = mockitoSession()
.mockStatic(LocalServices.class, spyStubOnly)
+ .mockStatic(KeyCharacterMap.class)
.strictness(Strictness.LENIENT)
.startMocking();
mPhoneWindowManager = spy(new PhoneWindowManager());
+ KeyCharacterMap virtualKcm = mContext.getSystemService(InputManager.class)
+ .getInputDevice(KeyCharacterMap.VIRTUAL_KEYBOARD).getKeyCharacterMap();
+ doReturn(virtualKcm).when(() -> KeyCharacterMap.load(anyInt()));
doReturn(mWindowManagerInternal).when(
() -> LocalServices.getService(eq(WindowManagerInternal.class)));
doReturn(mActivityManagerInternal).when(
diff --git a/tests/Input/res/xml/bookmarks.xml b/tests/Input/res/xml/bookmarks.xml
index ba3f187..a4c898d 100644
--- a/tests/Input/res/xml/bookmarks.xml
+++ b/tests/Input/res/xml/bookmarks.xml
@@ -14,47 +14,55 @@
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
-<bookmarks>
+<bookmarks xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
<!-- the key combinations for the following shortcuts must be in sync
with the key combinations sent by the test in KeyGestureControllerTests.java -->
<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" />
<bookmark
role="android.app.role.BROWSER"
- shortcut="b"
- shift="true" />
+ androidprv:keycode="KEYCODE_B"
+ androidprv:modifierState="META|SHIFT" />
<bookmark
category="android.intent.category.APP_CONTACTS"
- shortcut="c"
+ androidprv:keycode="KEYCODE_C"
shift="true" />
<bookmark
package="com.test"
class="com.test.BookmarkTest"
- shortcut="j"
+ androidprv:keycode="KEYCODE_J"
shift="true" />
</bookmarks>
\ No newline at end of file
diff --git a/tests/Input/res/xml/bookmarks_legacy.xml b/tests/Input/res/xml/bookmarks_legacy.xml
new file mode 100644
index 0000000..8bacf49
--- /dev/null
+++ b/tests/Input/res/xml/bookmarks_legacy.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright 2024 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+<bookmarks>
+ <!-- The key combinations for the following shortcuts are legacy way defining bookmarks and we
+ should prefer new way of defining bookmarks as shown in {@link bookmarks.xml} -->
+ <bookmark
+ role="android.app.role.BROWSER"
+ shortcut="b" />
+ <bookmark
+ category="android.intent.category.APP_CONTACTS"
+ shortcut="c" />
+ <bookmark
+ category="android.intent.category.APP_EMAIL"
+ shortcut="e" />
+ <bookmark
+ category="android.intent.category.APP_CALENDAR"
+ shortcut="k" />
+ <bookmark
+ category="android.intent.category.APP_MAPS"
+ shortcut="m" />
+ <bookmark
+ category="android.intent.category.APP_MUSIC"
+ shortcut="p" />
+ <bookmark
+ role="android.app.role.SMS"
+ shortcut="s" />
+ <bookmark
+ category="android.intent.category.APP_CALCULATOR"
+ shortcut="u" />
+
+ <bookmark
+ role="android.app.role.BROWSER"
+ shortcut="b"
+ shift="true" />
+
+ <bookmark
+ category="android.intent.category.APP_CONTACTS"
+ shortcut="c"
+ shift="true" />
+
+ <bookmark
+ package="com.test"
+ class="com.test.BookmarkTest"
+ shortcut="j"
+ shift="true" />
+</bookmarks>
\ No newline at end of file
diff --git a/tests/Input/src/com/android/server/input/KeyGestureControllerTests.kt b/tests/Input/src/com/android/server/input/KeyGestureControllerTests.kt
index 09a686c..d1f8668 100644
--- a/tests/Input/src/com/android/server/input/KeyGestureControllerTests.kt
+++ b/tests/Input/src/com/android/server/input/KeyGestureControllerTests.kt
@@ -115,13 +115,11 @@
private lateinit var iInputManager: IInputManager
@Mock
- private lateinit var resources: Resources
-
- @Mock
private lateinit var packageManager: PackageManager
private var currentPid = 0
private lateinit var context: Context
+ private lateinit var resources: Resources
private lateinit var keyGestureController: KeyGestureController
private lateinit var inputManagerGlobalSession: InputManagerGlobal.TestSession
private lateinit var testLooper: TestLooper
@@ -130,6 +128,7 @@
@Before
fun setup() {
context = Mockito.spy(ContextWrapper(ApplicationProvider.getApplicationContext()))
+ resources = Mockito.spy(context.resources)
setupInputDevices()
setupBehaviors()
testLooper = TestLooper()
@@ -146,10 +145,6 @@
private fun setupBehaviors() {
Mockito.`when`(SystemProperties.get("ro.debuggable")).thenReturn("1")
Mockito.`when`(resources.getBoolean(R.bool.config_enableScreenshotChord)).thenReturn(true)
- val testBookmarks: XmlResourceParser = context.resources.getXml(
- com.android.test.input.R.xml.bookmarks
- )
- Mockito.`when`(resources.getXml(R.xml.bookmarks)).thenReturn(testBookmarks)
Mockito.`when`(context.resources).thenReturn(resources)
Mockito.`when`(packageManager.hasSystemFeature(PackageManager.FEATURE_WATCH))
.thenReturn(true)
@@ -158,6 +153,11 @@
Mockito.`when`(context.packageManager).thenReturn(packageManager)
}
+ private fun setupBookmarks(bookmarkRes: Int) {
+ val testBookmarks: XmlResourceParser = context.resources.getXml(bookmarkRes)
+ Mockito.`when`(resources.getXml(R.xml.bookmarks)).thenReturn(testBookmarks)
+ }
+
private fun setupInputDevices() {
val correctIm = context.getSystemService(InputManager::class.java)!!
val virtualDevice = correctIm.getInputDevice(KeyCharacterMap.VIRTUAL_KEYBOARD)!!
@@ -604,45 +604,6 @@
AppLaunchData.createLaunchDataForCategory(Intent.CATEGORY_APP_CALCULATOR)
),
TestData(
- "META + SHIFT + B -> Launch Default Browser",
- intArrayOf(
- KeyEvent.KEYCODE_META_LEFT,
- KeyEvent.KEYCODE_SHIFT_LEFT,
- KeyEvent.KEYCODE_B
- ),
- KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_APPLICATION,
- intArrayOf(KeyEvent.KEYCODE_B),
- KeyEvent.META_META_ON or KeyEvent.META_SHIFT_ON,
- intArrayOf(KeyGestureEvent.ACTION_GESTURE_COMPLETE),
- AppLaunchData.createLaunchDataForRole(RoleManager.ROLE_BROWSER)
- ),
- TestData(
- "META + SHIFT + C -> Launch Default Contacts",
- intArrayOf(
- KeyEvent.KEYCODE_META_LEFT,
- KeyEvent.KEYCODE_SHIFT_LEFT,
- KeyEvent.KEYCODE_C
- ),
- KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_APPLICATION,
- intArrayOf(KeyEvent.KEYCODE_C),
- KeyEvent.META_META_ON or KeyEvent.META_SHIFT_ON,
- intArrayOf(KeyGestureEvent.ACTION_GESTURE_COMPLETE),
- AppLaunchData.createLaunchDataForCategory(Intent.CATEGORY_APP_CONTACTS)
- ),
- TestData(
- "META + SHIFT + J -> Launch Target Activity",
- intArrayOf(
- KeyEvent.KEYCODE_META_LEFT,
- KeyEvent.KEYCODE_SHIFT_LEFT,
- KeyEvent.KEYCODE_J
- ),
- KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_APPLICATION,
- intArrayOf(KeyEvent.KEYCODE_J),
- KeyEvent.META_META_ON or KeyEvent.META_SHIFT_ON,
- intArrayOf(KeyGestureEvent.ACTION_GESTURE_COMPLETE),
- AppLaunchData.createLaunchDataForComponent("com.test", "com.test.BookmarkTest")
- ),
- TestData(
"META + CTRL + DEL -> Trigger Bug Report",
intArrayOf(
KeyEvent.KEYCODE_META_LEFT,
@@ -866,6 +827,139 @@
}
@Keep
+ private fun bookmarkArguments(): Array<TestData> {
+ return arrayOf(
+ TestData(
+ "META + B -> Launch Default Browser",
+ intArrayOf(KeyEvent.KEYCODE_META_LEFT, KeyEvent.KEYCODE_B),
+ KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_APPLICATION,
+ intArrayOf(KeyEvent.KEYCODE_B),
+ KeyEvent.META_META_ON,
+ intArrayOf(KeyGestureEvent.ACTION_GESTURE_COMPLETE),
+ AppLaunchData.createLaunchDataForRole(RoleManager.ROLE_BROWSER)
+ ),
+ TestData(
+ "META + C -> Launch Default Contacts",
+ intArrayOf(KeyEvent.KEYCODE_META_LEFT, KeyEvent.KEYCODE_C),
+ KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_APPLICATION,
+ intArrayOf(KeyEvent.KEYCODE_C),
+ KeyEvent.META_META_ON,
+ intArrayOf(KeyGestureEvent.ACTION_GESTURE_COMPLETE),
+ AppLaunchData.createLaunchDataForCategory(Intent.CATEGORY_APP_CONTACTS)
+ ),
+ TestData(
+ "META + E -> Launch Default Email",
+ intArrayOf(KeyEvent.KEYCODE_META_LEFT, KeyEvent.KEYCODE_E),
+ KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_APPLICATION,
+ intArrayOf(KeyEvent.KEYCODE_E),
+ KeyEvent.META_META_ON,
+ intArrayOf(KeyGestureEvent.ACTION_GESTURE_COMPLETE),
+ AppLaunchData.createLaunchDataForCategory(Intent.CATEGORY_APP_EMAIL)
+ ),
+ TestData(
+ "META + K -> Launch Default Calendar",
+ intArrayOf(KeyEvent.KEYCODE_META_LEFT, KeyEvent.KEYCODE_K),
+ KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_APPLICATION,
+ intArrayOf(KeyEvent.KEYCODE_K),
+ KeyEvent.META_META_ON,
+ intArrayOf(KeyGestureEvent.ACTION_GESTURE_COMPLETE),
+ AppLaunchData.createLaunchDataForCategory(Intent.CATEGORY_APP_CALENDAR)
+ ),
+ TestData(
+ "META + M -> Launch Default Maps",
+ intArrayOf(KeyEvent.KEYCODE_META_LEFT, KeyEvent.KEYCODE_M),
+ KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_APPLICATION,
+ intArrayOf(KeyEvent.KEYCODE_M),
+ KeyEvent.META_META_ON,
+ intArrayOf(KeyGestureEvent.ACTION_GESTURE_COMPLETE),
+ AppLaunchData.createLaunchDataForCategory(Intent.CATEGORY_APP_MAPS)
+ ),
+ TestData(
+ "META + P -> Launch Default Music",
+ intArrayOf(KeyEvent.KEYCODE_META_LEFT, KeyEvent.KEYCODE_P),
+ KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_APPLICATION,
+ intArrayOf(KeyEvent.KEYCODE_P),
+ KeyEvent.META_META_ON,
+ intArrayOf(KeyGestureEvent.ACTION_GESTURE_COMPLETE),
+ AppLaunchData.createLaunchDataForCategory(Intent.CATEGORY_APP_MUSIC)
+ ),
+ TestData(
+ "META + S -> Launch Default SMS",
+ intArrayOf(KeyEvent.KEYCODE_META_LEFT, KeyEvent.KEYCODE_S),
+ KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_APPLICATION,
+ intArrayOf(KeyEvent.KEYCODE_S),
+ KeyEvent.META_META_ON,
+ intArrayOf(KeyGestureEvent.ACTION_GESTURE_COMPLETE),
+ AppLaunchData.createLaunchDataForRole(RoleManager.ROLE_SMS)
+ ),
+ TestData(
+ "META + U -> Launch Default Calculator",
+ intArrayOf(KeyEvent.KEYCODE_META_LEFT, KeyEvent.KEYCODE_U),
+ KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_APPLICATION,
+ intArrayOf(KeyEvent.KEYCODE_U),
+ KeyEvent.META_META_ON,
+ intArrayOf(KeyGestureEvent.ACTION_GESTURE_COMPLETE),
+ AppLaunchData.createLaunchDataForCategory(Intent.CATEGORY_APP_CALCULATOR)
+ ),
+ TestData(
+ "META + SHIFT + B -> Launch Default Browser",
+ intArrayOf(
+ KeyEvent.KEYCODE_META_LEFT,
+ KeyEvent.KEYCODE_SHIFT_LEFT,
+ KeyEvent.KEYCODE_B
+ ),
+ KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_APPLICATION,
+ intArrayOf(KeyEvent.KEYCODE_B),
+ KeyEvent.META_META_ON or KeyEvent.META_SHIFT_ON,
+ intArrayOf(KeyGestureEvent.ACTION_GESTURE_COMPLETE),
+ AppLaunchData.createLaunchDataForRole(RoleManager.ROLE_BROWSER)
+ ),
+ TestData(
+ "META + SHIFT + C -> Launch Default Contacts",
+ intArrayOf(
+ KeyEvent.KEYCODE_META_LEFT,
+ KeyEvent.KEYCODE_SHIFT_LEFT,
+ KeyEvent.KEYCODE_C
+ ),
+ KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_APPLICATION,
+ intArrayOf(KeyEvent.KEYCODE_C),
+ KeyEvent.META_META_ON or KeyEvent.META_SHIFT_ON,
+ intArrayOf(KeyGestureEvent.ACTION_GESTURE_COMPLETE),
+ AppLaunchData.createLaunchDataForCategory(Intent.CATEGORY_APP_CONTACTS)
+ ),
+ TestData(
+ "META + SHIFT + J -> Launch Target Activity",
+ intArrayOf(
+ KeyEvent.KEYCODE_META_LEFT,
+ KeyEvent.KEYCODE_SHIFT_LEFT,
+ KeyEvent.KEYCODE_J
+ ),
+ KeyGestureEvent.KEY_GESTURE_TYPE_LAUNCH_APPLICATION,
+ intArrayOf(KeyEvent.KEYCODE_J),
+ KeyEvent.META_META_ON or KeyEvent.META_SHIFT_ON,
+ intArrayOf(KeyGestureEvent.ACTION_GESTURE_COMPLETE),
+ AppLaunchData.createLaunchDataForComponent("com.test", "com.test.BookmarkTest")
+ )
+ )
+ }
+
+ @Test
+ @Parameters(method = "bookmarkArguments")
+ fun testBookmarks(test: TestData) {
+ setupBookmarks(com.android.test.input.R.xml.bookmarks)
+ setupKeyGestureController()
+ testKeyGestureInternal(test)
+ }
+
+ @Test
+ @Parameters(method = "bookmarkArguments")
+ fun testBookmarksLegacy(test: TestData) {
+ setupBookmarks(com.android.test.input.R.xml.bookmarks_legacy)
+ setupKeyGestureController()
+ testKeyGestureInternal(test)
+ }
+
+ @Keep
private fun systemKeysTestArguments(): Array<TestData> {
return arrayOf(
TestData(