From 32447e59c1225ecdc4630af24a20efdec7a2618e Mon Sep 17 00:00:00 2001 From: Peter Liang Date: Fri, 11 Nov 2022 01:44:32 +0800 Subject: [PATCH] Fix the shortcut still turned on after drag to remove the FM in the another user mode. Solution: Should disable the corresponding service when the fragment type is INVISIBLE_TOGGLE, which will enable service when the shortcut is on. Bug: 257851549 Test: atest MenuViewLayerTest Change-Id: I7dd254f7845b2334092eaa59859478c798370dcb --- .../floatingmenu/MenuViewLayer.java | 23 ++++- .../floatingmenu/MenuViewLayerTest.java | 87 ++++++++++++++++++- 2 files changed, 105 insertions(+), 5 deletions(-) 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 33e155df80e32..b8f14aef648a1 100644 --- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayer.java +++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayer.java @@ -16,14 +16,19 @@ package com.android.systemui.accessibility.floatingmenu; +import static com.android.internal.accessibility.common.ShortcutConstants.AccessibilityFragmentType.INVISIBLE_TOGGLE; +import static com.android.internal.accessibility.util.AccessibilityUtils.getAccessibilityServiceFragmentType; +import static com.android.internal.accessibility.util.AccessibilityUtils.setAccessibilityServiceState; import static com.android.systemui.accessibility.floatingmenu.MenuMessageView.Index; +import android.accessibilityservice.AccessibilityServiceInfo; import android.annotation.IntDef; import android.annotation.SuppressLint; import android.content.Context; import android.content.res.Configuration; import android.os.Handler; import android.os.Looper; +import android.os.UserHandle; import android.provider.Settings; import android.util.PluralsMessageFormatter; import android.view.MotionEvent; @@ -82,8 +87,22 @@ class MenuViewLayer extends FrameLayout { final Runnable mDismissMenuAction = new Runnable() { @Override public void run() { - Settings.Secure.putString(getContext().getContentResolver(), - Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS, /* value= */ ""); + Settings.Secure.putStringForUser(getContext().getContentResolver(), + Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS, /* value= */ "", + UserHandle.USER_CURRENT); + + // 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(mContext, info.getComponentName(), /* 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 d20eeafde09c9..2d5188fcb95ac 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 @@ -19,12 +19,22 @@ package com.android.systemui.accessibility.floatingmenu; import static android.view.View.GONE; import static android.view.View.VISIBLE; +import static com.android.internal.accessibility.AccessibilityShortcutController.MAGNIFICATION_COMPONENT_NAME; import static com.android.systemui.accessibility.floatingmenu.MenuViewLayer.LayerIndex; import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import android.accessibilityservice.AccessibilityServiceInfo; +import android.content.ComponentName; +import android.content.pm.ApplicationInfo; +import android.content.pm.ResolveInfo; +import android.content.pm.ServiceInfo; +import android.os.Build; +import android.os.UserHandle; +import android.provider.Settings; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; import android.view.View; @@ -35,6 +45,7 @@ import androidx.test.filters.SmallTest; import com.android.systemui.SysuiTestCase; +import org.junit.After; import org.junit.Before; import org.junit.Rule; import org.junit.Test; @@ -43,12 +54,23 @@ import org.mockito.Mock; import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; +import java.util.ArrayList; +import java.util.List; + /** Tests for {@link MenuViewLayer}. */ @RunWith(AndroidTestingRunner.class) @TestableLooper.RunWithLooper(setAsMainLooper = true) @SmallTest public class MenuViewLayerTest extends SysuiTestCase { + private static final String SELECT_TO_SPEAK_PACKAGE_NAME = "com.google.android.marvin.talkback"; + private static final String SELECT_TO_SPEAK_SERVICE_NAME = + "com.google.android.accessibility.selecttospeak.SelectToSpeakService"; + private static final ComponentName TEST_SELECT_TO_SPEAK_COMPONENT_NAME = new ComponentName( + SELECT_TO_SPEAK_PACKAGE_NAME, SELECT_TO_SPEAK_SERVICE_NAME); + private MenuViewLayer mMenuViewLayer; + private String mLastAccessibilityButtonTargets; + private String mLastEnabledAccessibilityServices; @Rule public MockitoRule mockito = MockitoJUnit.rule(); @@ -56,13 +78,31 @@ public class MenuViewLayerTest extends SysuiTestCase { @Mock private IAccessibilityFloatingMenu mFloatingMenu; + @Mock + private AccessibilityManager mStubAccessibilityManager; + @Before public void setUp() throws Exception { final WindowManager stubWindowManager = mContext.getSystemService(WindowManager.class); - final AccessibilityManager stubAccessibilityManager = mContext.getSystemService( - AccessibilityManager.class); - mMenuViewLayer = new MenuViewLayer(mContext, stubWindowManager, stubAccessibilityManager, + mMenuViewLayer = new MenuViewLayer(mContext, stubWindowManager, mStubAccessibilityManager, mFloatingMenu); + + mLastAccessibilityButtonTargets = + Settings.Secure.getStringForUser(mContext.getContentResolver(), + Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS, UserHandle.USER_CURRENT); + mLastEnabledAccessibilityServices = + Settings.Secure.getStringForUser(mContext.getContentResolver(), + Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, UserHandle.USER_CURRENT); + } + + @After + public void tearDown() throws Exception { + Settings.Secure.putStringForUser(mContext.getContentResolver(), + Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS, mLastAccessibilityButtonTargets, + UserHandle.USER_CURRENT); + Settings.Secure.putStringForUser(mContext.getContentResolver(), + Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, mLastEnabledAccessibilityServices, + UserHandle.USER_CURRENT); } @Test @@ -87,4 +127,45 @@ public class MenuViewLayerTest extends SysuiTestCase { verify(mFloatingMenu).hide(); } + + @Test + public void tiggerDismissMenuAction_matchA11yButtonTargetsResult() { + Settings.Secure.putStringForUser(mContext.getContentResolver(), + Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS, + MAGNIFICATION_COMPONENT_NAME.flattenToString(), UserHandle.USER_CURRENT); + + mMenuViewLayer.mDismissMenuAction.run(); + final String value = + Settings.Secure.getStringForUser(mContext.getContentResolver(), + Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS, UserHandle.USER_CURRENT); + + assertThat(value).isEqualTo(""); + } + + @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); + + mMenuViewLayer.mDismissMenuAction.run(); + final String value = Settings.Secure.getString(mContext.getContentResolver(), + Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES); + + assertThat(value).isEqualTo(""); + } }