Merge "Fix the GAR issue of the Switch Access user can not move." into sc-dev
This commit is contained in:
@@ -167,5 +167,11 @@
|
|||||||
<item type="id" name="accessibility_action_move_right"/>
|
<item type="id" name="accessibility_action_move_right"/>
|
||||||
<item type="id" name="accessibility_action_move_up"/>
|
<item type="id" name="accessibility_action_move_up"/>
|
||||||
<item type="id" name="accessibility_action_move_down"/>
|
<item type="id" name="accessibility_action_move_down"/>
|
||||||
|
|
||||||
|
<!-- Accessibility actions for Accessibility floating menu. -->
|
||||||
|
<item type="id" name="action_move_top_left"/>
|
||||||
|
<item type="id" name="action_move_top_right"/>
|
||||||
|
<item type="id" name="action_move_bottom_left"/>
|
||||||
|
<item type="id" name="action_move_bottom_right"/>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
||||||
|
|||||||
@@ -2693,6 +2693,14 @@
|
|||||||
<string name="accessibility_floating_button_migration_tooltip">Accessibility button replaced the accessibility gesture\n\n<annotation id="link">View settings</annotation></string>
|
<string name="accessibility_floating_button_migration_tooltip">Accessibility button replaced the accessibility gesture\n\n<annotation id="link">View settings</annotation></string>
|
||||||
<!-- Message for the accessibility floating button docking tooltip. It shows when the user first time drag the button. It will tell the user about docking behavior. [CHAR LIMIT=70] -->
|
<!-- Message for the accessibility floating button docking tooltip. It shows when the user first time drag the button. It will tell the user about docking behavior. [CHAR LIMIT=70] -->
|
||||||
<string name="accessibility_floating_button_docking_tooltip">Move button to the edge to hide it temporarily</string>
|
<string name="accessibility_floating_button_docking_tooltip">Move button to the edge to hide it temporarily</string>
|
||||||
|
<!-- Action in accessibility menu to move the accessibility floating button to the top left of the screen. [CHAR LIMIT=30] -->
|
||||||
|
<string name="accessibility_floating_button_action_move_top_left">Move top left</string>
|
||||||
|
<!-- Action in accessibility menu to move the accessibility floating button to the top right of the screen. [CHAR LIMIT=30] -->
|
||||||
|
<string name="accessibility_floating_button_action_move_top_right">Move top right</string>
|
||||||
|
<!-- Action in accessibility menu to move the accessibility floating button to the bottom left of the screen. [CHAR LIMIT=30]-->
|
||||||
|
<string name="accessibility_floating_button_action_move_bottom_left">Move bottom left</string>
|
||||||
|
<!-- Action in accessibility menu to move the accessibility floating button to the bottom right of the screen. [CHAR LIMIT=30]-->
|
||||||
|
<string name="accessibility_floating_button_action_move_bottom_right">Move bottom right</string>
|
||||||
|
|
||||||
<!-- Device Controls strings -->
|
<!-- Device Controls strings -->
|
||||||
<!-- Device Controls empty state, title [CHAR LIMIT=30] -->
|
<!-- Device Controls empty state, title [CHAR LIMIT=30] -->
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ import android.graphics.Rect;
|
|||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.graphics.drawable.GradientDrawable;
|
import android.graphics.drawable.GradientDrawable;
|
||||||
import android.graphics.drawable.LayerDrawable;
|
import android.graphics.drawable.LayerDrawable;
|
||||||
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import android.util.DisplayMetrics;
|
import android.util.DisplayMetrics;
|
||||||
@@ -39,6 +40,8 @@ import android.view.MotionEvent;
|
|||||||
import android.view.ViewConfiguration;
|
import android.view.ViewConfiguration;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.view.WindowManager;
|
import android.view.WindowManager;
|
||||||
|
import android.view.accessibility.AccessibilityNodeInfo;
|
||||||
|
import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
|
||||||
import android.view.animation.OvershootInterpolator;
|
import android.view.animation.OvershootInterpolator;
|
||||||
import android.widget.FrameLayout;
|
import android.widget.FrameLayout;
|
||||||
|
|
||||||
@@ -284,6 +287,44 @@ public class AccessibilityFloatingMenuView extends FrameLayout
|
|||||||
// Do Nothing
|
// Do Nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
|
||||||
|
super.onInitializeAccessibilityNodeInfo(info);
|
||||||
|
setupAccessibilityActions(info);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean performAccessibilityAction(int action, Bundle arguments) {
|
||||||
|
if (super.performAccessibilityAction(action, arguments)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
fadeIn();
|
||||||
|
|
||||||
|
final Rect bounds = getAvailableBounds();
|
||||||
|
if (action == R.id.action_move_top_left) {
|
||||||
|
snapToLocation(bounds.left, bounds.top);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (action == R.id.action_move_top_right) {
|
||||||
|
snapToLocation(bounds.right, bounds.top);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (action == R.id.action_move_bottom_left) {
|
||||||
|
snapToLocation(bounds.left, bounds.bottom);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (action == R.id.action_move_bottom_right) {
|
||||||
|
snapToLocation(bounds.right, bounds.bottom);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void show() {
|
void show() {
|
||||||
if (isShowing()) {
|
if (isShowing()) {
|
||||||
return;
|
return;
|
||||||
@@ -380,6 +421,33 @@ public class AccessibilityFloatingMenuView extends FrameLayout
|
|||||||
mUiHandler.postDelayed(() -> mFadeOutAnimator.start(), FADE_EFFECT_DURATION_MS);
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
private boolean onTouched(MotionEvent event) {
|
private boolean onTouched(MotionEvent event) {
|
||||||
final int action = event.getAction();
|
final int action = event.getAction();
|
||||||
final int currentX = (int) event.getX();
|
final int currentX = (int) event.getX();
|
||||||
@@ -524,7 +592,8 @@ public class AccessibilityFloatingMenuView extends FrameLayout
|
|||||||
updateLocationWith(mAlignment, mPercentageY);
|
updateLocationWith(mAlignment, mPercentageY);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void snapToLocation(int endX, int endY) {
|
@VisibleForTesting
|
||||||
|
void snapToLocation(int endX, int endY) {
|
||||||
mDragAnimator.cancel();
|
mDragAnimator.cancel();
|
||||||
mDragAnimator.removeAllUpdateListeners();
|
mDragAnimator.removeAllUpdateListeners();
|
||||||
mDragAnimator.addUpdateListener(anim -> onDragAnimationUpdate(anim, endX, endY));
|
mDragAnimator.addUpdateListener(anim -> onDragAnimationUpdate(anim, endX, endY));
|
||||||
@@ -662,6 +731,11 @@ public class AccessibilityFloatingMenuView extends FrameLayout
|
|||||||
: R.dimen.accessibility_floating_menu_large_single_radius;
|
: R.dimen.accessibility_floating_menu_large_single_radius;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
Rect getAvailableBounds() {
|
||||||
|
return new Rect(0, 0, mScreenWidth - getWindowWidth(), mScreenHeight - getWindowHeight());
|
||||||
|
}
|
||||||
|
|
||||||
private int getLayoutWidth() {
|
private int getLayoutWidth() {
|
||||||
return mPadding * 2 + mIconWidth;
|
return mPadding * 2 + mIconWidth;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ import static org.mockito.Mockito.verify;
|
|||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
|
import android.graphics.Rect;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.graphics.drawable.GradientDrawable;
|
import android.graphics.drawable.GradientDrawable;
|
||||||
import android.graphics.drawable.LayerDrawable;
|
import android.graphics.drawable.LayerDrawable;
|
||||||
@@ -40,6 +41,7 @@ import android.view.MotionEvent;
|
|||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewPropertyAnimator;
|
import android.view.ViewPropertyAnimator;
|
||||||
import android.view.WindowManager;
|
import android.view.WindowManager;
|
||||||
|
import android.view.accessibility.AccessibilityNodeInfo;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
@@ -78,6 +80,8 @@ public class AccessibilityFloatingMenuViewTest extends SysuiTestCase {
|
|||||||
|
|
||||||
private RecyclerView mListView;
|
private RecyclerView mListView;
|
||||||
|
|
||||||
|
private Rect mAvailableBounds = new Rect(100, 200, 300, 400);
|
||||||
|
|
||||||
private int mMenuHalfWidth;
|
private int mMenuHalfWidth;
|
||||||
private int mMenuHalfHeight;
|
private int mMenuHalfHeight;
|
||||||
private int mScreenHalfWidth;
|
private int mScreenHalfWidth;
|
||||||
@@ -339,6 +343,66 @@ public class AccessibilityFloatingMenuViewTest extends SysuiTestCase {
|
|||||||
assertThat(mMenuView.mShapeType).isEqualTo(/* halfOval */ 1);
|
assertThat(mMenuView.mShapeType).isEqualTo(/* halfOval */ 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getAccessibilityActionList_matchResult() {
|
||||||
|
final AccessibilityNodeInfo infos = new AccessibilityNodeInfo();
|
||||||
|
mMenuView.onInitializeAccessibilityNodeInfo(infos);
|
||||||
|
|
||||||
|
assertThat(infos.getActionList().size()).isEqualTo(4);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void accessibilityActionMove_moveTopLeft_success() {
|
||||||
|
final AccessibilityFloatingMenuView menuView =
|
||||||
|
spy(new AccessibilityFloatingMenuView(mContext));
|
||||||
|
doReturn(mAvailableBounds).when(menuView).getAvailableBounds();
|
||||||
|
|
||||||
|
final boolean isActionPerformed =
|
||||||
|
menuView.performAccessibilityAction(R.id.action_move_top_left, null);
|
||||||
|
|
||||||
|
assertThat(isActionPerformed).isTrue();
|
||||||
|
verify(menuView).snapToLocation(mAvailableBounds.left, mAvailableBounds.top);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void accessibilityActionMove_moveTopRight_success() {
|
||||||
|
final AccessibilityFloatingMenuView menuView =
|
||||||
|
spy(new AccessibilityFloatingMenuView(mContext));
|
||||||
|
doReturn(mAvailableBounds).when(menuView).getAvailableBounds();
|
||||||
|
|
||||||
|
final boolean isActionPerformed =
|
||||||
|
menuView.performAccessibilityAction(R.id.action_move_top_right, null);
|
||||||
|
|
||||||
|
assertThat(isActionPerformed).isTrue();
|
||||||
|
verify(menuView).snapToLocation(mAvailableBounds.right, mAvailableBounds.top);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void accessibilityActionMove_moveBottomLeft_success() {
|
||||||
|
final AccessibilityFloatingMenuView menuView =
|
||||||
|
spy(new AccessibilityFloatingMenuView(mContext));
|
||||||
|
doReturn(mAvailableBounds).when(menuView).getAvailableBounds();
|
||||||
|
|
||||||
|
final boolean isActionPerformed =
|
||||||
|
menuView.performAccessibilityAction(R.id.action_move_bottom_left, null);
|
||||||
|
|
||||||
|
assertThat(isActionPerformed).isTrue();
|
||||||
|
verify(menuView).snapToLocation(mAvailableBounds.left, mAvailableBounds.bottom);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void accessibilityActionMove_moveBottomRight_success() {
|
||||||
|
final AccessibilityFloatingMenuView menuView =
|
||||||
|
spy(new AccessibilityFloatingMenuView(mContext));
|
||||||
|
doReturn(mAvailableBounds).when(menuView).getAvailableBounds();
|
||||||
|
|
||||||
|
final boolean isActionPerformed =
|
||||||
|
menuView.performAccessibilityAction(R.id.action_move_bottom_right, null);
|
||||||
|
|
||||||
|
assertThat(isActionPerformed).isTrue();
|
||||||
|
verify(menuView).snapToLocation(mAvailableBounds.right, mAvailableBounds.bottom);
|
||||||
|
}
|
||||||
|
|
||||||
@After
|
@After
|
||||||
public void tearDown() {
|
public void tearDown() {
|
||||||
mInterceptMotionEvent = null;
|
mInterceptMotionEvent = null;
|
||||||
|
|||||||
Reference in New Issue
Block a user