Using state controller for moving the hotseat.

Using state controller ensures that when the state changes the UI is
properly updated based on the state properties.
This would prevent user getting stuck in an inconsistent UI

Bug: 72173796
Change-Id: I7690a94eed7c8a620479e4247d2b681a7374ce45
diff --git a/quickstep/src/com/android/quickstep/NavBarSwipeInteractionHandler.java b/quickstep/src/com/android/quickstep/NavBarSwipeInteractionHandler.java
index 168c1fe..eb5195c 100644
--- a/quickstep/src/com/android/quickstep/NavBarSwipeInteractionHandler.java
+++ b/quickstep/src/com/android/quickstep/NavBarSwipeInteractionHandler.java
@@ -27,7 +27,6 @@
 import android.graphics.Color;
 import android.graphics.Rect;
 import android.os.Build;
-import android.os.Handler;
 import android.os.UserHandle;
 import android.support.annotation.UiThread;
 import android.view.View;
@@ -41,12 +40,12 @@
 import com.android.launcher3.LauncherState;
 import com.android.launcher3.R;
 import com.android.launcher3.Utilities;
+import com.android.launcher3.allapps.AllAppsTransitionController;
 import com.android.launcher3.anim.AnimationSuccessListener;
 import com.android.launcher3.anim.Interpolators;
 import com.android.launcher3.states.InternalStateHandler;
 import com.android.launcher3.uioverrides.RecentsViewStateController;
 import com.android.launcher3.util.TraceHelper;
-import com.android.launcher3.views.AllAppsScrim;
 import com.android.systemui.shared.recents.model.RecentsTaskLoadPlan;
 import com.android.systemui.shared.recents.model.Task;
 import com.android.systemui.shared.recents.model.Task.TaskKey;
@@ -61,7 +60,6 @@
     private static final int STATE_SCALED_SNAPSHOT_RECENTS = 1 << 5;
     private static final int STATE_SCALED_SNAPSHOT_APP = 1 << 6;
 
-    private static final long RECENTS_VIEW_VISIBILITY_DURATION = 150;
     private static final long MAX_SWIPE_DURATION = 200;
     private static final long MIN_SWIPE_DURATION = 80;
     private static final int QUICK_SWITCH_SNAP_DURATION = 120;
@@ -98,7 +96,6 @@
     private RecentsViewStateController mStateController;
     private QuickScrubController mQuickScrubController;
     private Hotseat mHotseat;
-    private AllAppsScrim mAllAppsScrim;
 
     private boolean mLauncherReady;
     private boolean mTouchEndHandled;
@@ -188,7 +185,6 @@
         mRecentsView.showTask(mRunningTask);
         mStateController = mRecentsView.getStateController();
         mHotseat = mLauncher.getHotseat();
-        mAllAppsScrim = mLauncher.findViewById(R.id.all_apps_scrim);
 
         AbstractFloatingView.closeAllOpenViews(mLauncher, alreadyOnHome);
         mLauncher.getStateManager().goToState(LauncherState.OVERVIEW, alreadyOnHome);
@@ -242,11 +238,10 @@
         }
 
         float shift = mCurrentShift.value * mActivityMultiplier.value;
-        int hotseatSize = getHotseatSize();
 
-        float hotseatTranslation = (1 - shift) * hotseatSize;
-        mHotseat.setTranslationY(hotseatTranslation);
-        mAllAppsScrim.setTranslationY(hotseatTranslation);
+        AllAppsTransitionController controller = mLauncher.getAllAppsController();
+        float range = getHotseatSize() / controller.getShiftRange();
+        controller.setProgress(1 + (1 - shift) * range);
 
         mRectEvaluator.evaluate(shift, mSourceRect, mTargetRect);
 
@@ -329,8 +324,7 @@
 
     private void cleanupLauncher() {
         // TODO: These should be done as part of ActivityOptions#OnAnimationStarted
-        mHotseat.setTranslationY(0);
-        mAllAppsScrim.setTranslationY(0);
+        mLauncher.getStateManager().reapplyState();
         mLauncher.setOnResumeCallback(() -> mDragView.close(false));
     }
 
diff --git a/src/com/android/launcher3/views/AllAppsScrim.java b/src/com/android/launcher3/views/AllAppsScrim.java
index 5d39adb..cc73182 100644
--- a/src/com/android/launcher3/views/AllAppsScrim.java
+++ b/src/com/android/launcher3/views/AllAppsScrim.java
@@ -46,6 +46,7 @@
     protected final WallpaperColorInfo mWallpaperColorInfo;
     private final Paint mFillPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
 
+    private final Rect mDrawRect = new Rect();
     private final Rect mPadding = new Rect();
     private final Rect mInsets = new Rect();
     private final DeviceProfile mGrid;
@@ -62,7 +63,7 @@
     private int mFillAlpha;
 
     private float mDrawHeight;
-    private float mTranslateY;
+    private float mDrawOffsetY;
 
     public AllAppsScrim(Context context) {
         this(context, null);
@@ -135,7 +136,7 @@
 
     @Override
     protected void onDraw(Canvas canvas) {
-        float edgeTop = getHeight() + mTranslateY - mDrawHeight + mPadding.top;
+        float edgeTop = getHeight() + mDrawOffsetY - mDrawHeight + mPadding.top;
         float edgeRight = getWidth() - mPadding.right;
 
         if (mPadding.left > 0 || mPadding.right > 0) {
@@ -153,12 +154,29 @@
     }
 
     public void setProgress(float translateY, float alpha) {
-        mFillAlpha = Math.round(alpha * mAlphaRange + mMinAlpha);
-        mFillPaint.setAlpha(mFillAlpha);
+        float newAlpha = Math.round(alpha * mAlphaRange + mMinAlpha);
+        // Negative translation means the scrim is moving up. For negative translation, we change
+        // draw offset as it requires redraw (since more area of the scrim needs to be shown). For
+        // position translation, we simply translate the scrim down as it avoids invalidate and
+        // hence could be optimized by the platform.
+        float drawOffsetY = Math.min(translateY, 0);
 
-        mTranslateY = translateY;
+        if (newAlpha != mFillAlpha || drawOffsetY != mDrawOffsetY) {
+            invalidateDrawRect();
 
-        invalidate();
+            mFillAlpha = Math.round(alpha * mAlphaRange + mMinAlpha);
+            mFillPaint.setAlpha(mFillAlpha);
+            mDrawOffsetY = drawOffsetY;
+            invalidateDrawRect();
+        }
+
+        setTranslationY(Math.max(translateY, 0));
+    }
+
+    private void invalidateDrawRect() {
+        mDrawRect.top = (int) (getHeight()
+                + mDrawOffsetY - mDrawHeight + mPadding.top - mShadowBlur - 0.5f);
+        invalidate(mDrawRect);
     }
 
     public void setDrawRegion(float height) {
@@ -178,6 +196,24 @@
             float scrimMargin = getResources().getDimension(R.dimen.all_apps_scrim_margin);
             setDrawRegion(mGrid.hotseatBarSizePx + insets.bottom + scrimMargin);
         }
+        updateDrawRect();
         invalidate();
     }
+
+    @Override
+    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+        super.onLayout(changed, left, top, right, bottom);
+        updateDrawRect();
+    }
+
+    private void updateDrawRect() {
+        mDrawRect.bottom = getHeight();
+        if (mGrid.isVerticalBarLayout()) {
+            mDrawRect.left = (int) (mPadding.left - mShadowBlur - 0.5f);
+            mDrawRect.right = (int) (getWidth() - mPadding.right + 0.5f);
+        } else {
+            mDrawRect.left = 0;
+            mDrawRect.right = getWidth();
+        }
+    }
 }