Merge "The shelf height was mistakenly provided as width, making it equal to 0." into tm-qpr-dev
diff --git a/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java b/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java
index 8782ee6..2e4e739 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java
@@ -28,11 +28,10 @@
 import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_TRANSLATE_X;
 import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_TRANSLATE_Y;
 import static com.android.launcher3.states.StateAnimationConfig.SKIP_OVERVIEW;
+import static com.android.quickstep.views.FloatingTaskView.PRIMARY_TRANSLATE_OFFSCREEN;
 import static com.android.quickstep.views.RecentsView.ADJACENT_PAGE_HORIZONTAL_OFFSET;
-import static com.android.quickstep.views.RecentsView.FIRST_FLOATING_TASK_TRANSLATE_OFFSCREEN;
 import static com.android.quickstep.views.RecentsView.RECENTS_GRID_PROGRESS;
 import static com.android.quickstep.views.RecentsView.RECENTS_SCALE_PROPERTY;
-import static com.android.quickstep.views.RecentsView.SPLIT_INSTRUCTIONS_FADE;
 import static com.android.quickstep.views.RecentsView.TASK_SECONDARY_TRANSLATION;
 import static com.android.quickstep.views.RecentsView.TASK_THUMBNAIL_SPLASH_ALPHA;
 
@@ -112,6 +111,7 @@
             // TODO (b/238651489): Refactor state management to avoid need for double check
             FloatingTaskView floatingTask = mRecentsView.getFirstFloatingTaskView();
             if (floatingTask != null) {
+                // We are in split selection state currently, transitioning to another state
                 DragLayer dragLayer = mLauncher.getDragLayer();
                 RectF onScreenRectF = new RectF();
                 Utilities.getBoundsForViewInDragLayer(mLauncher.getDragLayer(), floatingTask,
@@ -127,8 +127,8 @@
                 );
 
                 setter.setFloat(
-                        mRecentsView,
-                        FIRST_FLOATING_TASK_TRANSLATE_OFFSCREEN,
+                        mRecentsView.getFirstFloatingTaskView(),
+                        PRIMARY_TRANSLATE_OFFSCREEN,
                         mRecentsView.getPagedOrientationHandler()
                                 .getFloatingTaskOffscreenTranslationTarget(
                                         floatingTask,
@@ -140,14 +140,14 @@
                                 ANIM_OVERVIEW_SPLIT_SELECT_FLOATING_TASK_TRANSLATE_OFFSCREEN,
                                 LINEAR
                         ));
-                setter.setFloat(
-                        mRecentsView,
-                        SPLIT_INSTRUCTIONS_FADE,
-                        1,
+                setter.setViewAlpha(
+                        mRecentsView.getSplitInstructionsView(),
+                        0,
                         config.getInterpolator(
                                 ANIM_OVERVIEW_SPLIT_SELECT_INSTRUCTIONS_FADE,
                                 LINEAR
-                        ));
+                        )
+                );
             }
         }
 
diff --git a/quickstep/src/com/android/quickstep/TaskViewUtils.java b/quickstep/src/com/android/quickstep/TaskViewUtils.java
index 93170cb..556b99e 100644
--- a/quickstep/src/com/android/quickstep/TaskViewUtils.java
+++ b/quickstep/src/com/android/quickstep/TaskViewUtils.java
@@ -43,7 +43,6 @@
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.animation.AnimatorSet;
-import android.animation.ObjectAnimator;
 import android.animation.ValueAnimator;
 import android.annotation.TargetApi;
 import android.app.PendingIntent;
@@ -198,8 +197,7 @@
         BaseActivity baseActivity = BaseActivity.fromContext(context);
         DeviceProfile dp = baseActivity.getDeviceProfile();
         boolean showAsGrid = dp.isTablet;
-        boolean parallaxCenterAndAdjacentTask =
-                taskIndex != recentsView.getCurrentPage() && !showAsGrid;
+        boolean parallaxCenterAndAdjacentTask = taskIndex != recentsView.getCurrentPage();
         int taskRectTranslationPrimary = recentsView.getScrollOffset(taskIndex);
         int taskRectTranslationSecondary = showAsGrid ? (int) v.getGridTranslationY() : 0;
 
@@ -603,11 +601,7 @@
             if (raController != null) {
                 raController.setWillFinishToHome(false);
             }
-            Context context = v.getContext();
-            DeviceProfile dp = BaseActivity.fromContext(context).getDeviceProfile();
-            launcherAnim = dp.isTablet
-                    ? ObjectAnimator.ofFloat(recentsView, RecentsView.CONTENT_ALPHA, 0)
-                    : recentsView.createAdjacentPageAnimForTaskLaunch(taskView);
+            launcherAnim = recentsView.createAdjacentPageAnimForTaskLaunch(taskView);
             launcherAnim.setInterpolator(Interpolators.TOUCH_RESPONSE_INTERPOLATOR);
             launcherAnim.setDuration(RECENTS_LAUNCH_DURATION);
 
diff --git a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
index eb739a6..7c96bf8 100644
--- a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
+++ b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
@@ -227,6 +227,11 @@
     }
 
     @Override
+    public void onStateTransitionFailed(RecentsState toState) {
+        reset();
+    }
+
+    @Override
     public void onStateTransitionComplete(RecentsState finalState) {
         if (finalState == HOME) {
             // Clean-up logic that occurs when recents is no longer in use/visible.
diff --git a/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java b/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java
index d37300c..0a49008 100644
--- a/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java
+++ b/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java
@@ -102,7 +102,7 @@
     private boolean mLayoutValid = false;
     private int mOrientationStateId;
     private SplitBounds mSplitBounds;
-    private boolean mDrawsBelowRecents;
+    private Boolean mDrawsBelowRecents = null;
     private boolean mIsGridTask;
     private int mTaskRectTranslationX;
     private int mTaskRectTranslationY;
@@ -391,7 +391,8 @@
                 .withWindowCrop(mTmpCropRect)
                 .withCornerRadius(getCurrentCornerRadius());
 
-        if (ENABLE_QUICKSTEP_LIVE_TILE.get()) {
+        // If mDrawsBelowRecents is unset, no reordering will be enforced.
+        if (ENABLE_QUICKSTEP_LIVE_TILE.get() && mDrawsBelowRecents != null) {
             // In legacy transitions, the animation leashes remain in same hierarchy in the
             // TaskDisplayArea, so we don't want to bump the layer too high otherwise it will
             // conflict with layers that WM core positions (ie. the input consumers).  For shell
diff --git a/quickstep/src/com/android/quickstep/views/FloatingTaskView.java b/quickstep/src/com/android/quickstep/views/FloatingTaskView.java
index 7a66ea0..c3bf041 100644
--- a/quickstep/src/com/android/quickstep/views/FloatingTaskView.java
+++ b/quickstep/src/com/android/quickstep/views/FloatingTaskView.java
@@ -14,6 +14,7 @@
 import android.graphics.RectF;
 import android.graphics.drawable.Drawable;
 import android.util.AttributeSet;
+import android.util.FloatProperty;
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.FrameLayout;
@@ -49,6 +50,29 @@
  */
 public class FloatingTaskView extends FrameLayout {
 
+    public static final FloatProperty<FloatingTaskView> PRIMARY_TRANSLATE_OFFSCREEN =
+            new FloatProperty<FloatingTaskView>("floatingTaskPrimaryTranslateOffscreen") {
+        @Override
+        public void setValue(FloatingTaskView view, float translation) {
+            ((RecentsView) view.mActivity.getOverviewPanel()).getPagedOrientationHandler()
+                    .setFloatingTaskPrimaryTranslation(
+                            view,
+                            translation,
+                            view.mActivity.getDeviceProfile()
+                    );
+        }
+
+        @Override
+        public Float get(FloatingTaskView view) {
+            return ((RecentsView) view.mActivity.getOverviewPanel())
+                    .getPagedOrientationHandler()
+                    .getFloatingTaskPrimaryTranslation(
+                            view,
+                            view.mActivity.getDeviceProfile()
+                    );
+        }
+    };
+
     private FloatingTaskThumbnailView mThumbnailView;
     private SplitPlaceholderView mSplitPlaceholderView;
     private RectF mStartingPosition;
diff --git a/quickstep/src/com/android/quickstep/views/GroupedTaskView.java b/quickstep/src/com/android/quickstep/views/GroupedTaskView.java
index a870f9c..2539ed6 100644
--- a/quickstep/src/com/android/quickstep/views/GroupedTaskView.java
+++ b/quickstep/src/com/android/quickstep/views/GroupedTaskView.java
@@ -319,4 +319,10 @@
         super.applyThumbnailSplashAlpha();
         mSnapshotView2.setSplashAlpha(mTaskThumbnailSplashAlpha);
     }
+
+    @Override
+    void setThumbnailVisibility(int visibility) {
+        super.setThumbnailVisibility(visibility);
+        mSnapshotView2.setVisibility(visibility);
+    }
 }
diff --git a/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java b/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
index 6a33d36..de7ccad 100644
--- a/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
@@ -120,6 +120,11 @@
     }
 
     @Override
+    public void onStateTransitionFailed(LauncherState toState) {
+        reset();
+    }
+
+    @Override
     public void onStateTransitionComplete(LauncherState finalState) {
         if (finalState == NORMAL || finalState == SPRING_LOADED) {
             // Clean-up logic that occurs when recents is no longer in use/visible.
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index 69557a8..f00e858 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -397,39 +397,6 @@
                 }
             };
 
-    public static final FloatProperty<RecentsView> FIRST_FLOATING_TASK_TRANSLATE_OFFSCREEN =
-            new FloatProperty<RecentsView>("firstFloatingTaskTranslateOffscreen") {
-                @Override
-                public void setValue(RecentsView view, float translation) {
-                    view.getPagedOrientationHandler().setFloatingTaskPrimaryTranslation(
-                            view.mFirstFloatingTaskView,
-                            translation,
-                            view.mActivity.getDeviceProfile()
-                    );
-                }
-
-                @Override
-                public Float get(RecentsView view) {
-                    return view.getPagedOrientationHandler().getFloatingTaskPrimaryTranslation(
-                            view.mFirstFloatingTaskView,
-                            view.mActivity.getDeviceProfile()
-                    );
-                }
-            };
-
-    public static final FloatProperty<RecentsView> SPLIT_INSTRUCTIONS_FADE =
-            new FloatProperty<RecentsView>("splitInstructionsFade") {
-                @Override
-                public void setValue(RecentsView view, float fade) {
-                    view.mSplitInstructionsView.setAlpha(1 - fade);
-                }
-
-                @Override
-                public Float get(RecentsView view) {
-                    return 1 - view.mSplitInstructionsView.getAlpha();
-                }
-            };
-
     // OverScroll constants
     private static final int OVERSCROLL_PAGE_SNAP_ANIMATION_DURATION = 270;
 
@@ -2827,7 +2794,11 @@
 
         RectF startingTaskRect = new RectF();
         if (mSplitHiddenTaskView != null) {
-            mSplitHiddenTaskView.setVisibility(INVISIBLE);
+            // Split staging is initiated, hide the original TaskView thumbnail.
+            // Toggled back on in resetFromSplitSelectionState().
+            mSplitHiddenTaskView.setThumbnailVisibility(INVISIBLE);
+            anim.addFloat(mSplitHiddenTaskView, TaskView.ICON_ALPHA, 1, 0,
+                    clampToProgress(LINEAR, 0, 0.167f));
             mFirstFloatingTaskView = FloatingTaskView.getFloatingTaskView(mActivity,
                     mSplitHiddenTaskView.getThumbnail(),
                     mSplitHiddenTaskView.getThumbnail().getThumbnail(),
@@ -2855,6 +2826,8 @@
                 InteractionJankMonitorWrapper.end(
                         InteractionJankMonitorWrapper.CUJ_SPLIT_SCREEN_ENTER);
             } else {
+                // If transition to split select was interrupted, clean up to prevent glitches
+                resetFromSplitSelectionState();
                 InteractionJankMonitorWrapper.cancel(
                         InteractionJankMonitorWrapper.CUJ_SPLIT_SCREEN_ENTER);
             }
@@ -4222,7 +4195,9 @@
         resetTaskVisuals();
         mSplitHiddenTaskViewIndex = -1;
         if (mSplitHiddenTaskView != null) {
-            mSplitHiddenTaskView.setVisibility(VISIBLE);
+            // Toggle thumbnail visibility back on (turned off in
+            // createInitialSplitSelectAnimation()).
+            mSplitHiddenTaskView.setThumbnailVisibility(VISIBLE);
             mSplitHiddenTaskView = null;
         }
     }
@@ -4342,25 +4317,27 @@
 
         int taskIndex = indexOfChild(tv);
         int centerTaskIndex = getCurrentPage();
-        boolean launchingCenterTask = taskIndex == centerTaskIndex;
 
         float toScale = getMaxScaleForFullScreen();
-        RecentsView recentsView = tv.getRecentsView();
+        boolean showAsGrid = showAsGrid();
+        boolean launchingCenterTask = showAsGrid
+                ? tv.isFocusedTask() && isTaskViewFullyVisible(tv)
+                : taskIndex == centerTaskIndex;
         if (launchingCenterTask) {
-            anim.play(ObjectAnimator.ofFloat(recentsView, RECENTS_SCALE_PROPERTY, toScale));
-            anim.play(ObjectAnimator.ofFloat(recentsView, FULLSCREEN_PROGRESS, 1));
-        } else {
+            anim.play(ObjectAnimator.ofFloat(this, RECENTS_SCALE_PROPERTY, toScale));
+            anim.play(ObjectAnimator.ofFloat(this, FULLSCREEN_PROGRESS, 1));
+        } else if (!showAsGrid) {
             // We are launching an adjacent task, so parallax the center and other adjacent task.
             float displacementX = tv.getWidth() * (toScale - 1f);
             float primaryTranslation = mIsRtl ? -displacementX : displacementX;
             anim.play(ObjectAnimator.ofFloat(getPageAt(centerTaskIndex),
                     mOrientationHandler.getPrimaryViewTranslate(), primaryTranslation));
-            int runningTaskIndex = recentsView.getRunningTaskIndex();
+            int runningTaskIndex = getRunningTaskIndex();
             if (ENABLE_QUICKSTEP_LIVE_TILE.get()
                     && runningTaskIndex != -1
                     && runningTaskIndex != taskIndex
-                    && recentsView.getRemoteTargetHandles() != null) {
-                for (RemoteTargetHandle remoteHandle : recentsView.getRemoteTargetHandles()) {
+                    && getRemoteTargetHandles() != null) {
+                for (RemoteTargetHandle remoteHandle : getRemoteTargetHandles()) {
                     anim.play(ObjectAnimator.ofFloat(
                             remoteHandle.getTaskViewSimulator().taskPrimaryTranslation,
                             AnimatedFloat.VALUE,
@@ -4380,7 +4357,7 @@
                         properties));
             }
         }
-        anim.play(ObjectAnimator.ofFloat(recentsView, TASK_THUMBNAIL_SPLASH_ALPHA, 0, 1));
+        anim.play(ObjectAnimator.ofFloat(this, TASK_THUMBNAIL_SPLASH_ALPHA, 0, 1));
         return anim;
     }
 
@@ -5334,6 +5311,11 @@
         return mFirstFloatingTaskView;
     }
 
+    @Nullable
+    public SplitInstructionsView getSplitInstructionsView() {
+        return mSplitInstructionsView;
+    }
+
     /** Update the current activity locus id to show the enabled state of Overview */
     public void updateLocusId() {
         String locusId = "Overview";
diff --git a/quickstep/src/com/android/quickstep/views/TaskView.java b/quickstep/src/com/android/quickstep/views/TaskView.java
index 34c2021..a84ea63 100644
--- a/quickstep/src/com/android/quickstep/views/TaskView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskView.java
@@ -323,6 +323,19 @@
                 }
             };
 
+    public static final FloatProperty<TaskView> ICON_ALPHA =
+            new FloatProperty<TaskView>("iconAlpha") {
+                @Override
+                public void setValue(TaskView taskView, float v) {
+                    taskView.mIconView.setAlpha(v);
+                }
+
+                @Override
+                public Float get(TaskView taskView) {
+                    return taskView.mIconView.getAlpha();
+                }
+            };
+
     @Nullable
     protected Task mTask;
     protected TaskThumbnailView mSnapshotView;
@@ -1488,6 +1501,10 @@
         return display != null ? display.getDisplayId() : DEFAULT_DISPLAY;
     }
 
+    void setThumbnailVisibility(int visibility) {
+        mSnapshotView.setVisibility(visibility);
+    }
+
     /**
      * We update and subsequently draw these in {@link #setFullscreenProgress(float)}.
      */
diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml
index e075559..c234900 100644
--- a/res/values-ar/strings.xml
+++ b/res/values-ar/strings.xml
@@ -101,7 +101,7 @@
     <string name="folder_name_format_exact" msgid="8626242716117004803">"المجلد: <xliff:g id="NAME">%1$s</xliff:g>، <xliff:g id="SIZE">%2$d</xliff:g> عنصر"</string>
     <string name="folder_name_format_overflow" msgid="4270108890534995199">"المجلد: <xliff:g id="NAME">%1$s</xliff:g>، <xliff:g id="SIZE">%2$d</xliff:g> عنصر أو أكثر"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"الخلفيات"</string>
-    <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"الخلفية والنمط"</string>
+    <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"الخلفية والأسلوب"</string>
     <string name="settings_button_text" msgid="8873672322605444408">"إعدادات الشاشة الرئيسية"</string>
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"أوقف المشرف هذه الميزة"</string>
     <string name="allow_rotation_title" msgid="7222049633713050106">"السماح بتدوير الشاشة الرئيسية"</string>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index a9d1127..2e886db 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -226,6 +226,7 @@
     <dimen name="drop_target_text_size">16sp</dimen>
     <dimen name="drop_target_shadow_elevation">2dp</dimen>
     <dimen name="drop_target_bar_margin_horizontal">4dp</dimen>
+    <dimen name="drop_target_button_drawable_size">20dp</dimen>
     <dimen name="drop_target_button_drawable_padding">8dp</dimen>
     <dimen name="drop_target_button_drawable_horizontal_padding">16dp</dimen>
     <dimen name="drop_target_button_drawable_vertical_padding">8dp</dimen>
diff --git a/src/com/android/launcher3/ButtonDropTarget.java b/src/com/android/launcher3/ButtonDropTarget.java
index 3b24df2..5abe3d3 100644
--- a/src/com/android/launcher3/ButtonDropTarget.java
+++ b/src/com/android/launcher3/ButtonDropTarget.java
@@ -91,7 +91,7 @@
 
         Resources resources = getResources();
         mDragDistanceThreshold = resources.getDimensionPixelSize(R.dimen.drag_distanceThreshold);
-        mDrawableSize = resources.getDimensionPixelSize(R.dimen.drop_target_text_size);
+        mDrawableSize = resources.getDimensionPixelSize(R.dimen.drop_target_button_drawable_size);
         mDrawablePadding = resources.getDimensionPixelSize(
                 R.dimen.drop_target_button_drawable_padding);
     }
@@ -374,11 +374,63 @@
         hideTooltip();
     }
 
+    /**
+     * Returns if the text will be truncated within the provided availableWidth.
+     */
     public boolean isTextTruncated(int availableWidth) {
-        availableWidth -= (getPaddingLeft() + getPaddingRight() + mDrawable.getIntrinsicWidth()
-                + getCompoundDrawablePadding());
-        CharSequence displayedText = TextUtils.ellipsize(mText, getPaint(), availableWidth,
+        availableWidth -= getPaddingLeft() + getPaddingRight();
+        if (mIconVisible) {
+            availableWidth -= mDrawable.getIntrinsicWidth() + getCompoundDrawablePadding();
+        }
+        if (availableWidth <= 0) {
+            return true;
+        }
+        CharSequence firstLine = TextUtils.ellipsize(mText, getPaint(), availableWidth,
                 TextUtils.TruncateAt.END);
-        return !mText.equals(displayedText);
+        if (!mTextMultiLine) {
+            return !TextUtils.equals(mText, firstLine);
+        }
+        if (TextUtils.equals(mText, firstLine)) {
+            // When multi-line is active, if it can display as one line, then text is not truncated.
+            return false;
+        }
+        CharSequence secondLine =
+                TextUtils.ellipsize(mText.subSequence(firstLine.length(), mText.length()),
+                        getPaint(), availableWidth, TextUtils.TruncateAt.END);
+        return !(TextUtils.equals(mText.subSequence(0, firstLine.length()), firstLine)
+                && TextUtils.equals(mText.subSequence(firstLine.length(), secondLine.length()),
+                secondLine));
+    }
+
+    /**
+     * Reduce the size of the text until it fits the measured width or reaches a minimum.
+     *
+     * The minimum size is defined by {@code R.dimen.button_drop_target_min_text_size} and
+     * it diminishes by intervals defined by
+     * {@code R.dimen.button_drop_target_resize_text_increment}
+     * This functionality is very similar to the option
+     * {@link TextView#setAutoSizeTextTypeWithDefaults(int)} but can't be used in this view because
+     * the layout width is {@code WRAP_CONTENT}.
+     *
+     * @return The biggest text size in SP that makes the text fit or if the text can't fit returns
+     *         the min available value
+     */
+    public float resizeTextToFit() {
+        float minSize = Utilities.pxToSp(getResources()
+                .getDimensionPixelSize(R.dimen.button_drop_target_min_text_size));
+        float step = Utilities.pxToSp(getResources()
+                .getDimensionPixelSize(R.dimen.button_drop_target_resize_text_increment));
+        float textSize = Utilities.pxToSp(getTextSize());
+
+        int availableWidth = getMeasuredWidth();
+        while (textSize > minSize) {
+            if (isTextTruncated(availableWidth)) {
+                textSize -= step;
+                setTextSize(textSize);
+            } else {
+                return textSize;
+            }
+        }
+        return minSize;
     }
 }
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index a330fb3..1febd68 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -1037,7 +1037,7 @@
                         / getCellLayoutHeight();
         scale = Math.min(scale, 1f);
 
-        // Reduce scale if next pages would not be visible after scaling the workspace
+        // Reduce scale if next pages would not be visible after scaling the workspace.
         int workspaceWidth = availableWidthPx;
         float scaledWorkspaceWidth = workspaceWidth * scale;
         float maxAvailableWidth = workspaceWidth - (2 * workspaceSpringLoadedMinNextPageVisiblePx);
diff --git a/src/com/android/launcher3/DropTargetBar.java b/src/com/android/launcher3/DropTargetBar.java
index d64cb26..98ecf3a 100644
--- a/src/com/android/launcher3/DropTargetBar.java
+++ b/src/com/android/launcher3/DropTargetBar.java
@@ -151,6 +151,8 @@
             int widthSpec = MeasureSpec.makeMeasureSpec(width, MeasureSpec.AT_MOST);
 
             ButtonDropTarget firstButton = mTempTargets[0];
+            firstButton.setTextSize(TypedValue.COMPLEX_UNIT_PX,
+                    mLauncher.getDeviceProfile().dropTargetTextSizePx);
             firstButton.setTextVisible(true);
             firstButton.setIconVisible(true);
             firstButton.measure(widthSpec, heightSpec);
@@ -160,14 +162,16 @@
             int horizontalPadding = dp.dropTargetHorizontalPaddingPx;
 
             ButtonDropTarget firstButton = mTempTargets[0];
+            firstButton.setTextSize(TypedValue.COMPLEX_UNIT_PX, dp.dropTargetTextSizePx);
             firstButton.setTextVisible(true);
             firstButton.setIconVisible(true);
             firstButton.setTextMultiLine(false);
-            // Reset second button padding in case it was previously changed to multi-line text.
+            // Reset first button padding in case it was previously changed to multi-line text.
             firstButton.setPadding(horizontalPadding, verticalPadding, horizontalPadding,
                     verticalPadding);
 
             ButtonDropTarget secondButton = mTempTargets[1];
+            secondButton.setTextSize(TypedValue.COMPLEX_UNIT_PX, dp.dropTargetTextSizePx);
             secondButton.setTextVisible(true);
             secondButton.setIconVisible(true);
             secondButton.setTextMultiLine(false);
@@ -175,20 +179,14 @@
             secondButton.setPadding(horizontalPadding, verticalPadding, horizontalPadding,
                     verticalPadding);
 
-            float scale = dp.getWorkspaceSpringLoadScale(mLauncher);
-            int scaledPanelWidth = (int) (dp.getCellLayoutWidth() * scale);
-
             int availableWidth;
             if (dp.isTwoPanels) {
-                // Both buttons for two panel fit to the width of one Cell Layout (less
-                // half of the center gap between the buttons).
-                int halfButtonGap = dp.dropTargetGapPx / 2;
-                availableWidth = scaledPanelWidth - halfButtonGap / 2;
+                // Each button for two panel fits to half the width of the screen excluding the
+                // center gap between the buttons.
+                availableWidth = (dp.availableWidthPx - dp.dropTargetGapPx) / 2;
             } else {
-                // Both buttons plus the button gap do not display past the edge of the scaled
-                // workspace, less a pre-defined gap from the edge of the workspace.
-                availableWidth = scaledPanelWidth - dp.dropTargetGapPx
-                        - 2 * dp.dropTargetButtonWorkspaceEdgeGapPx;
+                // Both buttons plus the button gap do not display past the edge of the screen.
+                availableWidth = dp.availableWidthPx - dp.dropTargetGapPx;
             }
 
             int widthSpec = MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.AT_MOST);
@@ -219,6 +217,15 @@
                             horizontalPadding, verticalPadding / 2);
                 }
             }
+
+            // If text is still truncated, shrink to fit in measured width and resize both targets.
+            float minTextSize =
+                    Math.min(firstButton.resizeTextToFit(), secondButton.resizeTextToFit());
+            if (firstButton.getTextSize() != minTextSize
+                    || secondButton.getTextSize() != minTextSize) {
+                firstButton.setTextSize(minTextSize);
+                secondButton.setTextSize(minTextSize);
+            }
         }
         setMeasuredDimension(width, height);
     }
diff --git a/src/com/android/launcher3/statemanager/StateManager.java b/src/com/android/launcher3/statemanager/StateManager.java
index 2aa9dde..c44e1e1 100644
--- a/src/com/android/launcher3/statemanager/StateManager.java
+++ b/src/com/android/launcher3/statemanager/StateManager.java
@@ -342,6 +342,11 @@
             public void onAnimationSuccess(Animator animator) {
                 onStateTransitionEnd(state);
             }
+
+            @Override
+            public void onAnimationCancel(Animator animation) {
+                onStateTransitionFailed(state);
+            }
         };
     }
 
@@ -354,6 +359,12 @@
         }
     }
 
+    private void onStateTransitionFailed(STATE_TYPE state) {
+        for (int i = mListeners.size() - 1; i >= 0; i--) {
+            mListeners.get(i).onStateTransitionFailed(state);
+        }
+    }
+
     private void onStateTransitionEnd(STATE_TYPE state) {
         // Only change the stable states after the transitions have finished
         if (state != mCurrentStableState) {
@@ -588,6 +599,11 @@
 
         default void onStateTransitionStart(STATE_TYPE toState) { }
 
+        /**
+         * If the state transition animation fails (e.g. is canceled by the user), this fires.
+         */
+        default void onStateTransitionFailed(STATE_TYPE toState) { }
+
         default void onStateTransitionComplete(STATE_TYPE finalState) { }
     }
 
diff --git a/tests/src/com/android/launcher3/celllayout/CellLayoutBoard.java b/tests/src/com/android/launcher3/celllayout/CellLayoutBoard.java
index 3ca05bc..a32ce3c 100644
--- a/tests/src/com/android/launcher3/celllayout/CellLayoutBoard.java
+++ b/tests/src/com/android/launcher3/celllayout/CellLayoutBoard.java
@@ -30,39 +30,117 @@
 
 public class CellLayoutBoard {
 
+    public static class CellType {
+        // The cells marked by this will be filled by 1x1 widgets and will be ignored when
+        // validating
+        public static final char IGNORE = 'x';
+        // The cells marked by this will be filled by app icons
+        public static final char ICON = 'i';
+        // Empty space
+        public static final char EMPTY = '-';
+        // Widget that will be saved as "main widget" for easier retrieval
+        public static final char MAIN_WIDGET = 'm';
+        // Everything else will be consider a widget
+    }
+
+    public static class WidgetRect {
+        public char mType;
+        public Rect mBounds;
+
+        WidgetRect(char type, Rect bounds) {
+            this.mType = type;
+            this.mBounds = bounds;
+        }
+
+        int getSpanX() {
+            return mBounds.right - mBounds.left + 1;
+        }
+
+        int getSpanY() {
+            return mBounds.top - mBounds.bottom + 1;
+        }
+
+        int getCellX() {
+            return mBounds.left;
+        }
+
+        int getCellY() {
+            return mBounds.bottom;
+        }
+
+        boolean shouldIgnore() {
+            return this.mType == CellType.IGNORE;
+        }
+
+        @Override
+        public String toString() {
+            return "WidgetRect type = " + mType + " bounds = " + mBounds.toString();
+        }
+    }
+
+    public static class IconPoint {
+        public Point coord;
+        public char mType;
+
+        public IconPoint(Point coord, char type) {
+            this.coord = coord;
+            mType = type;
+        }
+
+        public char getType() {
+            return mType;
+        }
+
+        public void setType(char type) {
+            mType = type;
+        }
+
+        public Point getCoord() {
+            return coord;
+        }
+
+        public void setCoord(Point coord) {
+            this.coord = coord;
+        }
+    }
+
     static final int INFINITE = 99999;
 
-    char[][] mBoard = new char[30][30];
+    char[][] mWidget = new char[30][30];
 
-    List<TestBoardWidget> mWidgetsRects = new ArrayList<>();
-    Map<Character, TestBoardWidget> mWidgetsMap = new HashMap<>();
+    List<WidgetRect> mWidgetsRects = new ArrayList<>();
+    Map<Character, WidgetRect> mWidgetsMap = new HashMap<>();
 
-    List<TestBoardAppIcon> mIconPoints = new ArrayList<>();
-    Map<Character, TestBoardAppIcon> mIconsMap = new HashMap<>();
+    List<IconPoint> mIconPoints = new ArrayList<>();
+    Map<Character, IconPoint> mIconsMap = new HashMap<>();
 
     Point mMain = new Point();
 
     CellLayoutBoard() {
-        for (int x = 0; x < mBoard.length; x++) {
-            for (int y = 0; y < mBoard[0].length; y++) {
-                mBoard[x][y] = '-';
+        for (int x = 0; x < mWidget.length; x++) {
+            for (int y = 0; y < mWidget[0].length; y++) {
+                mWidget[x][y] = CellType.EMPTY;
             }
         }
     }
 
-    public List<TestBoardWidget> getWidgets() {
+    public List<WidgetRect> getWidgets() {
         return mWidgetsRects;
     }
 
+    public List<IconPoint> getIcons() {
+        return mIconPoints;
+    }
+
     public Point getMain() {
         return mMain;
     }
 
-    public TestBoardWidget getWidgetRect(char c) {
+    public WidgetRect getWidgetRect(char c) {
         return mWidgetsMap.get(c);
     }
 
-    public static TestBoardWidget getWidgetRect(int x, int y, Set<Point> used, char[][] board) {
+    public static WidgetRect getWidgetRect(int x, int y, Set<Point> used, char[][] board) {
         char type = board[x][y];
         Queue<Point> search = new ArrayDeque<Point>();
         Point current = new Point(x, y);
@@ -91,20 +169,20 @@
                 }
             }
         }
-        return new TestBoardWidget(type, widgetRect);
+        return new WidgetRect(type, widgetRect);
     }
 
     public static boolean isWidget(char type) {
-        return type != 'i' && type != '-';
+        return type != CellType.ICON && type != CellType.EMPTY;
     }
 
     public static boolean isIcon(char type) {
-        return type == 'i';
+        return type == CellType.ICON;
     }
 
-    private static List<TestBoardWidget> getRects(char[][] board) {
+    private static List<WidgetRect> getRects(char[][] board) {
         Set<Point> used = new HashSet<>();
-        List<TestBoardWidget> widgetsRects = new ArrayList<>();
+        List<WidgetRect> widgetsRects = new ArrayList<>();
         for (int x = 0; x < board.length; x++) {
             for (int y = 0; y < board[0].length; y++) {
                 if (!used.contains(new Point(x, y)) && isWidget(board[x][y])) {
@@ -115,12 +193,12 @@
         return widgetsRects;
     }
 
-    private static List<TestBoardAppIcon> getIconPoints(char[][] board) {
-        List<TestBoardAppIcon> iconPoints = new ArrayList<>();
+    private static List<IconPoint> getIconPoints(char[][] board) {
+        List<IconPoint> iconPoints = new ArrayList<>();
         for (int x = 0; x < board.length; x++) {
             for (int y = 0; y < board[0].length; y++) {
                 if (isIcon(board[x][y])) {
-                    iconPoints.add(new TestBoardAppIcon(new Point(x, y), board[x][y]));
+                    iconPoints.add(new IconPoint(new Point(x, y), board[x][y]));
                 }
             }
         }
@@ -135,18 +213,18 @@
             String line = lines[y];
             for (int x = 0; x < line.length(); x++) {
                 char c = line.charAt(x);
-                if (c == 'm') {
+                if (c == CellType.MAIN_WIDGET) {
                     board.mMain = new Point(x, y);
                 }
-                if (c != '-') {
-                    board.mBoard[x][y] = line.charAt(x);
+                if (c != CellType.EMPTY) {
+                    board.mWidget[x][y] = line.charAt(x);
                 }
             }
         }
-        board.mWidgetsRects = getRects(board.mBoard);
+        board.mWidgetsRects = getRects(board.mWidget);
         board.mWidgetsRects.forEach(
                 widgetRect -> board.mWidgetsMap.put(widgetRect.mType, widgetRect));
-        board.mIconPoints = getIconPoints(board.mBoard);
+        board.mIconPoints = getIconPoints(board.mWidget);
         return board;
     }
 }
diff --git a/tests/src/com/android/launcher3/celllayout/ReorderWidgets.java b/tests/src/com/android/launcher3/celllayout/ReorderWidgets.java
index 5f5dfea..93fbf97 100644
--- a/tests/src/com/android/launcher3/celllayout/ReorderWidgets.java
+++ b/tests/src/com/android/launcher3/celllayout/ReorderWidgets.java
@@ -15,16 +15,13 @@
  */
 package com.android.launcher3.celllayout;
 
-import static com.android.launcher3.util.WidgetUtils.createWidgetInfo;
-
+import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 
 import android.graphics.Point;
-import android.graphics.Rect;
 import android.util.Log;
 import android.view.View;
 
-import androidx.test.core.app.ApplicationProvider;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
@@ -34,13 +31,14 @@
 import com.android.launcher3.celllayout.testcases.PushReorderCase;
 import com.android.launcher3.celllayout.testcases.ReorderTestCase;
 import com.android.launcher3.celllayout.testcases.SimpleReorderCase;
-import com.android.launcher3.model.data.LauncherAppWidgetInfo;
+import com.android.launcher3.tapl.Widget;
+import com.android.launcher3.tapl.WidgetResizeFrame;
 import com.android.launcher3.ui.AbstractLauncherUiTest;
 import com.android.launcher3.ui.TaplTestsLauncher3;
-import com.android.launcher3.ui.TestViewHelpers;
 import com.android.launcher3.util.rule.ScreenRecordRule.ScreenRecord;
 import com.android.launcher3.util.rule.ShellCommandRule;
-import com.android.launcher3.widget.LauncherAppWidgetProviderInfo;
+import com.android.launcher3.views.DoubleShadowBubbleTextView;
+import com.android.launcher3.widget.LauncherAppWidgetHostView;
 
 import org.junit.Assume;
 import org.junit.Before;
@@ -60,6 +58,8 @@
 
     private static final String TAG = ReorderWidgets.class.getSimpleName();
 
+    TestWorkspaceBuilder mBoardBuilder;
+
     private View getViewAt(int cellX, int cellY) {
         return getFromLauncher(l -> l.getWorkspace().getScreenWithId(
                 l.getWorkspace().getScreenIdForPageIndex(0)).getChildAt(cellX, cellY));
@@ -76,6 +76,7 @@
 
     @Before
     public void setup() throws Throwable {
+        mBoardBuilder = new TestWorkspaceBuilder(this);
         TaplTestsLauncher3.initialize(this);
         clearHomescreen();
     }
@@ -86,78 +87,44 @@
     private boolean validateBoard(CellLayoutBoard board) {
         boolean match = true;
         Point cellDimensions = getCellDimensions();
-        for (TestBoardWidget widgetRect: board.getWidgets()) {
+        for (CellLayoutBoard.WidgetRect widgetRect: board.getWidgets()) {
             if (widgetRect.shouldIgnore()) {
                 continue;
             }
             View widget = getViewAt(widgetRect.getCellX(), widgetRect.getCellY());
+            assertTrue("The view selected at " + board + " is not a widget",
+                    widget instanceof LauncherAppWidgetHostView);
             match &= widgetRect.getSpanX()
                     == Math.round(widget.getWidth() / (float) cellDimensions.x);
             match &= widgetRect.getSpanY()
                     == Math.round(widget.getHeight() / (float) cellDimensions.y);
             if (!match) return match;
         }
+        for (CellLayoutBoard.IconPoint iconPoint : board.getIcons()) {
+            View icon = getViewAt(iconPoint.getCoord().x, iconPoint.getCoord().y);
+            assertTrue("The view selected at " + iconPoint.coord + " is not an Icon",
+                    icon instanceof DoubleShadowBubbleTextView);
+        }
         return match;
     }
 
-    /**
-     * Fills the given rect in WidgetRect with 1x1 widgets. This is useful to equalize cases.
-     */
-    private void fillWithWidgets(TestBoardWidget widgetRect) {
-        int initX = widgetRect.getCellX();
-        int initY = widgetRect.getCellY();
-        for (int x = 0; x < widgetRect.getSpanX(); x++) {
-            for (int y = 0; y < widgetRect.getSpanY(); y++) {
-                int auxX = initX + x;
-                int auxY = initY + y;
-                try {
-                    // this widgets are filling, we don't care if we can't place them
-                    addWidgetInCell(
-                            new TestBoardWidget('x',
-                                    new Rect(auxX, auxY, auxX, auxY))
-                    );
-                } catch (Exception e) {
-                    Log.d(TAG, "Unable to place filling widget at " + auxX + "," + auxY);
-                }
-            }
-        }
-    }
-
-    private void addWidgetInCell(TestBoardWidget widgetRect) {
-        LauncherAppWidgetProviderInfo info = TestViewHelpers.findWidgetProvider(this, false);
-        LauncherAppWidgetInfo item = createWidgetInfo(info,
-                ApplicationProvider.getApplicationContext(), true);
-        item.cellX = widgetRect.getCellX();
-        item.cellY = widgetRect.getCellY();
-
-        item.spanX = widgetRect.getSpanX();
-        item.spanY = widgetRect.getSpanY();
-        addItemToScreen(item);
-    }
-
-    private void addCorrespondingWidgetRect(TestBoardWidget widgetRect) {
-        if (widgetRect.mType == 'x') {
-            fillWithWidgets(widgetRect);
-        } else {
-            addWidgetInCell(widgetRect);
-        }
-    }
-
     private void runTestCase(ReorderTestCase testCase) {
         Point mainWidgetCellPos = testCase.mStart.getMain();
 
-        testCase.mStart.getWidgets().forEach(this::addCorrespondingWidgetRect);
+        mBoardBuilder.buildBoard(testCase.mStart);
 
-        mLauncher.getWorkspace()
-                .getWidgetAtCell(mainWidgetCellPos.x, mainWidgetCellPos.y)
-                .dragWidgetToWorkspace(testCase.moveMainTo.x, testCase.moveMainTo.y)
-                .dismiss(); // dismiss resize frame
+        Widget widget = mLauncher.getWorkspace().getWidgetAtCell(mainWidgetCellPos.x,
+                mainWidgetCellPos.y);
+        assertNotNull(widget);
+        WidgetResizeFrame resizeFrame = widget.dragWidgetToWorkspace(testCase.moveMainTo.x,
+                testCase.moveMainTo.y);
+        resizeFrame.dismiss();
 
         boolean isValid = false;
         for (CellLayoutBoard board : testCase.mEnd) {
             isValid |= validateBoard(board);
         }
-        assertTrue("None of the valid boards match with the current state", isValid);
+        assertTrue("Non of the valid boards match with the current state", isValid);
     }
 
     /**
diff --git a/tests/src/com/android/launcher3/celllayout/TestWorkspaceBuilder.java b/tests/src/com/android/launcher3/celllayout/TestWorkspaceBuilder.java
new file mode 100644
index 0000000..10e399d
--- /dev/null
+++ b/tests/src/com/android/launcher3/celllayout/TestWorkspaceBuilder.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2022 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.launcher3.celllayout;
+
+import static com.android.launcher3.util.WidgetUtils.createWidgetInfo;
+
+import android.content.ComponentName;
+import android.graphics.Rect;
+import android.os.Process;
+import android.os.UserHandle;
+import android.util.Log;
+
+import androidx.test.core.app.ApplicationProvider;
+
+import com.android.launcher3.LauncherSettings;
+import com.android.launcher3.model.data.AppInfo;
+import com.android.launcher3.model.data.LauncherAppWidgetInfo;
+import com.android.launcher3.model.data.WorkspaceItemInfo;
+import com.android.launcher3.ui.AbstractLauncherUiTest;
+import com.android.launcher3.ui.TestViewHelpers;
+import com.android.launcher3.widget.LauncherAppWidgetProviderInfo;
+
+public class TestWorkspaceBuilder {
+
+    private static final ComponentName APP_COMPONENT_NAME = new ComponentName(
+            "com.google.android.calculator", "com.android.calculator2.Calculator");
+
+    public AbstractLauncherUiTest mTest;
+
+    private UserHandle mMyUser;
+
+    public TestWorkspaceBuilder(AbstractLauncherUiTest test) {
+        mTest = test;
+        mMyUser = Process.myUserHandle();
+    }
+
+    private static final String TAG = "CellLayoutBoardBuilder";
+
+    /**
+     * Fills the given rect in WidgetRect with 1x1 widgets. This is useful to equalize cases.
+     */
+    private void fillWithWidgets(CellLayoutBoard.WidgetRect widgetRect) {
+        int initX = widgetRect.getCellX();
+        int initY = widgetRect.getCellY();
+        for (int x = initX; x < initX + widgetRect.getSpanX(); x++) {
+            for (int y = initY; y < initY + widgetRect.getSpanY(); y++) {
+                try {
+                    // this widgets are filling, we don't care if we can't place them
+                    addWidgetInCell(
+                            new CellLayoutBoard.WidgetRect(CellLayoutBoard.CellType.IGNORE,
+                                    new Rect(x, y, x, y))
+                    );
+                } catch (Exception e) {
+                    Log.d(TAG, "Unable to place filling widget at " + x + "," + y);
+                }
+            }
+        }
+    }
+
+    private void addWidgetInCell(CellLayoutBoard.WidgetRect widgetRect) {
+        LauncherAppWidgetProviderInfo info = TestViewHelpers.findWidgetProvider(mTest, false);
+        LauncherAppWidgetInfo item = createWidgetInfo(info,
+                ApplicationProvider.getApplicationContext(), true);
+
+        item.cellX = widgetRect.getCellX();
+        item.cellY = widgetRect.getCellY();
+        item.spanX = widgetRect.getSpanX();
+        item.spanY = widgetRect.getSpanY();
+        mTest.addItemToScreen(item);
+    }
+
+    private void addIconInCell(CellLayoutBoard.IconPoint iconPoint) {
+        AppInfo appInfo = new AppInfo(APP_COMPONENT_NAME, "test icon", mMyUser,
+                AppInfo.makeLaunchIntent(APP_COMPONENT_NAME));
+
+        appInfo.cellX = iconPoint.getCoord().x;
+        appInfo.cellY = iconPoint.getCoord().y;
+        appInfo.minSpanY = appInfo.minSpanX = appInfo.spanX = appInfo.spanY = 1;
+        appInfo.container = LauncherSettings.Favorites.CONTAINER_DESKTOP;
+        appInfo.componentName = APP_COMPONENT_NAME;
+
+        mTest.addItemToScreen(new WorkspaceItemInfo(appInfo));
+    }
+
+    private void addCorrespondingWidgetRect(CellLayoutBoard.WidgetRect widgetRect) {
+        if (widgetRect.mType == 'x') {
+            fillWithWidgets(widgetRect);
+        } else {
+            addWidgetInCell(widgetRect);
+        }
+    }
+
+    public void buildBoard(CellLayoutBoard board) {
+        board.getWidgets().forEach(this::addCorrespondingWidgetRect);
+        board.getIcons().forEach(this::addIconInCell);
+    }
+}
diff --git a/tests/src/com/android/launcher3/celllayout/testcases/FullReorderCase.java b/tests/src/com/android/launcher3/celllayout/testcases/FullReorderCase.java
index 1326389..94e55cf 100644
--- a/tests/src/com/android/launcher3/celllayout/testcases/FullReorderCase.java
+++ b/tests/src/com/android/launcher3/celllayout/testcases/FullReorderCase.java
@@ -19,6 +19,10 @@
 
 import java.util.Map;
 
+/**
+ * The grids represent the workspace to be build by TestWorkspaceBuilder, to see what each character
+ * in the board mean refer to {@code CellType}
+ */
 public class FullReorderCase {
 
     /** 5x5 Test
diff --git a/tests/src/com/android/launcher3/celllayout/testcases/MoveOutReorderCase.java b/tests/src/com/android/launcher3/celllayout/testcases/MoveOutReorderCase.java
index 1701390..a222d3d 100644
--- a/tests/src/com/android/launcher3/celllayout/testcases/MoveOutReorderCase.java
+++ b/tests/src/com/android/launcher3/celllayout/testcases/MoveOutReorderCase.java
@@ -19,6 +19,10 @@
 
 import java.util.Map;
 
+/**
+ * The grids represent the workspace to be build by TestWorkspaceBuilder, to see what each character
+ * in the board mean refer to {@code CellType}
+ */
 public class MoveOutReorderCase {
 
     /** 5x5 Test
diff --git a/tests/src/com/android/launcher3/celllayout/testcases/PushReorderCase.java b/tests/src/com/android/launcher3/celllayout/testcases/PushReorderCase.java
index bb8d5e9..e16ff42 100644
--- a/tests/src/com/android/launcher3/celllayout/testcases/PushReorderCase.java
+++ b/tests/src/com/android/launcher3/celllayout/testcases/PushReorderCase.java
@@ -19,6 +19,10 @@
 
 import java.util.Map;
 
+/**
+ * The grids represent the workspace to be build by TestWorkspaceBuilder, to see what each character
+ * in the board mean refer to {@code CellType}
+ */
 public class PushReorderCase {
 
     /** 5x5 Test
diff --git a/tests/src/com/android/launcher3/celllayout/testcases/SimpleReorderCase.java b/tests/src/com/android/launcher3/celllayout/testcases/SimpleReorderCase.java
index 30269a0..546c48b 100644
--- a/tests/src/com/android/launcher3/celllayout/testcases/SimpleReorderCase.java
+++ b/tests/src/com/android/launcher3/celllayout/testcases/SimpleReorderCase.java
@@ -19,6 +19,10 @@
 
 import java.util.Map;
 
+/**
+ * The grids represent the workspace to be build by TestWorkspaceBuilder, to see what each character
+ * in the board mean refer to {@code CellType}
+ */
 public class SimpleReorderCase {
 
     /** 5x5 Test
diff --git a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
index 304153f..a66b09a 100644
--- a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
+++ b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
@@ -319,7 +319,7 @@
     /**
      * Adds {@param item} on the homescreen on the 0th screen
      */
-    protected void addItemToScreen(ItemInfo item) {
+    public void addItemToScreen(ItemInfo item) {
         WidgetUtils.addItemToScreen(item, mTargetContext);
         resetLoaderState();