diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayer.java b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayer.java index d0c426d410060..3f41a76823574 100644 --- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayer.java +++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayer.java @@ -17,6 +17,7 @@ package com.android.systemui.accessibility.floatingmenu; import static android.view.WindowInsets.Type.ime; +import static android.view.accessibility.AccessibilityManager.ACCESSIBILITY_SHORTCUT_KEY; import static androidx.core.view.WindowInsetsCompat.Type; @@ -32,6 +33,7 @@ import android.annotation.IntDef; import android.annotation.StringDef; import android.annotation.SuppressLint; import android.content.ComponentCallbacks; +import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.res.Configuration; @@ -132,16 +134,30 @@ class MenuViewLayer extends FrameLayout implements Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS, /* value= */ "", UserHandle.USER_CURRENT); + final List hardwareKeyShortcutComponents = + mAccessibilityManager.getAccessibilityShortcutTargets( + ACCESSIBILITY_SHORTCUT_KEY) + .stream() + .map(ComponentName::unflattenFromString) + .toList(); + // Should disable the corresponding service when the fragment type is // INVISIBLE_TOGGLE, which will enable service when the shortcut is on. final List serviceInfoList = mAccessibilityManager.getEnabledAccessibilityServiceList( AccessibilityServiceInfo.FEEDBACK_ALL_MASK); serviceInfoList.forEach(info -> { - if (getAccessibilityServiceFragmentType(info) == INVISIBLE_TOGGLE) { - setAccessibilityServiceState(getContext(), - info.getComponentName(), /* enabled= */ false); + if (getAccessibilityServiceFragmentType(info) != INVISIBLE_TOGGLE) { + return; } + + final ComponentName serviceComponentName = info.getComponentName(); + if (hardwareKeyShortcutComponents.contains(serviceComponentName)) { + return; + } + + setAccessibilityServiceState(getContext(), serviceComponentName, /* enabled= */ + false); }); mFloatingMenu.hide(); diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayerTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayerTest.java index 728ea1e71801d..5bb5e01675bee 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayerTest.java @@ -165,14 +165,14 @@ public class MenuViewLayerTest extends SysuiTestCase { } @Test - public void tiggerDismissMenuAction_hideFloatingMenu() { + public void triggerDismissMenuAction_hideFloatingMenu() { mMenuViewLayer.mDismissMenuAction.run(); verify(mFloatingMenu).hide(); } @Test - public void tiggerDismissMenuAction_matchA11yButtonTargetsResult() { + public void triggerDismissMenuAction_matchA11yButtonTargetsResult() { mMenuViewLayer.mDismissMenuAction.run(); verify(mSecureSettings).putStringForUser( Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS, /* value= */ "", @@ -180,24 +180,8 @@ public class MenuViewLayerTest extends SysuiTestCase { } @Test - public void tiggerDismissMenuAction_matchEnabledA11yServicesResult() { - Settings.Secure.putString(mContext.getContentResolver(), - Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, - TEST_SELECT_TO_SPEAK_COMPONENT_NAME.flattenToString()); - final ResolveInfo resolveInfo = new ResolveInfo(); - final ServiceInfo serviceInfo = new ServiceInfo(); - final ApplicationInfo applicationInfo = new ApplicationInfo(); - resolveInfo.serviceInfo = serviceInfo; - serviceInfo.applicationInfo = applicationInfo; - applicationInfo.targetSdkVersion = Build.VERSION_CODES.R; - final AccessibilityServiceInfo accessibilityServiceInfo = new AccessibilityServiceInfo(); - accessibilityServiceInfo.setResolveInfo(resolveInfo); - accessibilityServiceInfo.flags = AccessibilityServiceInfo.FLAG_REQUEST_ACCESSIBILITY_BUTTON; - final List serviceInfoList = new ArrayList<>(); - accessibilityServiceInfo.setComponentName(TEST_SELECT_TO_SPEAK_COMPONENT_NAME); - serviceInfoList.add(accessibilityServiceInfo); - when(mStubAccessibilityManager.getEnabledAccessibilityServiceList( - AccessibilityServiceInfo.FEEDBACK_ALL_MASK)).thenReturn(serviceInfoList); + public void triggerDismissMenuAction_matchEnabledA11yServicesResult() { + setupEnabledAccessibilityServiceList(); mMenuViewLayer.mDismissMenuAction.run(); final String value = Settings.Secure.getString(mContext.getContentResolver(), @@ -206,6 +190,21 @@ public class MenuViewLayerTest extends SysuiTestCase { assertThat(value).isEqualTo(""); } + @Test + public void triggerDismissMenuAction_hasHardwareKeyShortcut_keepEnabledStatus() { + setupEnabledAccessibilityServiceList(); + final List stubShortcutTargets = new ArrayList<>(); + stubShortcutTargets.add(TEST_SELECT_TO_SPEAK_COMPONENT_NAME.flattenToString()); + when(mStubAccessibilityManager.getAccessibilityShortcutTargets( + AccessibilityManager.ACCESSIBILITY_SHORTCUT_KEY)).thenReturn(stubShortcutTargets); + + mMenuViewLayer.mDismissMenuAction.run(); + final String value = Settings.Secure.getString(mContext.getContentResolver(), + Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES); + + assertThat(value).isEqualTo(TEST_SELECT_TO_SPEAK_COMPONENT_NAME.flattenToString()); + } + @Test public void showingImeInsetsChange_notOverlapOnIme_menuKeepOriginalPosition() { final float menuTop = STATUS_BAR_HEIGHT + 100; @@ -241,6 +240,27 @@ public class MenuViewLayerTest extends SysuiTestCase { assertThat(mMenuView.getTranslationY()).isEqualTo(menuTop); } + private void setupEnabledAccessibilityServiceList() { + Settings.Secure.putString(mContext.getContentResolver(), + Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, + TEST_SELECT_TO_SPEAK_COMPONENT_NAME.flattenToString()); + + final ResolveInfo resolveInfo = new ResolveInfo(); + final ServiceInfo serviceInfo = new ServiceInfo(); + final ApplicationInfo applicationInfo = new ApplicationInfo(); + resolveInfo.serviceInfo = serviceInfo; + serviceInfo.applicationInfo = applicationInfo; + applicationInfo.targetSdkVersion = Build.VERSION_CODES.R; + final AccessibilityServiceInfo accessibilityServiceInfo = new AccessibilityServiceInfo(); + accessibilityServiceInfo.setResolveInfo(resolveInfo); + accessibilityServiceInfo.flags = AccessibilityServiceInfo.FLAG_REQUEST_ACCESSIBILITY_BUTTON; + final List serviceInfoList = new ArrayList<>(); + accessibilityServiceInfo.setComponentName(TEST_SELECT_TO_SPEAK_COMPONENT_NAME); + serviceInfoList.add(accessibilityServiceInfo); + when(mStubAccessibilityManager.getEnabledAccessibilityServiceList( + AccessibilityServiceInfo.FEEDBACK_ALL_MASK)).thenReturn(serviceInfoList); + } + private void dispatchShowingImeInsets() { final WindowInsets fakeShowingImeInsets = fakeImeInsets(/* isImeVisible= */ true); doReturn(fakeShowingImeInsets).when(mWindowMetrics).getWindowInsets();