Merge changes I78dd3268,I8ce35a82 into main
* changes:
system_server: make UnlockedDeviceRequired fix unconditional
Add unit test coverage for unlock attempts in TrustManagerServiceTest
diff --git a/core/api/current.txt b/core/api/current.txt
index 2866e71..d645938 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -3454,6 +3454,8 @@
field public static final int GLOBAL_ACTION_HOME = 2; // 0x2
field public static final int GLOBAL_ACTION_KEYCODE_HEADSETHOOK = 10; // 0xa
field public static final int GLOBAL_ACTION_LOCK_SCREEN = 8; // 0x8
+ field @FlaggedApi("android.view.accessibility.global_action_media_play_pause") public static final int GLOBAL_ACTION_MEDIA_PLAY_PAUSE = 22; // 0x16
+ field @FlaggedApi("android.view.accessibility.global_action_menu") public static final int GLOBAL_ACTION_MENU = 21; // 0x15
field public static final int GLOBAL_ACTION_NOTIFICATIONS = 4; // 0x4
field public static final int GLOBAL_ACTION_POWER_DIALOG = 6; // 0x6
field public static final int GLOBAL_ACTION_QUICK_SETTINGS = 5; // 0x5
diff --git a/core/java/android/accessibilityservice/AccessibilityService.java b/core/java/android/accessibilityservice/AccessibilityService.java
index d70fa19..81cc674 100644
--- a/core/java/android/accessibilityservice/AccessibilityService.java
+++ b/core/java/android/accessibilityservice/AccessibilityService.java
@@ -67,6 +67,7 @@
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
import android.view.accessibility.AccessibilityWindowInfo;
+import android.view.accessibility.Flags;
import android.view.inputmethod.EditorInfo;
import com.android.internal.annotations.VisibleForTesting;
@@ -625,6 +626,18 @@
*/
public static final int GLOBAL_ACTION_DPAD_CENTER = 20;
+ /**
+ * Action to trigger menu key event.
+ */
+ @FlaggedApi(Flags.FLAG_GLOBAL_ACTION_MENU)
+ public static final int GLOBAL_ACTION_MENU = 21;
+
+ /**
+ * Action to trigger media play/pause key event.
+ */
+ @FlaggedApi(Flags.FLAG_GLOBAL_ACTION_MEDIA_PLAY_PAUSE)
+ public static final int GLOBAL_ACTION_MEDIA_PLAY_PAUSE = 22;
+
private static final String LOG_TAG = "AccessibilityService";
/**
diff --git a/core/java/android/view/accessibility/flags/accessibility_flags.aconfig b/core/java/android/view/accessibility/flags/accessibility_flags.aconfig
index 685654a..a62efdf 100644
--- a/core/java/android/view/accessibility/flags/accessibility_flags.aconfig
+++ b/core/java/android/view/accessibility/flags/accessibility_flags.aconfig
@@ -82,6 +82,20 @@
flag {
namespace: "accessibility"
+ name: "global_action_menu"
+ description: "Allow AccessibilityService to perform GLOBAL_ACTION_MENU"
+ bug: "334954140"
+}
+
+flag {
+ namespace: "accessibility"
+ name: "global_action_media_play_pause"
+ description: "Allow AccessibilityService to perform GLOBAL_ACTION_MEDIA_PLAY_PAUSE"
+ bug: "334954140"
+}
+
+flag {
+ namespace: "accessibility"
name: "granular_scrolling"
description: "Allow the use of granular scrolling. This allows scrollable nodes to scroll by increments other than a full screen"
bug: "302376158"
diff --git a/core/java/android/window/flags/OWNERS b/core/java/android/window/flags/OWNERS
index fd73d35..0472b6c4 100644
--- a/core/java/android/window/flags/OWNERS
+++ b/core/java/android/window/flags/OWNERS
@@ -1,3 +1,4 @@
per-file responsible_apis.aconfig = file:/BAL_OWNERS
per-file large_screen_experiences_app_compat.aconfig = file:/LSE_APP_COMPAT_OWNERS
per-file accessibility.aconfig = file:/core/java/android/view/accessibility/OWNERS
+per-file lse_desktop_experience.aconfig = file:/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/OWNERS
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 59066eb..0b9bde8 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -5937,6 +5937,10 @@
<string name="accessibility_system_action_hardware_a11y_shortcut_label">Accessibility Shortcut</string>
<!-- Label for dismissing the notification shade [CHAR LIMIT=NONE] -->
<string name="accessibility_system_action_dismiss_notification_shade">Dismiss Notification Shade</string>
+ <!-- Label for menu action [CHAR LIMIT=NONE] -->
+ <string name="accessibility_system_action_menu_label">Menu</string>
+ <!-- Label for media play/pause action [CHAR LIMIT=NONE] -->
+ <string name="accessibility_system_action_media_play_pause_label">Media Play/Pause</string>
<!-- Label for Dpad up action [CHAR LIMIT=NONE] -->
<string name="accessibility_system_action_dpad_up_label">Dpad Up</string>
<!-- Label for Dpad down action [CHAR LIMIT=NONE] -->
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 54ab147..8b13a11 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -4433,6 +4433,8 @@
<java-symbol type="string" name="accessibility_system_action_on_screen_a11y_shortcut_chooser_label" />
<java-symbol type="string" name="accessibility_system_action_hardware_a11y_shortcut_label" />
<java-symbol type="string" name="accessibility_system_action_dismiss_notification_shade" />
+ <java-symbol type="string" name="accessibility_system_action_menu_label" />
+ <java-symbol type="string" name="accessibility_system_action_media_play_pause_label" />
<java-symbol type="string" name="accessibility_system_action_dpad_up_label" />
<java-symbol type="string" name="accessibility_system_action_dpad_down_label" />
<java-symbol type="string" name="accessibility_system_action_dpad_left_label" />
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/SystemActions.java b/packages/SystemUI/src/com/android/systemui/accessibility/SystemActions.java
index da49201..5c5ff1e 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/SystemActions.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/SystemActions.java
@@ -42,6 +42,7 @@
import android.view.KeyEvent;
import android.view.WindowManagerGlobal;
import android.view.accessibility.AccessibilityManager;
+import android.view.accessibility.Flags;
import com.android.internal.R;
import com.android.internal.accessibility.dialog.AccessibilityButtonChooserActivity;
@@ -178,6 +179,18 @@
private static final int SYSTEM_ACTION_ID_DPAD_CENTER =
AccessibilityService.GLOBAL_ACTION_DPAD_CENTER; // 20
+ /**
+ * Action ID to trigger menu key event.
+ */
+ private static final int SYSTEM_ACTION_ID_MENU =
+ AccessibilityService.GLOBAL_ACTION_MENU; // 21
+
+ /**
+ * Action ID to trigger media play/pause key event.
+ */
+ private static final int SYSTEM_ACTION_ID_MEDIA_PLAY_PAUSE =
+ AccessibilityService.GLOBAL_ACTION_MEDIA_PLAY_PAUSE; // 22
+
private static final String PERMISSION_SELF = "com.android.systemui.permission.SELF";
private final SystemActionsBroadcastReceiver mReceiver;
@@ -305,6 +318,14 @@
R.string.accessibility_system_action_dpad_center_label,
SystemActionsBroadcastReceiver.INTENT_ACTION_DPAD_CENTER);
+ RemoteAction actionMenu = createRemoteAction(
+ R.string.accessibility_system_action_menu_label,
+ SystemActionsBroadcastReceiver.INTENT_ACTION_MENU);
+
+ RemoteAction actionMediaPlayPause = createRemoteAction(
+ R.string.accessibility_system_action_media_play_pause_label,
+ SystemActionsBroadcastReceiver.INTENT_ACTION_MEDIA_PLAY_PAUSE);
+
mA11yManager.registerSystemAction(actionBack, SYSTEM_ACTION_ID_BACK);
mA11yManager.registerSystemAction(actionHome, SYSTEM_ACTION_ID_HOME);
mA11yManager.registerSystemAction(actionRecents, SYSTEM_ACTION_ID_RECENTS);
@@ -324,6 +345,8 @@
mA11yManager.registerSystemAction(actionDpadLeft, SYSTEM_ACTION_ID_DPAD_LEFT);
mA11yManager.registerSystemAction(actionDpadRight, SYSTEM_ACTION_ID_DPAD_RIGHT);
mA11yManager.registerSystemAction(actionDpadCenter, SYSTEM_ACTION_ID_DPAD_CENTER);
+ mA11yManager.registerSystemAction(actionMenu, SYSTEM_ACTION_ID_MENU);
+ mA11yManager.registerSystemAction(actionMediaPlayPause, SYSTEM_ACTION_ID_MEDIA_PLAY_PAUSE);
registerOrUnregisterDismissNotificationShadeAction();
}
@@ -433,6 +456,14 @@
labelId = R.string.accessibility_system_action_dpad_center_label;
intent = SystemActionsBroadcastReceiver.INTENT_ACTION_DPAD_CENTER;
break;
+ case SYSTEM_ACTION_ID_MENU:
+ labelId = R.string.accessibility_system_action_menu_label;
+ intent = SystemActionsBroadcastReceiver.INTENT_ACTION_MENU;
+ break;
+ case SYSTEM_ACTION_ID_MEDIA_PLAY_PAUSE:
+ labelId = R.string.accessibility_system_action_media_play_pause_label;
+ intent = SystemActionsBroadcastReceiver.INTENT_ACTION_MEDIA_PLAY_PAUSE;
+ break;
default:
return;
}
@@ -569,6 +600,16 @@
sendDownAndUpKeyEvents(KeyEvent.KEYCODE_DPAD_CENTER);
}
+ @VisibleForTesting
+ void handleMenu() {
+ sendDownAndUpKeyEvents(KeyEvent.KEYCODE_MENU);
+ }
+
+ @VisibleForTesting
+ void handleMediaPlayPause() {
+ sendDownAndUpKeyEvents(KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE);
+ }
+
private class SystemActionsBroadcastReceiver extends BroadcastReceiver {
private static final String INTENT_ACTION_BACK = "SYSTEM_ACTION_BACK";
private static final String INTENT_ACTION_HOME = "SYSTEM_ACTION_HOME";
@@ -592,6 +633,9 @@
private static final String INTENT_ACTION_DPAD_LEFT = "SYSTEM_ACTION_DPAD_LEFT";
private static final String INTENT_ACTION_DPAD_RIGHT = "SYSTEM_ACTION_DPAD_RIGHT";
private static final String INTENT_ACTION_DPAD_CENTER = "SYSTEM_ACTION_DPAD_CENTER";
+ private static final String INTENT_ACTION_MENU = "SYSTEM_ACTION_MENU";
+ private static final String INTENT_ACTION_MEDIA_PLAY_PAUSE =
+ "SYSTEM_ACTION_MEDIA_PLAY_PAUSE";
private PendingIntent createPendingIntent(Context context, String intentAction) {
switch (intentAction) {
@@ -612,7 +656,9 @@
case INTENT_ACTION_DPAD_DOWN:
case INTENT_ACTION_DPAD_LEFT:
case INTENT_ACTION_DPAD_RIGHT:
- case INTENT_ACTION_DPAD_CENTER: {
+ case INTENT_ACTION_DPAD_CENTER:
+ case INTENT_ACTION_MENU:
+ case INTENT_ACTION_MEDIA_PLAY_PAUSE: {
Intent intent = new Intent(intentAction);
intent.setPackage(context.getPackageName());
intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
@@ -645,6 +691,8 @@
intentFilter.addAction(INTENT_ACTION_DPAD_LEFT);
intentFilter.addAction(INTENT_ACTION_DPAD_RIGHT);
intentFilter.addAction(INTENT_ACTION_DPAD_CENTER);
+ intentFilter.addAction(INTENT_ACTION_MENU);
+ intentFilter.addAction(INTENT_ACTION_MEDIA_PLAY_PAUSE);
return intentFilter;
}
@@ -724,6 +772,18 @@
handleDpadCenter();
break;
}
+ case INTENT_ACTION_MENU: {
+ if (Flags.globalActionMenu()) {
+ handleMenu();
+ }
+ break;
+ }
+ case INTENT_ACTION_MEDIA_PLAY_PAUSE: {
+ if (Flags.globalActionMediaPlayPause()) {
+ handleMediaPlayPause();
+ }
+ break;
+ }
default:
break;
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/SystemActionsTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/SystemActionsTest.java
index b478d5c..da3e487 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/SystemActionsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/SystemActionsTest.java
@@ -17,6 +17,7 @@
package com.android.systemui.accessibility;
import static com.google.common.truth.Truth.assertThat;
+
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.doAnswer;
@@ -25,11 +26,15 @@
import android.hardware.input.InputManager;
import android.os.RemoteException;
+import android.platform.test.annotations.RequiresFlagsEnabled;
+import android.platform.test.flag.junit.CheckFlagsRule;
+import android.platform.test.flag.junit.DeviceFlagsValueProvider;
import android.telecom.TelecomManager;
import android.telephony.TelephonyManager;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.view.KeyEvent;
+import android.view.accessibility.Flags;
import androidx.test.filters.SmallTest;
@@ -43,6 +48,7 @@
import com.android.systemui.statusbar.policy.KeyguardStateController;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
@@ -76,6 +82,9 @@
private SystemActions mSystemActions;
+ @Rule
+ public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
+
@Before
public void setUp() throws RemoteException {
MockitoAnnotations.initMocks(this);
@@ -130,4 +139,40 @@
verify(mTelecomManager).endCall();
}
+
+ @Test
+ @RequiresFlagsEnabled(Flags.FLAG_GLOBAL_ACTION_MENU)
+ public void handleMenu_injectsKeyEvents() {
+ final List<KeyEvent> keyEvents = new ArrayList<>();
+ doAnswer(invocation -> {
+ keyEvents.add(new KeyEvent(invocation.getArgument(0)));
+ return null;
+ }).when(mInputManager).injectInputEvent(any(), anyInt());
+
+ mSystemActions.handleMenu();
+
+ assertThat(keyEvents.size()).isEqualTo(2);
+ assertThat(keyEvents.get(0).getKeyCode()).isEqualTo(KeyEvent.KEYCODE_MENU);
+ assertThat(keyEvents.get(0).getAction()).isEqualTo(KeyEvent.ACTION_DOWN);
+ assertThat(keyEvents.get(1).getKeyCode()).isEqualTo(KeyEvent.KEYCODE_MENU);
+ assertThat(keyEvents.get(1).getAction()).isEqualTo(KeyEvent.ACTION_UP);
+ }
+
+ @Test
+ @RequiresFlagsEnabled(Flags.FLAG_GLOBAL_ACTION_MEDIA_PLAY_PAUSE)
+ public void handleMediaPlayPause_injectsKeyEvents() {
+ final List<KeyEvent> keyEvents = new ArrayList<>();
+ doAnswer(invocation -> {
+ keyEvents.add(new KeyEvent(invocation.getArgument(0)));
+ return null;
+ }).when(mInputManager).injectInputEvent(any(), anyInt());
+
+ mSystemActions.handleMediaPlayPause();
+
+ assertThat(keyEvents.size()).isEqualTo(2);
+ assertThat(keyEvents.get(0).getKeyCode()).isEqualTo(KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE);
+ assertThat(keyEvents.get(0).getAction()).isEqualTo(KeyEvent.ACTION_DOWN);
+ assertThat(keyEvents.get(1).getKeyCode()).isEqualTo(KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE);
+ assertThat(keyEvents.get(1).getAction()).isEqualTo(KeyEvent.ACTION_UP);
+ }
}
diff --git a/services/accessibility/java/com/android/server/accessibility/SystemActionPerformer.java b/services/accessibility/java/com/android/server/accessibility/SystemActionPerformer.java
index 9747579..2945af5 100644
--- a/services/accessibility/java/com/android/server/accessibility/SystemActionPerformer.java
+++ b/services/accessibility/java/com/android/server/accessibility/SystemActionPerformer.java
@@ -34,6 +34,7 @@
import android.view.KeyEvent;
import android.view.WindowManager;
import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
+import android.view.accessibility.Flags;
import com.android.internal.R;
import com.android.internal.accessibility.util.AccessibilityUtils;
@@ -328,6 +329,18 @@
sendDownAndUpKeyEvents(KeyEvent.KEYCODE_DPAD_CENTER,
InputDevice.SOURCE_KEYBOARD | InputDevice.SOURCE_DPAD);
return true;
+ case AccessibilityService.GLOBAL_ACTION_MENU:
+ if (Flags.globalActionMenu()) {
+ sendDownAndUpKeyEvents(KeyEvent.KEYCODE_MENU,
+ InputDevice.SOURCE_KEYBOARD);
+ }
+ return true;
+ case AccessibilityService.GLOBAL_ACTION_MEDIA_PLAY_PAUSE:
+ if (Flags.globalActionMediaPlayPause()) {
+ sendDownAndUpKeyEvents(KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE,
+ InputDevice.SOURCE_KEYBOARD);
+ }
+ return true;
default:
Slog.e(TAG, "Invalid action id: " + actionId);
return false;