Fix the volume key shortcut will be turned off automatically after removing the FAB.

Goal:
Before disable any accessibility service with invisible_toggle type, should check whether it is with hardware key shortcut.

Bug: 267953111
Test: atest MenuViewLayerTest
Change-Id: I0412acc3732837e8e7fd4117e3c2f605fa6de83a
This commit is contained in:
Peter Liang
2023-02-06 13:41:32 +08:00
committed by PETER LIANG
parent 37ac20311d
commit e3f8ae1408
2 changed files with 59 additions and 23 deletions

View File

@@ -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<ComponentName> 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<AccessibilityServiceInfo> 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();

View File

@@ -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<AccessibilityServiceInfo> 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<String> 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<AccessibilityServiceInfo> 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();