Merge "Hyphenate options in home screen long-press menu"
diff --git a/quickstep/res/layout/taskbar.xml b/quickstep/res/layout/taskbar.xml
index 94d7d2b..3b1d217 100644
--- a/quickstep/res/layout/taskbar.xml
+++ b/quickstep/res/layout/taskbar.xml
@@ -30,6 +30,11 @@
         android:layout_gravity="bottom"
         android:clipChildren="false" />
 
+    <com.android.launcher3.taskbar.TaskbarScrimView
+        android:id="@+id/taskbar_scrim"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"/>
+
     <FrameLayout
         android:id="@+id/navbuttons_view"
         android:layout_width="match_parent"
diff --git a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
index 16dcf46..5a4b9f0 100644
--- a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
@@ -18,6 +18,7 @@
 import static com.android.launcher3.LauncherState.HOTSEAT_ICONS;
 import static com.android.launcher3.taskbar.TaskbarStashController.FLAG_IN_APP;
 import static com.android.launcher3.taskbar.TaskbarStashController.FLAG_IN_STASHED_LAUNCHER_STATE;
+import static com.android.launcher3.taskbar.TaskbarStashController.FLAG_STASHED_IN_APP_SETUP;
 import static com.android.launcher3.taskbar.TaskbarViewController.ALPHA_INDEX_HOME;
 
 import android.animation.Animator;
@@ -128,7 +129,7 @@
         mLauncher.setTaskbarUIController(this);
         mKeyguardController = taskbarControllers.taskbarKeyguardController;
 
-        onLauncherResumedOrPaused(mLauncher.hasBeenResumed());
+        onLauncherResumedOrPaused(mLauncher.hasBeenResumed(), true /* fromInit */);
         mIconAlignmentForResumedState.finishAnimation();
         onIconAlignmentRatioChanged();
 
@@ -170,6 +171,10 @@
      * Should be called from onResume() and onPause(), and animates the Taskbar accordingly.
      */
     public void onLauncherResumedOrPaused(boolean isResumed) {
+        onLauncherResumedOrPaused(isResumed, false /* fromInit */);
+    }
+
+    private void onLauncherResumedOrPaused(boolean isResumed, boolean fromInit) {
         if (mKeyguardController.isScreenOff()) {
             if (!isResumed) {
                 return;
@@ -180,6 +185,11 @@
         }
 
         long duration = QuickstepTransitionManager.CONTENT_ALPHA_DURATION;
+        if (fromInit) {
+            // Since we are creating the starting state, we don't have a state to animate from, so
+            // set our state immediately.
+            duration = 0;
+        }
         ObjectAnimator anim = mIconAlignmentForResumedState.animateToValue(
                 getCurrentIconAlignmentRatio(), isResumed ? 1 : 0)
                 .setDuration(duration);
@@ -191,6 +201,10 @@
 
         TaskbarStashController stashController = mControllers.taskbarStashController;
         stashController.updateStateForFlag(FLAG_IN_APP, !isResumed);
+        if (isResumed) {
+            // Launcher is resumed, meaning setup must be finished.
+            stashController.updateStateForFlag(FLAG_STASHED_IN_APP_SETUP, false);
+        }
         stashController.applyState(duration);
     }
 
diff --git a/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java b/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java
index 67bec49..f2ca711 100644
--- a/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java
@@ -36,12 +36,14 @@
 import android.annotation.DrawableRes;
 import android.annotation.IdRes;
 import android.annotation.LayoutRes;
+import android.content.res.ColorStateList;
 import android.graphics.Rect;
 import android.graphics.Region;
 import android.graphics.Region.Op;
 import android.graphics.drawable.AnimatedVectorDrawable;
 import android.provider.Settings;
 import android.util.Property;
+import android.view.Gravity;
 import android.view.View;
 import android.view.View.OnClickListener;
 import android.view.View.OnHoverListener;
@@ -58,6 +60,7 @@
 import com.android.launcher3.taskbar.contextual.RotationButtonController;
 import com.android.launcher3.util.MultiValueAlpha;
 import com.android.launcher3.util.SettingsCache;
+import com.android.launcher3.util.Themes;
 import com.android.quickstep.AnimatedFloat;
 
 import java.util.ArrayList;
@@ -148,12 +151,33 @@
                 flags -> (flags & FLAG_KEYGUARD_VISIBLE) == 0, AnimatedFloat.VALUE, 1, 0));
 
         // Force nav buttons (specifically back button) to be visible during setup wizard.
-        boolean areButtonsForcedVisible = !SettingsCache.INSTANCE.get(mContext).getValue(
+        boolean isInSetup = !SettingsCache.INSTANCE.get(mContext).getValue(
                 Settings.Secure.getUriFor(Settings.Secure.USER_SETUP_COMPLETE), 0);
-        if (isThreeButtonNav || areButtonsForcedVisible) {
+        if (isThreeButtonNav || isInSetup) {
             initButtons(mNavButtonContainer, mEndContextualContainer,
                     mControllers.navButtonController);
 
+            if (isInSetup) {
+                // Since setup wizard only has back button enabled, it looks strange to be
+                // end-aligned, so start-align instead.
+                FrameLayout.LayoutParams navButtonsLayoutParams = (FrameLayout.LayoutParams)
+                        mNavButtonContainer.getLayoutParams();
+                navButtonsLayoutParams.setMarginStart(navButtonsLayoutParams.getMarginEnd());
+                navButtonsLayoutParams.setMarginEnd(0);
+                navButtonsLayoutParams.gravity = Gravity.START;
+                mNavButtonContainer.requestLayout();
+
+                if (!isThreeButtonNav) {
+                    // Tint all the nav buttons since there's no taskbar background in SUW.
+                    for (int i = 0; i < mNavButtonContainer.getChildCount(); i++) {
+                        if (!(mNavButtonContainer.getChildAt(i) instanceof ImageView)) continue;
+                        ImageView button = (ImageView) mNavButtonContainer.getChildAt(i);
+                        button.setImageTintList(ColorStateList.valueOf(Themes.getAttrColor(
+                                button.getContext(), android.R.attr.textColorPrimary)));
+                    }
+                }
+            }
+
             // Animate taskbar background when IME shows
             mPropertyHolders.add(new StatePropertyHolder(
                     mControllers.taskbarDragLayerController.getNavbarBackgroundAlpha(),
@@ -287,6 +311,13 @@
     }
 
     /**
+     * Returns true if the home button is disabled
+     */
+    public boolean isHomeDisabled() {
+        return (mState & FLAG_DISABLE_HOME) != 0;
+    }
+
+    /**
      * Returns true if the recents (overview) button is disabled
      */
     public boolean isRecentsDisabled() {
diff --git a/quickstep/src/com/android/launcher3/taskbar/StashedHandleViewController.java b/quickstep/src/com/android/launcher3/taskbar/StashedHandleViewController.java
index 10da826..2c80f06 100644
--- a/quickstep/src/com/android/launcher3/taskbar/StashedHandleViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/StashedHandleViewController.java
@@ -30,6 +30,7 @@
 import com.android.launcher3.anim.RevealOutlineAnimation;
 import com.android.launcher3.anim.RoundedRectRevealOutlineProvider;
 import com.android.launcher3.util.Executors;
+import com.android.launcher3.util.MultiValueAlpha;
 import com.android.quickstep.AnimatedFloat;
 import com.android.systemui.shared.navigationbar.RegionSamplingHelper;
 
@@ -38,6 +39,10 @@
  */
 public class StashedHandleViewController {
 
+    public static final int ALPHA_INDEX_STASHED = 0;
+    public static final int ALPHA_INDEX_HOME_DISABLED = 1;
+    private static final int NUM_ALPHA_CHANNELS = 2;
+
     /**
      * The SharedPreferences key for whether the stashed handle region is dark.
      */
@@ -50,8 +55,7 @@
     private final int mStashedHandleWidth;
     private final int mStashedHandleHeight;
     private final RegionSamplingHelper mRegionSamplingHelper;
-    private final AnimatedFloat mTaskbarStashedHandleAlpha = new AnimatedFloat(
-            this::updateStashedHandleAlpha);
+    private final MultiValueAlpha mTaskbarStashedHandleAlpha;
     private final AnimatedFloat mTaskbarStashedHandleHintScale = new AnimatedFloat(
             this::updateStashedHandleHintScale);
 
@@ -69,6 +73,8 @@
         mActivity = activity;
         mPrefs = Utilities.getPrefs(mActivity);
         mStashedHandleView = stashedHandleView;
+        mTaskbarStashedHandleAlpha = new MultiValueAlpha(mStashedHandleView, NUM_ALPHA_CHANNELS);
+        mTaskbarStashedHandleAlpha.setUpdateVisibility(true);
         mStashedHandleView.updateHandleColor(
                 mPrefs.getBoolean(SHARED_PREFS_STASHED_HANDLE_REGION_DARK_KEY, false),
                 false /* animate */);
@@ -96,7 +102,7 @@
         mControllers = controllers;
         mStashedHandleView.getLayoutParams().height = mActivity.getDeviceProfile().taskbarSize;
 
-        updateStashedHandleAlpha();
+        mTaskbarStashedHandleAlpha.getProperty(ALPHA_INDEX_STASHED).setValue(0);
         mTaskbarStashedHandleHintScale.updateValue(1f);
 
         final int stashedTaskbarHeight = mControllers.taskbarStashController.getStashedHeight();
@@ -129,7 +135,7 @@
         mRegionSamplingHelper.stopAndDestroy();
     }
 
-    public AnimatedFloat getStashedHandleAlpha() {
+    public MultiValueAlpha getStashedHandleAlpha() {
         return mTaskbarStashedHandleAlpha;
     }
 
@@ -163,12 +169,20 @@
         }
     }
 
-    protected void updateStashedHandleAlpha() {
-        mStashedHandleView.setAlpha(mTaskbarStashedHandleAlpha.value);
-    }
-
     protected void updateStashedHandleHintScale() {
         mStashedHandleView.setScaleX(mTaskbarStashedHandleHintScale.value);
         mStashedHandleView.setScaleY(mTaskbarStashedHandleHintScale.value);
     }
+
+    /**
+     * Should be called when the home button is disabled, so we can hide this handle as well.
+     */
+    public void setIsHomeButtonDisabled(boolean homeDisabled) {
+        mTaskbarStashedHandleAlpha.getProperty(ALPHA_INDEX_HOME_DISABLED).setValue(
+                homeDisabled ? 0 : 1);
+    }
+
+    public boolean isStashedHandleVisible() {
+        return mStashedHandleView.getVisibility() == View.VISIBLE;
+    }
 }
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
index a8c94ce..973c52b 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
@@ -125,6 +125,7 @@
         mDragLayer = (TaskbarDragLayer) mLayoutInflater.inflate(
                 R.layout.taskbar, null, false);
         TaskbarView taskbarView = mDragLayer.findViewById(R.id.taskbar_view);
+        TaskbarScrimView taskbarScrimView = mDragLayer.findViewById(R.id.taskbar_scrim);
         FrameLayout navButtonsView = mDragLayer.findViewById(R.id.navbuttons_view);
         StashedHandleView stashedHandleView = mDragLayer.findViewById(R.id.stashed_handle);
 
@@ -145,6 +146,7 @@
                         R.color.popup_color_primary_light),
                 new TaskbarDragLayerController(this, mDragLayer),
                 new TaskbarViewController(this, taskbarView),
+                new TaskbarScrimViewController(this, taskbarScrimView),
                 new TaskbarUnfoldAnimationController(unfoldTransitionProgressProvider,
                         mWindowManager),
                 new TaskbarKeyguardController(this),
@@ -321,8 +323,11 @@
                 panelExpanded || inSettings);
         mControllers.taskbarViewController.setRecentsButtonDisabled(
                 mControllers.navbarButtonsViewController.isRecentsDisabled());
+        mControllers.stashedHandleViewController.setIsHomeButtonDisabled(
+                mControllers.navbarButtonsViewController.isHomeDisabled());
         mControllers.taskbarKeyguardController.updateStateForSysuiFlags(systemUiStateFlags);
         mControllers.taskbarStashController.updateStateForSysuiFlags(systemUiStateFlags);
+        mControllers.taskbarScrimViewController.updateStateForSysuiFlags(systemUiStateFlags);
     }
 
     public void onRotationProposal(int rotation, boolean isValid) {
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java
index e49c6ae..e13f849 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java
@@ -30,6 +30,7 @@
     public final NavbarButtonsViewController navbarButtonsViewController;
     public final RotationButtonController rotationButtonController;
     public final TaskbarDragLayerController taskbarDragLayerController;
+    public final TaskbarScrimViewController taskbarScrimViewController;
     public final TaskbarViewController taskbarViewController;
     public final TaskbarUnfoldAnimationController taskbarUnfoldAnimationController;
     public final TaskbarKeyguardController taskbarKeyguardController;
@@ -47,6 +48,7 @@
             RotationButtonController rotationButtonController,
             TaskbarDragLayerController taskbarDragLayerController,
             TaskbarViewController taskbarViewController,
+            TaskbarScrimViewController taskbarScrimViewController,
             TaskbarUnfoldAnimationController taskbarUnfoldAnimationController,
             TaskbarKeyguardController taskbarKeyguardController,
             StashedHandleViewController stashedHandleViewController,
@@ -59,6 +61,7 @@
         this.rotationButtonController = rotationButtonController;
         this.taskbarDragLayerController = taskbarDragLayerController;
         this.taskbarViewController = taskbarViewController;
+        this.taskbarScrimViewController = taskbarScrimViewController;
         this.taskbarUnfoldAnimationController = taskbarUnfoldAnimationController;
         this.taskbarKeyguardController = taskbarKeyguardController;
         this.stashedHandleViewController = stashedHandleViewController;
@@ -78,6 +81,7 @@
         }
         taskbarDragLayerController.init(this);
         taskbarViewController.init(this);
+        taskbarScrimViewController.init(this);
         taskbarUnfoldAnimationController.init(this);
         taskbarKeyguardController.init(navbarButtonsViewController);
         stashedHandleViewController.init(this);
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarScrimView.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarScrimView.java
new file mode 100644
index 0000000..94a3307
--- /dev/null
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarScrimView.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2021 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.taskbar;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.Path;
+import android.util.AttributeSet;
+import android.view.View;
+
+/**
+ * View that handles scrimming the taskbar and the inverted corners it draws. The scrim is used
+ * when bubbles is expanded.
+ */
+public class TaskbarScrimView extends View {
+    private final Paint mTaskbarScrimPaint;
+    private final Path mInvertedLeftCornerPath, mInvertedRightCornerPath;
+
+    private boolean mShowScrim;
+    private float mLeftCornerRadius, mRightCornerRadius;
+    private float mBackgroundHeight;
+
+    public TaskbarScrimView(Context context) {
+        this(context, null);
+    }
+
+    public TaskbarScrimView(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public TaskbarScrimView(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public TaskbarScrimView(Context context, AttributeSet attrs, int defStyleAttr,
+            int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+
+        mTaskbarScrimPaint = new Paint();
+        mTaskbarScrimPaint.setColor(getResources().getColor(android.R.color.system_neutral1_1000));
+        mTaskbarScrimPaint.setFlags(Paint.ANTI_ALIAS_FLAG);
+        mTaskbarScrimPaint.setStyle(Paint.Style.FILL);
+
+        mInvertedLeftCornerPath = new Path();
+        mInvertedRightCornerPath = new Path();
+    }
+
+    @Override
+    protected void onDraw(Canvas canvas) {
+        super.onDraw(canvas);
+
+        if (mShowScrim) {
+            canvas.save();
+            canvas.translate(0, canvas.getHeight() - mBackgroundHeight);
+
+            // Scrim the taskbar itself.
+            canvas.drawRect(0, 0, canvas.getWidth(), mBackgroundHeight, mTaskbarScrimPaint);
+
+            // Scrim the inverted rounded corners above the taskbar.
+            canvas.translate(0, -mLeftCornerRadius);
+            canvas.drawPath(mInvertedLeftCornerPath, mTaskbarScrimPaint);
+            canvas.translate(0, mLeftCornerRadius);
+            canvas.translate(canvas.getWidth() - mRightCornerRadius, -mRightCornerRadius);
+            canvas.drawPath(mInvertedRightCornerPath, mTaskbarScrimPaint);
+
+            canvas.restore();
+        }
+    }
+
+    /**
+     * Sets the height of the taskbar background.
+     * @param height the height of the background.
+     */
+    protected void setBackgroundHeight(float height) {
+        mBackgroundHeight = height;
+        if (mShowScrim) {
+            invalidate();
+        }
+    }
+
+    /**
+     * Sets the alpha of the taskbar scrim.
+     * @param alpha the alpha of the scrim.
+     */
+    protected void setScrimAlpha(float alpha) {
+        mShowScrim = alpha > 0f;
+        mTaskbarScrimPaint.setAlpha((int) (alpha * 255));
+        invalidate();
+    }
+
+    /**
+     * Sets the radius of the left and right corners above the taskbar.
+     * @param leftCornerRadius the radius of the left corner.
+     * @param rightCornerRadius the radius of the right corner.
+     */
+    protected void setCornerSizes(float leftCornerRadius, float rightCornerRadius) {
+        mLeftCornerRadius = leftCornerRadius;
+        mRightCornerRadius = rightCornerRadius;
+
+        Path square = new Path();
+        square.addRect(0, 0, mLeftCornerRadius, mLeftCornerRadius, Path.Direction.CW);
+        Path circle = new Path();
+        circle.addCircle(mLeftCornerRadius, 0, mLeftCornerRadius, Path.Direction.CW);
+        mInvertedLeftCornerPath.op(square, circle, Path.Op.DIFFERENCE);
+        square.reset();
+        square.addRect(0, 0, mRightCornerRadius, mRightCornerRadius, Path.Direction.CW);
+        circle.reset();
+        circle.addCircle(0, 0, mRightCornerRadius, Path.Direction.CW);
+        mInvertedRightCornerPath.op(square, circle, Path.Op.DIFFERENCE);
+
+        if (mShowScrim) {
+            invalidate();
+        }
+    }
+}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarScrimViewController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarScrimViewController.java
new file mode 100644
index 0000000..e7e55ef
--- /dev/null
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarScrimViewController.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2021 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.taskbar;
+
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BUBBLES_EXPANDED;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BUBBLES_MANAGE_MENU_EXPANDED;
+
+import android.animation.ObjectAnimator;
+import android.view.animation.Interpolator;
+import android.view.animation.PathInterpolator;
+
+import com.android.quickstep.AnimatedFloat;
+import com.android.quickstep.SystemUiProxy;
+
+/**
+ * Handles properties/data collection, and passes the results to {@link TaskbarScrimView} to render.
+ */
+public class TaskbarScrimViewController {
+
+    private static final float SCRIM_ALPHA = 0.6f;
+
+    private static final Interpolator SCRIM_ALPHA_IN = new PathInterpolator(0.4f, 0f, 1f, 1f);
+    private static final Interpolator SCRIM_ALPHA_OUT = new PathInterpolator(0f, 0f, 0.8f, 1f);
+
+    private final TaskbarActivityContext mActivity;
+    private final TaskbarScrimView mScrimView;
+
+    // Alpha property for the scrim.
+    private final AnimatedFloat mScrimAlpha = new AnimatedFloat(this::updateScrimAlpha);
+
+    // Initialized in init.
+    private TaskbarControllers mControllers;
+
+    public TaskbarScrimViewController(TaskbarActivityContext activity, TaskbarScrimView scrimView) {
+        mActivity = activity;
+        mScrimView = scrimView;
+        mScrimView.setCornerSizes(mActivity.getLeftCornerRadius(),
+                mActivity.getRightCornerRadius());
+        mScrimView.setBackgroundHeight(mActivity.getDeviceProfile().taskbarSize);
+    }
+
+    /**
+     * Initializes the controller
+     */
+    public void init(TaskbarControllers controllers) {
+        mControllers = controllers;
+    }
+
+    /**
+     * Updates the scrim state based on the flags.
+     */
+    public void updateStateForSysuiFlags(int stateFlags) {
+        final boolean bubblesExpanded = (stateFlags & SYSUI_STATE_BUBBLES_EXPANDED) != 0;
+        final boolean manageMenuExpanded =
+                (stateFlags & SYSUI_STATE_BUBBLES_MANAGE_MENU_EXPANDED) != 0;
+        final boolean showScrim = !mControllers.navbarButtonsViewController.isImeVisible()
+                && bubblesExpanded && mControllers.taskbarStashController.isInAppAndNotStashed();
+        final float scrimAlpha = manageMenuExpanded
+                // When manage menu shows there's the first scrim and second scrim so figure out
+                // what the total transparency would be.
+                ? (SCRIM_ALPHA + (SCRIM_ALPHA * (1 - SCRIM_ALPHA)))
+                : showScrim ? SCRIM_ALPHA : 0;
+        showScrim(showScrim, scrimAlpha);
+    }
+
+    private void showScrim(boolean showScrim, float alpha) {
+        mScrimView.setOnClickListener(showScrim ? (view) -> onClick() : null);
+        mScrimView.setClickable(showScrim);
+        ObjectAnimator anim = mScrimAlpha.animateToValue(showScrim ? alpha : 0);
+        anim.setInterpolator(showScrim ? SCRIM_ALPHA_IN : SCRIM_ALPHA_OUT);
+        anim.start();
+    }
+
+    private void updateScrimAlpha() {
+        mScrimView.setScrimAlpha(mScrimAlpha.value);
+    }
+
+    private void onClick() {
+        SystemUiProxy.INSTANCE.get(mActivity).onBackPressed();
+    }
+}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
index 6d6f0f2..56c6f61 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
@@ -25,15 +25,21 @@
 import android.animation.AnimatorListenerAdapter;
 import android.animation.AnimatorSet;
 import android.annotation.Nullable;
+import android.app.ActivityManager;
+import android.content.ComponentName;
 import android.content.SharedPreferences;
 import android.content.res.Resources;
+import android.provider.Settings;
 import android.view.ViewConfiguration;
 
 import com.android.launcher3.R;
 import com.android.launcher3.Utilities;
 import com.android.launcher3.util.MultiValueAlpha.AlphaProperty;
+import com.android.launcher3.util.SettingsCache;
 import com.android.quickstep.AnimatedFloat;
 import com.android.quickstep.SystemUiProxy;
+import com.android.quickstep.interaction.AllSetActivity;
+import com.android.systemui.shared.system.ActivityManagerWrapper;
 
 import java.util.function.IntPredicate;
 
@@ -47,11 +53,12 @@
     public static final int FLAG_STASHED_IN_APP_MANUAL = 1 << 1; // long press, persisted
     public static final int FLAG_STASHED_IN_APP_PINNED = 1 << 2; // app pinning
     public static final int FLAG_STASHED_IN_APP_EMPTY = 1 << 3; // no hotseat icons
-    public static final int FLAG_IN_STASHED_LAUNCHER_STATE = 1 << 4;
+    public static final int FLAG_STASHED_IN_APP_SETUP = 1 << 4; // setup wizard and AllSetActivity
+    public static final int FLAG_IN_STASHED_LAUNCHER_STATE = 1 << 5;
 
     // If we're in an app and any of these flags are enabled, taskbar should be stashed.
     public static final int FLAGS_STASHED_IN_APP = FLAG_STASHED_IN_APP_MANUAL
-            | FLAG_STASHED_IN_APP_PINNED | FLAG_STASHED_IN_APP_EMPTY;
+            | FLAG_STASHED_IN_APP_PINNED | FLAG_STASHED_IN_APP_EMPTY | FLAG_STASHED_IN_APP_SETUP;
 
     /**
      * How long to stash/unstash when manually invoked via long press.
@@ -103,7 +110,7 @@
     private AnimatedFloat mIconScaleForStash;
     private AnimatedFloat mIconTranslationYForStash;
     // Stashed handle properties.
-    private AnimatedFloat mTaskbarStashedHandleAlpha;
+    private AlphaProperty mTaskbarStashedHandleAlpha;
     private AnimatedFloat mTaskbarStashedHandleHintScale;
 
     /** Whether we are currently visually stashed (might change based on launcher state). */
@@ -143,12 +150,14 @@
 
         StashedHandleViewController stashedHandleController =
                 controllers.stashedHandleViewController;
-        mTaskbarStashedHandleAlpha = stashedHandleController.getStashedHandleAlpha();
+        mTaskbarStashedHandleAlpha = stashedHandleController.getStashedHandleAlpha().getProperty(
+                StashedHandleViewController.ALPHA_INDEX_STASHED);
         mTaskbarStashedHandleHintScale = stashedHandleController.getStashedHandleHintScale();
 
         boolean isManuallyStashedInApp = supportsManualStashing()
                 && mPrefs.getBoolean(SHARED_PREFS_STASHED_KEY, DEFAULT_STASHED_PREF);
         updateStateForFlag(FLAG_STASHED_IN_APP_MANUAL, isManuallyStashedInApp);
+        updateStateForFlag(FLAG_STASHED_IN_APP_SETUP, isInSetup());
         applyState();
 
         SystemUiProxy.INSTANCE.get(mActivity)
@@ -177,6 +186,23 @@
     }
 
     /**
+     * Returns whether we are in Setup Wizard or the corresponding AllSetActivity that follows it.
+     */
+    private boolean isInSetup() {
+        boolean isInSetup = !SettingsCache.INSTANCE.get(mActivity).getValue(
+                Settings.Secure.getUriFor(Settings.Secure.USER_SETUP_COMPLETE), 0);
+        if (isInSetup) {
+            return true;
+        }
+        ActivityManager.RunningTaskInfo runningTask =
+                ActivityManagerWrapper.getInstance().getRunningTask();
+        if (runningTask == null || runningTask.baseActivity == null) {
+            return false;
+        }
+        return runningTask.baseActivity.equals(new ComponentName(mActivity, AllSetActivity.class));
+    }
+
+    /**
      * Returns whether the taskbar is currently visually stashed.
      */
     public boolean isStashed() {
@@ -198,8 +224,21 @@
         return (flags & flagMask) != 0;
     }
 
+
+    /**
+     * Returns whether the taskbar is currently visible and in an app.
+     */
+    public boolean isInAppAndNotStashed() {
+        return !mIsStashed && (mState & FLAG_IN_APP) != 0;
+    }
+
     public int getContentHeight() {
-        return isStashed() ? mStashedHeight : mUnstashedHeight;
+        if (isStashed()) {
+            boolean isAnimating = mAnimator != null && mAnimator.isStarted();
+            return mControllers.stashedHandleViewController.isStashedHandleVisible() || isAnimating
+                    ? mStashedHeight : 0;
+        }
+        return mUnstashedHeight;
     }
 
     public int getStashedHeight() {
diff --git a/quickstep/src/com/android/quickstep/TaskViewUtils.java b/quickstep/src/com/android/quickstep/TaskViewUtils.java
index 284bc03..12b071d 100644
--- a/quickstep/src/com/android/quickstep/TaskViewUtils.java
+++ b/quickstep/src/com/android/quickstep/TaskViewUtils.java
@@ -170,7 +170,7 @@
 
         RemoteTargetHandle[] remoteTargetHandles;
         RemoteTargetHandle[] recentsViewHandles = recentsView.getRemoteTargetHandles();
-        if (v.isRunningTask()) {
+        if (v.isRunningTask() && recentsViewHandles != null) {
             // Re-use existing handles
             remoteTargetHandles = recentsViewHandles;
         } else {
diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java
index 7bf4e8d..a3d9ba7 100644
--- a/src/com/android/launcher3/config/FeatureFlags.java
+++ b/src/com/android/launcher3/config/FeatureFlags.java
@@ -144,7 +144,7 @@
             "ENABLE_OVERVIEW_SELECTIONS", true, "Show Select Mode button in Overview Actions");
 
     public static final BooleanFlag ENABLE_WIDGETS_PICKER_AIAI_SEARCH = new DeviceFlag(
-            "ENABLE_WIDGETS_PICKER_AIAI_SEARCH", false, "Enable AiAi search in the widgets picker");
+            "ENABLE_WIDGETS_PICKER_AIAI_SEARCH", true, "Enable AiAi search in the widgets picker");
 
     public static final BooleanFlag ENABLE_OVERVIEW_SHARING_TO_PEOPLE = getDebugFlag(
             "ENABLE_OVERVIEW_SHARING_TO_PEOPLE", true,
diff --git a/tests/dummy_app/Android.bp b/tests/dummy_app/Android.bp
new file mode 100644
index 0000000..4f83bb7
--- /dev/null
+++ b/tests/dummy_app/Android.bp
@@ -0,0 +1,28 @@
+//
+// Copyright (C) 2021 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 {
+    default_applicable_licenses:   ["packages_apps_Launcher3_license"],
+}
+
+android_app {
+    name: "Aardwolf",
+    srcs: ["src/**/*.java"],
+    sdk_version: "current",
+    dex_preopt: {
+        enabled: false,
+    },
+}
diff --git a/tests/dummy_app/Android.mk b/tests/dummy_app/Android.mk
deleted file mode 100644
index 3472079..0000000
--- a/tests/dummy_app/Android.mk
+++ /dev/null
@@ -1,21 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := samples
-
-# Only compile source java files in this apk.
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_PACKAGE_NAME := Aardwolf
-LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
-LOCAL_LICENSE_CONDITIONS := notice
-LOCAL_NOTICE_FILE  := $(LOCAL_PATH)/../../NOTICE
-
-LOCAL_SDK_VERSION := current
-
-LOCAL_DEX_PREOPT := false
-
-include $(BUILD_PACKAGE)
-
-# Use the following include to make our test apk.
-include $(call all-makefiles-under,$(LOCAL_PATH))