Refactor FolderInsetAnimationCallback to be used with any view

- Update ic_corp_off icon to outline
- Remove shadow from work toggle
- Translate work fab when keyboard is shown

Screenshot: https://screenshot.googleplex.com/593tEg7bE4kSS4y

Bug: 191251404
Bug: 191250785
Test: local
Change-Id: Ie7dddfd17eb90575a1e1f67e281070dd8d268f8d
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/dimens.xml b/res/values/dimens.xml
index 12f50e5..481b3b1 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -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/src/com/android/launcher3/allapps/AllAppsContainerView.java b/src/com/android/launcher3/allapps/AllAppsContainerView.java
index 7003df1..90bb5c8 100644
--- a/src/com/android/launcher3/allapps/AllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsContainerView.java
@@ -132,7 +132,6 @@
     private ScrimView mScrimView;
     private int mHeaderColor;
 
-
     public AllAppsContainerView(Context context) {
         this(context, null);
     }
@@ -572,6 +571,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..31f0c4f 100644
--- a/src/com/android/launcher3/allapps/WorkModeSwitch.java
+++ b/src/com/android/launcher3/allapps/WorkModeSwitch.java
@@ -18,6 +18,7 @@
 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 +27,15 @@
 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.Utilities;
+import com.android.launcher3.anim.KeyboardInsetAnimationCallback;
 import com.android.launcher3.pm.UserCache;
 
 /**
@@ -42,6 +46,10 @@
     private Rect mInsets = new Rect();
     private boolean mWorkEnabled;
 
+
+    @Nullable
+    private KeyboardInsetAnimationCallback mKeyboardInsetAnimationCallback;
+
     public WorkModeSwitch(Context context) {
         this(context, null, 0);
     }
@@ -58,6 +66,10 @@
     protected void onFinishInflate() {
         super.onFinishInflate();
         setOnClickListener(this);
+        if (Utilities.ATLEAST_R) {
+            mKeyboardInsetAnimationCallback = new KeyboardInsetAnimationCallback(this);
+            setWindowInsetsAnimationCallback(mKeyboardInsetAnimationCallback);
+        }
     }
 
     @Override
@@ -117,4 +129,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/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..00ce80f 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");
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/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) {