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:
@@ -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] -->
|
||||||
|
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -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();
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user