Merge "Fix spring not springing when unstashing." into tm-qpr-dev
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java
index 4e79011..f7e6ee6 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java
@@ -159,7 +159,7 @@
             if (iconShift != null) {
                 dragView.animateShift(-iconShift.x, -iconShift.y);
             }
-            btv.getIcon().setIsDisabled(true);
+            btv.setIconDisabled(true);
             mControllers.taskbarAutohideSuspendController.updateFlag(
                     TaskbarAutohideSuspendController.FLAG_AUTOHIDE_SUSPEND_DRAGGING, true);
         });
@@ -453,7 +453,7 @@
 
     private void maybeOnDragEnd() {
         if (!isDragging()) {
-            ((BubbleTextView) mDragObject.originalView).getIcon().setIsDisabled(false);
+            ((BubbleTextView) mDragObject.originalView).setIconDisabled(false);
             mControllers.taskbarAutohideSuspendController.updateFlag(
                     TaskbarAutohideSuspendController.FLAG_AUTOHIDE_SUSPEND_DRAGGING, false);
             mActivity.onDragEnd();
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java
index aa81bfd..d997f56 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java
@@ -377,7 +377,7 @@
             }
         }
 
-        if (hasAnyFlag(changedFlags, FLAGS_LAUNCHER_ACTIVE)) {
+        if (hasAnyFlag(changedFlags, FLAGS_LAUNCHER_ACTIVE | FLAG_SCREEN_ON)) {
             animatorSet.addListener(new AnimatorListenerAdapter() {
                 @Override
                 public void onAnimationStart(Animator animation) {
diff --git a/quickstep/src/com/android/launcher3/uioverrides/PredictedAppIcon.java b/quickstep/src/com/android/launcher3/uioverrides/PredictedAppIcon.java
index 25207d4..3990dad 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/PredictedAppIcon.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/PredictedAppIcon.java
@@ -17,6 +17,7 @@
 
 import static com.android.launcher3.anim.Interpolators.ACCEL_DEACCEL;
 import static com.android.launcher3.icons.BitmapInfo.FLAG_THEMED;
+import static com.android.launcher3.icons.FastBitmapDrawable.getDisabledColorFilter;
 
 import android.animation.Animator;
 import android.animation.AnimatorSet;
@@ -54,6 +55,7 @@
 import com.android.launcher3.icons.GraphicsUtils;
 import com.android.launcher3.icons.IconNormalizer;
 import com.android.launcher3.icons.LauncherIcons;
+import com.android.launcher3.model.data.ItemInfoWithIcon;
 import com.android.launcher3.model.data.WorkspaceItemInfo;
 import com.android.launcher3.touch.ItemClickHandler;
 import com.android.launcher3.touch.ItemLongClickListener;
@@ -361,6 +363,19 @@
     }
 
     @Override
+    public void setIconDisabled(boolean isDisabled) {
+        super.setIconDisabled(isDisabled);
+        mIconRingPaint.setColorFilter(isDisabled ? getDisabledColorFilter() : null);
+        invalidate();
+    }
+
+    @Override
+    protected void setItemInfo(ItemInfoWithIcon itemInfo) {
+        super.setItemInfo(itemInfo);
+        setIconDisabled(itemInfo.isDisabled());
+    }
+
+    @Override
     public void getSourceVisualDragBounds(Rect bounds) {
         super.getSourceVisualDragBounds(bounds);
         if (!mIsPinned) {
diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
index 753d736..f3fb259 100644
--- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
+++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
@@ -278,8 +278,6 @@
     private RunningWindowAnim[] mRunningWindowAnim;
     // Possible second animation running at the same time as mRunningWindowAnim
     private Animator mParallelRunningAnim;
-    // Current running divider animation
-    private ValueAnimator mDividerAnimator;
     private boolean mIsMotionPaused;
     private boolean mHasMotionEverBeenPaused;
 
@@ -325,8 +323,8 @@
     private final boolean mIsTransientTaskbar;
     // May be set to false when mIsTransientTaskbar is true.
     private boolean mCanSlowSwipeGoHome = true;
-    private boolean mHasReachedOverviewThreshold = false;
-    private boolean mDividerHiddenBeforeAnimation = false;
+    // Indicates whether the divider is shown, only used when split screen is activated.
+    private boolean mIsDividerShown = true;
 
     @Nullable
     private RemoteAnimationTargets.ReleaseCheck mSwipePipToHomeReleaseCheck = null;
@@ -767,10 +765,6 @@
 
     private void setIsLikelyToStartNewTask(boolean isLikelyToStartNewTask, boolean animate) {
         if (mIsLikelyToStartNewTask != isLikelyToStartNewTask) {
-            if (isLikelyToStartNewTask && mIsTransientTaskbar) {
-                setDividerShown(false /* shown */, true /* immediate */);
-            }
-
             mIsLikelyToStartNewTask = isLikelyToStartNewTask;
             maybeUpdateRecentsAttachedState(animate);
         }
@@ -1110,9 +1104,8 @@
                 } else {
                     mStateCallback.setState(STATE_RESUME_LAST_TASK);
                 }
-                if (mRecentsAnimationTargets != null) {
-                    setDividerShown(true /* shown */, true /* immediate */);
-                }
+                // Restore the divider as it resumes the last top-tasks.
+                setDividerShown(true);
                 break;
         }
         ActiveGestureLog.INSTANCE.addLog(
@@ -1284,9 +1277,6 @@
             if (mRecentsAnimationController != null) {
                 mRecentsAnimationController.detachNavigationBarFromApp(true);
             }
-            if (mIsTransientTaskbar) {
-                setDividerShown(false /* shown */, true /* immediate */);
-            }
         } else if (endTarget == RECENTS) {
             if (mRecentsView != null) {
                 int nearestPage = mRecentsView.getDestinationPage();
@@ -1686,12 +1676,6 @@
         }
 
         mRecentsAnimationController.enableInputConsumer();
-
-        // Start hiding the divider
-        if (!mIsTransientTaskbar || mTaskbarAlreadyOpen || mIsTaskbarAllAppsOpen
-                || mDividerHiddenBeforeAnimation) {
-            setDividerShown(false /* shown */, true /* immediate */);
-        }
     }
 
     private void computeRecentsScrollIfInvisible() {
@@ -2155,9 +2139,6 @@
 
     @Override
     public void onRecentsAnimationFinished(RecentsAnimationController controller) {
-        if (!controller.getFinishTargetIsLauncher()) {
-            setDividerShown(true /* shown */, false /* immediate */);
-        }
         mRecentsAnimationController = null;
         mRecentsAnimationTargets = null;
         if (mRecentsView != null) {
@@ -2257,18 +2238,23 @@
         boolean notSwipingToHome = mRecentsAnimationTargets != null
                 && mGestureState.getEndTarget() != HOME;
         boolean setRecentsScroll = mRecentsViewScrollLinked && mRecentsView != null;
+        float progress = Math.max(mCurrentShift.value, getScaleProgressDueToScroll());
+        int scrollOffset = setRecentsScroll ? mRecentsView.getScrollOffset() : 0;
+        if (progress > 0 || scrollOffset != 0) {
+            // Hide the divider as the tasks start moving.
+            setDividerShown(false);
+        }
         for (RemoteTargetHandle remoteHandle : mRemoteTargetHandles) {
             AnimatorControllerWithResistance playbackController =
                     remoteHandle.getPlaybackController();
             if (playbackController != null) {
-                playbackController.setProgress(Math.max(mCurrentShift.value,
-                        getScaleProgressDueToScroll()), mDragLengthFactor);
+                playbackController.setProgress(progress, mDragLengthFactor);
             }
 
             if (notSwipingToHome) {
                 TaskViewSimulator taskViewSimulator = remoteHandle.getTaskViewSimulator();
                 if (setRecentsScroll) {
-                    taskViewSimulator.setScroll(mRecentsView.getScrollOffset());
+                    taskViewSimulator.setScroll(scrollOffset);
                 }
                 taskViewSimulator.apply(remoteHandle.getTransformParams());
             }
@@ -2327,10 +2313,6 @@
 
         // "Catch up" with the displacement at mTaskbarCatchUpThreshold.
         if (displacement < mTaskbarCatchUpThreshold) {
-            if (!mHasReachedOverviewThreshold) {
-                setDividerShown(false /* shown */, true /* immediate */);
-                mHasReachedOverviewThreshold = true;
-            }
             return Utilities.mapToRange(displacement, mTaskbarAppWindowThreshold,
                     mTaskbarCatchUpThreshold, 0, mTaskbarCatchUpThreshold, ACCEL_DEACCEL);
         }
@@ -2338,23 +2320,13 @@
         return displacement;
     }
 
-    private void setDividerShown(boolean shown, boolean immediate) {
-        if (mRecentsAnimationTargets == null) {
-            if (!shown) {
-                mDividerHiddenBeforeAnimation = true;
-            }
+    private void setDividerShown(boolean shown) {
+        if (mRecentsAnimationTargets == null || mIsDividerShown == shown) {
             return;
         }
-        if (mDividerAnimator != null) {
-            mDividerAnimator.cancel();
-        }
-        mDividerAnimator = TaskViewUtils.createSplitAuxiliarySurfacesAnimator(
-                mRecentsAnimationTargets.nonApps, shown, (dividerAnimator) -> {
-                    dividerAnimator.start();
-                    if (immediate) {
-                        dividerAnimator.end();
-                    }
-                });
+        mIsDividerShown = shown;
+        TaskViewUtils.createSplitAuxiliarySurfacesAnimator(
+                mRecentsAnimationTargets.nonApps, shown, null /* animatorHandler */);
     }
 
     /**
diff --git a/quickstep/src/com/android/quickstep/TaskAnimationManager.java b/quickstep/src/com/android/quickstep/TaskAnimationManager.java
index 725f9e7..dde5d55 100644
--- a/quickstep/src/com/android/quickstep/TaskAnimationManager.java
+++ b/quickstep/src/com/android/quickstep/TaskAnimationManager.java
@@ -188,12 +188,8 @@
                         return;
                     }
                 } else if (nonAppTargets.length > 0) {
-                    TaskViewUtils.createSplitAuxiliarySurfacesAnimator(
-                            nonAppTargets /* nonApps */,
-                            true /*shown*/, dividerAnimator -> {
-                                dividerAnimator.start();
-                                dividerAnimator.end();
-                            });
+                    TaskViewUtils.createSplitAuxiliarySurfacesAnimator(nonAppTargets /* nonApps */,
+                            true /*shown*/, null /* animatorHandler */);
                 }
                 if (mController != null) {
                     if (mLastAppearedTaskTarget == null
diff --git a/quickstep/src/com/android/quickstep/TaskViewUtils.java b/quickstep/src/com/android/quickstep/TaskViewUtils.java
index da97df6..f0d0bdb 100644
--- a/quickstep/src/com/android/quickstep/TaskViewUtils.java
+++ b/quickstep/src/com/android/quickstep/TaskViewUtils.java
@@ -679,28 +679,36 @@
     /**
      * Creates an animation to show/hide the auxiliary surfaces (aka. divider bar), only calling
      * {@param animatorHandler} if there are valid surfaces to animate.
+     * Passing null handler to apply the visibility immediately.
      *
      * @return the animator animating the surfaces
      */
     public static ValueAnimator createSplitAuxiliarySurfacesAnimator(
-            RemoteAnimationTarget[] nonApps, boolean shown,
-            Consumer<ValueAnimator> animatorHandler) {
+            @Nullable RemoteAnimationTarget[] nonApps, boolean shown,
+            @Nullable Consumer<ValueAnimator> animatorHandler) {
         if (nonApps == null || nonApps.length == 0) {
             return null;
         }
 
-        SurfaceControl.Transaction t = new SurfaceControl.Transaction();
-        List<SurfaceControl> auxiliarySurfaces = new ArrayList<>(nonApps.length);
-        boolean hasSurfaceToAnimate = false;
-        for (int i = 0; i < nonApps.length; ++i) {
-            final RemoteAnimationTarget targ = nonApps[i];
-            final SurfaceControl leash = targ.leash;
-            if (targ.windowType == TYPE_DOCK_DIVIDER && leash != null && leash.isValid()) {
+        List<SurfaceControl> auxiliarySurfaces = new ArrayList<>();
+        for (RemoteAnimationTarget target : nonApps) {
+            final SurfaceControl leash = target.leash;
+            if (target.windowType == TYPE_DOCK_DIVIDER && leash != null && leash.isValid()) {
                 auxiliarySurfaces.add(leash);
-                hasSurfaceToAnimate = true;
             }
         }
-        if (!hasSurfaceToAnimate) {
+        if (auxiliarySurfaces.isEmpty()) {
+            return null;
+        }
+
+        SurfaceControl.Transaction t = new SurfaceControl.Transaction();
+        if (animatorHandler == null) {
+            // Apply the visibility directly without fade animation.
+            for (SurfaceControl leash : auxiliarySurfaces) {
+                t.setVisibility(leash, shown);
+            }
+            t.apply();
+            t.close();
             return null;
         }
 
diff --git a/src/com/android/launcher3/BubbleTextView.java b/src/com/android/launcher3/BubbleTextView.java
index ea79c55..8e1c279 100644
--- a/src/com/android/launcher3/BubbleTextView.java
+++ b/src/com/android/launcher3/BubbleTextView.java
@@ -72,9 +72,9 @@
 import com.android.launcher3.model.data.ItemInfoWithIcon;
 import com.android.launcher3.model.data.WorkspaceItemInfo;
 import com.android.launcher3.popup.PopupContainerWithArrow;
-import com.android.launcher3.util.MultiTranslateDelegate;
 import com.android.launcher3.search.StringMatcherUtility;
 import com.android.launcher3.util.IntArray;
+import com.android.launcher3.util.MultiTranslateDelegate;
 import com.android.launcher3.util.SafeCloseable;
 import com.android.launcher3.util.ShortcutUtil;
 import com.android.launcher3.views.ActivityContext;
@@ -220,7 +220,6 @@
             defaultIconSize = grid.folderChildIconSizePx;
         } else if (mDisplay == DISPLAY_SEARCH_RESULT) {
             setTextSize(TypedValue.COMPLEX_UNIT_PX, grid.allAppsIconTextSizePx);
-            setCompoundDrawablePadding(grid.allAppsIconDrawablePaddingPx);
             defaultIconSize = getResources().getDimensionPixelSize(R.dimen.search_row_icon_size);
         } else if (mDisplay == DISPLAY_SEARCH_RESULT_SMALL) {
             defaultIconSize = getResources().getDimensionPixelSize(
@@ -978,6 +977,13 @@
         applyCompoundDrawables(icon);
     }
 
+    /** Sets the icon visual state to disabled or not. */
+    public void setIconDisabled(boolean isDisabled) {
+        if (mIcon != null) {
+            mIcon.setIsDisabled(isDisabled);
+        }
+    }
+
     protected boolean iconUpdateAnimationEnabled() {
         return mEnableIconUpdateAnimation;
     }
diff --git a/src/com/android/launcher3/DeleteDropTarget.java b/src/com/android/launcher3/DeleteDropTarget.java
index 95d3ad9..9ef9320 100644
--- a/src/com/android/launcher3/DeleteDropTarget.java
+++ b/src/com/android/launcher3/DeleteDropTarget.java
@@ -121,7 +121,6 @@
     public void onDrop(DragObject d, DragOptions options) {
         if (canRemove(d.dragInfo)) {
             mLauncher.getModelWriter().prepareToUndoDelete();
-            d.dragInfo.container = NO_ID;
         }
         super.onDrop(d, options);
         mStatsLogManager.logger().withInstanceId(d.logInstanceId)
diff --git a/src/com/android/launcher3/LauncherPrefs.kt b/src/com/android/launcher3/LauncherPrefs.kt
index e675add..fb4da0c 100644
--- a/src/com/android/launcher3/LauncherPrefs.kt
+++ b/src/com/android/launcher3/LauncherPrefs.kt
@@ -36,6 +36,8 @@
  * Use same context for shared preferences, so that we use a single cached instance
  *
  * TODO(b/262721340): Replace all direct SharedPreference refs with LauncherPrefs / Item methods.
+ * TODO(b/274501660): Fix ReorderWidgets#simpleReorder test before enabling
+ *   isBootAwareStartupDataEnabled
  */
 class LauncherPrefs(private val encryptedContext: Context) {
     private val deviceProtectedStorageContext =
@@ -228,7 +230,7 @@
      * files.
      *
      * @return a list of editors with all transactions added so that the caller can determine to use
-     * .apply() or .commit()
+     *   .apply() or .commit()
      */
     private fun prepareToRemove(items: Array<out Item>): List<SharedPreferences.Editor> {
         val itemsPerFile = items.groupBy { it.encryptedPrefs }.toMutableMap()
diff --git a/src/com/android/launcher3/widget/WidgetCell.java b/src/com/android/launcher3/widget/WidgetCell.java
index 80bc1a7..9984991 100644
--- a/src/com/android/launcher3/widget/WidgetCell.java
+++ b/src/com/android/launcher3/widget/WidgetCell.java
@@ -16,6 +16,7 @@
 
 package com.android.launcher3.widget;
 
+import static android.view.View.MeasureSpec.getSize;
 import static android.view.View.MeasureSpec.makeMeasureSpec;
 import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
 import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
@@ -118,6 +119,8 @@
     private TextView mWidgetName;
     private TextView mWidgetDims;
     private TextView mWidgetDescription;
+    private Consumer<Bitmap> mCallback;
+    private @Nullable Bitmap mCachedPreview;
 
     protected WidgetItem mItem;
 
@@ -429,6 +432,8 @@
      */
     private void ensurePreviewWithCallback(Consumer<Bitmap> callback,
             @Nullable Bitmap cachedPreview) {
+        mCallback = callback;
+        mCachedPreview = cachedPreview;
         if (mAppWidgetHostViewPreview != null) {
             int containerWidth = (int) (mTargetPreviewWidth * mPreviewContainerScale);
             int containerHeight = (int) (mTargetPreviewHeight * mPreviewContainerScale);
@@ -469,6 +474,7 @@
                     INDEX_WIDGET_CENTERING,
                     -(params.width - (params.width * mPreviewContainerScale)) / 2.0f,
                     -(params.height - (params.height * mPreviewContainerScale)) / 2.0f);
+            mWidgetImageContainer.removeAllViews();
             mWidgetImageContainer.addView(mAppWidgetHostViewPreview, /* index= */ 0);
             mWidgetImage.setVisibility(View.GONE);
             applyPreview(null);
@@ -579,4 +585,19 @@
                 (mTargetPreviewHeight - verticalPadding) * mPreviewContainerScale
                         / appWidgetContentHeight);
     }
+
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        int padding = getPaddingLeft() + getPaddingRight();
+        int allowedWidth = getSize(widthMeasureSpec) - padding;
+
+        // Here we prevent having clipped widgets when they're too large as the preview width is
+        // larger than the max allowed width. We then re-do the preview with the new preview width
+        if (allowedWidth > 0 && mCachedPreview == null && allowedWidth < mTargetPreviewWidth) {
+            mTargetPreviewWidth = allowedWidth;
+            ensurePreviewWithCallback(mCallback, null);
+        }
+
+        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+    }
 }
diff --git a/tests/src/com/android/launcher3/LauncherPrefsTest.kt b/tests/src/com/android/launcher3/LauncherPrefsTest.kt
index 41ef3de..d59e02a 100644
--- a/tests/src/com/android/launcher3/LauncherPrefsTest.kt
+++ b/tests/src/com/android/launcher3/LauncherPrefsTest.kt
@@ -25,6 +25,8 @@
 import com.google.common.truth.Truth.assertThat
 import java.util.concurrent.CountDownLatch
 import java.util.concurrent.TimeUnit
+import org.junit.AfterClass
+import org.junit.BeforeClass
 import org.junit.Test
 import org.junit.runner.RunWith
 
@@ -45,8 +47,18 @@
     private val context by lazy { InstrumentationRegistry.getInstrumentation().targetContext }
     private val launcherPrefs by lazy { LauncherPrefs.get(context) }
 
-    init {
-        isBootAwareStartupDataEnabled = true
+    companion object {
+        @BeforeClass
+        @JvmStatic
+        fun setup() {
+            isBootAwareStartupDataEnabled = true
+        }
+
+        @AfterClass
+        @JvmStatic
+        fun teardown() {
+            isBootAwareStartupDataEnabled = false
+        }
     }
 
     @Test