Snap for 7468789 from efa5df380c8087ae7b9d945a2067da6c797da691 to sc-release

Change-Id: I24d17878b0b1a09fafee009238c2bf7c8af1a44a
diff --git a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
index 65df237..31cf51c 100644
--- a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
+++ b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
@@ -34,6 +34,7 @@
 import static com.android.launcher3.anim.Interpolators.DEACCEL_1_7;
 import static com.android.launcher3.anim.Interpolators.EXAGGERATED_EASE;
 import static com.android.launcher3.anim.Interpolators.LINEAR;
+import static com.android.launcher3.config.FeatureFlags.ENABLE_SCRIM_FOR_APP_LAUNCH;
 import static com.android.launcher3.config.FeatureFlags.KEYGUARD_ANIMATION;
 import static com.android.launcher3.config.FeatureFlags.SEPARATE_RECENTS_ACTIVITY;
 import static com.android.launcher3.dragndrop.DragLayer.ALPHA_INDEX_TRANSITIONS;
@@ -508,20 +509,23 @@
                 launcherAnimator.play(scaleAnim);
             });
 
-            int scrimColor = Themes.getAttrColor(mLauncher, R.attr.overviewScrimColor);
-            int scrimColorTrans = ColorUtils.setAlphaComponent(scrimColor, 0);
-            int[] colors = isAppOpening
-                    ? new int[] {scrimColorTrans, scrimColor}
-                    : new int[] {scrimColor, scrimColorTrans};
-            ScrimView scrimView = mLauncher.getScrimView();
-            if (scrimView.getBackground() instanceof ColorDrawable) {
-                scrimView.setBackgroundColor(colors[0]);
+            final boolean scrimEnabled = ENABLE_SCRIM_FOR_APP_LAUNCH.get();
+            if (scrimEnabled) {
+                int scrimColor = Themes.getAttrColor(mLauncher, R.attr.overviewScrimColor);
+                int scrimColorTrans = ColorUtils.setAlphaComponent(scrimColor, 0);
+                int[] colors = isAppOpening
+                        ? new int[]{scrimColorTrans, scrimColor}
+                        : new int[]{scrimColor, scrimColorTrans};
+                ScrimView scrimView = mLauncher.getScrimView();
+                if (scrimView.getBackground() instanceof ColorDrawable) {
+                    scrimView.setBackgroundColor(colors[0]);
 
-                ObjectAnimator scrim = ObjectAnimator.ofArgb(scrimView, VIEW_BACKGROUND_COLOR,
-                        colors);
-                scrim.setDuration(CONTENT_SCRIM_DURATION);
-                scrim.setInterpolator(DEACCEL_1_5);
-                launcherAnimator.play(scrim);
+                    ObjectAnimator scrim = ObjectAnimator.ofArgb(scrimView, VIEW_BACKGROUND_COLOR,
+                            colors);
+                    scrim.setDuration(CONTENT_SCRIM_DURATION);
+                    scrim.setInterpolator(DEACCEL_1_5);
+                    launcherAnimator.play(scrim);
+                }
             }
 
             // Pause page indicator animations as they lead to layer trashing.
@@ -532,7 +536,9 @@
                     SCALE_PROPERTY.set(view, 1f);
                     view.setLayerType(View.LAYER_TYPE_NONE, null);
                 });
-                scrimView.setBackgroundColor(Color.TRANSPARENT);
+                if (scrimEnabled) {
+                    mLauncher.getScrimView().setBackgroundColor(Color.TRANSPARENT);
+                }
                 mLauncher.getWorkspace().getPageIndicator().skipAnimationsToEnd();
             };
         }
diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
index 0ebaea2..4d47ef1 100644
--- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
+++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
@@ -1381,11 +1381,17 @@
 
     /**
      * Cancels any running animation so that the active target can be overriden by a new swipe
-     * handle (in case of quick switch).
+     * handler (in case of quick switch).
      */
     private void cancelCurrentAnimation() {
         mCanceled = true;
         mCurrentShift.cancelAnimation();
+
+        // Cleanup when switching handlers
+        mInputConsumerProxy.unregisterCallback();
+        mActivityInitListener.unregister();
+        ActivityManagerWrapper.getInstance().unregisterTaskStackListener(mActivityRestartListener);
+        mTaskSnapshot = null;
     }
 
     private void invalidateHandler() {
diff --git a/quickstep/tests/src/com/android/quickstep/ViewInflationDuringSwipeUp.java b/quickstep/tests/src/com/android/quickstep/ViewInflationDuringSwipeUp.java
index ea7b7f5..f33abb0 100644
--- a/quickstep/tests/src/com/android/quickstep/ViewInflationDuringSwipeUp.java
+++ b/quickstep/tests/src/com/android/quickstep/ViewInflationDuringSwipeUp.java
@@ -114,6 +114,7 @@
 
     @Test
     @NavigationModeSwitch(mode = ZERO_BUTTON)
+    @Suppress // until b/190618549 is fixed
     public void testSwipeUpFromApp() throws Exception {
         try {
             // Go to overview once so that all views are initialized and cached
diff --git a/res/drawable/ic_corp_off.xml b/res/drawable/ic_corp_off.xml
index 62a9787..117258e 100644
--- a/res/drawable/ic_corp_off.xml
+++ b/res/drawable/ic_corp_off.xml
@@ -1,5 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2020 The Android Open Source Project
+<?xml version="1.0" encoding="utf-8"?><!-- Copyright (C) 2020 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.
@@ -16,10 +15,10 @@
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
     android:width="24dp"
     android:height="24dp"
-    android:viewportWidth="24.0"
-    android:viewportHeight="24.0"
-    android:tint="?android:attr/textColorHint" >
+    android:viewportWidth="24"
+    android:viewportHeight="24"
+    android:tint="?android:attr/textColorHint">
     <path
-        android:pathData="M22 7.95c.05-1.11-.84-2-1.95-1.95H16V3.95c0-1.11-.84-2-1.95-1.95h-4C8.94 1.95 8 2.84 8 3.95v.32l14 14V7.95zM14 6h-4V4h4v2zm7.54 14.28l-7.56-7.56v.01l-1.7-1.7h.01L7.21 5.95 3.25 1.99 1.99 3.27 4.69 6h-.64c-1.11 0-1.99.86-1.99 1.97l-.01 11.02c0 1.11.89 2.01 2 2.01h15.64l2.05 2.02L23 21.75l-1.46-1.47z"
-        android:fillColor="@android:color/white"/>
+        android:fillColor="@android:color/white"
+        android:pathData="M20,6h-4L16,4c0,-1.11 -0.89,-2 -2,-2h-4c-1.11,0 -2,0.89 -2,2v1.17L10.83,8L20,8v9.17l1.98,1.98c0,-0.05 0.02,-0.1 0.02,-0.16L22,8c0,-1.11 -0.89,-2 -2,-2zM14,6h-4L10,4h4v2zM19,19L8,8 6,6 2.81,2.81 1.39,4.22 3.3,6.13C2.54,6.41 2.01,7.14 2.01,8L2,19c0,1.11 0.89,2 2,2h14.17l1.61,1.61 1.41,-1.41 -0.37,-0.37L19,19zM4,19L4,8h1.17l11,11L4,19z" />
 </vector>
\ No newline at end of file
diff --git a/res/drawable/work_card_btn.xml b/res/drawable/rounded_action_button.xml
similarity index 84%
rename from res/drawable/work_card_btn.xml
rename to res/drawable/rounded_action_button.xml
index 3c93919..0c8755f 100644
--- a/res/drawable/work_card_btn.xml
+++ b/res/drawable/rounded_action_button.xml
@@ -18,10 +18,10 @@
 <shape xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
     android:shape="rectangle">
-    <corners android:radius="@dimen/work_edu_card_margin" />
+    <corners android:radius="@dimen/rounded_button_radius" />
     <stroke android:width="1dp" android:color="?androidprv:attr/colorAccentPrimaryVariant" />
     <padding
-        android:left="@dimen/work_fab_radius"
-        android:right="@dimen/work_fab_radius" />
+        android:left="@dimen/rounded_button_padding"
+        android:right="@dimen/rounded_button_padding" />
 </shape>
 
diff --git a/res/layout/work_apps_edu.xml b/res/layout/work_apps_edu.xml
index ffbf962..97feb23 100644
--- a/res/layout/work_apps_edu.xml
+++ b/res/layout/work_apps_edu.xml
@@ -47,7 +47,8 @@
             android:textColor="?attr/workProfileOverlayTextColor"
             android:text="@string/work_profile_edu_accept"
             android:textAlignment="center"
-            android:background="@drawable/work_card_btn"
+            android:background="@drawable/rounded_action_button"
+
             android:textSize="14sp" />
     </LinearLayout>
 </com.android.launcher3.allapps.WorkEduCard>
\ No newline at end of file
diff --git a/res/layout/work_apps_paused.xml b/res/layout/work_apps_paused.xml
index 14dcb8c..3819256 100644
--- a/res/layout/work_apps_paused.xml
+++ b/res/layout/work_apps_paused.xml
@@ -48,6 +48,6 @@
         android:textColor="?attr/workProfileOverlayTextColor"
         android:text="@string/work_apps_enable_btn_text"
         android:textAlignment="center"
-        android:background="@drawable/work_card_btn"
+        android:background="@drawable/rounded_action_button"
         android:textSize="14sp" />
 </com.android.launcher3.allapps.WorkPausedCard>
\ No newline at end of file
diff --git a/res/layout/work_mode_fab.xml b/res/layout/work_mode_fab.xml
index 4209192..1771d37 100644
--- a/res/layout/work_mode_fab.xml
+++ b/res/layout/work_mode_fab.xml
@@ -25,7 +25,6 @@
     android:background="@drawable/work_apps_toggle_background"
     android:drawablePadding="16dp"
     android:drawableStart="@drawable/ic_corp_off"
-    android:elevation="10dp"
     android:layout_marginBottom="@dimen/work_fab_margin"
     android:layout_marginEnd="@dimen/work_fab_margin"
     android:text="@string/work_apps_pause_btn_text" />
\ No newline at end of file
diff --git a/res/values-v28/styles.xml b/res/values-v28/styles.xml
deleted file mode 100644
index 7df9ce5..0000000
--- a/res/values-v28/styles.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-* Copyright (C) 2019 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.
-*/
--->
-<resources>
-    <style name="TextHeadline" parent="@android:style/TextAppearance.DeviceDefault.DialogWindowTitle" >
-        <item name="android:textFontWeight">400</item>
-    </style>
-</resources>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 1ee4244..9048d87 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -48,7 +48,7 @@
     <dimen name="workspace_page_indicator_overlap_workspace">0dp</dimen>
 
 <!-- Drop target bar -->
-    <dimen name="dynamic_grid_drop_target_size">48dp</dimen>
+    <dimen name="dynamic_grid_drop_target_size">52dp</dimen>
     <dimen name="drop_target_vertical_gap">20dp</dimen>
 
 <!-- App Widget resize frame -->
@@ -120,11 +120,16 @@
 <!-- Floating action button inside work tab to toggle work profile -->
     <dimen name="work_fab_height">48dp</dimen>
     <dimen name="work_fab_radius">24dp</dimen>
-    <dimen name="work_fab_margin">18dp</dimen>
+    <dimen name="work_fab_margin">16dp</dimen>
     <dimen name="work_profile_footer_padding">20dp</dimen>
     <dimen name="work_profile_footer_text_size">16sp</dimen>
     <dimen name="work_edu_card_margin">16dp</dimen>
 
+    <!-- rounded button shown inside card views, and snack bars  -->
+    <dimen name="rounded_button_height">32dp</dimen>
+    <dimen name="rounded_button_radius">16dp</dimen>
+    <dimen name="rounded_button_padding">8dp</dimen>
+
 
     <!-- Widget tray -->
     <dimen name="widget_cell_vertical_padding">8dp</dimen>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 9823df3..60c0774 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -190,11 +190,11 @@
     <!-- Widgets: -->
     <skip />    
 
-    <!-- Text to show user in place of a gadget when we can't display it properly -->
-    <string name="gadget_error_text">Problem loading widget</string>
+    <!-- Error text that lets a user know that the widget can't load. -->
+    <string name="gadget_error_text">Can\'t load widget</string>
 
-    <!-- Text to show user in place of a gadget when it is not yet initialized. -->
-    <string name="gadget_setup_text">Setup</string>
+    <!-- Instructional text to encourage a user to finish setting up the widget. -->
+    <string name="gadget_setup_text">Tap to finish setup</string>
 
     <!-- Text to inform the user that they can't uninstall a system application -->
     <string name="uninstall_system_app_text">This is a system app and can\'t be uninstalled.</string>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 6f7d727..2119e58 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -214,7 +214,9 @@
         <item name="disabledIconAlpha">.54</item>
     </style>
 
-    <style name="BaseIconUnBounded" parent="@android:style/TextAppearance.DeviceDefault.DialogWindowTitle">
+    <style name="BaseIconRoot" parent="@android:style/TextAppearance.DeviceDefault.DialogWindowTitle"/>
+
+    <style name="BaseIconUnBounded" parent="BaseIconRoot">
         <item name="android:layout_width">match_parent</item>
         <item name="android:layout_height">match_parent</item>
         <item name="android:layout_gravity">center</item>
@@ -264,9 +266,8 @@
 
     <!-- Drop targets -->
     <style name="DropTargetButtonBase" parent="@android:style/TextAppearance.DeviceDefault">
-        <item name="android:drawablePadding">7.5dp</item>
-        <item name="android:paddingLeft">16dp</item>
-        <item name="android:paddingRight">16dp</item>
+        <item name="android:drawablePadding">8dp</item>
+        <item name="android:padding">16dp</item>
         <item name="android:textColor">?android:attr/textColorPrimary</item>
         <item name="android:textSize">@dimen/drop_target_text_size</item>
         <item name="android:singleLine">true</item>
@@ -276,7 +277,7 @@
 
     <style name="DropTargetButton" parent="DropTargetButtonBase" />
 
-    <style name="TextHeadline" parent="@android:style/TextAppearance.DeviceDefault" />
+    <style name="TextHeadline" parent="@android:style/TextAppearance.DeviceDefault.DialogWindowTitle" />
 
     <style name="PrimaryHeadline" parent="@android:style/TextAppearance.DeviceDefault.DialogWindowTitle"/>
 
diff --git a/robolectric_tests/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfoTest.java b/robolectric_tests/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfoTest.java
index c7286e5..2d87957 100644
--- a/robolectric_tests/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfoTest.java
+++ b/robolectric_tests/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfoTest.java
@@ -36,6 +36,10 @@
 import org.robolectric.RobolectricTestRunner;
 import org.robolectric.RuntimeEnvironment;
 
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
 @RunWith(RobolectricTestRunner.class)
 public final class LauncherAppWidgetProviderInfoTest {
 
@@ -234,10 +238,11 @@
         Mockito.when(profile.getCellSize()).thenReturn(new Point(CELL_SIZE, CELL_SIZE));
 
         InvariantDeviceProfile idp = new InvariantDeviceProfile();
-        idp.supportedProfiles.add(profile);
+        List<DeviceProfile> supportedProfiles = new ArrayList<>(idp.supportedProfiles);
+        supportedProfiles.add(profile);
+        idp.supportedProfiles = Collections.unmodifiableList(supportedProfiles);
         idp.numColumns = NUM_OF_COLS;
         idp.numRows = NUM_OF_ROWS;
         return idp;
     }
-
 }
diff --git a/src/com/android/launcher3/ButtonDropTarget.java b/src/com/android/launcher3/ButtonDropTarget.java
index 13bf437..d1cb5b8 100644
--- a/src/com/android/launcher3/ButtonDropTarget.java
+++ b/src/com/android/launcher3/ButtonDropTarget.java
@@ -121,19 +121,11 @@
     }
 
     protected void setDrawable(int resId) {
-        mDrawable = getContext().getDrawable(resId).mutate();
-        mDrawable.setBounds(0, 0, mDrawableSize, mDrawableSize);
-        setDrawable(mDrawable);
-    }
-
-    private void setDrawable(Drawable drawable) {
         // We do not set the drawable in the xml as that inflates two drawables corresponding to
         // drawableLeft and drawableStart.
-        if (mTextVisible) {
-            setCompoundDrawablesRelative(drawable, null, null, null);
-        } else {
-            setCompoundDrawablesRelative(null, drawable, null, null);
-        }
+        mDrawable = getContext().getDrawable(resId).mutate();
+        mDrawable.setBounds(0, 0, mDrawableSize, mDrawableSize);
+        setCompoundDrawablesRelative(mDrawable, null, null, null);
     }
 
     public void setDropTargetBar(DropTargetBar dropTargetBar) {
@@ -334,7 +326,7 @@
         if (mTextVisible != isVisible || !TextUtils.equals(newText, getText())) {
             mTextVisible = isVisible;
             setText(newText);
-            setDrawable(mDrawable);
+            setCompoundDrawablesRelative(mDrawable, null, null, null);
         }
     }
 
diff --git a/src/com/android/launcher3/InvariantDeviceProfile.java b/src/com/android/launcher3/InvariantDeviceProfile.java
index 318dde1..29a0223 100644
--- a/src/com/android/launcher3/InvariantDeviceProfile.java
+++ b/src/com/android/launcher3/InvariantDeviceProfile.java
@@ -140,7 +140,10 @@
     public int defaultLayoutId;
     int demoModeLayoutId;
 
-    public final List<DeviceProfile> supportedProfiles = new ArrayList<>();
+    /**
+     * An immutable list of supported profiles.
+     */
+    public List<DeviceProfile> supportedProfiles = Collections.EMPTY_LIST;
 
     @Nullable public DevicePaddings devicePaddings;
 
@@ -322,10 +325,10 @@
         // Supported overrides: numRows, numColumns, iconSize
         applyPartnerDeviceProfileOverrides(context, metrics);
 
-        supportedProfiles.clear();
+        final List<DeviceProfile> localSupportedProfiles = new ArrayList<>();
         defaultWallpaperSize = new Point(displayInfo.currentSize);
         for (WindowBounds bounds : displayInfo.supportedBounds) {
-            supportedProfiles.add(new DeviceProfile.Builder(context, this, displayInfo)
+            localSupportedProfiles.add(new DeviceProfile.Builder(context, this, displayInfo)
                     .setUseTwoPanels(isSplitDisplay)
                     .setWindowBounds(bounds).build());
 
@@ -343,6 +346,7 @@
             defaultWallpaperSize.x =
                     Math.max(defaultWallpaperSize.x, Math.round(parallaxFactor * displayWidth));
         }
+        supportedProfiles = Collections.unmodifiableList(localSupportedProfiles);
 
         ComponentName cn = new ComponentName(context.getPackageName(), getClass().getName());
         defaultWidgetPadding = AppWidgetHostView.getDefaultPaddingForWidget(context, cn, null);
diff --git a/src/com/android/launcher3/Utilities.java b/src/com/android/launcher3/Utilities.java
index a2d86bc..75f6278 100644
--- a/src/com/android/launcher3/Utilities.java
+++ b/src/com/android/launcher3/Utilities.java
@@ -122,7 +122,8 @@
 
     public static final boolean ATLEAST_R = Build.VERSION.SDK_INT >= Build.VERSION_CODES.R;
 
-    public static final boolean ATLEAST_S = BuildCompat.isAtLeastS();
+    public static final boolean ATLEAST_S = BuildCompat.isAtLeastS()
+            || Build.VERSION.SDK_INT >= Build.VERSION_CODES.S;
 
     /**
      * Set on a motion event dispatched from the nav bar. See {@link MotionEvent#setEdgeFlags(int)}.
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index 2e1cc58..303bb01 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -2791,6 +2791,10 @@
                 removeWorkspaceItem(mDragInfo.cell);
             }
         } else if (mDragInfo != null) {
+            // When drag is cancelled, reattach content view back to its original parent.
+            if (mDragInfo.cell instanceof LauncherAppWidgetHostView) {
+                d.dragView.detachContentView(/* reattachToPreviousParent= */ true);
+            }
             final CellLayout cellLayout = mLauncher.getCellLayout(
                     mDragInfo.container, mDragInfo.screenId);
             if (cellLayout != null) {
diff --git a/src/com/android/launcher3/allapps/AllAppsContainerView.java b/src/com/android/launcher3/allapps/AllAppsContainerView.java
index 39d1a00..8076b27 100644
--- a/src/com/android/launcher3/allapps/AllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsContainerView.java
@@ -131,7 +131,6 @@
     private ScrimView mScrimView;
     private int mHeaderColor;
 
-
     public AllAppsContainerView(Context context) {
         this(context, null);
     }
@@ -571,6 +570,10 @@
         return mViewPager == null ? getActiveRecyclerView() : mViewPager;
     }
 
+    public int getCurrentPage() {
+        return mViewPager != null ? mViewPager.getCurrentPage() : AdapterHolder.MAIN;
+    }
+
     /**
      * Handles selection on focused view and returns success
      */
diff --git a/src/com/android/launcher3/allapps/WorkModeSwitch.java b/src/com/android/launcher3/allapps/WorkModeSwitch.java
index 866694f..6d57aa6 100644
--- a/src/com/android/launcher3/allapps/WorkModeSwitch.java
+++ b/src/com/android/launcher3/allapps/WorkModeSwitch.java
@@ -15,9 +15,11 @@
  */
 package com.android.launcher3.allapps;
 
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TURN_OFF_WORK_APPS_TAP;
 import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
 
 import android.content.Context;
+import android.graphics.Insets;
 import android.graphics.Rect;
 import android.os.Build;
 import android.os.Process;
@@ -26,12 +28,16 @@
 import android.util.AttributeSet;
 import android.view.View;
 import android.view.ViewGroup;
+import android.view.WindowInsets;
 import android.widget.Button;
 
+import androidx.annotation.Nullable;
 import androidx.annotation.RequiresApi;
 
 import com.android.launcher3.Insettable;
+import com.android.launcher3.Launcher;
 import com.android.launcher3.Utilities;
+import com.android.launcher3.anim.KeyboardInsetAnimationCallback;
 import com.android.launcher3.pm.UserCache;
 
 /**
@@ -42,6 +48,10 @@
     private Rect mInsets = new Rect();
     private boolean mWorkEnabled;
 
+
+    @Nullable
+    private KeyboardInsetAnimationCallback mKeyboardInsetAnimationCallback;
+
     public WorkModeSwitch(Context context) {
         this(context, null, 0);
     }
@@ -58,6 +68,10 @@
     protected void onFinishInflate() {
         super.onFinishInflate();
         setOnClickListener(this);
+        if (Utilities.ATLEAST_R) {
+            mKeyboardInsetAnimationCallback = new KeyboardInsetAnimationCallback(this);
+            setWindowInsetsAnimationCallback(mKeyboardInsetAnimationCallback);
+        }
     }
 
     @Override
@@ -92,6 +106,8 @@
     public void onClick(View view) {
         if (Utilities.ATLEAST_P) {
             setEnabled(false);
+            Launcher.fromContext(getContext()).getStatsLogManager().logger().log(
+                    LAUNCHER_TURN_OFF_WORK_APPS_TAP);
             UI_HELPER_EXECUTOR.post(() -> setWorkProfileEnabled(getContext(), false));
         }
     }
@@ -117,4 +133,16 @@
         }
         return showConfirm;
     }
+
+    @Override
+    public WindowInsets onApplyWindowInsets(WindowInsets insets) {
+        if (Utilities.ATLEAST_R) {
+            setTranslationY(0);
+            if (insets.isVisible(WindowInsets.Type.ime())) {
+                Insets keyboardInsets = insets.getInsets(WindowInsets.Type.ime());
+                setTranslationY(mInsets.bottom - keyboardInsets.bottom);
+            }
+        }
+        return insets;
+    }
 }
diff --git a/src/com/android/launcher3/allapps/WorkPausedCard.java b/src/com/android/launcher3/allapps/WorkPausedCard.java
index 3955a9a..7908b63 100644
--- a/src/com/android/launcher3/allapps/WorkPausedCard.java
+++ b/src/com/android/launcher3/allapps/WorkPausedCard.java
@@ -15,6 +15,7 @@
  */
 package com.android.launcher3.allapps;
 
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TURN_ON_WORK_APPS_TAP;
 import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
 
 import android.content.Context;
@@ -61,6 +62,7 @@
     public void onClick(View view) {
         if (Utilities.ATLEAST_P) {
             setEnabled(false);
+            mLauncher.getStatsLogManager().logger().log(LAUNCHER_TURN_ON_WORK_APPS_TAP);
             UI_HELPER_EXECUTOR.post(() -> WorkModeSwitch.setWorkProfileEnabled(getContext(), true));
         }
     }
diff --git a/src/com/android/launcher3/anim/KeyboardInsetAnimationCallback.java b/src/com/android/launcher3/anim/KeyboardInsetAnimationCallback.java
new file mode 100644
index 0000000..ef4ada3
--- /dev/null
+++ b/src/com/android/launcher3/anim/KeyboardInsetAnimationCallback.java
@@ -0,0 +1,71 @@
+/*
+ * 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.anim;
+
+import android.os.Build;
+import android.view.View;
+import android.view.WindowInsets;
+import android.view.WindowInsetsAnimation;
+
+import androidx.annotation.RequiresApi;
+
+import com.android.launcher3.Utilities;
+
+import java.util.List;
+
+/**
+ * Callback that animates views above the IME
+ */
+@RequiresApi(api = Build.VERSION_CODES.R)
+public class KeyboardInsetAnimationCallback extends WindowInsetsAnimation.Callback {
+    private final View mView;
+
+    private float mInitialTranslation;
+    private float mTerminalTranslation;
+
+    public KeyboardInsetAnimationCallback(View view) {
+        super(DISPATCH_MODE_STOP);
+        mView = view;
+    }
+
+    @Override
+    public void onPrepare(WindowInsetsAnimation animation) {
+        mInitialTranslation = mView.getTranslationY();
+    }
+
+
+    @Override
+    public WindowInsets onProgress(WindowInsets windowInsets, List<WindowInsetsAnimation> list) {
+        if (list.size() == 0) {
+            mView.setTranslationY(mInitialTranslation);
+            return windowInsets;
+        }
+        float progress = list.get(0).getInterpolatedFraction();
+
+        mView.setTranslationY(
+                Utilities.mapRange(progress, mInitialTranslation, mTerminalTranslation));
+
+        return windowInsets;
+    }
+
+    @Override
+    public WindowInsetsAnimation.Bounds onStart(WindowInsetsAnimation animation,
+            WindowInsetsAnimation.Bounds bounds) {
+        mTerminalTranslation = mView.getTranslationY();
+        mView.setTranslationY(mInitialTranslation);
+        return super.onStart(animation, bounds);
+    }
+}
diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java
index 0e710b7..d65eb22 100644
--- a/src/com/android/launcher3/config/FeatureFlags.java
+++ b/src/com/android/launcher3/config/FeatureFlags.java
@@ -99,6 +99,9 @@
     public static final BooleanFlag ENABLE_DEVICE_SEARCH = new DeviceFlag(
             "ENABLE_DEVICE_SEARCH", true, "Allows on device search in all apps");
 
+    public static final BooleanFlag IME_STICKY_SNACKBAR_EDU = getDebugFlag(
+            "IME_STICKY_SNACKBAR_EDU", true, "Show sticky IME edu in AllApps");
+
     public static final BooleanFlag ENABLE_PEOPLE_TILE_PREVIEW = getDebugFlag(
             "ENABLE_PEOPLE_TILE_PREVIEW", false,
             "Experimental: Shows conversation shortcuts on home screen as search results");
@@ -220,6 +223,10 @@
             "ENABLE_TWO_PANEL_HOME", false,
             "Uses two panel on home screen. Only applicable on large screen devices.");
 
+    public static final BooleanFlag ENABLE_SCRIM_FOR_APP_LAUNCH = getDebugFlag(
+            "ENABLE_SCRIM_FOR_APP_LAUNCH", false,
+            "Enables scrim during app launch animation.");
+
     public static final BooleanFlag ENABLE_SPLIT_SELECT = getDebugFlag(
             "ENABLE_SPLIT_SELECT", false, "Uses new split screen selection overview UI");
 
diff --git a/src/com/android/launcher3/folder/ClippedFolderIconLayoutRule.java b/src/com/android/launcher3/folder/ClippedFolderIconLayoutRule.java
index 3457804..54967a9 100644
--- a/src/com/android/launcher3/folder/ClippedFolderIconLayoutRule.java
+++ b/src/com/android/launcher3/folder/ClippedFolderIconLayoutRule.java
@@ -34,7 +34,6 @@
         float totalScale = scaleForItem(curNumItems);
         float transX;
         float transY;
-        float overlayAlpha = 0;
 
         if (index == EXIT_INDEX) {
             // 0 1 * <-- Exit position (row 0, col 2)
@@ -55,10 +54,9 @@
         transY = mTmpPoint[1];
 
         if (params == null) {
-            params = new PreviewItemDrawingParams(transX, transY, totalScale, overlayAlpha);
+            params = new PreviewItemDrawingParams(transX, transY, totalScale);
         } else {
             params.update(transX, transY, totalScale);
-            params.overlayAlpha = overlayAlpha;
         }
         return params;
     }
diff --git a/src/com/android/launcher3/folder/Folder.java b/src/com/android/launcher3/folder/Folder.java
index 5dcd75a..22bb56c 100644
--- a/src/com/android/launcher3/folder/Folder.java
+++ b/src/com/android/launcher3/folder/Folder.java
@@ -17,7 +17,6 @@
 package com.android.launcher3.folder;
 
 import static android.text.TextUtils.isEmpty;
-import static android.view.WindowInsetsAnimation.Callback.DISPATCH_MODE_STOP;
 
 import static com.android.launcher3.LauncherAnimUtils.SPRING_LOADED_EXIT_DELAY;
 import static com.android.launcher3.LauncherState.NORMAL;
@@ -39,7 +38,6 @@
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.GradientDrawable;
-import android.os.Build;
 import android.text.InputType;
 import android.text.Selection;
 import android.text.TextUtils;
@@ -54,15 +52,12 @@
 import android.view.View;
 import android.view.ViewDebug;
 import android.view.WindowInsets;
-import android.view.WindowInsetsAnimation;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.animation.AnimationUtils;
 import android.view.inputmethod.EditorInfo;
 import android.widget.TextView;
 
-import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
-import androidx.annotation.RequiresApi;
 import androidx.core.content.res.ResourcesCompat;
 
 import com.android.launcher3.AbstractFloatingView;
@@ -83,6 +78,7 @@
 import com.android.launcher3.Workspace.ItemOperator;
 import com.android.launcher3.accessibility.AccessibleDragListenerAdapter;
 import com.android.launcher3.accessibility.FolderAccessibilityHelper;
+import com.android.launcher3.anim.KeyboardInsetAnimationCallback;
 import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.dragndrop.DragController;
 import com.android.launcher3.dragndrop.DragController.DragListener;
@@ -164,9 +160,9 @@
     private final Alarm mReorderAlarm = new Alarm();
     private final Alarm mOnExitAlarm = new Alarm();
     private final Alarm mOnScrollHintAlarm = new Alarm();
-    @Thunk final Alarm mScrollPauseAlarm = new Alarm();
+    final Alarm mScrollPauseAlarm = new Alarm();
 
-    @Thunk final ArrayList<View> mItemsInReadingOrder = new ArrayList<View>();
+    final ArrayList<View> mItemsInReadingOrder = new ArrayList<View>();
 
     private AnimatorSet mCurrentAnimator;
     private boolean mIsAnimatingClosed = false;
@@ -182,9 +178,11 @@
     private CharSequence mFromTitle;
     private FromState mFromLabelState;
 
-    @Thunk FolderIcon mFolderIcon;
+    @Thunk
+    FolderIcon mFolderIcon;
 
-    @Thunk FolderPagedView mContent;
+    @Thunk
+    FolderPagedView mContent;
     public FolderNameEditText mFolderName;
     private PageIndicatorDots mPageIndicator;
 
@@ -192,7 +190,8 @@
     private int mFooterHeight;
 
     // Cell ranks used for drag and drop
-    @Thunk int mTargetRank, mPrevTargetRank, mEmptyCellRank;
+    @Thunk
+    int mTargetRank, mPrevTargetRank, mEmptyCellRank;
 
     private Path mClipPath;
 
@@ -203,7 +202,8 @@
                     @ViewDebug.IntToString(from = STATE_ANIMATING, to = "STATE_ANIMATING"),
                     @ViewDebug.IntToString(from = STATE_OPEN, to = "STATE_OPEN"),
             })
-    @Thunk int mState = STATE_NONE;
+    @Thunk
+    int mState = STATE_NONE;
     @ViewDebug.ExportedProperty(category = "launcher")
     private boolean mRearrangeOnClose = false;
     boolean mItemsInvalidated = false;
@@ -221,12 +221,15 @@
     // Folder scrolling
     private int mScrollAreaOffset;
 
-    @Thunk int mScrollHintDir = SCROLL_NONE;
-    @Thunk int mCurrentScrollDir = SCROLL_NONE;
+    @Thunk
+    int mScrollHintDir = SCROLL_NONE;
+    @Thunk
+    int mCurrentScrollDir = SCROLL_NONE;
 
     private StatsLogManager mStatsLogManager;
 
-    @Nullable private FolderWindowInsetsAnimationCallback mFolderWindowInsetsAnimationCallback;
+    @Nullable
+    private KeyboardInsetAnimationCallback mKeyboardInsetAnimationCallback;
 
     private GradientDrawable mBackground;
 
@@ -234,7 +237,7 @@
      * Used to inflate the Workspace from XML.
      *
      * @param context The application's context.
-     * @param attrs The attributes set containing the Workspace's customization values.
+     * @param attrs   The attributes set containing the Workspace's customization values.
      */
     public Folder(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -246,7 +249,8 @@
         mStatsLogManager = StatsLogManager.newInstance(context);
         // We need this view to be focusable in touch mode so that when text editing of the folder
         // name is complete, we have something to focus on, thus hiding the cursor and giving
-        // reliable behavior when clicking the text field (since it will always gain focus on click).
+        // reliable behavior when clicking the text field (since it will always gain focus on
+        // click).
         setFocusableInTouchMode(true);
 
     }
@@ -286,10 +290,8 @@
         mFooterHeight = getResources().getDimensionPixelSize(R.dimen.folder_label_height);
 
         if (Utilities.ATLEAST_R) {
-            mFolderWindowInsetsAnimationCallback =
-                    new FolderWindowInsetsAnimationCallback(DISPATCH_MODE_STOP, this);
-
-            setWindowInsetsAnimationCallback(mFolderWindowInsetsAnimationCallback);
+            mKeyboardInsetAnimationCallback = new KeyboardInsetAnimationCallback(this);
+            setWindowInsetsAnimationCallback(mKeyboardInsetAnimationCallback);
         }
     }
 
@@ -311,14 +313,14 @@
             if (options.isAccessibleDrag) {
                 mDragController.addDragListener(new AccessibleDragListenerAdapter(
                         mContent, FolderAccessibilityHelper::new) {
-                            @Override
-                            protected void enableAccessibleDrag(boolean enable) {
-                                super.enableAccessibleDrag(enable);
-                                mFooter.setImportantForAccessibility(enable
-                                        ? IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS
-                                        : IMPORTANT_FOR_ACCESSIBILITY_AUTO);
-                            }
-                        });
+                    @Override
+                    protected void enableAccessibleDrag(boolean enable) {
+                        super.enableAccessibleDrag(enable);
+                        mFooter.setImportantForAccessibility(enable
+                                ? IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS
+                                : IMPORTANT_FOR_ACCESSIBILITY_AUTO);
+                    }
+                });
             }
 
             mLauncherDelegate.beginDragShared(v, this, options);
@@ -539,7 +541,6 @@
      *
      * @param activityContext The main ActivityContext in which to inflate this Folder. It must also
      *                        be an instance or ContextWrapper around the Launcher activity context.
-     *
      * @return A new UserFolder.
      */
     @SuppressLint("InflateParams")
@@ -677,6 +678,7 @@
                 mFolderIcon.setIconVisible(false);
                 mFolderIcon.drawLeaveBehindIfExists();
             }
+
             @Override
             public void onAnimationEnd(Animator animation) {
                 mState = STATE_OPEN;
@@ -691,7 +693,7 @@
             int footerWidth = mContent.getDesiredWidth()
                     - mFooter.getPaddingLeft() - mFooter.getPaddingRight();
 
-            float textWidth =  mFolderName.getPaint().measureText(mFolderName.getText().toString());
+            float textWidth = mFolderName.getPaint().measureText(mFolderName.getText().toString());
             float translation = (footerWidth - textWidth) / 2;
             mFolderName.setTranslationX(mContent.mIsRtl ? -translation : translation);
             mPageIndicator.prepareEntryAnimation();
@@ -705,9 +707,9 @@
                 @Override
                 public void onAnimationEnd(Animator animation) {
                     mFolderName.animate().setDuration(FOLDER_NAME_ANIMATION_DURATION)
-                        .translationX(0)
-                        .setInterpolator(AnimationUtils.loadInterpolator(
-                                getContext(), android.R.interpolator.fast_out_slow_in));
+                            .translationX(0)
+                            .setInterpolator(AnimationUtils.loadInterpolator(
+                                    getContext(), android.R.interpolator.fast_out_slow_in));
                     mPageIndicator.playEntryAnimation();
 
                     if (updateAnimationFlag) {
@@ -794,8 +796,8 @@
 
             @Override
             public void onAnimationEnd(Animator animation) {
-                if (Utilities.ATLEAST_R && mFolderWindowInsetsAnimationCallback != null) {
-                    setWindowInsetsAnimationCallback(mFolderWindowInsetsAnimationCallback);
+                if (Utilities.ATLEAST_R && mKeyboardInsetAnimationCallback != null) {
+                    setWindowInsetsAnimationCallback(mKeyboardInsetAnimationCallback);
                 }
                 closeComplete(true);
                 announceAccessibilityChanges();
@@ -1109,7 +1111,7 @@
         sTempRect.set(mActivityContext.getFolderBoundingBox());
         int left = Utilities.boundToRange(centeredLeft, sTempRect.left, sTempRect.right - width);
         int top = Utilities.boundToRange(centeredTop, sTempRect.top, sTempRect.bottom - height);
-        int[] inOutPosition = new int[] {left, top};
+        int[] inOutPosition = new int[]{left, top};
         mActivityContext.updateOpenFolderPosition(inOutPosition, sTempRect, width, height);
         left = inOutPosition[0];
         top = inOutPosition[1];
@@ -1193,7 +1195,7 @@
         return mInfo.contents.size();
     }
 
-    @Thunk void replaceFolderWithFinalItem() {
+    void replaceFolderWithFinalItem() {
         mLauncherDelegate.replaceFolderWithFinalItem(this);
         mDestroyed = true;
     }
@@ -1352,6 +1354,7 @@
             v.setVisibility(INVISIBLE);
         }
     }
+
     public void showItem(WorkspaceItemInfo info) {
         View v = getViewForInfo(info);
         if (v != null) {
@@ -1646,55 +1649,4 @@
 
         return windowBottomPx - folderBottomPx;
     }
-
-    /** Callback that animates a folder sliding up above the ime. */
-    @RequiresApi(api = Build.VERSION_CODES.R)
-    private static class FolderWindowInsetsAnimationCallback
-            extends WindowInsetsAnimation.Callback {
-
-        private final Folder mFolder;
-        float mFolderTranslationStart;
-        float mFolderTranslationEnd;
-
-        FolderWindowInsetsAnimationCallback(int dispatchMode, Folder folder) {
-            super(dispatchMode);
-
-            mFolder = folder;
-        }
-
-        @Override
-        public void onPrepare(@NonNull WindowInsetsAnimation animation) {
-            mFolderTranslationStart = mFolder.getTranslationY();
-        }
-
-        @NonNull
-        @Override
-        public WindowInsetsAnimation.Bounds onStart(
-                @NonNull WindowInsetsAnimation animation,
-                @NonNull WindowInsetsAnimation.Bounds bounds) {
-            mFolderTranslationEnd = mFolder.getTranslationY();
-
-            mFolder.setTranslationY(mFolderTranslationStart);
-
-            return super.onStart(animation, bounds);
-        }
-
-        @NonNull
-        @Override
-        public WindowInsets onProgress(@NonNull WindowInsets windowInsets,
-                @NonNull List<WindowInsetsAnimation> list) {
-            if (list.size() == 0) {
-                mFolder.setTranslationY(0);
-
-                return windowInsets;
-            }
-            float progress = list.get(0).getInterpolatedFraction();
-
-            mFolder.setTranslationY(
-                    Utilities.mapRange(progress, mFolderTranslationStart, mFolderTranslationEnd));
-
-            return windowInsets;
-        }
-
-    }
 }
diff --git a/src/com/android/launcher3/folder/FolderAnimationManager.java b/src/com/android/launcher3/folder/FolderAnimationManager.java
index 57b289e..4fe85be 100644
--- a/src/com/android/launcher3/folder/FolderAnimationManager.java
+++ b/src/com/android/launcher3/folder/FolderAnimationManager.java
@@ -79,7 +79,7 @@
     private final TimeInterpolator mLargeFolderPreviewItemOpenInterpolator;
     private final TimeInterpolator mLargeFolderPreviewItemCloseInterpolator;
 
-    private final PreviewItemDrawingParams mTmpParams = new PreviewItemDrawingParams(0, 0, 0, 0);
+    private final PreviewItemDrawingParams mTmpParams = new PreviewItemDrawingParams(0, 0, 0);
     private final FolderGridOrganizer mPreviewVerifier;
 
     private ObjectAnimator mBgColorAnimator;
diff --git a/src/com/android/launcher3/folder/FolderIcon.java b/src/com/android/launcher3/folder/FolderIcon.java
index ed2d0a9..5c11451 100644
--- a/src/com/android/launcher3/folder/FolderIcon.java
+++ b/src/com/android/launcher3/folder/FolderIcon.java
@@ -113,7 +113,7 @@
     FolderGridOrganizer mPreviewVerifier;
     ClippedFolderIconLayoutRule mPreviewLayoutRule;
     private PreviewItemManager mPreviewItemManager;
-    private PreviewItemDrawingParams mTmpParams = new PreviewItemDrawingParams(0, 0, 0, 0);
+    private PreviewItemDrawingParams mTmpParams = new PreviewItemDrawingParams(0, 0, 0);
     private List<WorkspaceItemInfo> mCurrentPreviewItems = new ArrayList<>();
 
     boolean mAnimating = false;
@@ -391,7 +391,7 @@
             to.offset(center[0] - animateView.getMeasuredWidth() / 2,
                     center[1] - animateView.getMeasuredHeight() / 2);
 
-            float finalAlpha = index < MAX_NUM_ITEMS_IN_PREVIEW ? 0.5f : 0f;
+            float finalAlpha = index < MAX_NUM_ITEMS_IN_PREVIEW ? 1f : 0f;
 
             float finalScale = scale * scaleRelativeToDragLayer;
 
@@ -402,15 +402,18 @@
                 finalScale *= containerScale;
             }
 
+            final int finalIndex = index;
             dragLayer.animateView(animateView, from, to, finalAlpha,
                     1, 1, finalScale, finalScale, DROP_IN_ANIMATION_DURATION,
                     Interpolators.DEACCEL_2, Interpolators.ACCEL_2,
-                    null, DragLayer.ANIMATION_END_DISAPPEAR, null);
+                    () -> {
+                        mPreviewItemManager.hidePreviewItem(finalIndex, false);
+                        mFolder.showItem(item);
+                    }, DragLayer.ANIMATION_END_DISAPPEAR, null);
 
             mFolder.hideItem(item);
 
             if (!itemAdded) mPreviewItemManager.hidePreviewItem(index, true);
-            final int finalIndex = index;
 
             FolderNameInfos nameInfos = new FolderNameInfos();
             if (FeatureFlags.FOLDER_NAME_SUGGEST.get()) {
@@ -430,8 +433,6 @@
     private void showFinalView(int finalIndex, final WorkspaceItemInfo item,
             FolderNameInfos nameInfos, InstanceId instanceId) {
         postDelayed(() -> {
-            mPreviewItemManager.hidePreviewItem(finalIndex, false);
-            mFolder.showItem(item);
             setLabelSuggestion(nameInfos, instanceId);
             invalidate();
         }, DROP_IN_ANIMATION_DURATION);
diff --git a/src/com/android/launcher3/folder/FolderPreviewItemAnim.java b/src/com/android/launcher3/folder/FolderPreviewItemAnim.java
index edfd2ba..e20bafb 100644
--- a/src/com/android/launcher3/folder/FolderPreviewItemAnim.java
+++ b/src/com/android/launcher3/folder/FolderPreviewItemAnim.java
@@ -45,7 +45,7 @@
             };
 
     private static final PreviewItemDrawingParams sTmpParams =
-            new PreviewItemDrawingParams(0, 0, 0, 0);
+            new PreviewItemDrawingParams(0, 0, 0);
     private static final float[] sTempParamsArray = new float[3];
 
     private final ObjectAnimator mAnimator;
diff --git a/src/com/android/launcher3/folder/PreviewItemDrawingParams.java b/src/com/android/launcher3/folder/PreviewItemDrawingParams.java
index 5746be8..58efdc1 100644
--- a/src/com/android/launcher3/folder/PreviewItemDrawingParams.java
+++ b/src/com/android/launcher3/folder/PreviewItemDrawingParams.java
@@ -27,17 +27,15 @@
     float transX;
     float transY;
     float scale;
-    float overlayAlpha;
     public FolderPreviewItemAnim anim;
     public boolean hidden;
     public Drawable drawable;
     public WorkspaceItemInfo item;
 
-    PreviewItemDrawingParams(float transX, float transY, float scale, float overlayAlpha) {
+    PreviewItemDrawingParams(float transX, float transY, float scale) {
         this.transX = transX;
         this.transY = transY;
         this.scale = scale;
-        this.overlayAlpha = overlayAlpha;
     }
 
     public void update(float transX, float transY, float scale) {
diff --git a/src/com/android/launcher3/folder/PreviewItemManager.java b/src/com/android/launcher3/folder/PreviewItemManager.java
index baafbc9..a6674fc 100644
--- a/src/com/android/launcher3/folder/PreviewItemManager.java
+++ b/src/com/android/launcher3/folder/PreviewItemManager.java
@@ -260,7 +260,7 @@
             params.remove(params.size() - 1);
         }
         while (items.size() > params.size()) {
-            params.add(new PreviewItemDrawingParams(0, 0, 0, 0));
+            params.add(new PreviewItemDrawingParams(0, 0, 0));
         }
 
         int numItemsInFirstPagePreview = page == 0 ? items.size() : MAX_NUM_ITEMS_IN_PREVIEW;
diff --git a/src/com/android/launcher3/logging/StatsLogManager.java b/src/com/android/launcher3/logging/StatsLogManager.java
index 345a2ac..ddff338 100644
--- a/src/com/android/launcher3/logging/StatsLogManager.java
+++ b/src/com/android/launcher3/logging/StatsLogManager.java
@@ -479,7 +479,13 @@
         LAUNCHER_THEMED_ICON_ENABLED(836),
 
         @UiEvent(doc = "User disabled themed icons option in wallpaper & style settings.")
-        LAUNCHER_THEMED_ICON_DISABLED(837)
+        LAUNCHER_THEMED_ICON_DISABLED(837),
+
+        @UiEvent(doc = "User tapped on 'Turn on work apps' button in all apps window.")
+        LAUNCHER_TURN_ON_WORK_APPS_TAP(838),
+
+        @UiEvent(doc = "User tapped on 'Turn off work apps' button in all apps window.")
+        LAUNCHER_TURN_OFF_WORK_APPS_TAP(839)
         ;
 
         // ADD MORE
diff --git a/src/com/android/launcher3/model/PackageUpdatedTask.java b/src/com/android/launcher3/model/PackageUpdatedTask.java
index 7bfa3ef..82b0f7c 100644
--- a/src/com/android/launcher3/model/PackageUpdatedTask.java
+++ b/src/com/android/launcher3/model/PackageUpdatedTask.java
@@ -29,6 +29,7 @@
 import android.os.UserManager;
 import android.util.Log;
 
+import com.android.launcher3.Launcher;
 import com.android.launcher3.LauncherAppState;
 import com.android.launcher3.LauncherSettings;
 import com.android.launcher3.LauncherSettings.Favorites;
@@ -123,6 +124,14 @@
                         activitiesLists.put(
                                 packages[i], appsList.updatePackage(context, packages[i], mUser));
                         app.getWidgetCache().removePackage(packages[i], mUser);
+
+                        // The update may have changed which shortcuts/widgets are available.
+                        // Refresh the widgets for the package if we have an activity running.
+                        Launcher launcher = Launcher.ACTIVITY_TRACKER.getCreatedActivity();
+                        if (launcher != null) {
+                            launcher.refreshAndBindWidgetsForPackageUser(
+                                    new PackageUserKey(packages[i], mUser));
+                        }
                     }
                 }
                 // Since package was just updated, the target must be available now.
@@ -212,7 +221,8 @@
                         }
 
                         if (si.isPromise() && isNewApkAvailable) {
-                            boolean isTargetValid = true;
+                            boolean isTargetValid = !cn.getClassName().equals(
+                                    IconCache.EMPTY_CLASS_NAME);
                             if (si.itemType == Favorites.ITEM_TYPE_DEEP_SHORTCUT) {
                                 List<ShortcutInfo> shortcut =
                                         new ShortcutRequest(context, mUser)
@@ -225,7 +235,7 @@
                                     si.updateFromDeepShortcutInfo(shortcut.get(0), context);
                                     infoUpdated = true;
                                 }
-                            } else if (!cn.getClassName().equals(IconCache.EMPTY_CLASS_NAME)) {
+                            } else if (isTargetValid) {
                                 isTargetValid = context.getSystemService(LauncherApps.class)
                                         .isActivityEnabled(cn, mUser);
                             }
diff --git a/src/com/android/launcher3/util/OnboardingPrefs.java b/src/com/android/launcher3/util/OnboardingPrefs.java
index 2e279fa..c395d6c 100644
--- a/src/com/android/launcher3/util/OnboardingPrefs.java
+++ b/src/com/android/launcher3/util/OnboardingPrefs.java
@@ -37,6 +37,7 @@
     public static final String HOTSEAT_DISCOVERY_TIP_COUNT = "launcher.hotseat_discovery_tip_count";
     public static final String HOTSEAT_LONGPRESS_TIP_SEEN = "launcher.hotseat_longpress_tip_seen";
     public static final String SEARCH_EDU_SEEN = "launcher.search_edu";
+    public static final String SEARCH_SNACKBAR_COUNT = "launcher.keyboard_snackbar_count";
 
     /**
      * Events that either have happened or have not (booleans).
@@ -47,23 +48,28 @@
             SEARCH_EDU_SEEN
     })
     @Retention(RetentionPolicy.SOURCE)
-    public @interface EventBoolKey {}
+    public @interface EventBoolKey {
+    }
 
     /**
      * Events that occur multiple times, which we count up to a max defined in {@link #MAX_COUNTS}.
      */
     @StringDef(value = {
             HOME_BOUNCE_COUNT,
-            HOTSEAT_DISCOVERY_TIP_COUNT
+            HOTSEAT_DISCOVERY_TIP_COUNT,
+            SEARCH_SNACKBAR_COUNT
     })
     @Retention(RetentionPolicy.SOURCE)
-    public @interface EventCountKey {}
+    public @interface EventCountKey {
+    }
 
     private static final Map<String, Integer> MAX_COUNTS;
+
     static {
         Map<String, Integer> maxCounts = new ArrayMap<>(4);
         maxCounts.put(HOME_BOUNCE_COUNT, 3);
         maxCounts.put(HOTSEAT_DISCOVERY_TIP_COUNT, 5);
+        maxCounts.put(SEARCH_SNACKBAR_COUNT, 3);
         MAX_COUNTS = Collections.unmodifiableMap(maxCounts);
     }
 
@@ -103,6 +109,7 @@
 
     /**
      * Add 1 to the given event count, if we haven't already reached the max count.
+     *
      * @return Whether we have now reached the max count.
      */
     public boolean incrementEventCount(@EventCountKey String eventKey) {
diff --git a/src/com/android/launcher3/util/UiThreadHelper.java b/src/com/android/launcher3/util/UiThreadHelper.java
index cb721e6..0f40179 100644
--- a/src/com/android/launcher3/util/UiThreadHelper.java
+++ b/src/com/android/launcher3/util/UiThreadHelper.java
@@ -21,6 +21,7 @@
 import android.annotation.SuppressLint;
 import android.app.Activity;
 import android.content.Context;
+import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Message;
@@ -42,15 +43,30 @@
     private static final int MSG_HIDE_KEYBOARD = 1;
     private static final int MSG_SET_ORIENTATION = 2;
     private static final int MSG_RUN_COMMAND = 3;
+    private static final String STATS_LOGGER_KEY = "STATS_LOGGER_KEY";
 
     @SuppressLint("NewApi")
     public static void hideKeyboardAsync(ActivityContext activityContext, IBinder token) {
         View root = activityContext.getDragLayer();
 
-        Message.obtain(HANDLER.get(root.getContext()),
-                MSG_HIDE_KEYBOARD, token).sendToTarget();
-        Launcher.cast(activityContext).getStatsLogManager().logger().log(
-                LAUNCHER_ALLAPPS_KEYBOARD_CLOSED);
+        // Since the launcher context cannot be accessed directly from callback, adding secondary
+        // message to log keyboard close event asynchronously.
+        Bundle mHideKeyboardLoggerMsg = new Bundle();
+        mHideKeyboardLoggerMsg.putParcelable(
+                STATS_LOGGER_KEY,
+                Message.obtain(
+                        HANDLER.get(root.getContext()),
+                        () -> Launcher.cast(activityContext)
+                                .getStatsLogManager()
+                                .logger()
+                                .log(LAUNCHER_ALLAPPS_KEYBOARD_CLOSED)
+                )
+        );
+
+        Message mHideKeyboardMsg = Message.obtain(HANDLER.get(root.getContext()), MSG_HIDE_KEYBOARD,
+                token);
+        mHideKeyboardMsg.setData(mHideKeyboardLoggerMsg);
+        mHideKeyboardMsg.sendToTarget();
     }
 
     public static void setOrientationAsync(Activity activity, int orientation) {
@@ -81,7 +97,11 @@
         public boolean handleMessage(Message message) {
             switch (message.what) {
                 case MSG_HIDE_KEYBOARD:
-                    mIMM.hideSoftInputFromWindow((IBinder) message.obj, 0);
+                    if (mIMM.hideSoftInputFromWindow((IBinder) message.obj, 0)) {
+                        // log keyboard close event only when keyboard is actually closed
+                        ((Message) message.getData().getParcelable(STATS_LOGGER_KEY))
+                                .sendToTarget();
+                    }
                     return true;
                 case MSG_SET_ORIENTATION:
                     ((Activity) message.obj).setRequestedOrientation(message.arg1);
diff --git a/src/com/android/launcher3/widget/PendingAppWidgetHostView.java b/src/com/android/launcher3/widget/PendingAppWidgetHostView.java
index 3308eec..47a8914 100644
--- a/src/com/android/launcher3/widget/PendingAppWidgetHostView.java
+++ b/src/com/android/launcher3/widget/PendingAppWidgetHostView.java
@@ -97,9 +97,9 @@
 
     @Override
     public void updateAppWidget(RemoteViews remoteViews) {
-        super.updateAppWidget(remoteViews);
         WidgetManagerHelper widgetManagerHelper = new WidgetManagerHelper(getContext());
         if (widgetManagerHelper.isAppWidgetRestored(mInfo.appWidgetId)) {
+            super.updateAppWidget(remoteViews);
             reInflate();
         }
     }
@@ -149,7 +149,7 @@
             // The view displays three modes,
             //   1) App icon in the center
             //   2) Preload icon in the center
-            //   3) Setup icon in the center and app icon in the top right corner.
+            //   3) App icon in the center with a setup icon on the top left corner.
             if (mDisabledForSafeMode) {
                 FastBitmapDrawable disabledIcon = info.newIcon(getContext());
                 disabledIcon.setIsDisabled(true);
diff --git a/src/com/android/launcher3/widget/util/WidgetSizes.java b/src/com/android/launcher3/widget/util/WidgetSizes.java
index 5c8ea72..fcc0dde 100644
--- a/src/com/android/launcher3/widget/util/WidgetSizes.java
+++ b/src/com/android/launcher3/widget/util/WidgetSizes.java
@@ -99,11 +99,13 @@
      */
     public static Bundle getWidgetSizeOptions(Context context, ComponentName provider, int spanX,
             int spanY) {
+        boolean shouldInsetWidgets =
+                LauncherAppState.getIDP(context).getDeviceProfile(context).shouldInsetWidgets();
         ArrayList<SizeF> sizes = getWidgetSizes(context, spanX, spanY);
         Rect padding = getDefaultPaddingForWidget(context, provider, null);
         float density = context.getResources().getDisplayMetrics().density;
-        float xPaddingDips = (padding.left + padding.right) / density;
-        float yPaddingDips = (padding.top + padding.bottom) / density;
+        float xPaddingDips = shouldInsetWidgets ? (padding.left + padding.right) / density : 0;
+        float yPaddingDips = shouldInsetWidgets ? (padding.top + padding.bottom) / density : 0;
 
         ArrayList<SizeF> paddedSizes = sizes.stream()
                 .map(size -> new SizeF(
diff --git a/src_shortcuts_overrides/com/android/launcher3/model/WidgetsModel.java b/src_shortcuts_overrides/com/android/launcher3/model/WidgetsModel.java
index 51c5b12..a66b031 100644
--- a/src_shortcuts_overrides/com/android/launcher3/model/WidgetsModel.java
+++ b/src_shortcuts_overrides/com/android/launcher3/model/WidgetsModel.java
@@ -15,6 +15,7 @@
 import android.util.Log;
 
 import androidx.annotation.Nullable;
+import androidx.collection.ArrayMap;
 
 import com.android.launcher3.AppFilter;
 import com.android.launcher3.InvariantDeviceProfile;
@@ -37,6 +38,7 @@
 
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collection;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -158,34 +160,29 @@
             Log.d(TAG, "addWidgetsAndShortcuts, widgetsShortcuts#=" + rawWidgetsShortcuts.size());
         }
 
-        // Temporary list for {@link PackageItemInfos} to avoid having to go through
+        // Temporary cache for {@link PackageItemInfos} to avoid having to go through
         // {@link mPackageItemInfos} to locate the key to be used for {@link #mWidgetsList}
-        HashMap<WidgetPackageOrCategoryKey, PackageItemInfo> tmpPackageItemInfos = new HashMap<>();
+        PackageItemInfoCache packageItemInfoCache = new PackageItemInfoCache();
 
-        // Clear the lists only if this is an update on all widgets and shortcuts. If packageUser
-        // isn't null, only updates the shortcuts and widgets for the app represented in
-        // packageUser.
         if (packageUser == null) {
+            // Clear the list if this is an update on all widgets and shortcuts.
             mWidgetsList.clear();
+        } else {
+            // Otherwise, only clear the widgets and shortcuts for the changed package.
+            mWidgetsList.remove(
+                    packageItemInfoCache.getOrCreate(new WidgetPackageOrCategoryKey(packageUser)));
         }
+
         // add and update.
         mWidgetsList.putAll(rawWidgetsShortcuts.stream()
                 .filter(new WidgetValidityCheck(app))
-                .collect(Collectors.groupingBy(item -> {
-                    WidgetPackageOrCategoryKey packageUserKey = getWidgetPackageOrCategoryKey(item);
-                    PackageItemInfo pInfo = tmpPackageItemInfos.get(packageUserKey);
-                    if (pInfo == null) {
-                        pInfo = new PackageItemInfo(item.componentName.getPackageName(),
-                                packageUserKey.mCategory);
-                        pInfo.user = item.user;
-                        tmpPackageItemInfos.put(packageUserKey,  pInfo);
-                    }
-                    return pInfo;
-                })));
+                .collect(Collectors.groupingBy(item ->
+                        packageItemInfoCache.getOrCreate(getWidgetPackageOrCategoryKey(item))
+                )));
 
         // Update each package entry
         IconCache iconCache = app.getIconCache();
-        for (PackageItemInfo p : tmpPackageItemInfos.values()) {
+        for (PackageItemInfo p : packageItemInfoCache.values()) {
             iconCache.getTitleAndIconForApp(p, true /* userLowResIcon */);
         }
     }
@@ -289,6 +286,10 @@
         public final UserHandle mUser;
         private final int mHashCode;
 
+        WidgetPackageOrCategoryKey(PackageUserKey key) {
+            this(key.mPackageName, key.mUser);
+        }
+
         WidgetPackageOrCategoryKey(String packageName, UserHandle user) {
             this(packageName,  PackageItemInfo.NO_CATEGORY, user);
         }
@@ -310,4 +311,22 @@
             return mHashCode;
         }
     }
+
+    private static final class PackageItemInfoCache {
+        private final Map<WidgetPackageOrCategoryKey, PackageItemInfo> mMap = new ArrayMap<>();
+
+        PackageItemInfo getOrCreate(WidgetPackageOrCategoryKey key) {
+            PackageItemInfo pInfo = mMap.get(key);
+            if (pInfo == null) {
+                pInfo = new PackageItemInfo(key.mPackage, key.mCategory);
+                pInfo.user = key.mUser;
+                mMap.put(key,  pInfo);
+            }
+            return pInfo;
+        }
+
+        Collection<PackageItemInfo> values() {
+            return mMap.values();
+        }
+    }
 }
\ No newline at end of file