Adds all_apps_blur flag.

This enables blur both for Taskbar and Launcher, but in slightly
different ways.

For Taskbar All Apps, we apply blur to the overlay window, and
for Launcher All Apps, we utilize the existing DepthController to
blur the wallpaper window. For similicity, we currently fade out
workspace/hotseat to avoid awkward view + window blurs which
don't look that good. This is not the POR, but I think it achieves
most of the effect and will help us get some blur exposure.

Separately I will continue to investigate options such as blurring
workspace in a clever way so it feels blended with the wallpaper,
reusing the Taskbar window and connecting it to LauncherState, or
using a SurfaceView (though I spent quite some time trying this and
it seemed the same as the original issue).

In both cases, we use a 20-30% opacity scrim with a set color, and a
panel that blends 40% opacity of a dark/light color with 10% white.

Also updated some incorrect isTablet checks which really should have
been checking shouldShowAllAppsOnSheet(), which includes the
all_apps_sheet_for_handheld flag.

Demo: https://drive.google.com/file/d/1Ov9Dg3R9YHNfisfxNf97ZIhlDeEA1IWj/view?usp=sharing&resourcekey=0-l_SDpqpS4HtOb10a3b_jNg

Other upcoming improvements: interpolator tweaks, colors of things
inside the app panel (tabs, private space, search results, etc).

Bug: 400827727
Bug: 371343636
Test: Manual
Flag: com.android.launcher3.all_apps_blur
Change-Id: Ic7063cd822f39a5977715b5477f825bf11e57bdf
diff --git a/aconfig/launcher.aconfig b/aconfig/launcher.aconfig
index 9f505a4..f816033 100644
--- a/aconfig/launcher.aconfig
+++ b/aconfig/launcher.aconfig
@@ -311,6 +311,13 @@
 }
 
 flag {
+    name: "all_apps_blur"
+    namespace: "launcher"
+    description: "Content behind the all apps panel in Launcher will be blurred."
+    bug: "400827727"
+}
+
+flag {
     name: "multiline_search_bar"
     namespace: "launcher"
     description: "Search bar can wrap to multi-line"
diff --git a/quickstep/res/values/config.xml b/quickstep/res/values/config.xml
index e69fa4d..1ce28cf 100644
--- a/quickstep/res/values/config.xml
+++ b/quickstep/res/values/config.xml
@@ -47,6 +47,7 @@
     <string name="wellbeing_provider_pkg" translatable="false"/>
 
     <integer name="max_depth_blur_radius">23</integer>
+    <dimen name="max_depth_blur_radius_enhanced">34dp</dimen>
 
     <!-- If predicted widgets from prediction service are less than this number, additional
     eligible widgets may be added locally by launcher. When set to 0, no widgets will be added
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java
index e8e5b30..561b021 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java
@@ -1318,7 +1318,6 @@
                         }
                     }
                 } else {
-
                     getCurrentActivityContext().onConfigurationChanged(configDiff);
                 }
                 mOldConfig = new Configuration(newConfig);
diff --git a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsSlideInView.java b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsSlideInView.java
index 5830095..916b28e 100644
--- a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsSlideInView.java
+++ b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsSlideInView.java
@@ -15,7 +15,9 @@
  */
 package com.android.launcher3.taskbar.allapps;
 
+import static com.android.app.animation.Interpolators.DECELERATED_EASE;
 import static com.android.app.animation.Interpolators.EMPHASIZED;
+import static com.android.app.animation.Interpolators.LINEAR;
 import static com.android.launcher3.touch.AllAppsSwipeController.ALL_APPS_FADE_MANUAL;
 import static com.android.launcher3.touch.AllAppsSwipeController.SCRIM_FADE_MANUAL;
 
@@ -35,6 +37,7 @@
 
 import com.android.app.animation.Interpolators;
 import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.Flags;
 import com.android.launcher3.Insettable;
 import com.android.launcher3.R;
 import com.android.launcher3.anim.AnimatorListeners;
@@ -48,9 +51,11 @@
 public class TaskbarAllAppsSlideInView extends AbstractSlideInView<TaskbarOverlayContext>
         implements Insettable, DeviceProfile.OnDeviceProfileChangeListener {
     private final Handler mHandler;
+    private final int mMaxBlurRadius;
 
     private TaskbarAllAppsContainerView mAppsView;
     private float mShiftRange;
+    private int mBlurRadius;
     private @Nullable Runnable mShowOnFullyAttachedToWindowRunnable;
 
     // Initialized in init.
@@ -64,6 +69,8 @@
             int defStyleAttr) {
         super(context, attrs, defStyleAttr);
         mHandler = new Handler(Looper.myLooper());
+        mMaxBlurRadius = getResources().getDimensionPixelSize(
+                R.dimen.max_depth_blur_radius_enhanced);
     }
 
     void init(TaskbarAllAppsCallbacks callbacks) {
@@ -99,6 +106,7 @@
         if (!animate) {
             mAllAppsCallbacks.onAllAppsTransitionEnd(true);
             setTranslationShift(TRANSLATION_SHIFT_OPENED);
+            mBlurRadius = mMaxBlurRadius;
             return;
         }
 
@@ -123,6 +131,16 @@
             animation.setViewAlpha(mAppsView, 1 - mToTranslationShift, allAppsFadeInterpolator);
         }
 
+        if (Flags.allAppsBlur()) {
+            Interpolator blurInterpolator = isOpening ? LINEAR : DECELERATED_EASE;
+            animation.addOnFrameListener(a -> {
+                float blurProgress =
+                        isOpening ? a.getAnimatedFraction() : 1 - a.getAnimatedFraction();
+                mBlurRadius =
+                        (int) (mMaxBlurRadius * blurInterpolator.getInterpolation(blurProgress));
+            });
+        }
+
         mAllAppsCallbacks.onAllAppsAnimationPending(animation, isOpening);
     }
 
@@ -219,6 +237,7 @@
         // to pass extra bottom offset to background scrim to fill the bottom gap during predictive
         // back swipe.
         mAppsView.drawOnScrimWithBottomOffset(canvas, getBottomOffsetPx());
+        mActivityContext.getOverlayController().setBackgroundBlurRadius(mBlurRadius);
         super.dispatchDraw(canvas);
     }
 
@@ -230,9 +249,13 @@
 
     @Override
     protected int getScrimColor(Context context) {
-        return mActivityContext.getDeviceProfile().isPhone
-                ? Themes.getAttrColor(context, R.attr.allAppsScrimColor)
-                : context.getColor(R.color.widgets_picker_scrim);
+        if (!mActivityContext.getDeviceProfile().shouldShowAllAppsOnSheet()) {
+            return Themes.getAttrColor(context, R.attr.allAppsScrimColor);
+        }
+        if (Flags.allAppsBlur()) {
+            return Themes.getAttrColor(context, R.attr.allAppsScrimColorOverBlur);
+        }
+        return context.getResources().getColor(R.color.widgets_picker_scrim);
     }
 
     @Override
@@ -254,6 +277,7 @@
     public void onDeviceProfileChanged(DeviceProfile dp) {
         setShiftRange(dp.allAppsShiftRange);
         setTranslationShift(TRANSLATION_SHIFT_OPENED);
+        mBlurRadius = mMaxBlurRadius;
     }
 
     private void setShiftRange(float shiftRange) {
diff --git a/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayController.java b/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayController.java
index 79cb748..79ba15f 100644
--- a/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayController.java
@@ -26,8 +26,12 @@
 import android.annotation.SuppressLint;
 import android.content.Context;
 import android.graphics.PixelFormat;
+import android.util.Log;
+import android.view.AttachedSurfaceControl;
 import android.view.Gravity;
 import android.view.MotionEvent;
+import android.view.SurfaceControl;
+import android.view.ViewRootImpl;
 import android.view.WindowManager;
 import android.view.WindowManager.LayoutParams;
 
@@ -36,8 +40,10 @@
 import com.android.launcher3.AbstractFloatingView;
 import com.android.launcher3.DeviceProfile;
 import com.android.launcher3.Flags;
+import com.android.launcher3.R;
 import com.android.launcher3.taskbar.TaskbarActivityContext;
 import com.android.launcher3.taskbar.TaskbarControllers;
+import com.android.systemui.shared.system.BlurUtils;
 import com.android.systemui.shared.system.TaskStackChangeListener;
 import com.android.systemui.shared.system.TaskStackChangeListeners;
 
@@ -52,12 +58,14 @@
  */
 public final class TaskbarOverlayController {
 
+    private static final String TAG = "TaskbarOverlayController";
     private static final String WINDOW_TITLE = "Taskbar Overlay";
 
     private final TaskbarActivityContext mTaskbarContext;
     private final Context mWindowContext;
     private final TaskbarOverlayProxyView mProxyView;
     private final LayoutParams mLayoutParams;
+    private final int mMaxBlurRadius;
 
     private final TaskStackChangeListener mTaskStackListener = new TaskStackChangeListener() {
         @Override
@@ -88,6 +96,8 @@
     private DeviceProfile mLauncherDeviceProfile;
     private @Nullable TaskbarOverlayContext mOverlayContext;
     private TaskbarControllers mControllers; // Initialized in init.
+    // True if we have alerted surface flinger of an expensive call for blur.
+    private boolean mInEarlyWakeUp;
 
     public TaskbarOverlayController(
             TaskbarActivityContext taskbarContext, DeviceProfile launcherDeviceProfile) {
@@ -96,6 +106,8 @@
         mProxyView = new TaskbarOverlayProxyView();
         mLayoutParams = createLayoutParams();
         mLauncherDeviceProfile = launcherDeviceProfile;
+        mMaxBlurRadius = mTaskbarContext.getResources().getDimensionPixelSize(
+                R.dimen.max_depth_blur_radius_enhanced);
     }
 
     /** Initialize the controller. */
@@ -197,6 +209,65 @@
     }
 
     /**
+     * Sets the blur radius for the overlay window.
+     *
+     * @param radius the blur radius in pixels. This will automatically change to {@code 0} if blurs
+     *               are unsupported on the device.
+     */
+    public void setBackgroundBlurRadius(int radius) {
+        if (!Flags.allAppsBlur()) {
+            return;
+        }
+        if (!BlurUtils.supportsBlursOnWindows()) {
+            Log.d(TAG, "setBackgroundBlurRadius: not supported, setting to 0");
+            radius = 0;
+            // intentionally falling through in case a non-0 blur was previously set.
+        }
+        if (mOverlayContext == null) {
+            Log.w(TAG, "setBackgroundBlurRadius: no overlay context");
+            return;
+        }
+        TaskbarOverlayDragLayer dragLayer = mOverlayContext.getDragLayer();
+        if (dragLayer == null) {
+            Log.w(TAG, "setBackgroundBlurRadius: no drag layer");
+            return;
+        }
+        ViewRootImpl dragLayerViewRoot = dragLayer.getViewRootImpl();
+        if (dragLayerViewRoot == null) {
+            Log.w(TAG, "setBackgroundBlurRadius: dragLayerViewRoot is null");
+            return;
+        }
+        AttachedSurfaceControl rootSurfaceControl = dragLayer.getRootSurfaceControl();
+        if (rootSurfaceControl == null) {
+            Log.w(TAG, "setBackgroundBlurRadius: rootSurfaceControl is null");
+            return;
+        }
+        SurfaceControl surfaceControl = dragLayerViewRoot.getSurfaceControl();
+        if (surfaceControl == null || !surfaceControl.isValid()) {
+            Log.w(TAG, "setBackgroundBlurRadius: surfaceControl is null or invalid");
+            return;
+        }
+        Log.v(TAG, "setBackgroundBlurRadius: " + radius);
+        SurfaceControl.Transaction transaction =
+                new SurfaceControl.Transaction().setBackgroundBlurRadius(surfaceControl, radius);
+
+        // Set early wake-up flags when we know we're executing an expensive operation, this way
+        // SurfaceFlinger will adjust its internal offsets to avoid jank.
+        boolean wantsEarlyWakeUp = radius > 0 && radius < mMaxBlurRadius;
+        if (wantsEarlyWakeUp && !mInEarlyWakeUp) {
+            Log.d(TAG, "setBackgroundBlurRadius: setting early wakeup");
+            transaction.setEarlyWakeupStart();
+            mInEarlyWakeUp = true;
+        } else if (!wantsEarlyWakeUp && mInEarlyWakeUp) {
+            Log.d(TAG, "setBackgroundBlurRadius: clearing early wakeup");
+            transaction.setEarlyWakeupEnd();
+            mInEarlyWakeUp = false;
+        }
+
+        rootSurfaceControl.applyTransactionOnDraw(transaction);
+    }
+
+    /**
      * Proxy view connecting taskbar drag layer to the overlay window.
      *
      * Overlays are in a separate window and has its own drag layer, but this proxy lets its views
diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java b/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java
index b27c6e8..54b4fa2 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java
@@ -23,6 +23,7 @@
 
 import com.android.internal.jank.Cuj;
 import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.Flags;
 import com.android.launcher3.Launcher;
 import com.android.launcher3.LauncherState;
 import com.android.launcher3.R;
@@ -153,7 +154,7 @@
         return new PageAlphaProvider(DECELERATE_2) {
             @Override
             public float getPageAlpha(int pageIndex) {
-                return launcher.getDeviceProfile().isTablet
+                return isWorkspaceVisible(launcher.getDeviceProfile())
                         ? superPageAlphaProvider.getPageAlpha(pageIndex)
                         : 0;
             }
@@ -163,13 +164,17 @@
     @Override
     public int getVisibleElements(Launcher launcher) {
         int elements = ALL_APPS_CONTENT | FLOATING_SEARCH_BAR;
-        // When All Apps is presented on a bottom sheet, HOTSEAT_ICONS are visible.
-        if (launcher.getDeviceProfile().isTablet) {
+        if (isWorkspaceVisible(launcher.getDeviceProfile())) {
             elements |= HOTSEAT_ICONS;
         }
         return elements;
     }
 
+    private static boolean isWorkspaceVisible(DeviceProfile deviceProfile) {
+        // Currently we hide the workspace with the all apps blur flag for simplicity.
+        return deviceProfile.isTablet && !Flags.allAppsBlur();
+    }
+
     @Override
     public int getFloatingSearchBarRestingMarginBottom(Launcher launcher) {
         return 0;
@@ -201,8 +206,12 @@
 
     @Override
     public int getWorkspaceScrimColor(Launcher launcher) {
-        return launcher.getDeviceProfile().shouldShowAllAppsOnSheet()
-                ? launcher.getResources().getColor(R.color.widgets_picker_scrim)
-                : Themes.getAttrColor(launcher, R.attr.allAppsScrimColor);
+        if (!launcher.getDeviceProfile().shouldShowAllAppsOnSheet()) {
+            return Themes.getAttrColor(launcher, R.attr.allAppsScrimColor);
+        }
+        if (Flags.allAppsBlur()) {
+            return Themes.getAttrColor(launcher, R.attr.allAppsScrimColorOverBlur);
+        }
+        return launcher.getResources().getColor(R.color.widgets_picker_scrim);
     }
 }
diff --git a/quickstep/src/com/android/quickstep/util/BaseDepthController.java b/quickstep/src/com/android/quickstep/util/BaseDepthController.java
index 5d6bb1d..f956a7c 100644
--- a/quickstep/src/com/android/quickstep/util/BaseDepthController.java
+++ b/quickstep/src/com/android/quickstep/util/BaseDepthController.java
@@ -24,6 +24,7 @@
 import android.view.AttachedSurfaceControl;
 import android.view.SurfaceControl;
 
+import com.android.launcher3.Flags;
 import com.android.launcher3.Launcher;
 import com.android.launcher3.R;
 import com.android.launcher3.Utilities;
@@ -101,7 +102,12 @@
 
     public BaseDepthController(Launcher activity) {
         mLauncher = activity;
-        mMaxBlurRadius = activity.getResources().getInteger(R.integer.max_depth_blur_radius);
+        if (Flags.allAppsBlur()) {
+            mMaxBlurRadius = activity.getResources().getDimensionPixelSize(
+                    R.dimen.max_depth_blur_radius_enhanced);
+        } else {
+            mMaxBlurRadius = activity.getResources().getInteger(R.integer.max_depth_blur_radius);
+        }
         mWallpaperManager = activity.getSystemService(WallpaperManager.class);
 
         MultiPropertyFactory<BaseDepthController> depthProperty =
diff --git a/res/values/attrs.xml b/res/values/attrs.xml
index a22f943..1ecac33 100644
--- a/res/values/attrs.xml
+++ b/res/values/attrs.xml
@@ -19,6 +19,7 @@
 
     <!-- Attributes used for launcher theme -->
     <attr name="allAppsScrimColor" format="color" />
+    <attr name="allAppsScrimColorOverBlur" format="color" />
     <attr name="allappsHeaderProtectionColor" format="color" />
     <attr name="allAppsNavBarScrimColor" format="color" />
     <attr name="allAppsTheme" format="reference" />
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 04421c0..39206d3 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -40,6 +40,7 @@
     <style name="LauncherTheme" parent="@style/DynamicColorsBaseLauncherTheme">
         <item name="android:textColorSecondary">#DE000000</item>
         <item name="allAppsScrimColor">@color/materialColorSurfaceDim</item>
+        <item name="allAppsScrimColorOverBlur">#33000000</item>
         <item name="allappsHeaderProtectionColor">@color/materialColorSurfaceContainerHighest</item>
         <item name="allAppsNavBarScrimColor">#66FFFFFF</item>
         <item name="popupColorPrimary">@color/popup_color_primary_light</item>
@@ -114,6 +115,7 @@
         <item name="android:colorControlHighlight">#19FFFFFF</item>
         <item name="android:colorPrimary">#FF212121</item>
         <item name="allAppsScrimColor">@color/materialColorSurfaceDim</item>
+        <item name="allAppsScrimColorOverBlur">#52000000</item>
         <item name="allappsHeaderProtectionColor">@color/materialColorSurfaceContainerLow</item>
         <item name="allAppsNavBarScrimColor">#80000000</item>
         <item name="popupColorPrimary">@color/popup_color_primary_dark</item>
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index c85ca49..9c4d5ba 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -508,9 +508,11 @@
 
         bottomSheetOpenDuration = res.getInteger(R.integer.config_bottomSheetOpenDuration);
         bottomSheetCloseDuration = res.getInteger(R.integer.config_bottomSheetCloseDuration);
-        if (isTablet) {
+        if (shouldShowAllAppsOnSheet()) {
             bottomSheetWorkspaceScale = workspaceContentScale;
-            if (isMultiDisplay) {
+            if (Flags.allAppsBlur()) {
+                bottomSheetDepth = 2f;
+            } else if (isMultiDisplay) {
                 // TODO(b/259893832): Revert to use maxWallpaperScale to calculate bottomSheetDepth
                 // when screen recorder bug is fixed.
                 if (enableScalingRevealHomeAnimation()) {
diff --git a/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java b/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java
index fafa60b..f60896e 100644
--- a/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java
@@ -181,6 +181,7 @@
     private ScrimView mScrimView;
     private int mHeaderColor;
     private int mBottomSheetBackgroundColor;
+    private float mBottomSheetBackgroundAlpha = 1f;
     private int mTabsProtectionAlpha;
     @Nullable private AllAppsTransitionController mAllAppsTransitionController;
 
@@ -311,7 +312,17 @@
                 0,
                 0 // Bottom left
         };
-        mBottomSheetBackgroundColor = getContext().getColor(R.color.materialColorSurfaceDim);
+        if (Flags.allAppsBlur()) {
+            int resId = Utilities.isDarkTheme(getContext())
+                    ? android.R.color.system_accent1_800 : android.R.color.system_accent1_100;
+            int layerAbove = ColorUtils.setAlphaComponent(getResources().getColor(resId, null),
+                    (int) (0.4f * 255));
+            int layerBelow = ColorUtils.setAlphaComponent(Color.WHITE, (int) (0.1f * 255));
+            mBottomSheetBackgroundColor = ColorUtils.compositeColors(layerAbove, layerBelow);
+        } else {
+            mBottomSheetBackgroundColor = getContext().getColor(R.color.materialColorSurfaceDim);
+        }
+        mBottomSheetBackgroundAlpha = Color.alpha(mBottomSheetBackgroundColor) / 255.0f;
         updateBackgroundVisibility(mActivityContext.getDeviceProfile());
         mSearchUiManager.initializeSearch(this);
     }
@@ -1152,7 +1163,7 @@
 
         if (!grid.isVerticalBarLayout() || FeatureFlags.enableResponsiveWorkspace()) {
             int topPadding = grid.allAppsPadding.top;
-            if (isSearchBarFloating() && !grid.isTablet) {
+            if (isSearchBarFloating() && !grid.shouldShowAllAppsOnSheet()) {
                 topPadding += getResources().getDimensionPixelSize(
                         R.dimen.all_apps_additional_top_padding_floating_search);
             }
@@ -1401,7 +1412,7 @@
         // Draw full background panel for tablets.
         if (hasBottomSheet) {
             mHeaderPaint.setColor(mBottomSheetBackgroundColor);
-            mHeaderPaint.setAlpha(255);
+            mHeaderPaint.setAlpha((int) (mBottomSheetBackgroundAlpha * 255));
 
             mTmpRectF.set(
                     leftWithScale,
@@ -1424,6 +1435,10 @@
             return;
         }
 
+        if (hasBottomSheet) {
+            mHeaderPaint.setAlpha((int) (mHeaderPaint.getAlpha() * mBottomSheetBackgroundAlpha));
+        }
+
         // Draw header on background panel
         final float headerBottomNoScale =
                 getHeaderBottom() + getVisibleContainerView().getPaddingTop();
@@ -1455,7 +1470,11 @@
                 mHeaderPaint.setColor(Color.BLUE);
                 mHeaderPaint.setAlpha(255);
             } else {
-                mHeaderPaint.setAlpha((int) (getAlpha() * mTabsProtectionAlpha));
+                float tabAlpha = getAlpha() * mTabsProtectionAlpha;
+                if (hasBottomSheet) {
+                    tabAlpha *= mBottomSheetBackgroundAlpha;
+                }
+                mHeaderPaint.setAlpha((int) tabAlpha);
             }
             float left = 0f;
             float right = canvas.getWidth();
@@ -1507,7 +1526,7 @@
     public int getHeaderBottom() {
         int bottom = (int) getTranslationY() + mHeader.getClipTop();
         if (isSearchBarFloating()) {
-            if (mActivityContext.getDeviceProfile().isTablet) {
+            if (mActivityContext.getDeviceProfile().shouldShowAllAppsOnSheet()) {
                 return bottom + mBottomSheetBackground.getTop();
             }
             return bottom;
diff --git a/src/com/android/launcher3/allapps/AllAppsTransitionController.java b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
index 4cc31d2..350f763 100644
--- a/src/com/android/launcher3/allapps/AllAppsTransitionController.java
+++ b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
@@ -290,7 +290,8 @@
     private void onScaleProgressChanged() {
         final float scaleProgress = mAllAppScale.value;
         SCALE_PROPERTY.set(mLauncher.getAppsView(), scaleProgress);
-        if (!mLauncher.getAppsView().isSearching() || !mLauncher.getDeviceProfile().isTablet) {
+        if (!mLauncher.getAppsView().isSearching()
+                || !mLauncher.getDeviceProfile().shouldShowAllAppsOnSheet()) {
             mLauncher.getScrimView().setScrimHeaderScale(scaleProgress);
         }
 
diff --git a/src/com/android/launcher3/touch/AllAppsSwipeController.java b/src/com/android/launcher3/touch/AllAppsSwipeController.java
index 2cc4909..f86fd6a 100644
--- a/src/com/android/launcher3/touch/AllAppsSwipeController.java
+++ b/src/com/android/launcher3/touch/AllAppsSwipeController.java
@@ -22,6 +22,7 @@
 import static com.android.app.animation.Interpolators.FINAL_FRAME;
 import static com.android.app.animation.Interpolators.INSTANT;
 import static com.android.app.animation.Interpolators.LINEAR;
+import static com.android.app.animation.Interpolators.clampToProgress;
 import static com.android.launcher3.LauncherState.ALL_APPS;
 import static com.android.launcher3.LauncherState.NORMAL;
 import static com.android.launcher3.states.StateAnimationConfig.ANIM_ALL_APPS_FADE;
@@ -39,6 +40,7 @@
 
 import com.android.app.animation.Interpolators;
 import com.android.launcher3.AbstractFloatingView;
+import com.android.launcher3.Flags;
 import com.android.launcher3.Launcher;
 import com.android.launcher3.LauncherState;
 import com.android.launcher3.states.StateAnimationConfig;
@@ -53,10 +55,10 @@
     private static final float ALL_APPS_SCRIM_VISIBLE_THRESHOLD = 0.1f;
     private static final float ALL_APPS_STAGGERED_FADE_THRESHOLD = 0.5f;
 
-    public static final Interpolator ALL_APPS_SCRIM_RESPONDER =
+    private static final Interpolator ALL_APPS_SCRIM_RESPONDER =
             Interpolators.clampToProgress(
                     LINEAR, ALL_APPS_SCRIM_VISIBLE_THRESHOLD, ALL_APPS_STAGGERED_FADE_THRESHOLD);
-    public static final Interpolator ALL_APPS_CLAMPING_RESPONDER =
+    private static final Interpolator ALL_APPS_CLAMPING_RESPONDER =
             Interpolators.clampToProgress(
                     LINEAR,
                     1 - ALL_APPS_CONTENT_FADE_MAX_CLAMPING_THRESHOLD,
@@ -207,7 +209,16 @@
             }
             config.setInterpolator(ANIM_WORKSPACE_SCALE, DECELERATED_EASE);
             config.setInterpolator(ANIM_DEPTH, DECELERATED_EASE);
-            if (launcher.getDeviceProfile().isPhone) {
+            if (Flags.allAppsBlur()) {
+                if (!config.isUserControlled()) {
+                    config.setInterpolator(ANIM_DEPTH, EMPHASIZED_DECELERATE);
+                }
+                config.setInterpolator(ANIM_WORKSPACE_FADE,
+                        clampToProgress(LINEAR, 1 - ALL_APPS_SCRIM_VISIBLE_THRESHOLD, 1));
+                config.setInterpolator(ANIM_HOTSEAT_FADE,
+                        clampToProgress(LINEAR, 1 - ALL_APPS_SCRIM_VISIBLE_THRESHOLD, 1));
+            } else if (launcher.getDeviceProfile().isPhone) {
+                // On phones without blur, reveal the workspace and hotseat when leaving All Apps.
                 config.setInterpolator(ANIM_WORKSPACE_FADE, INSTANT);
                 config.setInterpolator(ANIM_HOTSEAT_FADE, INSTANT);
                 config.animFlags |= StateAnimationConfig.SKIP_DEPTH_CONTROLLER;
@@ -253,7 +264,14 @@
             }
             config.setInterpolator(ANIM_WORKSPACE_SCALE, DECELERATED_EASE);
             config.setInterpolator(ANIM_DEPTH, DECELERATED_EASE);
-            if (launcher.getDeviceProfile().isPhone) {
+            if (Flags.allAppsBlur()) {
+                config.setInterpolator(ANIM_DEPTH, LINEAR);
+                config.setInterpolator(ANIM_WORKSPACE_FADE,
+                        clampToProgress(LINEAR, 0, ALL_APPS_SCRIM_VISIBLE_THRESHOLD));
+                config.setInterpolator(ANIM_HOTSEAT_FADE,
+                        clampToProgress(LINEAR, 0, ALL_APPS_SCRIM_VISIBLE_THRESHOLD));
+            } else if (launcher.getDeviceProfile().isPhone) {
+                // On phones without blur, hide the workspace and hotseat when entering All Apps.
                 config.setInterpolator(ANIM_WORKSPACE_FADE, FINAL_FRAME);
                 config.setInterpolator(ANIM_HOTSEAT_FADE, FINAL_FRAME);
                 config.animFlags |= StateAnimationConfig.SKIP_DEPTH_CONTROLLER;
diff --git a/src/com/android/launcher3/touch/WorkspaceTouchListener.java b/src/com/android/launcher3/touch/WorkspaceTouchListener.java
index d72e6f9..576f176 100644
--- a/src/com/android/launcher3/touch/WorkspaceTouchListener.java
+++ b/src/com/android/launcher3/touch/WorkspaceTouchListener.java
@@ -131,7 +131,7 @@
         }
 
         boolean isInAllAppsBottomSheet = mLauncher.isInState(ALL_APPS)
-                && mLauncher.getDeviceProfile().isTablet;
+                && mLauncher.getDeviceProfile().shouldShowAllAppsOnSheet();
 
         final boolean result;
         if (mLongPressState == STATE_COMPLETED) {
diff --git a/src/com/android/launcher3/views/ScrimView.java b/src/com/android/launcher3/views/ScrimView.java
index ce58de1..ec71f31 100644
--- a/src/com/android/launcher3/views/ScrimView.java
+++ b/src/com/android/launcher3/views/ScrimView.java
@@ -54,8 +54,7 @@
     }
 
     @Override
-    public void setInsets(Rect insets) {
-    }
+    public void setInsets(Rect insets) {}
 
     @Override
     public boolean hasOverlappingRendering() {
diff --git a/tests/assets/dumpTests/DeviceProfileDumpTest/phonePortrait.txt b/tests/assets/dumpTests/DeviceProfileDumpTest/phonePortrait.txt
index a13d63b..6a0d774 100644
--- a/tests/assets/dumpTests/DeviceProfileDumpTest/phonePortrait.txt
+++ b/tests/assets/dumpTests/DeviceProfileDumpTest/phonePortrait.txt
@@ -53,7 +53,7 @@
 	bottomSheetTopPadding: 146.0px (55.61905dp)
 	bottomSheetOpenDuration: 267
 	bottomSheetCloseDuration: 267
-	bottomSheetWorkspaceScale: 1.0
+	bottomSheetWorkspaceScale: 0.97
 	bottomSheetDepth: 0.0
 	allAppsShiftRange: 2400.0px (914.2857dp)
 	allAppsOpenDuration: 600
diff --git a/tests/assets/dumpTests/DeviceProfileDumpTest/phonePortrait3Button.txt b/tests/assets/dumpTests/DeviceProfileDumpTest/phonePortrait3Button.txt
index 3c24885..9e2397c 100644
--- a/tests/assets/dumpTests/DeviceProfileDumpTest/phonePortrait3Button.txt
+++ b/tests/assets/dumpTests/DeviceProfileDumpTest/phonePortrait3Button.txt
@@ -53,7 +53,7 @@
 	bottomSheetTopPadding: 146.0px (55.61905dp)
 	bottomSheetOpenDuration: 267
 	bottomSheetCloseDuration: 267
-	bottomSheetWorkspaceScale: 1.0
+	bottomSheetWorkspaceScale: 0.97
 	bottomSheetDepth: 0.0
 	allAppsShiftRange: 2400.0px (914.2857dp)
 	allAppsOpenDuration: 600
diff --git a/tests/assets/dumpTests/DeviceProfileDumpTest/phoneVerticalBar.txt b/tests/assets/dumpTests/DeviceProfileDumpTest/phoneVerticalBar.txt
index 5e06513..f25ab42 100644
--- a/tests/assets/dumpTests/DeviceProfileDumpTest/phoneVerticalBar.txt
+++ b/tests/assets/dumpTests/DeviceProfileDumpTest/phoneVerticalBar.txt
@@ -53,7 +53,7 @@
 	bottomSheetTopPadding: 114.0px (43.42857dp)
 	bottomSheetOpenDuration: 267
 	bottomSheetCloseDuration: 267
-	bottomSheetWorkspaceScale: 1.0
+	bottomSheetWorkspaceScale: 0.97
 	bottomSheetDepth: 0.0
 	allAppsShiftRange: 1080.0px (411.42856dp)
 	allAppsOpenDuration: 600
diff --git a/tests/assets/dumpTests/DeviceProfileDumpTest/phoneVerticalBar3Button.txt b/tests/assets/dumpTests/DeviceProfileDumpTest/phoneVerticalBar3Button.txt
index d107988..053dd62 100644
--- a/tests/assets/dumpTests/DeviceProfileDumpTest/phoneVerticalBar3Button.txt
+++ b/tests/assets/dumpTests/DeviceProfileDumpTest/phoneVerticalBar3Button.txt
@@ -53,7 +53,7 @@
 	bottomSheetTopPadding: 114.0px (43.42857dp)
 	bottomSheetOpenDuration: 267
 	bottomSheetCloseDuration: 267
-	bottomSheetWorkspaceScale: 1.0
+	bottomSheetWorkspaceScale: 0.97
 	bottomSheetDepth: 0.0
 	allAppsShiftRange: 1080.0px (411.42856dp)
 	allAppsOpenDuration: 600