Tune AllApps bottom sheet VisD and motion

- Make AllApps bottom sheet solid and appears from bottom
- Teleport AllApps bottom sheet as user drag to reduce drag range
  - Consider teleport interpolation for state transition sdetection
- Tuned workspace motions for AllApps bottom sheet (no translate, shrink)
- Add portrait vertical translate for tablet portrait including taskbar AllApps
- Updated bottom sheet handle and created common variables for other bottom sheets

Bug: 208599118
Test: manual on tablet AllApps, taskbar Allapps and handheld AllApps
Change-Id: I69dba5f155914cd012cc8ef3be1ef71fb2be5a40
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index 62703ad..7189ef7 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -171,7 +171,8 @@
 
     // All apps
     public Point allAppsBorderSpacePx;
-    public int allAppsOpenVerticalTranslate;
+    public int allAppsShiftRange;
+    public int allAppsTopPadding;
     public int allAppsCellHeightPx;
     public int allAppsCellWidthPx;
     public int allAppsIconSizePx;
@@ -288,8 +289,11 @@
         desiredWorkspaceHorizontalMarginPx = getHorizontalMarginPx(inv, res);
         desiredWorkspaceHorizontalMarginOriginalPx = desiredWorkspaceHorizontalMarginPx;
 
-        allAppsOpenVerticalTranslate = res.getDimensionPixelSize(
-                R.dimen.all_apps_open_vertical_translate);
+        allAppsTopPadding = res.getDimensionPixelSize(R.dimen.all_apps_top_padding)
+                + (isTablet ? heightPx - availableHeightPx : 0);
+        allAppsShiftRange = isTablet
+                ? heightPx - allAppsTopPadding
+                : res.getDimensionPixelSize(R.dimen.all_apps_starting_vertical_translate);
 
         folderLabelTextScale = res.getFloat(R.dimen.folder_label_text_scale);
         folderContentPaddingLeftRight =
diff --git a/src/com/android/launcher3/allapps/AllAppsTransitionController.java b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
index b6a2459..cdc313f 100644
--- a/src/com/android/launcher3/allapps/AllAppsTransitionController.java
+++ b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
@@ -89,15 +89,15 @@
     private float mShiftRange;      // changes depending on the orientation
     private float mProgress;        // [0, 1], mShiftRange * mProgress = shiftCurrent
 
-    private float mScrollRangeDelta = 0;
     private ScrimView mScrimView;
 
     public AllAppsTransitionController(Launcher l) {
         mLauncher = l;
-        mShiftRange = mLauncher.getDeviceProfile().heightPx;
+        DeviceProfile dp = mLauncher.getDeviceProfile();
+        setShiftRange(dp.allAppsShiftRange);
         mProgress = 1f;
 
-        mIsVerticalLayout = mLauncher.getDeviceProfile().isVerticalBarLayout();
+        mIsVerticalLayout = dp.isVerticalBarLayout();
         mLauncher.addOnDeviceProfileChangeListener(this);
     }
 
@@ -108,7 +108,7 @@
     @Override
     public void onDeviceProfileChanged(DeviceProfile dp) {
         mIsVerticalLayout = dp.isVerticalBarLayout();
-        setScrollRangeDelta(mScrollRangeDelta);
+        setShiftRange(dp.allAppsShiftRange);
 
         if (mIsVerticalLayout) {
             mLauncher.getHotseat().setTranslationY(0);
@@ -160,12 +160,14 @@
         }
 
         // need to decide depending on the release velocity
-        Interpolator interpolator = (config.userControlled ? LINEAR : DEACCEL_1_7);
-
+        Interpolator verticalProgressInterpolator = config.getInterpolator(ANIM_VERTICAL_PROGRESS,
+                config.userControlled ? LINEAR : DEACCEL_1_7);
         Animator anim = createSpringAnimation(mProgress, targetProgress);
-        anim.setInterpolator(config.getInterpolator(ANIM_VERTICAL_PROGRESS, interpolator));
+        anim.setInterpolator(verticalProgressInterpolator);
         anim.addListener(getProgressAnimatorListener());
         builder.add(anim);
+        // Use ANIM_VERTICAL_PROGRESS's interpolator to determine state transition threshold.
+        builder.setInterpolator(verticalProgressInterpolator);
 
         setAlphas(toState, config, builder);
 
@@ -215,9 +217,8 @@
     /**
      * Updates the total scroll range but does not update the UI.
      */
-    public void setScrollRangeDelta(float delta) {
-        mScrollRangeDelta = delta;
-        mShiftRange = mLauncher.getDeviceProfile().heightPx - mScrollRangeDelta;
+    public void setShiftRange(float shiftRange) {
+        mShiftRange = shiftRange;
     }
 
     /**
diff --git a/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java b/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java
index 59e21c0..bfc7515 100644
--- a/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java
@@ -408,7 +408,7 @@
         if (grid.isVerticalBarLayout()) {
             setPadding(grid.workspacePadding.left, 0, grid.workspacePadding.right, 0);
         } else {
-            setPadding(0, grid.isTablet ? insets.top : 0, 0, 0);
+            setPadding(0, grid.allAppsTopPadding, 0, 0);
         }
 
         InsettableFrameLayout.dispatchInsets(this, insets);
@@ -765,4 +765,11 @@
                     && mVerticalFadingEdge);
         }
     }
+
+    /**
+     * Returns a view that denotes the visible part of all apps container view.
+     */
+    public View getVisibleContainerView() {
+        return mActivityContext.getDeviceProfile().isTablet ? mBottomSheetBackground : this;
+    }
 }
diff --git a/src/com/android/launcher3/allapps/LauncherAllAppsContainerView.java b/src/com/android/launcher3/allapps/LauncherAllAppsContainerView.java
index 30d33f9..8601819 100644
--- a/src/com/android/launcher3/allapps/LauncherAllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/LauncherAllAppsContainerView.java
@@ -16,7 +16,6 @@
 package com.android.launcher3.allapps;
 
 import android.content.Context;
-import android.graphics.Rect;
 import android.util.AttributeSet;
 import android.view.MotionEvent;
 
@@ -59,12 +58,4 @@
         }
         return super.onTouchEvent(ev);
     }
-
-    @Override
-    public void setInsets(Rect insets) {
-        super.setInsets(insets);
-        int allAppsStartingPositionY = mActivityContext.getDeviceProfile().availableHeightPx
-                - mActivityContext.getDeviceProfile().allAppsOpenVerticalTranslate;
-        mActivityContext.getAllAppsController().setScrollRangeDelta(allAppsStartingPositionY);
-    }
 }
diff --git a/src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java b/src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java
index ffc049b..4a886a4 100644
--- a/src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java
+++ b/src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java
@@ -82,7 +82,7 @@
         setHint(prefixTextWithIcon(getContext(), R.drawable.ic_allapps_search, getHint()));
 
         mContentOverlap =
-                getResources().getDimensionPixelSize(R.dimen.all_apps_search_bar_field_height) / 2;
+                getResources().getDimensionPixelSize(R.dimen.all_apps_search_bar_content_overlap);
     }
 
     @Override
diff --git a/src/com/android/launcher3/anim/Interpolators.java b/src/com/android/launcher3/anim/Interpolators.java
index 1e7b224..9c12abd 100644
--- a/src/com/android/launcher3/anim/Interpolators.java
+++ b/src/com/android/launcher3/anim/Interpolators.java
@@ -130,6 +130,23 @@
         }
     };
 
+    public static final Interpolator LINEAR_TELEPORT = t -> {
+        float startTeleport = 0.2f;
+        float endTeleport = 0.4f;
+        float teleportProgress = 0.5f;
+        float v;
+        if (t < startTeleport) {
+            v = LINEAR.getInterpolation(t);
+        } else if (t < endTeleport) {
+            v = Utilities.mapToRange(t, startTeleport, endTeleport, startTeleport,
+                    endTeleport + teleportProgress, ACCEL_DEACCEL);
+        } else {
+            v = LINEAR.getInterpolation(t) + teleportProgress;
+        }
+        v = Utilities.boundToRange(v, 0f, 1f);
+        return v;
+    };
+
     private static final float FAST_FLING_PX_MS = 10;
 
     public static Interpolator scrollInterpolatorForVelocity(float velocity) {
diff --git a/src/com/android/launcher3/anim/PendingAnimation.java b/src/com/android/launcher3/anim/PendingAnimation.java
index 3ab893b..1300ce7 100644
--- a/src/com/android/launcher3/anim/PendingAnimation.java
+++ b/src/com/android/launcher3/anim/PendingAnimation.java
@@ -77,6 +77,13 @@
         addAnimationHoldersRecur(a, mDuration, springProperty, mAnimHolders);
     }
 
+    /**
+     * Configures interpolator of the underlying AnimatorSet.
+     */
+    public void setInterpolator(TimeInterpolator interpolator) {
+        mAnim.setInterpolator(interpolator);
+    }
+
     @Override
     public void setViewAlpha(View view, float alpha, TimeInterpolator interpolator) {
         if (view == null || view.getAlpha() == alpha) {
diff --git a/src/com/android/launcher3/touch/AllAppsSwipeController.java b/src/com/android/launcher3/touch/AllAppsSwipeController.java
index 989a9e4..f7d3492 100644
--- a/src/com/android/launcher3/touch/AllAppsSwipeController.java
+++ b/src/com/android/launcher3/touch/AllAppsSwipeController.java
@@ -17,9 +17,13 @@
 
 import static com.android.launcher3.LauncherState.ALL_APPS;
 import static com.android.launcher3.LauncherState.NORMAL;
+import static com.android.launcher3.anim.Interpolators.FINAL_FRAME;
+import static com.android.launcher3.anim.Interpolators.INSTANT;
 import static com.android.launcher3.anim.Interpolators.LINEAR;
+import static com.android.launcher3.anim.Interpolators.LINEAR_TELEPORT;
 import static com.android.launcher3.states.StateAnimationConfig.ANIM_ALL_APPS_FADE;
 import static com.android.launcher3.states.StateAnimationConfig.ANIM_SCRIM_FADE;
+import static com.android.launcher3.states.StateAnimationConfig.ANIM_VERTICAL_PROGRESS;
 
 import android.view.MotionEvent;
 import android.view.animation.Interpolator;
@@ -94,9 +98,9 @@
             LauncherState toState) {
         StateAnimationConfig config = super.getConfigForStates(fromState, toState);
         if (fromState == NORMAL && toState == ALL_APPS) {
-            applyNormalToAllAppsAnimConfig(config);
+            applyNormalToAllAppsAnimConfig(mLauncher, config);
         } else if (fromState == ALL_APPS && toState == NORMAL) {
-            applyAllAppsToNormalConfig(config);
+            applyAllAppsToNormalConfig(mLauncher, config);
         }
         return config;
     }
@@ -104,17 +108,24 @@
     /**
      * Applies Animation config values for transition from all apps to home
      */
-    public static void applyAllAppsToNormalConfig(StateAnimationConfig config) {
+    public static void applyAllAppsToNormalConfig(Launcher launcher, StateAnimationConfig config) {
+        boolean isTablet = launcher.getDeviceProfile().isTablet;
         config.setInterpolator(ANIM_SCRIM_FADE, ALLAPPS_STAGGERED_FADE_LATE_RESPONDER);
-        config.setInterpolator(ANIM_ALL_APPS_FADE, ALLAPPS_STAGGERED_FADE_EARLY_RESPONDER);
+        config.setInterpolator(ANIM_ALL_APPS_FADE, isTablet
+                ? FINAL_FRAME : ALLAPPS_STAGGERED_FADE_EARLY_RESPONDER);
+        config.setInterpolator(ANIM_VERTICAL_PROGRESS, isTablet ? LINEAR_TELEPORT : LINEAR);
     }
 
     /**
      * Applies Animation config values for transition from home to all apps
      */
-    public static void applyNormalToAllAppsAnimConfig(StateAnimationConfig config) {
+    public static void applyNormalToAllAppsAnimConfig(Launcher launcher,
+            StateAnimationConfig config) {
+        boolean isTablet = launcher.getDeviceProfile().isTablet;
         config.setInterpolator(ANIM_SCRIM_FADE, ALLAPPS_STAGGERED_FADE_EARLY_RESPONDER);
-        config.setInterpolator(ANIM_ALL_APPS_FADE, ALLAPPS_STAGGERED_FADE_LATE_RESPONDER);
+        config.setInterpolator(ANIM_ALL_APPS_FADE, isTablet
+                ? INSTANT : ALLAPPS_STAGGERED_FADE_LATE_RESPONDER);
+        config.setInterpolator(ANIM_VERTICAL_PROGRESS, isTablet ? LINEAR_TELEPORT : LINEAR);
     }
 
 
diff --git a/src/com/android/launcher3/views/AbstractSlideInView.java b/src/com/android/launcher3/views/AbstractSlideInView.java
index c22d60d..5d88884 100644
--- a/src/com/android/launcher3/views/AbstractSlideInView.java
+++ b/src/com/android/launcher3/views/AbstractSlideInView.java
@@ -113,9 +113,16 @@
         return -1;
     }
 
+    /**
+     * Returns the range in height that the slide in view can be dragged.
+     */
+    protected float getShiftRange() {
+        return mContent.getHeight();
+    }
+
     protected void setTranslationShift(float translationShift) {
         mTranslationShift = translationShift;
-        mContent.setTranslationY(mTranslationShift * mContent.getHeight());
+        mContent.setTranslationY(mTranslationShift * getShiftRange());
         if (mColorScrim != null) {
             mColorScrim.setAlpha(1 - mTranslationShift);
         }
@@ -132,8 +139,7 @@
         mSwipeDetector.setDetectableScrollConditions(
                 directionsToDetectScroll, false);
         mSwipeDetector.onTouchEvent(ev);
-        return mSwipeDetector.isDraggingOrSettling()
-                || !getPopupContainer().isEventOverView(mContent, ev);
+        return mSwipeDetector.isDraggingOrSettling() || !isEventOverContent(ev);
     }
 
     @Override
@@ -142,13 +148,23 @@
         if (ev.getAction() == MotionEvent.ACTION_UP && mSwipeDetector.isIdleState()
                 && !isOpeningAnimationRunning()) {
             // If we got ACTION_UP without ever starting swipe, close the panel.
-            if (!getPopupContainer().isEventOverView(mContent, ev)) {
+            if (!isEventOverContent(ev)) {
                 close(true);
             }
         }
         return true;
     }
 
+    /**
+     * Returns {@code true} if the touch event is over the visible area of the bottom sheet.
+     *
+     * By default will check if the touch event is over {@code mContent}, subclasses should override
+     * this method if the visible area of the bottom sheet is different from {@code mContent}.
+     */
+    protected boolean isEventOverContent(MotionEvent ev) {
+        return getPopupContainer().isEventOverView(mContent, ev);
+    }
+
     private boolean isOpeningAnimationRunning() {
         return mIsOpen && mOpenCloseAnimator.isRunning();
     }
@@ -160,7 +176,7 @@
 
     @Override
     public boolean onDrag(float displacement) {
-        float range = mContent.getHeight();
+        float range = getShiftRange();
         displacement = Utilities.boundToRange(displacement, 0, range);
         setTranslationShift(displacement / range);
         return true;