Fix the GAR issue of the Switch Access user can not move.

Root cause:
Not set and export the corresponding Accessibility actions.

Solution:
Exported the four Accessibility actions used to
move the floating menu to the screen corners like a system bubble.

Bug: 178433098
Test: atest AccessibilityFloatingMenuViewTest
Change-Id: Ic2e205a1ed2e8c1ea8794e25835f56444271b9df
diff --git a/packages/SystemUI/res/values/ids.xml b/packages/SystemUI/res/values/ids.xml
index 5f68bdb4..9665c89 100644
--- a/packages/SystemUI/res/values/ids.xml
+++ b/packages/SystemUI/res/values/ids.xml
@@ -167,5 +167,11 @@
     <item type="id" name="accessibility_action_move_right"/>
     <item type="id" name="accessibility_action_move_up"/>
     <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>
 
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 3ca885a..f5357d7 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -2681,6 +2681,14 @@
     <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] -->
     <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 empty state, title [CHAR LIMIT=30] -->
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuView.java b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuView.java
index ab05c2a..57be4e8 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuView.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuView.java
@@ -31,6 +31,7 @@
 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;
@@ -39,6 +40,8 @@
 import android.view.ViewConfiguration;
 import android.view.ViewGroup;
 import android.view.WindowManager;
+import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
 import android.view.animation.OvershootInterpolator;
 import android.widget.FrameLayout;
 
@@ -284,6 +287,44 @@
         // 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() {
         if (isShowing()) {
             return;
@@ -380,6 +421,33 @@
         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) {
         final int action = event.getAction();
         final int currentX = (int) event.getX();
@@ -524,7 +592,8 @@
         updateLocationWith(mAlignment, mPercentageY);
     }
 
-    private void snapToLocation(int endX, int endY) {
+    @VisibleForTesting
+    void snapToLocation(int endX, int endY) {
         mDragAnimator.cancel();
         mDragAnimator.removeAllUpdateListeners();
         mDragAnimator.addUpdateListener(anim -> onDragAnimationUpdate(anim, endX, endY));
@@ -662,6 +731,11 @@
                 : R.dimen.accessibility_floating_menu_large_single_radius;
     }
 
+    @VisibleForTesting
+    Rect getAvailableBounds() {
+        return new Rect(0, 0, mScreenWidth - getWindowWidth(), mScreenHeight - getWindowHeight());
+    }
+
     private int getLayoutWidth() {
         return mPadding * 2 + mIconWidth;
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuViewTest.java
index 8683dd6..814f073 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuViewTest.java
@@ -31,6 +31,7 @@
 
 import android.content.Context;
 import android.content.res.Resources;
+import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.GradientDrawable;
 import android.graphics.drawable.LayerDrawable;
@@ -40,6 +41,7 @@
 import android.view.View;
 import android.view.ViewPropertyAnimator;
 import android.view.WindowManager;
+import android.view.accessibility.AccessibilityNodeInfo;
 
 import androidx.annotation.NonNull;
 import androidx.recyclerview.widget.RecyclerView;
@@ -78,6 +80,8 @@
 
     private RecyclerView mListView;
 
+    private Rect mAvailableBounds = new Rect(100, 200, 300, 400);
+
     private int mMenuHalfWidth;
     private int mMenuHalfHeight;
     private int mScreenHalfWidth;
@@ -339,6 +343,66 @@
         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
     public void tearDown() {
         mInterceptMotionEvent = null;