Translate the TutorialStepIndicator to prevent overlapping skip and done buttons

On large fonts and display sizes, the TutorialStepIndicator can overlap the skip and/or done buttons. Adding some additional translation to account for this.

Fixes: 269588989
Test: tried the tutorial on the largest and default font and display sizes on a phone
Change-Id: I45a276bba3e9cb10336c6f3aa363b7a5c7a73543
diff --git a/quickstep/src/com/android/quickstep/interaction/RootSandboxLayout.java b/quickstep/src/com/android/quickstep/interaction/RootSandboxLayout.java
index ac0c17d..bd0ce34 100644
--- a/quickstep/src/com/android/quickstep/interaction/RootSandboxLayout.java
+++ b/quickstep/src/com/android/quickstep/interaction/RootSandboxLayout.java
@@ -15,17 +15,30 @@
  */
 package com.android.quickstep.interaction;
 
+import static com.android.launcher3.config.FeatureFlags.ENABLE_NEW_GESTURE_NAV_TUTORIAL;
+
 import android.content.Context;
 import android.graphics.Insets;
 import android.util.AttributeSet;
 import android.view.MotionEvent;
+import android.view.View;
 import android.view.WindowInsets;
 import android.widget.RelativeLayout;
 
+import androidx.annotation.NonNull;
 import androidx.fragment.app.FragmentManager;
 
+import com.android.launcher3.R;
+import com.android.launcher3.Utilities;
+
 /** Root layout that TutorialFragment uses to intercept motion events. */
 public class RootSandboxLayout extends RelativeLayout {
+
+    private View mFeedbackView;
+    private View mTutorialStepView;
+    private View mSkipButton;
+    private View mDoneButton;
+
     public RootSandboxLayout(Context context) {
         super(context);
     }
@@ -52,4 +65,51 @@
 
         return getHeight() + insets.top + insets.bottom;
     }
+
+    @Override
+    protected void onFinishInflate() {
+        super.onFinishInflate();
+        if (ENABLE_NEW_GESTURE_NAV_TUTORIAL.get()) {
+            return;
+        }
+        mFeedbackView = findViewById(R.id.gesture_tutorial_fragment_feedback_view);
+        mTutorialStepView =
+                mFeedbackView.findViewById(R.id.gesture_tutorial_fragment_feedback_tutorial_step);
+        mSkipButton = mFeedbackView.findViewById(R.id.gesture_tutorial_fragment_close_button);
+        mDoneButton = mFeedbackView.findViewById(R.id.gesture_tutorial_fragment_action_button);
+
+        mFeedbackView.addOnLayoutChangeListener(
+                (v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) -> {
+                    if (mSkipButton.getVisibility() != VISIBLE
+                            && mDoneButton.getVisibility() != VISIBLE) {
+                        return;
+                    }
+                    // Either the skip or the done button is ever shown at once, never both.
+                    boolean showingSkipButton = mSkipButton.getVisibility() == VISIBLE;
+                    boolean isRTL = Utilities.isRtl(getContext().getResources());
+                    updateTutorialStepViewTranslation(
+                            showingSkipButton ? mSkipButton : mDoneButton,
+                            // Translate the step indicator away from whichever button is being
+                            // shown. The skip button in on the left in LTR or on the right in RTL.
+                            // The done button is on the right in LTR or left in RTL.
+                            (showingSkipButton && !isRTL) || (!showingSkipButton && isRTL));
+                });
+    }
+
+    private void updateTutorialStepViewTranslation(
+            @NonNull View anchorView, boolean translateToRight) {
+        mTutorialStepView.setTranslationX(translateToRight
+                ? Math.min(
+                        // Translate to the right if the views are overlapping on large fonts and
+                        // display sizes.
+                        Math.max(0, anchorView.getRight() - mTutorialStepView.getLeft()),
+                        // Do not translate beyond the bounds of the container view.
+                        mFeedbackView.getWidth() - mTutorialStepView.getRight())
+                : Math.max(
+                        // Translate to the left if the views are overlapping on large fonts and
+                        // display sizes.
+                        Math.min(0, anchorView.getLeft() - mTutorialStepView.getRight()),
+                        // Do not translate beyond the bounds of the container view.
+                        -mTutorialStepView.getLeft()));
+    }
 }