Allow users dismiss accessibility quick settings tooltips when clicked

Problem: When Talkback on, users cannot use double tap or swipe to move focus on the next window.
Solution: Talkback speaks out "double tap to dismiss" to allow dismissing this tooltips.

Bug: 215656141
Test: make RunSettingsRoboTests ROBOTEST_FILTER=AccessibilityQuickSettingsTooltipWindowTest
Change-Id: I8f7066a805ec963f9f0f8fee1b81ad008418c4a6
This commit is contained in:
menghanli
2022-01-19 09:29:13 +08:00
parent a67bb94388
commit 238639c494
3 changed files with 65 additions and 20 deletions

View File

@@ -5481,6 +5481,8 @@
<string name="accessibility_service_primary_open_title">Open <xliff:g id="accessibility_app_name" example="TalkBack">%1$s</xliff:g></string> <string name="accessibility_service_primary_open_title">Open <xliff:g id="accessibility_app_name" example="TalkBack">%1$s</xliff:g></string>
<!-- Used in the accessibility service settings to show quick settings tooltips. [CHAR LIMIT=NONE] --> <!-- Used in the accessibility service settings to show quick settings tooltips. [CHAR LIMIT=NONE] -->
<string name="accessibility_service_quick_settings_tooltips_content">Swipe down to quickly turn <xliff:g id="accessibility_app_name" example="TalkBack">%1$s</xliff:g> on or off in quick settings</string> <string name="accessibility_service_quick_settings_tooltips_content">Swipe down to quickly turn <xliff:g id="accessibility_app_name" example="TalkBack">%1$s</xliff:g> on or off in quick settings</string>
<!-- Used in the accessibility action for accessibility quick settings tooltips to dismiss. [CHAR LIMIT=NONE] -->
<string name="accessibility_quick_settings_tooltips_dismiss">Dismiss</string>
<!-- Used in the Color correction settings screen to control turning on/off the feature entirely [CHAR LIMIT=60] --> <!-- Used in the Color correction settings screen to control turning on/off the feature entirely [CHAR LIMIT=60] -->
<string name="accessibility_daltonizer_primary_switch_title">Use color correction</string> <string name="accessibility_daltonizer_primary_switch_title">Use color correction</string>
<!-- Title for accessibility shortcut preference for color correction. [CHAR LIMIT=60] --> <!-- Title for accessibility shortcut preference for color correction. [CHAR LIMIT=60] -->

View File

@@ -19,10 +19,14 @@ package com.android.settings.accessibility;
import android.content.Context; import android.content.Context;
import android.content.res.Resources; import android.content.res.Resources;
import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.view.Gravity; import android.view.Gravity;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.View.AccessibilityDelegate;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.PopupWindow; import android.widget.PopupWindow;
import android.widget.TextView; import android.widget.TextView;
@@ -49,6 +53,25 @@ public class AccessibilityQuickSettingsTooltipWindow extends PopupWindow {
this.mContext = context; this.mContext = context;
} }
private final AccessibilityDelegate mAccessibilityDelegate = new AccessibilityDelegate() {
@Override
public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) {
super.onInitializeAccessibilityNodeInfo(host, info);
final AccessibilityAction clickAction = new AccessibilityAction(
AccessibilityNodeInfo.ACTION_CLICK,
mContext.getString(R.string.accessibility_quick_settings_tooltips_dismiss));
info.addAction(clickAction);
}
@Override
public boolean performAccessibilityAction(View host, int action, Bundle args) {
if (action == AccessibilityNodeInfo.ACTION_CLICK) {
dismiss();
return true;
}
return super.performAccessibilityAction(host, action, args);
}
};
/** /**
* Sets up {@link #AccessibilityQuickSettingsTooltipWindow}'s layout and content. * Sets up {@link #AccessibilityQuickSettingsTooltipWindow}'s layout and content.
* *
@@ -74,13 +97,16 @@ public class AccessibilityQuickSettingsTooltipWindow extends PopupWindow {
final LayoutInflater inflater = mContext.getSystemService(LayoutInflater.class); final LayoutInflater inflater = mContext.getSystemService(LayoutInflater.class);
final View popupView = final View popupView =
inflater.inflate(R.layout.accessibility_qs_tooltips, /* root= */ null); inflater.inflate(R.layout.accessibility_qs_tooltips, /* root= */ null);
popupView.setFocusable(/* focusable= */ true);
popupView.setAccessibilityDelegate(mAccessibilityDelegate);
setContentView(popupView); setContentView(popupView);
final TextView textView = getContentView().findViewById(R.id.qs_content); final TextView textView = getContentView().findViewById(R.id.qs_content);
textView.setText(text); textView.setText(text);
setWidth(getWindowWidthWith(textView)); setWidth(getWindowWidthWith(textView));
setHeight(LinearLayout.LayoutParams.WRAP_CONTENT); setHeight(LinearLayout.LayoutParams.WRAP_CONTENT);
setFocusable(/* focusable= */ true); setFocusable(/* focusable= */ true);
setOutsideTouchable(/* touchable= */ true);
} }
/** /**

View File

@@ -22,6 +22,7 @@ import static org.mockito.Mockito.verify;
import android.content.Context; import android.content.Context;
import android.view.View; import android.view.View;
import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.PopupWindow; import android.widget.PopupWindow;
import androidx.test.core.app.ApplicationProvider; import androidx.test.core.app.ApplicationProvider;
@@ -53,52 +54,68 @@ public class AccessibilityQuickSettingsTooltipWindowTest {
private static final String TEST_PACKAGE_NAME = "com.test.package"; private static final String TEST_PACKAGE_NAME = "com.test.package";
private final Context mContext = ApplicationProvider.getApplicationContext(); private final Context mContext = ApplicationProvider.getApplicationContext();
private AccessibilityQuickSettingsTooltipWindow mToolTipView; private AccessibilityQuickSettingsTooltipWindow mTooltipView;
private View mView; private View mView;
@Before @Before
public void setUp() { public void setUp() {
mToolTipView = new AccessibilityQuickSettingsTooltipWindow(mContext); mTooltipView = new AccessibilityQuickSettingsTooltipWindow(mContext);
mView = new View(RuntimeEnvironment.application); mView = new View(RuntimeEnvironment.application);
} }
@Test @Test
public void initToolTipView_atMostAvailableTextWidth() { public void initTooltipView_atMostAvailableTextWidth() {
final String quickSettingsTooltipsContent = mContext.getString( final String quickSettingsTooltipsContent = mContext.getString(
R.string.accessibility_service_quick_settings_tooltips_content, TEST_PACKAGE_NAME); R.string.accessibility_service_quick_settings_tooltips_content, TEST_PACKAGE_NAME);
mToolTipView.setup(quickSettingsTooltipsContent); mTooltipView.setup(quickSettingsTooltipsContent);
final int getMaxWidth = mToolTipView.getAvailableWindowWidth(); final int getMaxWidth = mTooltipView.getAvailableWindowWidth();
assertThat(mToolTipView.getWidth()).isAtMost(getMaxWidth); assertThat(mTooltipView.getWidth()).isAtMost(getMaxWidth);
} }
@Test @Test
public void showToolTipView_success() { public void showTooltipView_success() {
mToolTipView.setup(TEST_PACKAGE_NAME); mTooltipView.setup(TEST_PACKAGE_NAME);
assertThat(getLatestPopupWindow()).isNull(); assertThat(getLatestPopupWindow()).isNull();
mToolTipView.showAtTopCenter(mView); mTooltipView.showAtTopCenter(mView);
assertThat(getLatestPopupWindow()).isSameInstanceAs(mToolTipView); assertThat(getLatestPopupWindow()).isSameInstanceAs(mTooltipView);
} }
@Test @Test
public void dismiss_toolTipViewShown_shouldInvokeCallbackAndNotShowing() { public void accessibilityClickActionOnTooltipViewShown_shouldInvokeCallbackAndNotShowing() {
mToolTipView.setup(TEST_PACKAGE_NAME); mTooltipView.setup(TEST_PACKAGE_NAME);
mToolTipView.setOnDismissListener(mMockOnDismissListener); mTooltipView.setOnDismissListener(mMockOnDismissListener);
mToolTipView.showAtTopCenter(mView); mTooltipView.showAtTopCenter(mView);
mToolTipView.dismiss(); final boolean isActionPerformed =
mTooltipView.getContentView().performAccessibilityAction(
AccessibilityNodeInfo.AccessibilityAction.ACTION_CLICK.getId(),
/* arguments= */ null);
assertThat(isActionPerformed).isTrue();
verify(mMockOnDismissListener).onDismiss();
assertThat(getLatestPopupWindow().isShowing()).isFalse();
}
@Test
public void dismiss_tooltipViewShown_shouldInvokeCallbackAndNotShowing() {
mTooltipView.setup(TEST_PACKAGE_NAME);
mTooltipView.setOnDismissListener(mMockOnDismissListener);
mTooltipView.showAtTopCenter(mView);
mTooltipView.dismiss();
verify(mMockOnDismissListener).onDismiss(); verify(mMockOnDismissListener).onDismiss();
assertThat(getLatestPopupWindow().isShowing()).isFalse(); assertThat(getLatestPopupWindow().isShowing()).isFalse();
} }
@Test @Test
public void waitAutoCloseDelayTime_toolTipViewShown_shouldInvokeCallbackAndNotShowing() { public void waitAutoCloseDelayTime_tooltipViewShown_shouldInvokeCallbackAndNotShowing() {
mToolTipView.setup(TEST_PACKAGE_NAME, /* closeDelayTimeMillis= */ 1); mTooltipView.setup(TEST_PACKAGE_NAME, /* closeDelayTimeMillis= */ 1);
mToolTipView.setOnDismissListener(mMockOnDismissListener); mTooltipView.setOnDismissListener(mMockOnDismissListener);
mToolTipView.showAtTopCenter(mView); mTooltipView.showAtTopCenter(mView);
ShadowLooper.runUiThreadTasksIncludingDelayedTasks(); ShadowLooper.runUiThreadTasksIncludingDelayedTasks();