Fixing the announcement of menu of a11y actions when using Talkback
or Switch Access. Root cause: The accessibility delegate was used for the root view instead of items. Actions: 1) Add the accessibility delegate to the individual items of the RecyclerView, and then override the functions onInitializeAccessibilityNodeInfo() and performAccessibilityAction(). 2) Remove the overridden functions onInitializeAccessibilityNodeInfo() and performAccessibilityAction() from the root view. Bug: 190326499 Bug: 190138534 Test: manual test Change-Id: Ife1787c2d7bb3090e4d55aed76c303e9842a1a98
This commit is contained in:
@@ -39,7 +39,6 @@ import android.graphics.Rect;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.graphics.drawable.GradientDrawable;
|
||||
import android.graphics.drawable.LayerDrawable;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.util.DisplayMetrics;
|
||||
@@ -50,8 +49,6 @@ import android.view.ViewGroup;
|
||||
import android.view.WindowInsets;
|
||||
import android.view.WindowManager;
|
||||
import android.view.WindowMetrics;
|
||||
import android.view.accessibility.AccessibilityNodeInfo;
|
||||
import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
|
||||
import android.view.animation.Animation;
|
||||
import android.view.animation.OvershootInterpolator;
|
||||
import android.view.animation.TranslateAnimation;
|
||||
@@ -59,8 +56,10 @@ import android.widget.FrameLayout;
|
||||
|
||||
import androidx.annotation.DimenRes;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.core.view.AccessibilityDelegateCompat;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import androidx.recyclerview.widget.RecyclerViewAccessibilityDelegate;
|
||||
|
||||
import com.android.internal.accessibility.dialog.AccessibilityTarget;
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
@@ -332,54 +331,6 @@ public class AccessibilityFloatingMenuView extends FrameLayout
|
||||
// Do Nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
|
||||
super.onInitializeAccessibilityNodeInfo(info);
|
||||
setupAccessibilityActions(info);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean performAccessibilityAction(int action, Bundle arguments) {
|
||||
fadeIn();
|
||||
|
||||
final Rect bounds = getAvailableBounds();
|
||||
if (action == R.id.action_move_top_left) {
|
||||
setShapeType(ShapeType.OVAL);
|
||||
snapToLocation(bounds.left, bounds.top);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (action == R.id.action_move_top_right) {
|
||||
setShapeType(ShapeType.OVAL);
|
||||
snapToLocation(bounds.right, bounds.top);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (action == R.id.action_move_bottom_left) {
|
||||
setShapeType(ShapeType.OVAL);
|
||||
snapToLocation(bounds.left, bounds.bottom);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (action == R.id.action_move_bottom_right) {
|
||||
setShapeType(ShapeType.OVAL);
|
||||
snapToLocation(bounds.right, bounds.bottom);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (action == R.id.action_move_to_edge_and_hide) {
|
||||
setShapeType(ShapeType.HALF_OVAL);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (action == R.id.action_move_out_edge_and_show) {
|
||||
setShapeType(ShapeType.OVAL);
|
||||
return true;
|
||||
}
|
||||
|
||||
return super.performAccessibilityAction(action, arguments);
|
||||
}
|
||||
|
||||
void show() {
|
||||
if (isShowing()) {
|
||||
return;
|
||||
@@ -526,43 +477,6 @@ public class AccessibilityFloatingMenuView extends FrameLayout
|
||||
mUiHandler.postDelayed(() -> mFadeOutAnimator.start(), FADE_EFFECT_DURATION_MS);
|
||||
}
|
||||
|
||||
private void setupAccessibilityActions(AccessibilityNodeInfo info) {
|
||||
final Resources res = mContext.getResources();
|
||||
final AccessibilityAction moveTopLeft =
|
||||
new AccessibilityAction(R.id.action_move_top_left,
|
||||
res.getString(
|
||||
R.string.accessibility_floating_button_action_move_top_left));
|
||||
info.addAction(moveTopLeft);
|
||||
|
||||
final AccessibilityAction moveTopRight =
|
||||
new AccessibilityAction(R.id.action_move_top_right,
|
||||
res.getString(
|
||||
R.string.accessibility_floating_button_action_move_top_right));
|
||||
info.addAction(moveTopRight);
|
||||
|
||||
final AccessibilityAction moveBottomLeft =
|
||||
new AccessibilityAction(R.id.action_move_bottom_left,
|
||||
res.getString(
|
||||
R.string.accessibility_floating_button_action_move_bottom_left));
|
||||
info.addAction(moveBottomLeft);
|
||||
|
||||
final AccessibilityAction moveBottomRight =
|
||||
new AccessibilityAction(R.id.action_move_bottom_right,
|
||||
res.getString(
|
||||
R.string.accessibility_floating_button_action_move_bottom_right));
|
||||
info.addAction(moveBottomRight);
|
||||
|
||||
final int moveEdgeId = mShapeType == ShapeType.OVAL
|
||||
? R.id.action_move_to_edge_and_hide
|
||||
: R.id.action_move_out_edge_and_show;
|
||||
final int moveEdgeTextResId = mShapeType == ShapeType.OVAL
|
||||
? R.string.accessibility_floating_button_action_move_to_edge_and_hide_to_half
|
||||
: R.string.accessibility_floating_button_action_move_out_edge_and_show;
|
||||
final AccessibilityAction moveToOrOutEdge =
|
||||
new AccessibilityAction(moveEdgeId, res.getString(moveEdgeTextResId));
|
||||
info.addAction(moveToOrOutEdge);
|
||||
}
|
||||
|
||||
private boolean onTouched(MotionEvent event) {
|
||||
final int action = event.getAction();
|
||||
final int currentX = (int) event.getX();
|
||||
@@ -685,6 +599,15 @@ public class AccessibilityFloatingMenuView extends FrameLayout
|
||||
mListView.setLayoutManager(layoutManager);
|
||||
mListView.addOnItemTouchListener(this);
|
||||
mListView.animate().setInterpolator(new OvershootInterpolator());
|
||||
mListView.setAccessibilityDelegateCompat(new RecyclerViewAccessibilityDelegate(mListView) {
|
||||
@NonNull
|
||||
@Override
|
||||
public AccessibilityDelegateCompat getItemDelegate() {
|
||||
return new ItemDelegateCompat(this,
|
||||
AccessibilityFloatingMenuView.this);
|
||||
}
|
||||
});
|
||||
|
||||
updateListViewWith(mLastConfiguration);
|
||||
|
||||
addView(mListView);
|
||||
|
||||
@@ -0,0 +1,141 @@
|
||||
/*
|
||||
* Copyright (C) 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.systemui.accessibility.floatingmenu;
|
||||
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Rect;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.core.view.accessibility.AccessibilityNodeInfoCompat;
|
||||
import androidx.recyclerview.widget.RecyclerViewAccessibilityDelegate;
|
||||
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.accessibility.floatingmenu.AccessibilityFloatingMenuView.ShapeType;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
/**
|
||||
* An accessibility item delegate for the individual items of the list view
|
||||
* {@link AccessibilityFloatingMenuView}.
|
||||
*/
|
||||
final class ItemDelegateCompat extends RecyclerViewAccessibilityDelegate.ItemDelegate {
|
||||
private final WeakReference<AccessibilityFloatingMenuView> mMenuViewRef;
|
||||
|
||||
ItemDelegateCompat(@NonNull RecyclerViewAccessibilityDelegate recyclerViewDelegate,
|
||||
AccessibilityFloatingMenuView menuView) {
|
||||
super(recyclerViewDelegate);
|
||||
this.mMenuViewRef = new WeakReference<>(menuView);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfoCompat info) {
|
||||
super.onInitializeAccessibilityNodeInfo(host, info);
|
||||
|
||||
if (mMenuViewRef.get() == null) {
|
||||
return;
|
||||
}
|
||||
final AccessibilityFloatingMenuView menuView = mMenuViewRef.get();
|
||||
|
||||
final Resources res = menuView.getResources();
|
||||
final AccessibilityNodeInfoCompat.AccessibilityActionCompat moveTopLeft =
|
||||
new AccessibilityNodeInfoCompat.AccessibilityActionCompat(R.id.action_move_top_left,
|
||||
res.getString(
|
||||
R.string.accessibility_floating_button_action_move_top_left));
|
||||
info.addAction(moveTopLeft);
|
||||
|
||||
final AccessibilityNodeInfoCompat.AccessibilityActionCompat moveTopRight =
|
||||
new AccessibilityNodeInfoCompat.AccessibilityActionCompat(
|
||||
R.id.action_move_top_right,
|
||||
res.getString(
|
||||
R.string.accessibility_floating_button_action_move_top_right));
|
||||
info.addAction(moveTopRight);
|
||||
|
||||
final AccessibilityNodeInfoCompat.AccessibilityActionCompat moveBottomLeft =
|
||||
new AccessibilityNodeInfoCompat.AccessibilityActionCompat(
|
||||
R.id.action_move_bottom_left,
|
||||
res.getString(
|
||||
R.string.accessibility_floating_button_action_move_bottom_left));
|
||||
info.addAction(moveBottomLeft);
|
||||
|
||||
final AccessibilityNodeInfoCompat.AccessibilityActionCompat moveBottomRight =
|
||||
new AccessibilityNodeInfoCompat.AccessibilityActionCompat(
|
||||
R.id.action_move_bottom_right,
|
||||
res.getString(
|
||||
R.string.accessibility_floating_button_action_move_bottom_right));
|
||||
info.addAction(moveBottomRight);
|
||||
|
||||
final int moveEdgeId = menuView.isOvalShape()
|
||||
? R.id.action_move_to_edge_and_hide
|
||||
: R.id.action_move_out_edge_and_show;
|
||||
final int moveEdgeTextResId = menuView.isOvalShape()
|
||||
? R.string.accessibility_floating_button_action_move_to_edge_and_hide_to_half
|
||||
: R.string.accessibility_floating_button_action_move_out_edge_and_show;
|
||||
final AccessibilityNodeInfoCompat.AccessibilityActionCompat moveToOrOutEdge =
|
||||
new AccessibilityNodeInfoCompat.AccessibilityActionCompat(moveEdgeId,
|
||||
res.getString(moveEdgeTextResId));
|
||||
info.addAction(moveToOrOutEdge);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean performAccessibilityAction(View host, int action, Bundle args) {
|
||||
if (mMenuViewRef.get() == null) {
|
||||
return super.performAccessibilityAction(host, action, args);
|
||||
}
|
||||
final AccessibilityFloatingMenuView menuView = mMenuViewRef.get();
|
||||
|
||||
menuView.fadeIn();
|
||||
|
||||
final Rect bounds = menuView.getAvailableBounds();
|
||||
if (action == R.id.action_move_top_left) {
|
||||
menuView.setShapeType(ShapeType.OVAL);
|
||||
menuView.snapToLocation(bounds.left, bounds.top);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (action == R.id.action_move_top_right) {
|
||||
menuView.setShapeType(ShapeType.OVAL);
|
||||
menuView.snapToLocation(bounds.right, bounds.top);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (action == R.id.action_move_bottom_left) {
|
||||
menuView.setShapeType(ShapeType.OVAL);
|
||||
menuView.snapToLocation(bounds.left, bounds.bottom);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (action == R.id.action_move_bottom_right) {
|
||||
menuView.setShapeType(ShapeType.OVAL);
|
||||
menuView.snapToLocation(bounds.right, bounds.bottom);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (action == R.id.action_move_to_edge_and_hide) {
|
||||
menuView.setShapeType(ShapeType.HALF_OVAL);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (action == R.id.action_move_out_edge_and_show) {
|
||||
menuView.setShapeType(ShapeType.OVAL);
|
||||
return true;
|
||||
}
|
||||
|
||||
return super.performAccessibilityAction(host, action, args);
|
||||
}
|
||||
}
|
||||
@@ -38,7 +38,6 @@ import static org.mockito.Mockito.when;
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Insets;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.drawable.GradientDrawable;
|
||||
import android.graphics.drawable.LayerDrawable;
|
||||
import android.testing.AndroidTestingRunner;
|
||||
@@ -49,7 +48,6 @@ import android.view.ViewPropertyAnimator;
|
||||
import android.view.WindowInsets;
|
||||
import android.view.WindowManager;
|
||||
import android.view.WindowMetrics;
|
||||
import android.view.accessibility.AccessibilityNodeInfo;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
@@ -87,7 +85,6 @@ public class AccessibilityFloatingMenuViewTest extends SysuiTestCase {
|
||||
private final List<AccessibilityTarget> mTargets = new ArrayList<>(
|
||||
Collections.singletonList(mock(AccessibilityTarget.class)));
|
||||
|
||||
private final Rect mAvailableBounds = new Rect(100, 200, 300, 400);
|
||||
private final Position mPlaceholderPosition = new Position(0.0f, 0.0f);
|
||||
|
||||
@Mock
|
||||
@@ -144,6 +141,7 @@ public class AccessibilityFloatingMenuViewTest extends SysuiTestCase {
|
||||
|
||||
@Test
|
||||
public void initListView_success() {
|
||||
assertThat(mListView.getCompatAccessibilityDelegate()).isNotNull();
|
||||
assertThat(mMenuView.getChildCount()).isEqualTo(1);
|
||||
}
|
||||
|
||||
@@ -369,90 +367,6 @@ public class AccessibilityFloatingMenuViewTest extends SysuiTestCase {
|
||||
assertThat(menuView.mShapeType).isEqualTo(/* halfOval */ 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAccessibilityActionList_matchResult() {
|
||||
final AccessibilityNodeInfo info = new AccessibilityNodeInfo();
|
||||
|
||||
mMenuView.onInitializeAccessibilityNodeInfo(info);
|
||||
|
||||
assertThat(info.getActionList().size()).isEqualTo(5);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void accessibilityActionMove_halfOval_moveTopLeft_success() {
|
||||
doReturn(mAvailableBounds).when(mMenuView).getAvailableBounds();
|
||||
mMenuView.setShapeType(/* halfOvalShape */ 1);
|
||||
|
||||
final boolean moveTopLeftAction =
|
||||
mMenuView.performAccessibilityAction(R.id.action_move_top_left, null);
|
||||
|
||||
assertThat(moveTopLeftAction).isTrue();
|
||||
assertThat(mMenuView.mShapeType).isEqualTo(/* ovalShape */ 0);
|
||||
verify(mMenuView).snapToLocation(mAvailableBounds.left, mAvailableBounds.top);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void accessibilityActionMove_halfOval_moveTopRight_success() {
|
||||
doReturn(mAvailableBounds).when(mMenuView).getAvailableBounds();
|
||||
mMenuView.setShapeType(/* halfOvalShape */ 1);
|
||||
|
||||
final boolean moveTopRightAction =
|
||||
mMenuView.performAccessibilityAction(R.id.action_move_top_right, null);
|
||||
|
||||
assertThat(moveTopRightAction).isTrue();
|
||||
assertThat(mMenuView.mShapeType).isEqualTo(/* ovalShape */ 0);
|
||||
verify(mMenuView).snapToLocation(mAvailableBounds.right, mAvailableBounds.top);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void accessibilityActionMove_halfOval_moveBottomLeft_success() {
|
||||
doReturn(mAvailableBounds).when(mMenuView).getAvailableBounds();
|
||||
mMenuView.setShapeType(/* halfOvalShape */ 1);
|
||||
|
||||
final boolean moveBottomLeftAction =
|
||||
mMenuView.performAccessibilityAction(R.id.action_move_bottom_left, null);
|
||||
|
||||
assertThat(moveBottomLeftAction).isTrue();
|
||||
assertThat(mMenuView.mShapeType).isEqualTo(/* ovalShape */ 0);
|
||||
verify(mMenuView).snapToLocation(mAvailableBounds.left, mAvailableBounds.bottom);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void accessibilityActionMove_halfOval_moveBottomRight_success() {
|
||||
doReturn(mAvailableBounds).when(mMenuView).getAvailableBounds();
|
||||
mMenuView.setShapeType(/* halfOvalShape */ 1);
|
||||
|
||||
final boolean moveBottomRightAction =
|
||||
mMenuView.performAccessibilityAction(R.id.action_move_bottom_right, null);
|
||||
|
||||
assertThat(moveBottomRightAction).isTrue();
|
||||
assertThat(mMenuView.mShapeType).isEqualTo(/* ovalShape */ 0);
|
||||
verify(mMenuView).snapToLocation(mAvailableBounds.right, mAvailableBounds.bottom);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void accessibilityActionMove_halfOval_moveOutEdgeAndShow_success() {
|
||||
doReturn(mAvailableBounds).when(mMenuView).getAvailableBounds();
|
||||
mMenuView.setShapeType(/* halfOvalShape */ 1);
|
||||
|
||||
final boolean moveOutEdgeAndShowAction =
|
||||
mMenuView.performAccessibilityAction(R.id.action_move_out_edge_and_show, null);
|
||||
|
||||
assertThat(moveOutEdgeAndShowAction).isTrue();
|
||||
assertThat(mMenuView.mShapeType).isEqualTo(/* ovalShape */ 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setupAccessibilityActions_oval_hasActionMoveToEdgeAndHide() {
|
||||
final AccessibilityNodeInfo info = new AccessibilityNodeInfo();
|
||||
mMenuView.setShapeType(/* ovalShape */ 0);
|
||||
|
||||
mMenuView.onInitializeAccessibilityNodeInfo(info);
|
||||
|
||||
assertThat(info.getActionList().stream().anyMatch(
|
||||
action -> action.getId() == R.id.action_move_to_edge_and_hide)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onTargetsChanged_exceedAvailableHeight_overScrollAlways() {
|
||||
doReturn(true).when(mMenuView).hasExceededMaxLayoutHeight();
|
||||
|
||||
@@ -0,0 +1,170 @@
|
||||
/*
|
||||
* Copyright (C) 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.systemui.accessibility.floatingmenu;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Rect;
|
||||
import android.testing.AndroidTestingRunner;
|
||||
import android.testing.TestableLooper;
|
||||
import android.view.WindowManager;
|
||||
import android.view.accessibility.AccessibilityNodeInfo;
|
||||
|
||||
import androidx.core.view.accessibility.AccessibilityNodeInfoCompat;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import androidx.recyclerview.widget.RecyclerViewAccessibilityDelegate;
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.SysuiTestCase;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnit;
|
||||
import org.mockito.junit.MockitoRule;
|
||||
|
||||
/** Tests for {@link ItemDelegateCompat}. */
|
||||
@SmallTest
|
||||
@RunWith(AndroidTestingRunner.class)
|
||||
@TestableLooper.RunWithLooper
|
||||
public class ItemDelegateCompatTest extends SysuiTestCase {
|
||||
@Rule
|
||||
public MockitoRule mockito = MockitoJUnit.rule();
|
||||
|
||||
@Mock
|
||||
private WindowManager mWindowManager;
|
||||
|
||||
private RecyclerView mListView;
|
||||
private AccessibilityFloatingMenuView mMenuView;
|
||||
private ItemDelegateCompat mItemDelegateCompat;
|
||||
private final Rect mAvailableBounds = new Rect(100, 200, 300, 400);
|
||||
private final Position mPlaceholderPosition = new Position(0.0f, 0.0f);
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
final WindowManager wm = mContext.getSystemService(WindowManager.class);
|
||||
doAnswer(invocation -> wm.getMaximumWindowMetrics()).when(
|
||||
mWindowManager).getMaximumWindowMetrics();
|
||||
mContext.addMockSystemService(Context.WINDOW_SERVICE, mWindowManager);
|
||||
|
||||
mListView = new RecyclerView(mContext);
|
||||
mMenuView =
|
||||
spy(new AccessibilityFloatingMenuView(mContext, mPlaceholderPosition, mListView));
|
||||
mItemDelegateCompat =
|
||||
new ItemDelegateCompat(new RecyclerViewAccessibilityDelegate(mListView), mMenuView);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAccessibilityActionList_matchResult() {
|
||||
final AccessibilityNodeInfoCompat info =
|
||||
new AccessibilityNodeInfoCompat(new AccessibilityNodeInfo());
|
||||
|
||||
mItemDelegateCompat.onInitializeAccessibilityNodeInfo(mListView, info);
|
||||
|
||||
assertThat(info.getActionList().size()).isEqualTo(5);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void performAccessibilityMoveTopLeftAction_halfOval_success() {
|
||||
doReturn(mAvailableBounds).when(mMenuView).getAvailableBounds();
|
||||
mMenuView.setShapeType(/* halfOvalShape */ 1);
|
||||
|
||||
final boolean moveTopLeftAction =
|
||||
mItemDelegateCompat.performAccessibilityAction(mListView, R.id.action_move_top_left,
|
||||
null);
|
||||
|
||||
assertThat(moveTopLeftAction).isTrue();
|
||||
assertThat(mMenuView.mShapeType).isEqualTo(/* ovalShape */ 0);
|
||||
verify(mMenuView).snapToLocation(mAvailableBounds.left, mAvailableBounds.top);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void performAccessibilityMoveTopRightAction_halfOval_success() {
|
||||
doReturn(mAvailableBounds).when(mMenuView).getAvailableBounds();
|
||||
mMenuView.setShapeType(/* halfOvalShape */ 1);
|
||||
|
||||
final boolean moveTopRightAction =
|
||||
mItemDelegateCompat.performAccessibilityAction(mListView,
|
||||
R.id.action_move_top_right, null);
|
||||
|
||||
assertThat(moveTopRightAction).isTrue();
|
||||
assertThat(mMenuView.mShapeType).isEqualTo(/* ovalShape */ 0);
|
||||
verify(mMenuView).snapToLocation(mAvailableBounds.right, mAvailableBounds.top);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void performAccessibilityMoveBottomLeftAction_halfOval_success() {
|
||||
doReturn(mAvailableBounds).when(mMenuView).getAvailableBounds();
|
||||
mMenuView.setShapeType(/* halfOvalShape */ 1);
|
||||
|
||||
final boolean moveBottomLeftAction =
|
||||
mItemDelegateCompat.performAccessibilityAction(mListView,
|
||||
R.id.action_move_bottom_left, null);
|
||||
|
||||
assertThat(moveBottomLeftAction).isTrue();
|
||||
assertThat(mMenuView.mShapeType).isEqualTo(/* ovalShape */ 0);
|
||||
verify(mMenuView).snapToLocation(mAvailableBounds.left, mAvailableBounds.bottom);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void performAccessibilityMoveBottomRightAction_halfOval_success() {
|
||||
doReturn(mAvailableBounds).when(mMenuView).getAvailableBounds();
|
||||
mMenuView.setShapeType(/* halfOvalShape */ 1);
|
||||
|
||||
final boolean moveBottomRightAction =
|
||||
mItemDelegateCompat.performAccessibilityAction(mListView,
|
||||
R.id.action_move_bottom_right, null);
|
||||
|
||||
assertThat(moveBottomRightAction).isTrue();
|
||||
assertThat(mMenuView.mShapeType).isEqualTo(/* ovalShape */ 0);
|
||||
verify(mMenuView).snapToLocation(mAvailableBounds.right, mAvailableBounds.bottom);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void performAccessibilityMoveOutEdgeAction_halfOval_success() {
|
||||
doReturn(mAvailableBounds).when(mMenuView).getAvailableBounds();
|
||||
mMenuView.setShapeType(/* halfOvalShape */ 1);
|
||||
|
||||
final boolean moveOutEdgeAndShowAction =
|
||||
mItemDelegateCompat.performAccessibilityAction(mListView,
|
||||
R.id.action_move_out_edge_and_show, null);
|
||||
|
||||
assertThat(moveOutEdgeAndShowAction).isTrue();
|
||||
assertThat(mMenuView.mShapeType).isEqualTo(/* ovalShape */ 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setupAccessibilityActions_oval_hasActionMoveToEdgeAndHide() {
|
||||
final AccessibilityNodeInfoCompat info =
|
||||
new AccessibilityNodeInfoCompat(new AccessibilityNodeInfo());
|
||||
mMenuView.setShapeType(/* ovalShape */ 0);
|
||||
|
||||
mItemDelegateCompat.onInitializeAccessibilityNodeInfo(mListView, info);
|
||||
|
||||
assertThat(info.getActionList().stream().anyMatch(
|
||||
action -> action.getId() == R.id.action_move_to_edge_and_hide)).isTrue();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user