Merge "Change dark overview scrim color to Neutral 2 palette with 35 luminosity." into sc-v2-dev
diff --git a/Android.bp b/Android.bp
index 45d022f..43d28c9 100644
--- a/Android.bp
+++ b/Android.bp
@@ -224,7 +224,6 @@
     srcs: ["proguard.flags"],
 }
 
-
 // Library with all the dependencies for building Launcher Go
 android_library {
     name: "LauncherGoResLib",
@@ -253,3 +252,24 @@
     },
 }
 
+// Build rule for Quickstep library
+android_library {
+    name: "Launcher3QuickStepLib",
+    srcs: [
+        ":launcher-src-no-build-config",
+    ],
+    resource_dirs: [
+        "quickstep/res",
+    ],
+    static_libs: [
+        "SystemUI-statsd",
+        "SystemUISharedLib",
+        "Launcher3CommonDepsLib"
+    ],
+    manifest: "quickstep/AndroidManifest.xml",
+    platform_apis: true,
+    min_sdk_version: "current",
+    lint: {
+        baseline_filename: "lint-baseline-launcher3.xml",
+    },
+}
diff --git a/Android.mk b/Android.mk
index c222f24..c1dbc53 100644
--- a/Android.mk
+++ b/Android.mk
@@ -53,42 +53,6 @@
 include $(BUILD_PACKAGE)
 
 #
-# Build rule for Quickstep library.
-#
-include $(CLEAR_VARS)
-LOCAL_USE_AAPT2 := true
-LOCAL_AAPT2_ONLY := true
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_STATIC_JAVA_LIBRARIES := \
-    SystemUI-statsd \
-    SystemUISharedLib
-ifneq (,$(wildcard frameworks/base))
-  LOCAL_PRIVATE_PLATFORM_APIS := true
-else
-  LOCAL_SDK_VERSION := system_current
-  LOCAL_MIN_SDK_VERSION := 26
-endif
-LOCAL_MODULE := Launcher3QuickStepLib
-LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
-LOCAL_LICENSE_CONDITIONS := notice
-LOCAL_NOTICE_FILE := $(LOCAL_PATH)/NOTICE
-LOCAL_PRIVILEGED_MODULE := true
-LOCAL_STATIC_ANDROID_LIBRARIES := Launcher3CommonDepsLib
-
-LOCAL_SRC_FILES := \
-    $(call all-java-files-under, src) \
-    $(call all-java-files-under, quickstep/src) \
-    $(call all-java-files-under, src_shortcuts_overrides)
-
-LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/quickstep/res
-LOCAL_PROGUARD_ENABLED := disabled
-
-
-LOCAL_MANIFEST_FILE := quickstep/AndroidManifest.xml
-include $(BUILD_STATIC_JAVA_LIBRARY)
-
-#
 # Build rule for Quickstep app.
 #
 include $(CLEAR_VARS)
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 8066816..c72f62d 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -31,6 +31,7 @@
         android:fullBackupOnly="true"
         android:fullBackupContent="@xml/backupscheme"
         android:hardwareAccelerated="true"
+        android:debuggable="true"
         android:icon="@drawable/ic_launcher_home"
         android:label="@string/derived_app_name"
         android:theme="@style/AppTheme"
diff --git a/buglist_with_title.txt b/buglist_with_title.txt
deleted file mode 100644
index aa8b413..0000000
--- a/buglist_with_title.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-144170434  twickham  P1        FIXED   Improve Overview ->  Home transition ----
-149934536  twickham  P2        FIXED   Update gesture nav pullback logic ----
-154951045  peanutbutter  P1        FIXED   Odd animation occuring at times when swiping to home ----
-154964045  awickham  P2        FIXED   "Clear all" text is not in the middle of app's window vertically ----
-158701272  twickham  P4        FIXED   Discontinuities when long-swiping to home ----
-160361464  tracyzhou  P2        FIXED   Place launcher above the target app in live tile mode ----
-160568387  twickham  P2        FIXED   Can't get to app switcher by swiping up (motion pause not detected) ----
-160718310  xuqiu     P1        FIXED   With "Select" overview action selected, App icon is missing in other overview apps after orientation change ----
-160748731  sunnygoyal  P2        ASSIGNED  Unify prediction model with Launcher model ----
-160759508  twickham  P2        FIXED   Swipe up cannot back to home screen in overview. ----
-161273376  xuqiu     P2        FIXED   [Overview Actions] Add logging and helpful messages ----
-161536946  twickham  P2        FIXED   Haptics don't indicate snap-to in overview,  ----
-161685099  winsonc   P2        FIXED   Screen still stay at the quick settings/notification when I swipe up with 3 finger to check the all apps. ----
-161801331  hyunyoungs  P2        FIXED   Change AllAppsSearch plugin to support only data fetch ----
-161901771  xuqiu     P1        FIXED   Overlapping layer of highlights with app layout getting darker when keep rotating the device from "Feedback" viewpoint in split screen ----
-161939759  sunnygoyal  P2        FIXED   RD1A: Going to overview in landscape mode clips the screen content ----
-162012217  perumaal  P2        ASSIGNED  Leaked Activity Caused by Gleams ----
-162454040  bookatz   P2        ASSIGNED  Create multiuser test that checks that opening an app works properly ----
-162480567  sfufa     P4        FIXED   Enable Item Decorations for search items ----
-162564471  tracyzhou  P2        FIXED   [Live tile] Handle tapping overview actions in live tile mode ----
-162623012  zakcohen  P1        ASSIGNED  Enable chips flag ----
-162812884  winsonc   P2        ASSIGNED  [R]The color have not changed in some page after turning on the dark theme. ----
-162861289  hyunyoungs  P2        FIXED   Add FocusIndicator support to DEVICE_SEARCH feature in S ----
-162871508  sfufa     P2        ASSIGNED  Introduce support for Hero app section ----
diff --git a/quickstep/Android.bp b/quickstep/Android.bp
index 38c9919..7b3e6c4 100644
--- a/quickstep/Android.bp
+++ b/quickstep/Android.bp
@@ -26,3 +26,19 @@
     path: "robolectric_tests",
     srcs: ["robolectric_tests/src/**/*.java"],
 }
+
+filegroup {
+    name: "launcher3-quickstep-tests-src",
+    path: "tests",
+    srcs: ["tests/src/**/*.java"],
+}
+
+filegroup {
+    name: "launcher3-quickstep-oop-tests-src",
+    path: "tests",
+    srcs: [
+        "tests/src/com/android/quickstep/NavigationModeSwitchRule.java",
+        "tests/src/com/android/quickstep/AbstractQuickStepTest.java",
+        "tests/src/com/android/quickstep/TaplTestsQuickstep.java",
+    ]
+}
diff --git a/quickstep/res/drawable/button_taskbar_edu_bordered.xml b/quickstep/res/drawable/button_taskbar_edu_bordered.xml
new file mode 100644
index 0000000..47f8e8f
--- /dev/null
+++ b/quickstep/res/drawable/button_taskbar_edu_bordered.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<inset
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
+    <ripple
+        android:color="?android:attr/colorControlHighlight">
+        <item>
+            <shape android:shape="rectangle">
+                <corners android:radius="16dp"  />
+                <solid android:color="?androidprv:attr/colorSurface"/>
+                <stroke
+                    android:width="1dp"
+                    android:color="?androidprv:attr/colorAccentPrimaryVariant"/>
+            </shape>
+        </item>
+    </ripple>
+</inset>
\ No newline at end of file
diff --git a/quickstep/res/drawable/button_taskbar_edu_colored.xml b/quickstep/res/drawable/button_taskbar_edu_colored.xml
new file mode 100644
index 0000000..70bfc9f
--- /dev/null
+++ b/quickstep/res/drawable/button_taskbar_edu_colored.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<inset
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
+    <ripple
+        android:color="?android:attr/colorControlHighlight">
+        <item>
+            <shape android:shape="rectangle">
+                <corners android:radius="16dp"/>
+                <solid android:color="?androidprv:attr/colorAccentPrimary"/>
+            </shape>
+        </item>
+    </ripple>
+</inset>
\ No newline at end of file
diff --git a/quickstep/res/drawable/gesture_tutorial_finger_dot.xml b/quickstep/res/drawable/gesture_tutorial_finger_dot.xml
new file mode 100644
index 0000000..5f8aafd
--- /dev/null
+++ b/quickstep/res/drawable/gesture_tutorial_finger_dot.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="oval">
+    <solid android:color="@color/gesture_tutorial_primary_color" />
+    <size android:width="92dp" android:height="92dp"/>
+</shape>
\ No newline at end of file
diff --git a/quickstep/res/drawable/gesture_tutorial_motion_back.xml b/quickstep/res/drawable/gesture_tutorial_motion_back.xml
deleted file mode 100644
index a6860fa..0000000
--- a/quickstep/res/drawable/gesture_tutorial_motion_back.xml
+++ /dev/null
@@ -1,1233 +0,0 @@
-<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:aapt="http://schemas.android.com/aapt">
-    <target android:name="_R_G_L_3_G_L_0_G_L_0_G_D_0_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="133"
-                    android:propertyName="fillAlpha"
-                    android:startOffset="1217"
-                    android:valueFrom="1"
-                    android:valueTo="0"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_3_G_L_0_G_L_0_G_D_1_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="133"
-                    android:propertyName="fillAlpha"
-                    android:startOffset="1217"
-                    android:valueFrom="1"
-                    android:valueTo="0"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_3_G_L_0_G_L_0_G_D_2_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="133"
-                    android:propertyName="fillAlpha"
-                    android:startOffset="1217"
-                    android:valueFrom="1"
-                    android:valueTo="0"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_3_G_L_0_G_L_0_G_D_3_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="133"
-                    android:propertyName="fillAlpha"
-                    android:startOffset="1217"
-                    android:valueFrom="1"
-                    android:valueTo="0"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_3_G_L_0_G_L_0_G_D_4_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="133"
-                    android:propertyName="fillAlpha"
-                    android:startOffset="1217"
-                    android:valueFrom="1"
-                    android:valueTo="0"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_3_G_L_0_G_L_0_G_D_5_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="133"
-                    android:propertyName="fillAlpha"
-                    android:startOffset="1217"
-                    android:valueFrom="1"
-                    android:valueTo="0"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_3_G_L_0_G_L_0_G_D_6_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="133"
-                    android:propertyName="fillAlpha"
-                    android:startOffset="1217"
-                    android:valueFrom="1"
-                    android:valueTo="0"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_3_G_L_0_G_L_0_G_D_7_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="133"
-                    android:propertyName="fillAlpha"
-                    android:startOffset="1217"
-                    android:valueFrom="1"
-                    android:valueTo="0"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_3_G_L_0_G_L_0_G_D_8_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="133"
-                    android:propertyName="fillAlpha"
-                    android:startOffset="1217"
-                    android:valueFrom="1"
-                    android:valueTo="0"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_3_G_L_0_G_L_0_G_D_9_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="133"
-                    android:propertyName="fillAlpha"
-                    android:startOffset="1217"
-                    android:valueFrom="1"
-                    android:valueTo="0"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_3_G_L_0_G_L_0_G_D_10_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="133"
-                    android:propertyName="fillAlpha"
-                    android:startOffset="1217"
-                    android:valueFrom="1"
-                    android:valueTo="0"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_3_G_L_0_G_L_0_G_D_11_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="133"
-                    android:propertyName="fillAlpha"
-                    android:startOffset="1217"
-                    android:valueFrom="1"
-                    android:valueTo="0"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_3_G_L_0_G_L_0_G_D_12_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="133"
-                    android:propertyName="fillAlpha"
-                    android:startOffset="1217"
-                    android:valueFrom="1"
-                    android:valueTo="0"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_3_G_L_0_G_L_0_G_D_13_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="133"
-                    android:propertyName="fillAlpha"
-                    android:startOffset="1217"
-                    android:valueFrom="1"
-                    android:valueTo="0"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_3_G_L_0_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="1367"
-                    android:valueFrom="1"
-                    android:valueTo="0"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_3_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="283"
-                    android:propertyName="scaleX"
-                    android:startOffset="1217"
-                    android:valueFrom="1"
-                    android:valueTo="0.88012"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,0.536 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="283"
-                    android:propertyName="scaleY"
-                    android:startOffset="1217"
-                    android:valueFrom="1"
-                    android:valueTo="0.88012"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,0.536 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_3_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="2417"
-                    android:valueFrom="1"
-                    android:valueTo="0"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_2_G_L_0_G_L_0_G_D_0_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="333"
-                    android:propertyName="fillAlpha"
-                    android:startOffset="1417"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_2_G_L_0_G_L_0_G_D_1_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="333"
-                    android:propertyName="fillAlpha"
-                    android:startOffset="1417"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_2_G_L_0_G_L_0_G_D_2_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="333"
-                    android:propertyName="fillAlpha"
-                    android:startOffset="1417"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_2_G_L_0_G_L_0_G_D_3_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="333"
-                    android:propertyName="fillAlpha"
-                    android:startOffset="1417"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_2_G_L_0_G_L_0_G_D_4_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="333"
-                    android:propertyName="fillAlpha"
-                    android:startOffset="1417"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_2_G_L_0_G_L_0_G_D_5_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="333"
-                    android:propertyName="fillAlpha"
-                    android:startOffset="1417"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_2_G_L_0_G_L_0_G_D_6_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="333"
-                    android:propertyName="fillAlpha"
-                    android:startOffset="1417"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_2_G_L_0_G_L_0_G_D_7_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="333"
-                    android:propertyName="fillAlpha"
-                    android:startOffset="1417"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_2_G_L_0_G_L_0_G_D_8_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="333"
-                    android:propertyName="fillAlpha"
-                    android:startOffset="1417"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_2_G_L_0_G_L_0_G_D_9_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="333"
-                    android:propertyName="fillAlpha"
-                    android:startOffset="1417"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_2_G_L_0_G_L_0_G_D_10_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="333"
-                    android:propertyName="fillAlpha"
-                    android:startOffset="1417"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_2_G_L_0_G_L_0_G_D_11_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="333"
-                    android:propertyName="fillAlpha"
-                    android:startOffset="1417"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_2_G_L_0_G_L_0_G_D_12_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="333"
-                    android:propertyName="fillAlpha"
-                    android:startOffset="1417"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_2_G_L_0_G_L_0_G_D_13_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="333"
-                    android:propertyName="fillAlpha"
-                    android:startOffset="1417"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_2_G_L_0_G_L_0_G_D_14_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="333"
-                    android:propertyName="fillAlpha"
-                    android:startOffset="1417"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_2_G_L_0_G_L_0_G_D_15_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="333"
-                    android:propertyName="fillAlpha"
-                    android:startOffset="1417"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_2_G_L_0_G_L_0_G_D_16_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="333"
-                    android:propertyName="fillAlpha"
-                    android:startOffset="1417"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_2_G_L_0_G_L_0_G_D_17_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="333"
-                    android:propertyName="fillAlpha"
-                    android:startOffset="1417"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_2_G_L_0_G_L_0_G_D_18_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="333"
-                    android:propertyName="fillAlpha"
-                    android:startOffset="1417"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_2_G_L_0_G_L_0_G_D_19_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="333"
-                    android:propertyName="fillAlpha"
-                    android:startOffset="1417"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_2_G_L_0_G_L_0_G_D_20_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="333"
-                    android:propertyName="fillAlpha"
-                    android:startOffset="1417"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_2_G_L_0_G_L_0_G_D_21_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="333"
-                    android:propertyName="fillAlpha"
-                    android:startOffset="1417"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_2_G_L_0_G_L_0_G_D_22_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="333"
-                    android:propertyName="fillAlpha"
-                    android:startOffset="1417"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_2_G_L_0_G_L_0_G_D_23_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="333"
-                    android:propertyName="fillAlpha"
-                    android:startOffset="1417"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_2_G_L_0_G_L_0_G_D_24_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="333"
-                    android:propertyName="fillAlpha"
-                    android:startOffset="1417"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_2_G_L_0_G_L_0_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="1417"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_2_G_L_0_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="1417"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_2_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="1417"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_1_G_D_0_P_0_G_0_T_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="667"
-                    android:pathData="M 123.282,129.757C 134.28199999999998,129.757 178.282,129.757 189.282,129.757"
-                    android:propertyName="translateXY"
-                    android:propertyXName="translateX"
-                    android:propertyYName="translateY"
-                    android:startOffset="217">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.5,0 0,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="333"
-                    android:pathData="M 189.282,129.757C 189.282,129.757 189.282,129.757 189.282,129.757"
-                    android:propertyName="translateXY"
-                    android:propertyXName="translateX"
-                    android:propertyYName="translateY"
-                    android:startOffset="883">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0.333 0.667,0.667 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="250"
-                    android:pathData="M 189.282,129.757C 178.282,129.757 134.28199999999998,129.757 123.282,129.757"
-                    android:propertyName="translateXY"
-                    android:propertyXName="translateX"
-                    android:propertyYName="translateY"
-                    android:startOffset="1217">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_1_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="217"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_1_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="2383"
-                    android:valueFrom="1"
-                    android:valueTo="0"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_0_G_D_0_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="217"
-                    android:propertyName="fillAlpha"
-                    android:startOffset="0"
-                    android:valueFrom="0"
-                    android:valueTo="0.75"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="967"
-                    android:propertyName="fillAlpha"
-                    android:startOffset="217"
-                    android:valueFrom="0.75"
-                    android:valueTo="0.75"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="167"
-                    android:propertyName="fillAlpha"
-                    android:startOffset="1183"
-                    android:valueFrom="0.75"
-                    android:valueTo="0"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0 0.833,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_0_G_D_0_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="217"
-                    android:propertyName="pathData"
-                    android:startOffset="0"
-                    android:valueFrom="M-206.5 13.5 C-186.34,13.5 -170,29.84 -170,50 C-170,70.16 -186.34,86.5 -206.5,86.5 C-226.66,86.5 -243,70.16 -243,50 C-243,29.84 -226.66,13.5 -206.5,13.5c "
-                    android:valueTo="M-206 0 C-178.39,0 -156,22.39 -156,50 C-156,77.61 -178.39,100 -206,100 C-233.61,100 -256,77.61 -256,50 C-256,22.39 -233.61,0 -206,0c "
-                    android:valueType="pathType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="583"
-                    android:propertyName="pathData"
-                    android:startOffset="217"
-                    android:valueFrom="M-206 0 C-178.39,0 -156,22.39 -156,50 C-156,77.61 -178.39,100 -206,100 C-233.61,100 -256,77.61 -256,50 C-256,22.39 -233.61,0 -206,0c "
-                    android:valueTo="M0 0 C27.61,0 50,22.39 50,50 C50,77.61 27.61,100 0,100 C-27.61,100 -50,77.61 -50,50 C-50,22.39 -27.61,0 0,0c "
-                    android:valueType="pathType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.5,0 0.5,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="383"
-                    android:propertyName="pathData"
-                    android:startOffset="800"
-                    android:valueFrom="M0 0 C27.61,0 50,22.39 50,50 C50,77.61 27.61,100 0,100 C-27.61,100 -50,77.61 -50,50 C-50,22.39 -27.61,0 0,0c "
-                    android:valueTo="M0 0 C27.61,0 50,22.39 50,50 C50,77.61 27.61,100 0,100 C-27.61,100 -50,77.61 -50,50 C-50,22.39 -27.61,0 0,0c "
-                    android:valueType="pathType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="167"
-                    android:propertyName="pathData"
-                    android:startOffset="1183"
-                    android:valueFrom="M0 0 C27.61,0 50,22.39 50,50 C50,77.61 27.61,100 0,100 C-27.61,100 -50,77.61 -50,50 C-50,22.39 -27.61,0 0,0c "
-                    android:valueTo="M0 13.5 C20.16,13.5 36.5,29.84 36.5,50 C36.5,70.16 20.16,86.5 0,86.5 C-20.16,86.5 -36.5,70.16 -36.5,50 C-36.5,29.84 -20.16,13.5 0,13.5c "
-                    android:valueType="pathType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="time_group">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="1767"
-                    android:propertyName="translateX"
-                    android:startOffset="0"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <aapt:attr name="android:drawable">
-        <vector
-            android:width="412dp"
-            android:height="892dp"
-            android:viewportHeight="892"
-            android:viewportWidth="412">
-            <group android:name="_R_G">
-                <group
-                    android:name="_R_G_L_4_G"
-                    android:translateX="206"
-                    android:translateY="446">
-                    <path
-                        android:name="_R_G_L_4_G_D_0_P_0"
-                        android:fillAlpha="1"
-                        android:fillColor="#dadce0"
-                        android:fillType="nonZero"
-                        android:pathData=" M206 -446 C206,-446 206,446 206,446 C206,446 -206,446 -206,446 C-206,446 -206,-446 -206,-446 C-206,-446 206,-446 206,-446c " />
-                </group>
-                <group
-                    android:name="_R_G_L_3_G"
-                    android:pivotX="206"
-                    android:pivotY="446"
-                    android:scaleX="1"
-                    android:scaleY="1">
-                    <group android:name="_R_G_L_3_G_L_0_G">
-                        <group android:name="_R_G_L_3_G_L_0_G_L_0_G">
-                            <path
-                                android:name="_R_G_L_3_G_L_0_G_L_0_G_D_0_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#f1f3f4"
-                                android:fillType="nonZero"
-                                android:pathData=" M412 101 C412,101 412,892 412,892 C412,892 0,892 0,892 C0,892 0,101 0,101 C0,101 412,101 412,101c " />
-                            <path
-                                android:name="_R_G_L_3_G_L_0_G_L_0_G_D_1_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#e8eaed"
-                                android:fillType="nonZero"
-                                android:pathData=" M412 0 C412,0 412,101 412,101 C412,101 0,101 0,101 C0,101 0,0 0,0 C0,0 412,0 412,0c " />
-                            <path
-                                android:name="_R_G_L_3_G_L_0_G_L_0_G_D_2_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#dadce0"
-                                android:fillType="nonZero"
-                                android:pathData=" M383 804 C383,816.15 373.15,826 361,826 C361,826 51,826 51,826 C38.85,826 29,816.15 29,804 C29,791.85 38.85,782 51,782 C51,782 361,782 361,782 C373.15,782 383,791.85 383,804c " />
-                            <path
-                                android:name="_R_G_L_3_G_L_0_G_L_0_G_D_3_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#dadce0"
-                                android:fillType="nonZero"
-                                android:pathData=" M201 47 C201,47 201,75 201,75 C201,77.21 199.21,79 197,79 C197,79 38,79 38,79 C35.79,79 34,77.21 34,75 C34,75 34,47 34,47 C34,44.79 35.79,43 38,43 C38,43 197,43 197,43 C199.21,43 201,44.79 201,47c " />
-                            <path
-                                android:name="_R_G_L_3_G_L_0_G_L_0_G_D_4_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#dadce0"
-                                android:fillType="nonZero"
-                                android:pathData=" M388 47 C388,47 388,75 388,75 C388,77.21 386.21,79 384,79 C384,79 356,79 356,79 C353.79,79 352,77.21 352,75 C352,75 352,47 352,47 C352,44.79 353.79,43 356,43 C356,43 384,43 384,43 C386.21,43 388,44.79 388,47c " />
-                            <path
-                                android:name="_R_G_L_3_G_L_0_G_L_0_G_D_5_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#dadce0"
-                                android:fillType="nonZero"
-                                android:pathData=" M336 47 C336,47 336,75 336,75 C336,77.21 334.21,79 332,79 C332,79 304,79 304,79 C301.79,79 300,77.21 300,75 C300,75 300,47 300,47 C300,44.79 301.79,43 304,43 C304,43 332,43 332,43 C334.21,43 336,44.79 336,47c " />
-                            <path
-                                android:name="_R_G_L_3_G_L_0_G_L_0_G_D_6_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#dadce0"
-                                android:fillType="nonZero"
-                                android:pathData=" M70 618 C70,630.15 60.15,640 48,640 C35.85,640 26,630.15 26,618 C26,605.85 35.85,596 48,596 C60.15,596 70,605.85 70,618c " />
-                            <path
-                                android:name="_R_G_L_3_G_L_0_G_L_0_G_D_7_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#dadce0"
-                                android:fillType="nonZero"
-                                android:pathData=" M70 396 C70,408.15 60.15,418 48,418 C35.85,418 26,408.15 26,396 C26,383.85 35.85,374 48,374 C60.15,374 70,383.85 70,396c " />
-                            <path
-                                android:name="_R_G_L_3_G_L_0_G_L_0_G_D_8_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#bdc1c6"
-                                android:fillType="nonZero"
-                                android:pathData=" M394 248 C394,248 394,324 394,324 C394,333.94 385.94,342 376,342 C376,342 142,342 142,342 C132.06,342 124,333.94 124,324 C124,324 124,248 124,248 C124,238.06 132.06,230 142,230 C142,230 376,230 376,230 C385.94,230 394,238.06 394,248c " />
-                            <path
-                                android:name="_R_G_L_3_G_L_0_G_L_0_G_D_9_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#bdc1c6"
-                                android:fillType="nonZero"
-                                android:pathData=" M393.94 468.38 C393.94,468.38 393.94,481.5 393.94,481.5 C393.94,483.71 392.15,485.5 389.94,485.5 C389.94,485.5 303.5,485.5 303.5,485.5 C301.29,485.5 299.5,483.71 299.5,481.5 C299.5,481.5 299.5,468.38 299.5,468.38 C299.5,466.17 301.29,464.38 303.5,464.38 C303.5,464.38 389.94,464.38 389.94,464.38 C392.15,464.38 393.94,466.17 393.94,468.38c  M394 468 C394,477.67 386.17,485.5 376.5,485.5 C376.5,485.5 290,485.5 290,485.5 C280.33,485.5 272.5,477.67 272.5,468 C272.5,458.34 280.33,450.5 290,450.5 C290,450.5 376.5,450.5 376.5,450.5 C386.17,450.5 394,458.34 394,468c " />
-                            <path
-                                android:name="_R_G_L_3_G_L_0_G_L_0_G_D_10_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#bdc1c6"
-                                android:fillType="nonZero"
-                                android:pathData=" M394 494 C394,494 394,547 394,547 C394,549.21 392.21,551 390,551 C390,551 164,551 164,551 C161.79,551 160,549.21 160,547 C160,547 160,494 160,494 C160,491.79 161.79,490 164,490 C164,490 390,490 390,490 C392.21,490 394,491.79 394,494c  M394 508 C394,508 394,545 394,545 C394,554.94 385.94,563 376,563 C376,563 142,563 142,563 C132.06,563 124,554.94 124,545 C124,545 124,508 124,508 C124,498.06 132.06,490 142,490 C142,490 376,490 376,490 C385.94,490 394,498.06 394,508c " />
-                            <path
-                                android:name="_R_G_L_3_G_L_0_G_L_0_G_D_11_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#bdc1c6"
-                                android:fillType="nonZero"
-                                android:pathData=" M394 690 C394,690 394,727 394,727 C394,736.94 385.94,745 376,745 C376,745 142,745 142,745 C132.06,745 124,736.94 124,727 C124,727 124,690 124,690 C124,680.06 132.06,672 142,672 C142,672 376,672 376,672 C385.94,672 394,680.06 394,690c " />
-                            <path
-                                android:name="_R_G_L_3_G_L_0_G_L_0_G_D_12_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#e8eaed"
-                                android:fillType="nonZero"
-                                android:pathData=" M267.5 617 C267.5,626.67 259.67,634.5 250,634.5 C250,634.5 104.5,634.5 104.5,634.5 C94.84,634.5 87,626.67 87,617 C87,607.34 94.84,599.5 104.5,599.5 C104.5,599.5 250,599.5 250,599.5 C259.67,599.5 267.5,607.34 267.5,617c " />
-                            <path
-                                android:name="_R_G_L_3_G_L_0_G_L_0_G_D_13_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#e8eaed"
-                                android:fillType="nonZero"
-                                android:pathData=" M299 395.5 C299,405.17 291.16,413 281.5,413 C281.5,413 104.5,413 104.5,413 C94.84,413 87,405.17 87,395.5 C87,385.84 94.84,378 104.5,378 C104.5,378 281.5,378 281.5,378 C291.16,378 299,385.84 299,395.5c " />
-                        </group>
-                    </group>
-                </group>
-                <group
-                    android:name="_R_G_L_2_G"
-                    android:scaleY="0">
-                    <group
-                        android:name="_R_G_L_2_G_L_0_G"
-                        android:scaleY="0">
-                        <group
-                            android:name="_R_G_L_2_G_L_0_G_L_0_G"
-                            android:scaleY="0">
-                            <path
-                                android:name="_R_G_L_2_G_L_0_G_L_0_G_D_0_P_0"
-                                android:fillAlpha="0"
-                                android:fillColor="#dadce0"
-                                android:fillType="nonZero"
-                                android:pathData=" M412 0 C412,0 412,892 412,892 C412,892 0,892 0,892 C0,892 0,0 0,0 C0,0 412,0 412,0c " />
-                            <path
-                                android:name="_R_G_L_2_G_L_0_G_L_0_G_D_1_P_0"
-                                android:fillAlpha="0"
-                                android:fillColor="#e8eaed"
-                                android:fillType="nonZero"
-                                android:pathData=" M412 0 C412,0 412,101 412,101 C412,101 0,101 0,101 C0,101 0,0 0,0 C0,0 412,0 412,0c " />
-                            <path
-                                android:name="_R_G_L_2_G_L_0_G_L_0_G_D_2_P_0"
-                                android:fillAlpha="0"
-                                android:fillColor="#bdc1c6"
-                                android:fillType="nonZero"
-                                android:pathData=" M195 143 C195,143 195,153 195,153 C195,155.21 193.21,157 191,157 C191,157 106,157 106,157 C103.79,157 102,155.21 102,153 C102,153 102,143 102,143 C102,140.79 103.79,139 106,139 C106,139 191,139 191,139 C193.21,139 195,140.79 195,143c " />
-                            <path
-                                android:name="_R_G_L_2_G_L_0_G_L_0_G_D_3_P_0"
-                                android:fillAlpha="0"
-                                android:fillColor="#bdc1c6"
-                                android:fillType="nonZero"
-                                android:pathData=" M270 165 C270,165 270,173 270,173 C270,175.21 268.21,177 266,177 C266,177 106,177 106,177 C103.79,177 102,175.21 102,173 C102,173 102,165 102,165 C102,162.79 103.79,161 106,161 C106,161 266,161 266,161 C268.21,161 270,162.79 270,165c " />
-                            <path
-                                android:name="_R_G_L_2_G_L_0_G_L_0_G_D_4_P_0"
-                                android:fillAlpha="0"
-                                android:fillColor="#bdc1c6"
-                                android:fillType="nonZero"
-                                android:pathData=" M222 231 C222,231 222,241 222,241 C222,243.21 220.21,245 218,245 C218,245 106,245 106,245 C103.79,245 102,243.21 102,241 C102,241 102,231 102,231 C102,228.79 103.79,227 106,227 C106,227 218,227 218,227 C220.21,227 222,228.79 222,231c " />
-                            <path
-                                android:name="_R_G_L_2_G_L_0_G_L_0_G_D_5_P_0"
-                                android:fillAlpha="0"
-                                android:fillColor="#bdc1c6"
-                                android:fillType="nonZero"
-                                android:pathData=" M241 253 C241,253 241,261 241,261 C241,263.21 239.21,265 237,265 C237,265 106,265 106,265 C103.79,265 102,263.21 102,261 C102,261 102,253 102,253 C102,250.79 103.79,249 106,249 C106,249 237,249 237,249 C239.21,249 241,250.79 241,253c " />
-                            <path
-                                android:name="_R_G_L_2_G_L_0_G_L_0_G_D_6_P_0"
-                                android:fillAlpha="0"
-                                android:fillColor="#bdc1c6"
-                                android:fillType="nonZero"
-                                android:pathData=" M214 319 C214,319 214,329 214,329 C214,331.21 212.21,333 210,333 C210,333 106,333 106,333 C103.79,333 102,331.21 102,329 C102,329 102,319 102,319 C102,316.79 103.79,315 106,315 C106,315 210,315 210,315 C212.21,315 214,316.79 214,319c " />
-                            <path
-                                android:name="_R_G_L_2_G_L_0_G_L_0_G_D_7_P_0"
-                                android:fillAlpha="0"
-                                android:fillColor="#bdc1c6"
-                                android:fillType="nonZero"
-                                android:pathData=" M333 341 C333,341 333,349 333,349 C333,351.21 331.21,353 329,353 C329,353 106,353 106,353 C103.79,353 102,351.21 102,349 C102,349 102,341 102,341 C102,338.79 103.79,337 106,337 C106,337 329,337 329,337 C331.21,337 333,338.79 333,341c " />
-                            <path
-                                android:name="_R_G_L_2_G_L_0_G_L_0_G_D_8_P_0"
-                                android:fillAlpha="0"
-                                android:fillColor="#bdc1c6"
-                                android:fillType="nonZero"
-                                android:pathData=" M238 407 C238,407 238,417 238,417 C238,419.21 236.21,421 234,421 C234,421 106,421 106,421 C103.79,421 102,419.21 102,417 C102,417 102,407 102,407 C102,404.79 103.79,403 106,403 C106,403 234,403 234,403 C236.21,403 238,404.79 238,407c " />
-                            <path
-                                android:name="_R_G_L_2_G_L_0_G_L_0_G_D_9_P_0"
-                                android:fillAlpha="0"
-                                android:fillColor="#bdc1c6"
-                                android:fillType="nonZero"
-                                android:pathData=" M295 429 C295,429 295,437 295,437 C295,439.21 293.21,441 291,441 C291,441 106,441 106,441 C103.79,441 102,439.21 102,437 C102,437 102,429 102,429 C102,426.79 103.79,425 106,425 C106,425 291,425 291,425 C293.21,425 295,426.79 295,429c " />
-                            <path
-                                android:name="_R_G_L_2_G_L_0_G_L_0_G_D_10_P_0"
-                                android:fillAlpha="0"
-                                android:fillColor="#bdc1c6"
-                                android:fillType="nonZero"
-                                android:pathData=" M168 495 C168,495 168,505 168,505 C168,507.21 166.21,509 164,509 C164,509 106,509 106,509 C103.79,509 102,507.21 102,505 C102,505 102,495 102,495 C102,492.79 103.79,491 106,491 C106,491 164,491 164,491 C166.21,491 168,492.79 168,495c " />
-                            <path
-                                android:name="_R_G_L_2_G_L_0_G_L_0_G_D_11_P_0"
-                                android:fillAlpha="0"
-                                android:fillColor="#bdc1c6"
-                                android:fillType="nonZero"
-                                android:pathData=" M269 517 C269,517 269,525 269,525 C269,527.21 267.21,529 265,529 C265,529 106,529 106,529 C103.79,529 102,527.21 102,525 C102,525 102,517 102,517 C102,514.79 103.79,513 106,513 C106,513 265,513 265,513 C267.21,513 269,514.79 269,517c " />
-                            <path
-                                android:name="_R_G_L_2_G_L_0_G_L_0_G_D_12_P_0"
-                                android:fillAlpha="0"
-                                android:fillColor="#bdc1c6"
-                                android:fillType="nonZero"
-                                android:pathData=" M235 583 C235,583 235,593 235,593 C235,595.21 233.21,597 231,597 C231,597 106,597 106,597 C103.79,597 102,595.21 102,593 C102,593 102,583 102,583 C102,580.79 103.79,579 106,579 C106,579 231,579 231,579 C233.21,579 235,580.79 235,583c " />
-                            <path
-                                android:name="_R_G_L_2_G_L_0_G_L_0_G_D_13_P_0"
-                                android:fillAlpha="0"
-                                android:fillColor="#bdc1c6"
-                                android:fillType="nonZero"
-                                android:pathData=" M295 605 C295,605 295,613 295,613 C295,615.21 293.21,617 291,617 C291,617 106,617 106,617 C103.79,617 102,615.21 102,613 C102,613 102,605 102,605 C102,602.79 103.79,601 106,601 C106,601 291,601 291,601 C293.21,601 295,602.79 295,605c " />
-                            <path
-                                android:name="_R_G_L_2_G_L_0_G_L_0_G_D_14_P_0"
-                                android:fillAlpha="0"
-                                android:fillColor="#bdc1c6"
-                                android:fillType="nonZero"
-                                android:pathData=" M223 671 C223,671 223,681 223,681 C223,683.21 221.21,685 219,685 C219,685 106,685 106,685 C103.79,685 102,683.21 102,681 C102,681 102,671 102,671 C102,668.79 103.79,667 106,667 C106,667 219,667 219,667 C221.21,667 223,668.79 223,671c " />
-                            <path
-                                android:name="_R_G_L_2_G_L_0_G_L_0_G_D_15_P_0"
-                                android:fillAlpha="0"
-                                android:fillColor="#bdc1c6"
-                                android:fillType="nonZero"
-                                android:pathData=" M246 693 C246,693 246,701 246,701 C246,703.21 244.21,705 242,705 C242,705 106,705 106,705 C103.79,705 102,703.21 102,701 C102,701 102,693 102,693 C102,690.79 103.79,689 106,689 C106,689 242,689 242,689 C244.21,689 246,690.79 246,693c " />
-                            <path
-                                android:name="_R_G_L_2_G_L_0_G_L_0_G_D_16_P_0"
-                                android:fillAlpha="0"
-                                android:fillColor="#bdc1c6"
-                                android:fillType="nonZero"
-                                android:pathData=" M388 798 C388,798 388,798 388,798 C388,813.45 375.45,826 360,826 C360,826 267,826 267,826 C251.55,826 239,813.45 239,798 C239,798 239,798 239,798 C239,782.55 251.55,770 267,770 C267,770 360,770 360,770 C375.45,770 388,782.55 388,798c " />
-                            <path
-                                android:name="_R_G_L_2_G_L_0_G_L_0_G_D_17_P_0"
-                                android:fillAlpha="0"
-                                android:fillColor="#f8f9fa"
-                                android:fillType="nonZero"
-                                android:pathData=" M377 47 C377,47 377,75 377,75 C377,77.21 375.21,79 373,79 C373,79 38,79 38,79 C35.79,79 34,77.21 34,75 C34,75 34,47 34,47 C34,44.79 35.79,43 38,43 C38,43 373,43 373,43 C375.21,43 377,44.79 377,47c " />
-                            <path
-                                android:name="_R_G_L_2_G_L_0_G_L_0_G_D_18_P_0"
-                                android:fillAlpha="0"
-                                android:fillColor="#9aa0a6"
-                                android:fillType="nonZero"
-                                android:pathData=" M82 157 C82,172.46 69.46,185 54,185 C38.54,185 26,172.46 26,157 C26,141.54 38.54,129 54,129 C69.46,129 82,141.54 82,157c " />
-                            <path
-                                android:name="_R_G_L_2_G_L_0_G_L_0_G_D_19_P_0"
-                                android:fillAlpha="0"
-                                android:fillColor="#9aa0a6"
-                                android:fillType="nonZero"
-                                android:pathData=" M82 245 C82,260.46 69.46,273 54,273 C38.54,273 26,260.46 26,245 C26,229.54 38.54,217 54,217 C69.46,217 82,229.54 82,245c " />
-                            <path
-                                android:name="_R_G_L_2_G_L_0_G_L_0_G_D_20_P_0"
-                                android:fillAlpha="0"
-                                android:fillColor="#9aa0a6"
-                                android:fillType="nonZero"
-                                android:pathData=" M82 333 C82,348.46 69.46,361 54,361 C38.54,361 26,348.46 26,333 C26,317.54 38.54,305 54,305 C69.46,305 82,317.54 82,333c " />
-                            <path
-                                android:name="_R_G_L_2_G_L_0_G_L_0_G_D_21_P_0"
-                                android:fillAlpha="0"
-                                android:fillColor="#9aa0a6"
-                                android:fillType="nonZero"
-                                android:pathData=" M82 421 C82,436.46 69.46,449 54,449 C38.54,449 26,436.46 26,421 C26,405.54 38.54,393 54,393 C69.46,393 82,405.54 82,421c " />
-                            <path
-                                android:name="_R_G_L_2_G_L_0_G_L_0_G_D_22_P_0"
-                                android:fillAlpha="0"
-                                android:fillColor="#9aa0a6"
-                                android:fillType="nonZero"
-                                android:pathData=" M82 509 C82,524.46 69.46,537 54,537 C38.54,537 26,524.46 26,509 C26,493.54 38.54,481 54,481 C69.46,481 82,493.54 82,509c " />
-                            <path
-                                android:name="_R_G_L_2_G_L_0_G_L_0_G_D_23_P_0"
-                                android:fillAlpha="0"
-                                android:fillColor="#9aa0a6"
-                                android:fillType="nonZero"
-                                android:pathData=" M82 597 C82,612.46 69.46,625 54,625 C38.54,625 26,612.46 26,597 C26,581.54 38.54,569 54,569 C69.46,569 82,581.54 82,597c " />
-                            <path
-                                android:name="_R_G_L_2_G_L_0_G_L_0_G_D_24_P_0"
-                                android:fillAlpha="0"
-                                android:fillColor="#9aa0a6"
-                                android:fillType="nonZero"
-                                android:pathData=" M82 685 C82,700.46 69.46,713 54,713 C38.54,713 26,700.46 26,685 C26,669.54 38.54,657 54,657 C69.46,657 82,669.54 82,685c " />
-                        </group>
-                    </group>
-                </group>
-                <group
-                    android:name="_R_G_L_1_G"
-                    android:scaleY="0"
-                    android:translateX="-17.875"
-                    android:translateY="322.017">
-                    <group
-                        android:name="_R_G_L_1_G_D_0_P_0_G_0_T_0"
-                        android:translateX="123.282"
-                        android:translateY="129.757">
-                        <path
-                            android:name="_R_G_L_1_G_D_0_P_0"
-                            android:fillAlpha="1"
-                            android:fillColor="#3b4043"
-                            android:fillType="nonZero"
-                            android:pathData=" M-109 27.43 C-109,27.43 -112.61,23.81 -112.61,23.81 C-112.61,23.81 -133.03,44.23 -133.03,44.23 C-133.03,44.23 -112.61,64.64 -112.61,64.64 C-112.61,64.64 -109,61.03 -109,61.03 C-109,61.03 -125.8,44.23 -125.8,44.23 C-125.8,44.23 -109,27.43 -109,27.43c " />
-                    </group>
-                </group>
-                <group
-                    android:name="_R_G_L_0_G"
-                    android:translateX="206"
-                    android:translateY="446">
-                    <path
-                        android:name="_R_G_L_0_G_D_0_P_0"
-                        android:fillAlpha="0"
-                        android:fillColor="@color/gesture_tutorial_primary_color"
-                        android:fillType="nonZero"
-                        android:pathData=" M-206.5 13.5 C-186.34,13.5 -170,29.84 -170,50 C-170,70.16 -186.34,86.5 -206.5,86.5 C-226.66,86.5 -243,70.16 -243,50 C-243,29.84 -226.66,13.5 -206.5,13.5c " />
-                </group>
-            </group>
-            <group android:name="time_group" />
-        </vector>
-    </aapt:attr>
-</animated-vector>
\ No newline at end of file
diff --git a/quickstep/res/drawable/gesture_tutorial_motion_home_dark_mode.xml b/quickstep/res/drawable/gesture_tutorial_motion_home_dark_mode.xml
deleted file mode 100644
index aff35c1..0000000
--- a/quickstep/res/drawable/gesture_tutorial_motion_home_dark_mode.xml
+++ /dev/null
@@ -1,1254 +0,0 @@
-<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:aapt="http://schemas.android.com/aapt">
-    <target android:name="_R_G_L_2_G_L_4_G_D_0_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="50"
-                    android:propertyName="fillAlpha"
-                    android:startOffset="600"
-                    android:valueFrom="0"
-                    android:valueTo="0"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="167"
-                    android:propertyName="fillAlpha"
-                    android:startOffset="650"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_2_G_L_4_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="50"
-                    android:pathData="M 206,776C 206,776 206,776 206,776"
-                    android:propertyName="translateXY"
-                    android:propertyXName="translateX"
-                    android:propertyYName="translateY"
-                    android:startOffset="600">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.27,0 0,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="700"
-                    android:pathData="M 206,776C 206,776 206,797 206,797"
-                    android:propertyName="translateXY"
-                    android:propertyXName="translateX"
-                    android:propertyYName="translateY"
-                    android:startOffset="650">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.27,0 0,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_2_G_L_4_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="650"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_2_G_L_3_G_D_0_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="167"
-                    android:propertyName="fillAlpha"
-                    android:startOffset="600"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_2_G_L_3_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="700"
-                    android:pathData="M 56,673C 56,673 56,706 56,706"
-                    android:propertyName="translateXY"
-                    android:propertyXName="translateX"
-                    android:propertyYName="translateY"
-                    android:startOffset="600">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.27,0 0,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_2_G_L_3_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="600"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_2_G_L_2_G_D_0_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="167"
-                    android:propertyName="fillAlpha"
-                    android:startOffset="600"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_2_G_L_2_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="700"
-                    android:pathData="M 156,673C 156,673 156,706 156,706"
-                    android:propertyName="translateXY"
-                    android:propertyXName="translateX"
-                    android:propertyYName="translateY"
-                    android:startOffset="600">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.27,0 0,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_2_G_L_2_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="600"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_2_G_L_1_G_D_0_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="167"
-                    android:propertyName="fillAlpha"
-                    android:startOffset="600"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_2_G_L_1_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="700"
-                    android:pathData="M 256,673C 256,673 256,706 256,706"
-                    android:propertyName="translateXY"
-                    android:propertyXName="translateX"
-                    android:propertyYName="translateY"
-                    android:startOffset="600">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.27,0 0,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_2_G_L_1_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="600"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_2_G_L_0_G_D_0_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="167"
-                    android:propertyName="fillAlpha"
-                    android:startOffset="600"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_2_G_L_0_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="700"
-                    android:pathData="M 356,673C 356,673 356,706 356,706"
-                    android:propertyName="translateXY"
-                    android:propertyXName="translateX"
-                    android:propertyYName="translateY"
-                    android:startOffset="600">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.27,0 0,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_2_G_L_0_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="600"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_2_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="600"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_1_G_L_4_G_L_11_G_D_0_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="100"
-                    android:propertyName="fillColor"
-                    android:startOffset="400"
-                    android:valueFrom="#dadce0"
-                    android:valueTo="#bac4d6"
-                    android:valueType="colorType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,1.215 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_1_G_L_4_G_L_10_G_D_0_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="100"
-                    android:propertyName="fillColor"
-                    android:startOffset="400"
-                    android:valueFrom="#bdc1c6"
-                    android:valueTo="#bac4d6"
-                    android:valueType="colorType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,1.92 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_1_G_L_4_G_L_9_G_D_0_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="100"
-                    android:propertyName="fillColor"
-                    android:startOffset="400"
-                    android:valueFrom="#bdc1c6"
-                    android:valueTo="#bac4d6"
-                    android:valueType="colorType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,1.92 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_1_G_L_4_G_L_8_G_D_0_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="100"
-                    android:propertyName="fillColor"
-                    android:startOffset="400"
-                    android:valueFrom="#bdc1c6"
-                    android:valueTo="#bac4d6"
-                    android:valueType="colorType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,1.92 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_1_G_L_4_G_L_7_G_D_0_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="100"
-                    android:propertyName="fillColor"
-                    android:startOffset="400"
-                    android:valueFrom="#bdc1c6"
-                    android:valueTo="#bac4d6"
-                    android:valueType="colorType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,1.92 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_1_G_L_4_G_L_6_G_D_0_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="100"
-                    android:propertyName="fillColor"
-                    android:startOffset="400"
-                    android:valueFrom="#bdc1c6"
-                    android:valueTo="#bac4d6"
-                    android:valueType="colorType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,1.92 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_1_G_L_4_G_L_5_G_D_0_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="100"
-                    android:propertyName="fillColor"
-                    android:startOffset="400"
-                    android:valueFrom="#bdc1c6"
-                    android:valueTo="#bac4d6"
-                    android:valueType="colorType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,1.92 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_1_G_L_4_G_L_4_G_D_0_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="100"
-                    android:propertyName="fillColor"
-                    android:startOffset="400"
-                    android:valueFrom="#bdc1c6"
-                    android:valueTo="#bac4d6"
-                    android:valueType="colorType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,1.92 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_1_G_L_4_G_L_3_G_D_0_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="100"
-                    android:propertyName="fillColor"
-                    android:startOffset="400"
-                    android:valueFrom="#bdc1c6"
-                    android:valueTo="#bac4d6"
-                    android:valueType="colorType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,1.92 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_1_G_L_4_G_L_2_G_D_0_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="100"
-                    android:propertyName="fillColor"
-                    android:startOffset="400"
-                    android:valueFrom="#bdc1c6"
-                    android:valueTo="#bac4d6"
-                    android:valueType="colorType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,1.92 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_1_G_L_4_G_L_1_G_D_0_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="100"
-                    android:propertyName="fillColor"
-                    android:startOffset="400"
-                    android:valueFrom="#bdc1c6"
-                    android:valueTo="#bac4d6"
-                    android:valueType="colorType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,1.92 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_1_G_L_4_G_L_0_G_D_0_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="100"
-                    android:propertyName="fillColor"
-                    android:startOffset="400"
-                    android:valueFrom="#bdc1c6"
-                    android:valueTo="#bac4d6"
-                    android:valueType="colorType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,1.92 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_1_G_L_4_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="517"
-                    android:valueFrom="1"
-                    android:valueTo="0"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_1_G_L_3_G_L_0_G_D_0_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="100"
-                    android:propertyName="fillColor"
-                    android:startOffset="400"
-                    android:valueFrom="#bdc1c6"
-                    android:valueTo="#bac4d6"
-                    android:valueType="colorType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,1.92 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_1_G_L_3_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="517"
-                    android:valueFrom="1"
-                    android:valueTo="0"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_1_G_L_2_G_L_2_G_D_0_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="100"
-                    android:propertyName="fillColor"
-                    android:startOffset="400"
-                    android:valueFrom="#e8eaed"
-                    android:valueTo="#bac4d6"
-                    android:valueType="colorType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,1.232 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_1_G_L_2_G_L_1_G_D_0_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="100"
-                    android:propertyName="fillColor"
-                    android:startOffset="400"
-                    android:valueFrom="#80868b"
-                    android:valueTo="#bac4d6"
-                    android:valueType="colorType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,0.674 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_1_G_L_2_G_L_0_G_D_0_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="100"
-                    android:propertyName="fillColor"
-                    android:startOffset="400"
-                    android:valueFrom="#80868b"
-                    android:valueTo="#bac4d6"
-                    android:valueType="colorType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,0.674 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_1_G_L_2_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="517"
-                    android:valueFrom="1"
-                    android:valueTo="0"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_1_G_L_1_G_L_2_G_D_0_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="150"
-                    android:propertyName="fillColor"
-                    android:startOffset="350"
-                    android:valueFrom="#202124"
-                    android:valueTo="#bac4d6"
-                    android:valueType="colorType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,0.69 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_1_G_L_1_G_L_1_G_D_0_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="150"
-                    android:propertyName="fillColor"
-                    android:startOffset="350"
-                    android:valueFrom="#202124"
-                    android:valueTo="#bac4d6"
-                    android:valueType="colorType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,0.69 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_1_G_L_1_G_L_0_G_D_0_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="150"
-                    android:propertyName="fillColor"
-                    android:startOffset="350"
-                    android:valueFrom="#3c4043"
-                    android:valueTo="#bac4d6"
-                    android:valueType="colorType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,0.69 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_1_G_L_1_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="517"
-                    android:valueFrom="1"
-                    android:valueTo="0"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_1_G_L_0_G_D_0_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="133"
-                    android:propertyName="fillColor"
-                    android:startOffset="500"
-                    android:valueFrom="#bac4d6"
-                    android:valueTo="#bac4d6"
-                    android:valueType="colorType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="50"
-                    android:propertyName="fillColor"
-                    android:startOffset="633"
-                    android:valueFrom="#bac4d6"
-                    android:valueTo="#8ab4f8"
-                    android:valueType="colorType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,-0.214 0.667,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_1_G_L_0_G_D_0_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="283"
-                    android:propertyName="fillAlpha"
-                    android:startOffset="500"
-                    android:valueFrom="1"
-                    android:valueTo="1"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.999,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_1_G_L_0_G_D_0_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="283"
-                    android:propertyName="pathData"
-                    android:startOffset="500"
-                    android:valueFrom="M206.06 -430.06 C206.06,-430.06 206,431 206,431 C206,446 189.75,446 189.79,446 C189.79,446 -189.98,446 -189.98,446 C-189.94,446 -206,446 -206,431 C-206,431 -206,-430 -206,-430 C-206,-446 -189.97,-446 -190.01,-446 C-190.01,-446 188.98,-446.06 188.98,-446.06 C188.94,-446.06 206,-446 206.06,-430.06c "
-                    android:valueTo="M60 -0.06 C60,-0.06 60,0.06 60,0.06 C60,28 36,60.25 -0.02,60.25 C-0.02,60.25 0.02,60.25 0.02,60.25 C-32.5,60.25 -60,31.5 -60,0.06 C-60,0.06 -60,-0.06 -60,-0.06 C-60,-31.25 -34,-59.25 0.02,-59.25 C0.02,-59.25 -0.02,-59.25 -0.02,-59.25 C33.5,-59.25 60,-38 60,-0.06c "
-                    android:valueType="pathType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.999,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_1_G_L_0_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="500"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_1_G_L_0_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="850"
-                    android:valueFrom="1"
-                    android:valueTo="0"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_1_G_T_1">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="283"
-                    android:pathData="M 206,446C 201.417,411.133 195,385.297 195,385.297"
-                    android:propertyName="translateXY"
-                    android:propertyXName="translateX"
-                    android:propertyYName="translateY"
-                    android:startOffset="217">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.5,0 0.833,0.833 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="333"
-                    android:pathData="M 195,385.297C 195,385.297 105.5,148.09000000000003 56,691.5"
-                    android:propertyName="translateXY"
-                    android:propertyXName="translateX"
-                    android:propertyYName="translateY"
-                    android:startOffset="500">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.443,0.093 0.5,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_1_G_T_1">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="467"
-                    android:propertyName="scaleX"
-                    android:startOffset="217"
-                    android:valueFrom="1"
-                    android:valueTo="0.5"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.5,0 0.5,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="467"
-                    android:propertyName="scaleY"
-                    android:startOffset="217"
-                    android:valueFrom="1"
-                    android:valueTo="0.5"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.5,0 0.5,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_1_G_T_1">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="2167"
-                    android:valueFrom="1"
-                    android:valueTo="0"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_0_G_D_0_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="217"
-                    android:propertyName="fillAlpha"
-                    android:startOffset="0"
-                    android:valueFrom="0"
-                    android:valueTo="0.75"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,0.833 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="233"
-                    android:propertyName="fillAlpha"
-                    android:startOffset="217"
-                    android:valueFrom="0.75"
-                    android:valueTo="0.75"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="167"
-                    android:propertyName="fillAlpha"
-                    android:startOffset="450"
-                    android:valueFrom="0.75"
-                    android:valueTo="0"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_0_G_D_0_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="217"
-                    android:propertyName="pathData"
-                    android:startOffset="0"
-                    android:valueFrom="M0 411 C19.33,411 35,426.67 35,446 C35,465.33 19.33,481 0,481 C-19.33,481 -35,465.33 -35,446 C-35,426.67 -19.33,411 0,411c "
-                    android:valueTo="M0 396 C27.61,396 50,418.39 50,446 C50,473.61 27.61,496 0,496 C-27.61,496 -50,473.61 -50,446 C-50,418.39 -27.61,396 0,396c "
-                    android:valueType="pathType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="433"
-                    android:propertyName="pathData"
-                    android:startOffset="217"
-                    android:valueFrom="M0 396 C27.61,396 50,418.39 50,446 C50,473.61 27.61,496 0,496 C-27.61,496 -50,473.61 -50,446 C-50,418.39 -27.61,396 0,396c "
-                    android:valueTo="M0 68 C27.61,68 50,90.39 50,118 C50,145.61 27.61,168 0,168 C-27.61,168 -50,145.61 -50,118 C-50,90.39 -27.61,68 0,68c "
-                    android:valueType="pathType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.5,0 0.5,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_0_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="0"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_0_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="2167"
-                    android:valueFrom="1"
-                    android:valueTo="0"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="time_group">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="1367"
-                    android:propertyName="translateX"
-                    android:startOffset="0"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <aapt:attr name="android:drawable">
-        <vector
-            android:width="412dp"
-            android:height="892dp"
-            android:viewportHeight="892"
-            android:viewportWidth="412">
-            <group android:name="_R_G">
-                <group
-                    android:name="_R_G_L_3_G"
-                    android:translateX="206"
-                    android:translateY="446">
-                    <path
-                        android:name="_R_G_L_3_G_D_0_P_0"
-                        android:fillAlpha="1"
-                        android:fillColor="@color/fake_wallpaper_color_dark_mode"
-                        android:fillType="nonZero"
-                        android:pathData=" M206 -446 C206,-446 206,446 206,446 C206,446 -206,446 -206,446 C-206,446 -206,-446 -206,-446 C-206,-446 206,-446 206,-446c " />
-                </group>
-                <group
-                    android:name="_R_G_L_2_G"
-                    android:scaleY="0">
-                    <group
-                        android:name="_R_G_L_2_G_L_4_G"
-                        android:scaleY="0"
-                        android:translateX="206"
-                        android:translateY="776">
-                        <path
-                            android:name="_R_G_L_2_G_L_4_G_D_0_P_0"
-                            android:fillAlpha="0"
-                            android:fillColor="#3c4043"
-                            android:fillType="nonZero"
-                            android:pathData=" M180 0 C180,0 180,0 180,0 C180,13.8 168.8,25 155,25 C155,25 -155,25 -155,25 C-168.8,25 -180,13.8 -180,0 C-180,0 -180,0 -180,0 C-180,-13.8 -168.8,-25 -155,-25 C-155,-25 155,-25 155,-25 C168.8,-25 180,-13.8 180,0c " />
-                    </group>
-                    <group
-                        android:name="_R_G_L_2_G_L_3_G"
-                        android:scaleY="0"
-                        android:translateX="56"
-                        android:translateY="673">
-                        <path
-                            android:name="_R_G_L_2_G_L_3_G_D_0_P_0"
-                            android:fillAlpha="0"
-                            android:fillColor="#8ab4f8"
-                            android:fillType="nonZero"
-                            android:pathData=" M0 -30 C16.56,-30 30,-16.56 30,0 C30,16.56 16.56,30 0,30 C-16.56,30 -30,16.56 -30,0 C-30,-16.56 -16.56,-30 0,-30c " />
-                    </group>
-                    <group
-                        android:name="_R_G_L_2_G_L_2_G"
-                        android:scaleY="0"
-                        android:translateX="156"
-                        android:translateY="673">
-                        <path
-                            android:name="_R_G_L_2_G_L_2_G_D_0_P_0"
-                            android:fillAlpha="0"
-                            android:fillColor="#f28b82"
-                            android:fillType="nonZero"
-                            android:pathData=" M0 -30 C16.56,-30 30,-16.56 30,0 C30,16.56 16.56,30 0,30 C-16.56,30 -30,16.56 -30,0 C-30,-16.56 -16.56,-30 0,-30c " />
-                    </group>
-                    <group
-                        android:name="_R_G_L_2_G_L_1_G"
-                        android:scaleY="0"
-                        android:translateX="256"
-                        android:translateY="673">
-                        <path
-                            android:name="_R_G_L_2_G_L_1_G_D_0_P_0"
-                            android:fillAlpha="0"
-                            android:fillColor="#fdd663"
-                            android:fillType="nonZero"
-                            android:pathData=" M0 -30 C16.56,-30 30,-16.56 30,0 C30,16.56 16.56,30 0,30 C-16.56,30 -30,16.56 -30,0 C-30,-16.56 -16.56,-30 0,-30c " />
-                    </group>
-                    <group
-                        android:name="_R_G_L_2_G_L_0_G"
-                        android:scaleY="0"
-                        android:translateX="356"
-                        android:translateY="673">
-                        <path
-                            android:name="_R_G_L_2_G_L_0_G_D_0_P_0"
-                            android:fillAlpha="0"
-                            android:fillColor="#81c995"
-                            android:fillType="nonZero"
-                            android:pathData=" M0 -30 C16.56,-30 30,-16.56 30,0 C30,16.56 16.56,30 0,30 C-16.56,30 -30,16.56 -30,0 C-30,-16.56 -16.56,-30 0,-30c " />
-                    </group>
-                </group>
-                <group
-                    android:name="_R_G_L_1_G_T_1"
-                    android:scaleX="1"
-                    android:scaleY="1"
-                    android:translateX="206"
-                    android:translateY="446">
-                    <group
-                        android:name="_R_G_L_1_G"
-                        android:translateX="-206"
-                        android:translateY="-446">
-                        <group android:name="_R_G_L_1_G_L_4_G">
-                            <group
-                                android:name="_R_G_L_1_G_L_4_G_L_11_G"
-                                android:scaleX="0.87473"
-                                android:scaleY="0.98643"
-                                android:translateX="206"
-                                android:translateY="472.769">
-                                <path
-                                    android:name="_R_G_L_1_G_L_4_G_L_11_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#dadce0"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M235.5 -407 C235.5,-407 235.5,407 235.5,407 C235.5,416.93 227.43,425 217.5,425 C217.5,425 -217.5,425 -217.5,425 C-227.43,425 -235.5,416.93 -235.5,407 C-235.5,407 -235.5,-407 -235.5,-407 C-235.5,-416.93 -227.43,-425 -217.5,-425 C-217.5,-425 217.5,-425 217.5,-425 C227.43,-425 235.5,-416.93 235.5,-407c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_1_G_L_4_G_L_10_G"
-                                android:translateX="182.5"
-                                android:translateY="831">
-                                <path
-                                    android:name="_R_G_L_1_G_L_4_G_L_10_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#bdc1c6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M158.5 -3 C158.5,-3 158.5,3 158.5,3 C158.5,7.42 154.92,11 150.5,11 C150.5,11 -150.5,11 -150.5,11 C-154.92,11 -158.5,7.42 -158.5,3 C-158.5,3 -158.5,-3 -158.5,-3 C-158.5,-7.42 -154.92,-11 -150.5,-11 C-150.5,-11 150.5,-11 150.5,-11 C154.92,-11 158.5,-7.42 158.5,-3c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_1_G_L_4_G_L_9_G"
-                                android:translateX="186"
-                                android:translateY="801">
-                                <path
-                                    android:name="_R_G_L_1_G_L_4_G_L_9_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#bdc1c6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M162 -3 C162,-3 162,3 162,3 C162,7.42 158.42,11 154,11 C154,11 -154,11 -154,11 C-158.42,11 -162,7.42 -162,3 C-162,3 -162,-3 -162,-3 C-162,-7.42 -158.42,-11 -154,-11 C-154,-11 154,-11 154,-11 C158.42,-11 162,-7.42 162,-3c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_1_G_L_4_G_L_8_G"
-                                android:translateX="119"
-                                android:translateY="755">
-                                <path
-                                    android:name="_R_G_L_1_G_L_4_G_L_8_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#bdc1c6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M95 -3 C95,-3 95,3 95,3 C95,7.42 91.42,11 87,11 C87,11 -87,11 -87,11 C-91.42,11 -95,7.42 -95,3 C-95,3 -95,-3 -95,-3 C-95,-7.42 -91.42,-11 -87,-11 C-87,-11 87,-11 87,-11 C91.42,-11 95,-7.42 95,-3c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_1_G_L_4_G_L_7_G"
-                                android:translateX="182.5"
-                                android:translateY="725">
-                                <path
-                                    android:name="_R_G_L_1_G_L_4_G_L_7_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#bdc1c6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M158.5 -3 C158.5,-3 158.5,3 158.5,3 C158.5,7.42 154.92,11 150.5,11 C150.5,11 -150.5,11 -150.5,11 C-154.92,11 -158.5,7.42 -158.5,3 C-158.5,3 -158.5,-3 -158.5,-3 C-158.5,-7.42 -154.92,-11 -150.5,-11 C-150.5,-11 150.5,-11 150.5,-11 C154.92,-11 158.5,-7.42 158.5,-3c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_1_G_L_4_G_L_6_G"
-                                android:translateX="197.5"
-                                android:translateY="695">
-                                <path
-                                    android:name="_R_G_L_1_G_L_4_G_L_6_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#bdc1c6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M173.5 -3 C173.5,-3 173.5,3 173.5,3 C173.5,7.42 169.92,11 165.5,11 C165.5,11 -165.5,11 -165.5,11 C-169.92,11 -173.5,7.42 -173.5,3 C-173.5,3 -173.5,-3 -173.5,-3 C-173.5,-7.42 -169.92,-11 -165.5,-11 C-165.5,-11 165.5,-11 165.5,-11 C169.92,-11 173.5,-7.42 173.5,-3c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_1_G_L_4_G_L_5_G"
-                                android:translateX="192"
-                                android:translateY="665">
-                                <path
-                                    android:name="_R_G_L_1_G_L_4_G_L_5_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#bdc1c6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M168 -3 C168,-3 168,3 168,3 C168,7.42 164.42,11 160,11 C160,11 -160,11 -160,11 C-164.42,11 -168,7.42 -168,3 C-168,3 -168,-3 -168,-3 C-168,-7.42 -164.42,-11 -160,-11 C-160,-11 160,-11 160,-11 C164.42,-11 168,-7.42 168,-3c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_1_G_L_4_G_L_4_G"
-                                android:translateX="105.5"
-                                android:translateY="360">
-                                <path
-                                    android:name="_R_G_L_1_G_L_4_G_L_4_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#bdc1c6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M23.5 -2 C23.5,-2 23.5,2 23.5,2 C23.5,4.21 21.71,6 19.5,6 C19.5,6 -19.5,6 -19.5,6 C-21.71,6 -23.5,4.21 -23.5,2 C-23.5,2 -23.5,-2 -23.5,-2 C-23.5,-4.21 -21.71,-6 -19.5,-6 C-19.5,-6 19.5,-6 19.5,-6 C21.71,-6 23.5,-4.21 23.5,-2c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_1_G_L_4_G_L_3_G"
-                                android:translateX="47.5"
-                                android:translateY="360">
-                                <path
-                                    android:name="_R_G_L_1_G_L_4_G_L_3_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#bdc1c6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M23.5 -2 C23.5,-2 23.5,2 23.5,2 C23.5,4.21 21.71,6 19.5,6 C19.5,6 -19.5,6 -19.5,6 C-21.71,6 -23.5,4.21 -23.5,2 C-23.5,2 -23.5,-2 -23.5,-2 C-23.5,-4.21 -21.71,-6 -19.5,-6 C-19.5,-6 19.5,-6 19.5,-6 C21.71,-6 23.5,-4.21 23.5,-2c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_1_G_L_4_G_L_2_G"
-                                android:translateX="142.5"
-                                android:translateY="328">
-                                <path
-                                    android:name="_R_G_L_1_G_L_4_G_L_2_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#bdc1c6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M118.5 -10 C118.5,-10 118.5,10 118.5,10 C118.5,14.42 114.92,18 110.5,18 C110.5,18 -110.5,18 -110.5,18 C-114.92,18 -118.5,14.42 -118.5,10 C-118.5,10 -118.5,-10 -118.5,-10 C-118.5,-14.42 -114.92,-18 -110.5,-18 C-110.5,-18 110.5,-18 110.5,-18 C114.92,-18 118.5,-14.42 118.5,-10c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_1_G_L_4_G_L_1_G"
-                                android:translateX="186"
-                                android:translateY="284">
-                                <path
-                                    android:name="_R_G_L_1_G_L_4_G_L_1_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#bdc1c6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M162 -10 C162,-10 162,10 162,10 C162,14.42 158.42,18 154,18 C154,18 -154,18 -154,18 C-158.42,18 -162,14.42 -162,10 C-162,10 -162,-10 -162,-10 C-162,-14.42 -158.42,-18 -154,-18 C-154,-18 154,-18 154,-18 C158.42,-18 162,-14.42 162,-10c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_1_G_L_4_G_L_0_G"
-                                android:translateX="155"
-                                android:translateY="240">
-                                <path
-                                    android:name="_R_G_L_1_G_L_4_G_L_0_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#bdc1c6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M131 -10 C131,-10 131,10 131,10 C131,14.42 127.42,18 123,18 C123,18 -123,18 -123,18 C-127.42,18 -131,14.42 -131,10 C-131,10 -131,-10 -131,-10 C-131,-14.42 -127.42,-18 -123,-18 C-123,-18 123,-18 123,-18 C127.42,-18 131,-14.42 131,-10c " />
-                            </group>
-                        </group>
-                        <group
-                            android:name="_R_G_L_1_G_L_3_G"
-                            android:translateX="24"
-                            android:translateY="390">
-                            <group
-                                android:name="_R_G_L_1_G_L_3_G_L_0_G"
-                                android:translateX="182"
-                                android:translateY="120">
-                                <path
-                                    android:name="_R_G_L_1_G_L_3_G_L_0_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#bdc1c6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M182 -98 C182,-98 182,98 182,98 C182,110.14 172.14,120 160,120 C160,120 -160,120 -160,120 C-172.14,120 -182,110.14 -182,98 C-182,98 -182,-98 -182,-98 C-182,-110.14 -172.14,-120 -160,-120 C-160,-120 160,-120 160,-120 C172.14,-120 182,-110.14 182,-98c " />
-                            </group>
-                        </group>
-                        <group android:name="_R_G_L_1_G_L_2_G">
-                            <group
-                                android:name="_R_G_L_1_G_L_2_G_L_2_G"
-                                android:translateX="206"
-                                android:translateY="145">
-                                <path
-                                    android:name="_R_G_L_1_G_L_2_G_L_2_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#e8eaed"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M206 -95.63 C206,-95.63 206,42.37 206,42.37 C206,43.47 205.1,44.37 204,44.37 C204,44.37 -204,44.37 -204,44.37 C-205.1,44.37 -206,43.47 -206,42.37 C-206,42.37 -206,-95.63 -206,-95.63 C-206,-96.73 -205.1,-97.63 -204,-97.63 C-204,-97.63 204,-97.63 204,-97.63 C205.1,-97.63 206,-96.73 206,-95.63c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_1_G_L_2_G_L_1_G"
-                                android:translateX="206"
-                                android:translateY="145">
-                                <path
-                                    android:name="_R_G_L_1_G_L_2_G_L_1_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#80868b"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M109 -14 C109,-14 109,14 109,14 C109,15.1 108.1,16 107,16 C107,16 -107,16 -107,16 C-108.1,16 -109,15.1 -109,14 C-109,14 -109,-14 -109,-14 C-109,-15.1 -108.1,-16 -107,-16 C-107,-16 107,-16 107,-16 C108.1,-16 109,-15.1 109,-14c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_1_G_L_2_G_L_0_G"
-                                android:translateX="46"
-                                android:translateY="145">
-                                <path
-                                    android:name="_R_G_L_1_G_L_2_G_L_0_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#80868b"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M22 -14 C22,-14 22,14 22,14 C22,18.42 18.42,22 14,22 C14,22 -14,22 -14,22 C-18.42,22 -22,18.42 -22,14 C-22,14 -22,-14 -22,-14 C-22,-18.42 -18.42,-22 -14,-22 C-14,-22 14,-22 14,-22 C18.42,-22 22,-18.42 22,-14c " />
-                            </group>
-                        </group>
-                        <group android:name="_R_G_L_1_G_L_1_G">
-                            <group
-                                android:name="_R_G_L_1_G_L_1_G_L_2_G"
-                                android:translateX="206"
-                                android:translateY="51">
-                                <path
-                                    android:name="_R_G_L_1_G_L_1_G_L_2_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#202124"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M206 -0.27 C206,-0.27 206,49.73 206,49.73 C206,49.73 -206,49.73 -206,49.73 C-206,49.73 -206,-0.27 -206,-0.27 C-206,-0.27 206,-0.27 206,-0.27c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_1_G_L_1_G_L_1_G"
-                                android:translateX="206"
-                                android:translateY="50.5">
-                                <path
-                                    android:name="_R_G_L_1_G_L_1_G_L_1_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#202124"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M206 -32.5 C206,-32.5 206,32.5 206,32.5 C206,42.43 197.93,50.5 188,50.5 C188,50.5 -188,50.5 -188,50.5 C-197.93,50.5 -206,42.43 -206,32.5 C-206,32.5 -206,-32.5 -206,-32.5 C-206,-42.43 -197.93,-50.5 -188,-50.5 C-188,-50.5 188,-50.5 188,-50.5 C197.93,-50.5 206,-42.43 206,-32.5c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_1_G_L_1_G_L_0_G"
-                                android:translateX="206"
-                                android:translateY="66.5">
-                                <path
-                                    android:name="_R_G_L_1_G_L_1_G_L_0_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#3c4043"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M190 0 C190,0 190,0 190,0 C190,10.21 181.71,18.5 171.5,18.5 C171.5,18.5 -171.5,18.5 -171.5,18.5 C-181.71,18.5 -190,10.21 -190,0 C-190,0 -190,0 -190,0 C-190,-10.21 -181.71,-18.5 -171.5,-18.5 C-171.5,-18.5 171.5,-18.5 171.5,-18.5 C181.71,-18.5 190,-10.21 190,0c " />
-                            </group>
-                        </group>
-                        <group
-                            android:name="_R_G_L_1_G_L_0_G"
-                            android:scaleY="0"
-                            android:translateX="206"
-                            android:translateY="446">
-                            <path
-                                android:name="_R_G_L_1_G_L_0_G_D_0_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#bac4d6"
-                                android:fillType="nonZero"
-                                android:pathData=" M206.06 -430.06 C206.06,-430.06 206,431 206,431 C206,446 189.75,446 189.79,446 C189.79,446 -189.98,446 -189.98,446 C-189.94,446 -206,446 -206,431 C-206,431 -206,-430 -206,-430 C-206,-446 -189.97,-446 -190.01,-446 C-190.01,-446 188.98,-446.06 188.98,-446.06 C188.94,-446.06 206,-446 206.06,-430.06c " />
-                        </group>
-                    </group>
-                </group>
-                <group
-                    android:name="_R_G_L_0_G"
-                    android:translateX="206"
-                    android:translateY="446">
-                    <path
-                        android:name="_R_G_L_0_G_D_0_P_0"
-                        android:fillAlpha="0"
-                        android:fillColor="@color/gesture_tutorial_primary_color"
-                        android:fillType="nonZero"
-                        android:pathData=" M0 411 C19.33,411 35,426.67 35,446 C35,465.33 19.33,481 0,481 C-19.33,481 -35,465.33 -35,446 C-35,426.67 -19.33,411 0,411c " />
-                </group>
-            </group>
-            <group android:name="time_group" />
-        </vector>
-    </aapt:attr>
-</animated-vector>
\ No newline at end of file
diff --git a/quickstep/res/drawable/gesture_tutorial_motion_home_light_mode.xml b/quickstep/res/drawable/gesture_tutorial_motion_home_light_mode.xml
deleted file mode 100644
index 98d97ad..0000000
--- a/quickstep/res/drawable/gesture_tutorial_motion_home_light_mode.xml
+++ /dev/null
@@ -1,1254 +0,0 @@
-<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:aapt="http://schemas.android.com/aapt">
-    <target android:name="_R_G_L_2_G_L_4_G_D_0_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="50"
-                    android:propertyName="fillAlpha"
-                    android:startOffset="600"
-                    android:valueFrom="0"
-                    android:valueTo="0"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="167"
-                    android:propertyName="fillAlpha"
-                    android:startOffset="650"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_2_G_L_4_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="50"
-                    android:pathData="M 206,776C 206,776 206,776 206,776"
-                    android:propertyName="translateXY"
-                    android:propertyXName="translateX"
-                    android:propertyYName="translateY"
-                    android:startOffset="600">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.27,0 0,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="700"
-                    android:pathData="M 206,776C 206,776 206,797 206,797"
-                    android:propertyName="translateXY"
-                    android:propertyXName="translateX"
-                    android:propertyYName="translateY"
-                    android:startOffset="650">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.27,0 0,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_2_G_L_4_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="650"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_2_G_L_3_G_D_0_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="167"
-                    android:propertyName="fillAlpha"
-                    android:startOffset="600"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_2_G_L_3_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="700"
-                    android:pathData="M 56,673C 56,673 56,706 56,706"
-                    android:propertyName="translateXY"
-                    android:propertyXName="translateX"
-                    android:propertyYName="translateY"
-                    android:startOffset="600">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.27,0 0,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_2_G_L_3_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="600"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_2_G_L_2_G_D_0_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="167"
-                    android:propertyName="fillAlpha"
-                    android:startOffset="600"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_2_G_L_2_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="700"
-                    android:pathData="M 156,673C 156,673 156,706 156,706"
-                    android:propertyName="translateXY"
-                    android:propertyXName="translateX"
-                    android:propertyYName="translateY"
-                    android:startOffset="600">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.27,0 0,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_2_G_L_2_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="600"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_2_G_L_1_G_D_0_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="167"
-                    android:propertyName="fillAlpha"
-                    android:startOffset="600"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_2_G_L_1_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="700"
-                    android:pathData="M 256,673C 256,673 256,706 256,706"
-                    android:propertyName="translateXY"
-                    android:propertyXName="translateX"
-                    android:propertyYName="translateY"
-                    android:startOffset="600">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.27,0 0,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_2_G_L_1_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="600"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_2_G_L_0_G_D_0_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="167"
-                    android:propertyName="fillAlpha"
-                    android:startOffset="600"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_2_G_L_0_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="700"
-                    android:pathData="M 356,673C 356,673 356,706 356,706"
-                    android:propertyName="translateXY"
-                    android:propertyXName="translateX"
-                    android:propertyYName="translateY"
-                    android:startOffset="600">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.27,0 0,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_2_G_L_0_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="600"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_2_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="600"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_1_G_L_4_G_L_11_G_D_0_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="100"
-                    android:propertyName="fillColor"
-                    android:startOffset="400"
-                    android:valueFrom="#dadce0"
-                    android:valueTo="#bac4d6"
-                    android:valueType="colorType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,1.215 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_1_G_L_4_G_L_10_G_D_0_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="100"
-                    android:propertyName="fillColor"
-                    android:startOffset="400"
-                    android:valueFrom="#bdc1c6"
-                    android:valueTo="#bac4d6"
-                    android:valueType="colorType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,1.92 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_1_G_L_4_G_L_9_G_D_0_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="100"
-                    android:propertyName="fillColor"
-                    android:startOffset="400"
-                    android:valueFrom="#bdc1c6"
-                    android:valueTo="#bac4d6"
-                    android:valueType="colorType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,1.92 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_1_G_L_4_G_L_8_G_D_0_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="100"
-                    android:propertyName="fillColor"
-                    android:startOffset="400"
-                    android:valueFrom="#bdc1c6"
-                    android:valueTo="#bac4d6"
-                    android:valueType="colorType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,1.92 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_1_G_L_4_G_L_7_G_D_0_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="100"
-                    android:propertyName="fillColor"
-                    android:startOffset="400"
-                    android:valueFrom="#bdc1c6"
-                    android:valueTo="#bac4d6"
-                    android:valueType="colorType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,1.92 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_1_G_L_4_G_L_6_G_D_0_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="100"
-                    android:propertyName="fillColor"
-                    android:startOffset="400"
-                    android:valueFrom="#bdc1c6"
-                    android:valueTo="#bac4d6"
-                    android:valueType="colorType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,1.92 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_1_G_L_4_G_L_5_G_D_0_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="100"
-                    android:propertyName="fillColor"
-                    android:startOffset="400"
-                    android:valueFrom="#bdc1c6"
-                    android:valueTo="#bac4d6"
-                    android:valueType="colorType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,1.92 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_1_G_L_4_G_L_4_G_D_0_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="100"
-                    android:propertyName="fillColor"
-                    android:startOffset="400"
-                    android:valueFrom="#bdc1c6"
-                    android:valueTo="#bac4d6"
-                    android:valueType="colorType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,1.92 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_1_G_L_4_G_L_3_G_D_0_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="100"
-                    android:propertyName="fillColor"
-                    android:startOffset="400"
-                    android:valueFrom="#bdc1c6"
-                    android:valueTo="#bac4d6"
-                    android:valueType="colorType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,1.92 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_1_G_L_4_G_L_2_G_D_0_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="100"
-                    android:propertyName="fillColor"
-                    android:startOffset="400"
-                    android:valueFrom="#bdc1c6"
-                    android:valueTo="#bac4d6"
-                    android:valueType="colorType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,1.92 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_1_G_L_4_G_L_1_G_D_0_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="100"
-                    android:propertyName="fillColor"
-                    android:startOffset="400"
-                    android:valueFrom="#bdc1c6"
-                    android:valueTo="#bac4d6"
-                    android:valueType="colorType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,1.92 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_1_G_L_4_G_L_0_G_D_0_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="100"
-                    android:propertyName="fillColor"
-                    android:startOffset="400"
-                    android:valueFrom="#bdc1c6"
-                    android:valueTo="#bac4d6"
-                    android:valueType="colorType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,1.92 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_1_G_L_4_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="517"
-                    android:valueFrom="1"
-                    android:valueTo="0"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_1_G_L_3_G_L_0_G_D_0_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="100"
-                    android:propertyName="fillColor"
-                    android:startOffset="400"
-                    android:valueFrom="#bdc1c6"
-                    android:valueTo="#bac4d6"
-                    android:valueType="colorType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,1.92 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_1_G_L_3_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="517"
-                    android:valueFrom="1"
-                    android:valueTo="0"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_1_G_L_2_G_L_2_G_D_0_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="100"
-                    android:propertyName="fillColor"
-                    android:startOffset="400"
-                    android:valueFrom="#e8eaed"
-                    android:valueTo="#bac4d6"
-                    android:valueType="colorType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,1.232 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_1_G_L_2_G_L_1_G_D_0_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="100"
-                    android:propertyName="fillColor"
-                    android:startOffset="400"
-                    android:valueFrom="#80868b"
-                    android:valueTo="#bac4d6"
-                    android:valueType="colorType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,0.674 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_1_G_L_2_G_L_0_G_D_0_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="100"
-                    android:propertyName="fillColor"
-                    android:startOffset="400"
-                    android:valueFrom="#80868b"
-                    android:valueTo="#bac4d6"
-                    android:valueType="colorType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,0.674 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_1_G_L_2_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="517"
-                    android:valueFrom="1"
-                    android:valueTo="0"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_1_G_L_1_G_L_2_G_D_0_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="150"
-                    android:propertyName="fillColor"
-                    android:startOffset="350"
-                    android:valueFrom="#6e7175"
-                    android:valueTo="#bac4d6"
-                    android:valueType="colorType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,0.674 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_1_G_L_1_G_L_1_G_D_0_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="150"
-                    android:propertyName="fillColor"
-                    android:startOffset="350"
-                    android:valueFrom="#6e7175"
-                    android:valueTo="#bac4d6"
-                    android:valueType="colorType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,0.676 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_1_G_L_1_G_L_0_G_D_0_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="150"
-                    android:propertyName="fillColor"
-                    android:startOffset="350"
-                    android:valueFrom="#9a9a9a"
-                    android:valueTo="#bac4d6"
-                    android:valueType="colorType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,0.584 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_1_G_L_1_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="517"
-                    android:valueFrom="1"
-                    android:valueTo="0"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_1_G_L_0_G_D_0_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="133"
-                    android:propertyName="fillColor"
-                    android:startOffset="500"
-                    android:valueFrom="#bac4d6"
-                    android:valueTo="#bac4d6"
-                    android:valueType="colorType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="50"
-                    android:propertyName="fillColor"
-                    android:startOffset="633"
-                    android:valueFrom="#bac4d6"
-                    android:valueTo="#8ab4f8"
-                    android:valueType="colorType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,-0.214 0.667,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_1_G_L_0_G_D_0_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="283"
-                    android:propertyName="fillAlpha"
-                    android:startOffset="500"
-                    android:valueFrom="1"
-                    android:valueTo="1"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.999,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_1_G_L_0_G_D_0_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="283"
-                    android:propertyName="pathData"
-                    android:startOffset="500"
-                    android:valueFrom="M206.06 -430.06 C206.06,-430.06 206,431 206,431 C206,446 189.75,446 189.79,446 C189.79,446 -189.98,446 -189.98,446 C-189.94,446 -206,446 -206,431 C-206,431 -206,-430 -206,-430 C-206,-446 -189.97,-446 -190.01,-446 C-190.01,-446 188.98,-446.06 188.98,-446.06 C188.94,-446.06 206,-446 206.06,-430.06c "
-                    android:valueTo="M60 -0.06 C60,-0.06 60,0.06 60,0.06 C60,28 36,60.25 -0.02,60.25 C-0.02,60.25 0.02,60.25 0.02,60.25 C-32.5,60.25 -60,31.5 -60,0.06 C-60,0.06 -60,-0.06 -60,-0.06 C-60,-31.25 -34,-59.25 0.02,-59.25 C0.02,-59.25 -0.02,-59.25 -0.02,-59.25 C33.5,-59.25 60,-38 60,-0.06c "
-                    android:valueType="pathType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.4,0 0.999,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_1_G_L_0_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="500"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_1_G_L_0_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="850"
-                    android:valueFrom="1"
-                    android:valueTo="0"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_1_G_T_1">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="283"
-                    android:pathData="M 206,446C 201.417,411.133 195,385.297 195,385.297"
-                    android:propertyName="translateXY"
-                    android:propertyXName="translateX"
-                    android:propertyYName="translateY"
-                    android:startOffset="217">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.5,0 0.833,0.833 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="333"
-                    android:pathData="M 195,385.297C 195,385.297 105.5,148.09000000000003 56,691.5"
-                    android:propertyName="translateXY"
-                    android:propertyXName="translateX"
-                    android:propertyYName="translateY"
-                    android:startOffset="500">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.443,0.093 0.5,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_1_G_T_1">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="467"
-                    android:propertyName="scaleX"
-                    android:startOffset="217"
-                    android:valueFrom="1"
-                    android:valueTo="0.5"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.5,0 0.5,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="467"
-                    android:propertyName="scaleY"
-                    android:startOffset="217"
-                    android:valueFrom="1"
-                    android:valueTo="0.5"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.5,0 0.5,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_1_G_T_1">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="2167"
-                    android:valueFrom="1"
-                    android:valueTo="0"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_0_G_D_0_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="217"
-                    android:propertyName="fillAlpha"
-                    android:startOffset="0"
-                    android:valueFrom="0"
-                    android:valueTo="0.75"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,0.833 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="233"
-                    android:propertyName="fillAlpha"
-                    android:startOffset="217"
-                    android:valueFrom="0.75"
-                    android:valueTo="0.75"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="167"
-                    android:propertyName="fillAlpha"
-                    android:startOffset="450"
-                    android:valueFrom="0.75"
-                    android:valueTo="0"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_0_G_D_0_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="217"
-                    android:propertyName="pathData"
-                    android:startOffset="0"
-                    android:valueFrom="M0 411 C19.33,411 35,426.67 35,446 C35,465.33 19.33,481 0,481 C-19.33,481 -35,465.33 -35,446 C-35,426.67 -19.33,411 0,411c "
-                    android:valueTo="M0 396 C27.61,396 50,418.39 50,446 C50,473.61 27.61,496 0,496 C-27.61,496 -50,473.61 -50,446 C-50,418.39 -27.61,396 0,396c "
-                    android:valueType="pathType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="433"
-                    android:propertyName="pathData"
-                    android:startOffset="217"
-                    android:valueFrom="M0 396 C27.61,396 50,418.39 50,446 C50,473.61 27.61,496 0,496 C-27.61,496 -50,473.61 -50,446 C-50,418.39 -27.61,396 0,396c "
-                    android:valueTo="M0 68 C27.61,68 50,90.39 50,118 C50,145.61 27.61,168 0,168 C-27.61,168 -50,145.61 -50,118 C-50,90.39 -27.61,68 0,68c "
-                    android:valueType="pathType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.5,0 0.5,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_0_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="0"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_0_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="2167"
-                    android:valueFrom="1"
-                    android:valueTo="0"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="time_group">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="1367"
-                    android:propertyName="translateX"
-                    android:startOffset="0"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <aapt:attr name="android:drawable">
-        <vector
-            android:width="412dp"
-            android:height="892dp"
-            android:viewportHeight="892"
-            android:viewportWidth="412">
-            <group android:name="_R_G">
-                <group
-                    android:name="_R_G_L_3_G"
-                    android:translateX="206"
-                    android:translateY="446">
-                    <path
-                        android:name="_R_G_L_3_G_D_0_P_0"
-                        android:fillAlpha="1"
-                        android:fillColor="@color/fake_wallpaper_color_light_mode"
-                        android:fillType="nonZero"
-                        android:pathData=" M206 -446 C206,-446 206,446 206,446 C206,446 -206,446 -206,446 C-206,446 -206,-446 -206,-446 C-206,-446 206,-446 206,-446c " />
-                </group>
-                <group
-                    android:name="_R_G_L_2_G"
-                    android:scaleY="0">
-                    <group
-                        android:name="_R_G_L_2_G_L_4_G"
-                        android:scaleY="0"
-                        android:translateX="206"
-                        android:translateY="776">
-                        <path
-                            android:name="_R_G_L_2_G_L_4_G_D_0_P_0"
-                            android:fillAlpha="0"
-                            android:fillColor="#d9d9da"
-                            android:fillType="nonZero"
-                            android:pathData=" M180 0 C180,0 180,0 180,0 C180,13.8 168.8,25 155,25 C155,25 -155,25 -155,25 C-168.8,25 -180,13.8 -180,0 C-180,0 -180,0 -180,0 C-180,-13.8 -168.8,-25 -155,-25 C-155,-25 155,-25 155,-25 C168.8,-25 180,-13.8 180,0c " />
-                    </group>
-                    <group
-                        android:name="_R_G_L_2_G_L_3_G"
-                        android:scaleY="0"
-                        android:translateX="56"
-                        android:translateY="673">
-                        <path
-                            android:name="_R_G_L_2_G_L_3_G_D_0_P_0"
-                            android:fillAlpha="0"
-                            android:fillColor="#8ab4f8"
-                            android:fillType="nonZero"
-                            android:pathData=" M0 -30 C16.56,-30 30,-16.56 30,0 C30,16.56 16.56,30 0,30 C-16.56,30 -30,16.56 -30,0 C-30,-16.56 -16.56,-30 0,-30c " />
-                    </group>
-                    <group
-                        android:name="_R_G_L_2_G_L_2_G"
-                        android:scaleY="0"
-                        android:translateX="156"
-                        android:translateY="673">
-                        <path
-                            android:name="_R_G_L_2_G_L_2_G_D_0_P_0"
-                            android:fillAlpha="0"
-                            android:fillColor="#f28b82"
-                            android:fillType="nonZero"
-                            android:pathData=" M0 -30 C16.56,-30 30,-16.56 30,0 C30,16.56 16.56,30 0,30 C-16.56,30 -30,16.56 -30,0 C-30,-16.56 -16.56,-30 0,-30c " />
-                    </group>
-                    <group
-                        android:name="_R_G_L_2_G_L_1_G"
-                        android:scaleY="0"
-                        android:translateX="256"
-                        android:translateY="673">
-                        <path
-                            android:name="_R_G_L_2_G_L_1_G_D_0_P_0"
-                            android:fillAlpha="0"
-                            android:fillColor="#fdd663"
-                            android:fillType="nonZero"
-                            android:pathData=" M0 -30 C16.56,-30 30,-16.56 30,0 C30,16.56 16.56,30 0,30 C-16.56,30 -30,16.56 -30,0 C-30,-16.56 -16.56,-30 0,-30c " />
-                    </group>
-                    <group
-                        android:name="_R_G_L_2_G_L_0_G"
-                        android:scaleY="0"
-                        android:translateX="356"
-                        android:translateY="673">
-                        <path
-                            android:name="_R_G_L_2_G_L_0_G_D_0_P_0"
-                            android:fillAlpha="0"
-                            android:fillColor="#81c995"
-                            android:fillType="nonZero"
-                            android:pathData=" M0 -30 C16.56,-30 30,-16.56 30,0 C30,16.56 16.56,30 0,30 C-16.56,30 -30,16.56 -30,0 C-30,-16.56 -16.56,-30 0,-30c " />
-                    </group>
-                </group>
-                <group
-                    android:name="_R_G_L_1_G_T_1"
-                    android:scaleX="1"
-                    android:scaleY="1"
-                    android:translateX="206"
-                    android:translateY="446">
-                    <group
-                        android:name="_R_G_L_1_G"
-                        android:translateX="-206"
-                        android:translateY="-446">
-                        <group android:name="_R_G_L_1_G_L_4_G">
-                            <group
-                                android:name="_R_G_L_1_G_L_4_G_L_11_G"
-                                android:scaleX="0.87473"
-                                android:scaleY="0.98643"
-                                android:translateX="206"
-                                android:translateY="472.769">
-                                <path
-                                    android:name="_R_G_L_1_G_L_4_G_L_11_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#dadce0"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M235.5 -407 C235.5,-407 235.5,407 235.5,407 C235.5,416.93 227.43,425 217.5,425 C217.5,425 -217.5,425 -217.5,425 C-227.43,425 -235.5,416.93 -235.5,407 C-235.5,407 -235.5,-407 -235.5,-407 C-235.5,-416.93 -227.43,-425 -217.5,-425 C-217.5,-425 217.5,-425 217.5,-425 C227.43,-425 235.5,-416.93 235.5,-407c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_1_G_L_4_G_L_10_G"
-                                android:translateX="182.5"
-                                android:translateY="831">
-                                <path
-                                    android:name="_R_G_L_1_G_L_4_G_L_10_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#bdc1c6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M158.5 -3 C158.5,-3 158.5,3 158.5,3 C158.5,7.42 154.92,11 150.5,11 C150.5,11 -150.5,11 -150.5,11 C-154.92,11 -158.5,7.42 -158.5,3 C-158.5,3 -158.5,-3 -158.5,-3 C-158.5,-7.42 -154.92,-11 -150.5,-11 C-150.5,-11 150.5,-11 150.5,-11 C154.92,-11 158.5,-7.42 158.5,-3c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_1_G_L_4_G_L_9_G"
-                                android:translateX="186"
-                                android:translateY="801">
-                                <path
-                                    android:name="_R_G_L_1_G_L_4_G_L_9_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#bdc1c6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M162 -3 C162,-3 162,3 162,3 C162,7.42 158.42,11 154,11 C154,11 -154,11 -154,11 C-158.42,11 -162,7.42 -162,3 C-162,3 -162,-3 -162,-3 C-162,-7.42 -158.42,-11 -154,-11 C-154,-11 154,-11 154,-11 C158.42,-11 162,-7.42 162,-3c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_1_G_L_4_G_L_8_G"
-                                android:translateX="119"
-                                android:translateY="755">
-                                <path
-                                    android:name="_R_G_L_1_G_L_4_G_L_8_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#bdc1c6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M95 -3 C95,-3 95,3 95,3 C95,7.42 91.42,11 87,11 C87,11 -87,11 -87,11 C-91.42,11 -95,7.42 -95,3 C-95,3 -95,-3 -95,-3 C-95,-7.42 -91.42,-11 -87,-11 C-87,-11 87,-11 87,-11 C91.42,-11 95,-7.42 95,-3c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_1_G_L_4_G_L_7_G"
-                                android:translateX="182.5"
-                                android:translateY="725">
-                                <path
-                                    android:name="_R_G_L_1_G_L_4_G_L_7_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#bdc1c6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M158.5 -3 C158.5,-3 158.5,3 158.5,3 C158.5,7.42 154.92,11 150.5,11 C150.5,11 -150.5,11 -150.5,11 C-154.92,11 -158.5,7.42 -158.5,3 C-158.5,3 -158.5,-3 -158.5,-3 C-158.5,-7.42 -154.92,-11 -150.5,-11 C-150.5,-11 150.5,-11 150.5,-11 C154.92,-11 158.5,-7.42 158.5,-3c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_1_G_L_4_G_L_6_G"
-                                android:translateX="197.5"
-                                android:translateY="695">
-                                <path
-                                    android:name="_R_G_L_1_G_L_4_G_L_6_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#bdc1c6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M173.5 -3 C173.5,-3 173.5,3 173.5,3 C173.5,7.42 169.92,11 165.5,11 C165.5,11 -165.5,11 -165.5,11 C-169.92,11 -173.5,7.42 -173.5,3 C-173.5,3 -173.5,-3 -173.5,-3 C-173.5,-7.42 -169.92,-11 -165.5,-11 C-165.5,-11 165.5,-11 165.5,-11 C169.92,-11 173.5,-7.42 173.5,-3c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_1_G_L_4_G_L_5_G"
-                                android:translateX="192"
-                                android:translateY="665">
-                                <path
-                                    android:name="_R_G_L_1_G_L_4_G_L_5_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#bdc1c6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M168 -3 C168,-3 168,3 168,3 C168,7.42 164.42,11 160,11 C160,11 -160,11 -160,11 C-164.42,11 -168,7.42 -168,3 C-168,3 -168,-3 -168,-3 C-168,-7.42 -164.42,-11 -160,-11 C-160,-11 160,-11 160,-11 C164.42,-11 168,-7.42 168,-3c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_1_G_L_4_G_L_4_G"
-                                android:translateX="105.5"
-                                android:translateY="360">
-                                <path
-                                    android:name="_R_G_L_1_G_L_4_G_L_4_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#bdc1c6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M23.5 -2 C23.5,-2 23.5,2 23.5,2 C23.5,4.21 21.71,6 19.5,6 C19.5,6 -19.5,6 -19.5,6 C-21.71,6 -23.5,4.21 -23.5,2 C-23.5,2 -23.5,-2 -23.5,-2 C-23.5,-4.21 -21.71,-6 -19.5,-6 C-19.5,-6 19.5,-6 19.5,-6 C21.71,-6 23.5,-4.21 23.5,-2c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_1_G_L_4_G_L_3_G"
-                                android:translateX="47.5"
-                                android:translateY="360">
-                                <path
-                                    android:name="_R_G_L_1_G_L_4_G_L_3_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#bdc1c6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M23.5 -2 C23.5,-2 23.5,2 23.5,2 C23.5,4.21 21.71,6 19.5,6 C19.5,6 -19.5,6 -19.5,6 C-21.71,6 -23.5,4.21 -23.5,2 C-23.5,2 -23.5,-2 -23.5,-2 C-23.5,-4.21 -21.71,-6 -19.5,-6 C-19.5,-6 19.5,-6 19.5,-6 C21.71,-6 23.5,-4.21 23.5,-2c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_1_G_L_4_G_L_2_G"
-                                android:translateX="142.5"
-                                android:translateY="328">
-                                <path
-                                    android:name="_R_G_L_1_G_L_4_G_L_2_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#bdc1c6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M118.5 -10 C118.5,-10 118.5,10 118.5,10 C118.5,14.42 114.92,18 110.5,18 C110.5,18 -110.5,18 -110.5,18 C-114.92,18 -118.5,14.42 -118.5,10 C-118.5,10 -118.5,-10 -118.5,-10 C-118.5,-14.42 -114.92,-18 -110.5,-18 C-110.5,-18 110.5,-18 110.5,-18 C114.92,-18 118.5,-14.42 118.5,-10c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_1_G_L_4_G_L_1_G"
-                                android:translateX="186"
-                                android:translateY="284">
-                                <path
-                                    android:name="_R_G_L_1_G_L_4_G_L_1_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#bdc1c6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M162 -10 C162,-10 162,10 162,10 C162,14.42 158.42,18 154,18 C154,18 -154,18 -154,18 C-158.42,18 -162,14.42 -162,10 C-162,10 -162,-10 -162,-10 C-162,-14.42 -158.42,-18 -154,-18 C-154,-18 154,-18 154,-18 C158.42,-18 162,-14.42 162,-10c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_1_G_L_4_G_L_0_G"
-                                android:translateX="155"
-                                android:translateY="240">
-                                <path
-                                    android:name="_R_G_L_1_G_L_4_G_L_0_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#bdc1c6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M131 -10 C131,-10 131,10 131,10 C131,14.42 127.42,18 123,18 C123,18 -123,18 -123,18 C-127.42,18 -131,14.42 -131,10 C-131,10 -131,-10 -131,-10 C-131,-14.42 -127.42,-18 -123,-18 C-123,-18 123,-18 123,-18 C127.42,-18 131,-14.42 131,-10c " />
-                            </group>
-                        </group>
-                        <group
-                            android:name="_R_G_L_1_G_L_3_G"
-                            android:translateX="24"
-                            android:translateY="390">
-                            <group
-                                android:name="_R_G_L_1_G_L_3_G_L_0_G"
-                                android:translateX="182"
-                                android:translateY="120">
-                                <path
-                                    android:name="_R_G_L_1_G_L_3_G_L_0_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#bdc1c6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M182 -98 C182,-98 182,98 182,98 C182,110.14 172.14,120 160,120 C160,120 -160,120 -160,120 C-172.14,120 -182,110.14 -182,98 C-182,98 -182,-98 -182,-98 C-182,-110.14 -172.14,-120 -160,-120 C-160,-120 160,-120 160,-120 C172.14,-120 182,-110.14 182,-98c " />
-                            </group>
-                        </group>
-                        <group android:name="_R_G_L_1_G_L_2_G">
-                            <group
-                                android:name="_R_G_L_1_G_L_2_G_L_2_G"
-                                android:translateX="206"
-                                android:translateY="145">
-                                <path
-                                    android:name="_R_G_L_1_G_L_2_G_L_2_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#e8eaed"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M206 -95.63 C206,-95.63 206,42.37 206,42.37 C206,43.47 205.1,44.37 204,44.37 C204,44.37 -204,44.37 -204,44.37 C-205.1,44.37 -206,43.47 -206,42.37 C-206,42.37 -206,-95.63 -206,-95.63 C-206,-96.73 -205.1,-97.63 -204,-97.63 C-204,-97.63 204,-97.63 204,-97.63 C205.1,-97.63 206,-96.73 206,-95.63c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_1_G_L_2_G_L_1_G"
-                                android:translateX="206"
-                                android:translateY="145">
-                                <path
-                                    android:name="_R_G_L_1_G_L_2_G_L_1_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#80868b"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M109 -14 C109,-14 109,14 109,14 C109,15.1 108.1,16 107,16 C107,16 -107,16 -107,16 C-108.1,16 -109,15.1 -109,14 C-109,14 -109,-14 -109,-14 C-109,-15.1 -108.1,-16 -107,-16 C-107,-16 107,-16 107,-16 C108.1,-16 109,-15.1 109,-14c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_1_G_L_2_G_L_0_G"
-                                android:translateX="46"
-                                android:translateY="145">
-                                <path
-                                    android:name="_R_G_L_1_G_L_2_G_L_0_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#80868b"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M22 -14 C22,-14 22,14 22,14 C22,18.42 18.42,22 14,22 C14,22 -14,22 -14,22 C-18.42,22 -22,18.42 -22,14 C-22,14 -22,-14 -22,-14 C-22,-18.42 -18.42,-22 -14,-22 C-14,-22 14,-22 14,-22 C18.42,-22 22,-18.42 22,-14c " />
-                            </group>
-                        </group>
-                        <group android:name="_R_G_L_1_G_L_1_G">
-                            <group
-                                android:name="_R_G_L_1_G_L_1_G_L_2_G"
-                                android:translateX="206"
-                                android:translateY="51">
-                                <path
-                                    android:name="_R_G_L_1_G_L_1_G_L_2_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#6e7175"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M206 -0.27 C206,-0.27 206,49.73 206,49.73 C206,49.73 -206,49.73 -206,49.73 C-206,49.73 -206,-0.27 -206,-0.27 C-206,-0.27 206,-0.27 206,-0.27c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_1_G_L_1_G_L_1_G"
-                                android:translateX="206"
-                                android:translateY="50.5">
-                                <path
-                                    android:name="_R_G_L_1_G_L_1_G_L_1_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#6e7175"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M206 -32.5 C206,-32.5 206,32.5 206,32.5 C206,42.43 197.93,50.5 188,50.5 C188,50.5 -188,50.5 -188,50.5 C-197.93,50.5 -206,42.43 -206,32.5 C-206,32.5 -206,-32.5 -206,-32.5 C-206,-42.43 -197.93,-50.5 -188,-50.5 C-188,-50.5 188,-50.5 188,-50.5 C197.93,-50.5 206,-42.43 206,-32.5c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_1_G_L_1_G_L_0_G"
-                                android:translateX="206"
-                                android:translateY="66.5">
-                                <path
-                                    android:name="_R_G_L_1_G_L_1_G_L_0_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#9a9a9a"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M190 0 C190,0 190,0 190,0 C190,10.21 181.71,18.5 171.5,18.5 C171.5,18.5 -171.5,18.5 -171.5,18.5 C-181.71,18.5 -190,10.21 -190,0 C-190,0 -190,0 -190,0 C-190,-10.21 -181.71,-18.5 -171.5,-18.5 C-171.5,-18.5 171.5,-18.5 171.5,-18.5 C181.71,-18.5 190,-10.21 190,0c " />
-                            </group>
-                        </group>
-                        <group
-                            android:name="_R_G_L_1_G_L_0_G"
-                            android:scaleY="0"
-                            android:translateX="206"
-                            android:translateY="446">
-                            <path
-                                android:name="_R_G_L_1_G_L_0_G_D_0_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#bac4d6"
-                                android:fillType="nonZero"
-                                android:pathData=" M206.06 -430.06 C206.06,-430.06 206,431 206,431 C206,446 189.75,446 189.79,446 C189.79,446 -189.98,446 -189.98,446 C-189.94,446 -206,446 -206,431 C-206,431 -206,-430 -206,-430 C-206,-446 -189.97,-446 -190.01,-446 C-190.01,-446 188.98,-446.06 188.98,-446.06 C188.94,-446.06 206,-446 206.06,-430.06c " />
-                        </group>
-                    </group>
-                </group>
-                <group
-                    android:name="_R_G_L_0_G"
-                    android:translateX="206"
-                    android:translateY="446">
-                    <path
-                        android:name="_R_G_L_0_G_D_0_P_0"
-                        android:fillAlpha="0"
-                        android:fillColor="#84ba69"
-                        android:fillType="nonZero"
-                        android:pathData=" M0 411 C19.33,411 35,426.67 35,446 C35,465.33 19.33,481 0,481 C-19.33,481 -35,465.33 -35,446 C-35,426.67 -19.33,411 0,411c " />
-                </group>
-            </group>
-            <group android:name="time_group" />
-        </vector>
-    </aapt:attr>
-</animated-vector>
\ No newline at end of file
diff --git a/quickstep/res/drawable/gesture_tutorial_motion_overview_dark_mode.xml b/quickstep/res/drawable/gesture_tutorial_motion_overview_dark_mode.xml
deleted file mode 100644
index b007d20..0000000
--- a/quickstep/res/drawable/gesture_tutorial_motion_overview_dark_mode.xml
+++ /dev/null
@@ -1,1623 +0,0 @@
-<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:aapt="http://schemas.android.com/aapt">
-    <target android:name="_R_G_L_4_G_N_3_T_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="1050"
-                    android:pathData="M 206,446C 206,446 206,395 206,395"
-                    android:propertyName="translateXY"
-                    android:propertyXName="translateX"
-                    android:propertyYName="translateY"
-                    android:startOffset="217">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.5,0 0.5,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_4_G_N_3_T_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="1050"
-                    android:propertyName="scaleX"
-                    android:startOffset="217"
-                    android:valueFrom="1"
-                    android:valueTo="0.6"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.5,0 0.5,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="1050"
-                    android:propertyName="scaleY"
-                    android:startOffset="217"
-                    android:valueFrom="1"
-                    android:valueTo="0.6"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.5,0 0.5,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_4_G_N_3_T_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="3400"
-                    android:valueFrom="1"
-                    android:valueTo="0"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_3_G_L_0_G_L_28_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="2083"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_3_G_L_0_G_L_27_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="2083"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_3_G_L_0_G_L_26_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="2083"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_3_G_L_0_G_L_25_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="2083"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_3_G_L_0_G_L_24_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="2083"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_3_G_L_0_G_L_23_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="2083"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_3_G_L_0_G_L_22_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="2083"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_3_G_L_0_G_L_21_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="2083"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_3_G_L_0_G_L_20_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="2083"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_3_G_L_0_G_L_19_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="2083"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_3_G_L_0_G_L_18_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="2083"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_3_G_L_0_G_L_17_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="2083"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_3_G_L_0_G_L_16_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="2083"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_3_G_L_0_G_L_15_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="2083"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_3_G_L_0_G_L_14_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="2083"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_3_G_L_0_G_L_13_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="2083"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_3_G_L_0_G_L_12_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="2083"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_3_G_L_0_G_L_11_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="2083"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_3_G_L_0_G_L_10_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="2083"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_3_G_L_0_G_L_9_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="2083"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_3_G_L_0_G_L_8_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="2083"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_3_G_L_0_G_L_7_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="2083"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_3_G_L_0_G_L_6_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="2083"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_3_G_L_0_G_L_5_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="2083"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_3_G_L_0_G_L_4_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="2083"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_3_G_L_0_G_L_3_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="2083"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_3_G_L_0_G_L_2_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="2083"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_3_G_L_0_G_L_1_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="2083"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_3_G_L_0_G_L_0_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="2083"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_3_G_L_0_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="2083"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_3_G_N_2_T_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="350"
-                    android:pathData="M 206,395C 206,403.5 206,437.5 206,446"
-                    android:propertyName="translateXY"
-                    android:propertyXName="translateX"
-                    android:propertyYName="translateY"
-                    android:startOffset="2083">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.34,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_3_G_N_2_T_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="350"
-                    android:propertyName="scaleX"
-                    android:startOffset="2083"
-                    android:valueFrom="0.6"
-                    android:valueTo="0.72718"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.34,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="350"
-                    android:propertyName="scaleY"
-                    android:startOffset="2083"
-                    android:valueFrom="0.6"
-                    android:valueTo="0.72718"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.34,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="217"
-                    android:propertyName="scaleX"
-                    android:startOffset="2433"
-                    android:valueFrom="0.72718"
-                    android:valueTo="0.72"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0 0.51,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="217"
-                    android:propertyName="scaleY"
-                    android:startOffset="2433"
-                    android:valueFrom="0.72718"
-                    android:valueTo="0.72"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0 0.51,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_3_G_N_2_T_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="2083"
-                    android:valueFrom="0"
-                    android:valueTo="0.6"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_2_G_D_0_P_0_G_0_T_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="167"
-                    android:propertyName="scaleX"
-                    android:startOffset="2567"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="167"
-                    android:propertyName="scaleY"
-                    android:startOffset="2567"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_2_G_N_2_T_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="350"
-                    android:pathData="M 206,395C 206,403.5 206,437.5 206,446"
-                    android:propertyName="translateXY"
-                    android:propertyXName="translateX"
-                    android:propertyYName="translateY"
-                    android:startOffset="2083">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.34,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_2_G_N_2_T_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="350"
-                    android:propertyName="scaleX"
-                    android:startOffset="2083"
-                    android:valueFrom="0.6"
-                    android:valueTo="0.72718"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.34,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="350"
-                    android:propertyName="scaleY"
-                    android:startOffset="2083"
-                    android:valueFrom="0.6"
-                    android:valueTo="0.72718"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.34,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="217"
-                    android:propertyName="scaleX"
-                    android:startOffset="2433"
-                    android:valueFrom="0.72718"
-                    android:valueTo="0.72"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0 0.51,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="217"
-                    android:propertyName="scaleY"
-                    android:startOffset="2433"
-                    android:valueFrom="0.72718"
-                    android:valueTo="0.72"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0 0.51,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_2_G_N_2_T_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="2567"
-                    android:valueFrom="0"
-                    android:valueTo="0.6"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_1_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="250"
-                    android:pathData="M -556.176,-7.307C -556.176,-7.307 -421.176,-7.307 -421.176,-7.307"
-                    android:propertyName="translateXY"
-                    android:propertyXName="translateX"
-                    android:propertyYName="translateY"
-                    android:startOffset="1350">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.272,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="417"
-                    android:pathData="M -421.176,-7.307C -421.176,-7.307 -429.51,-7.307 -429.51,-7.307"
-                    android:propertyName="translateXY"
-                    android:propertyXName="translateX"
-                    android:propertyYName="translateY"
-                    android:startOffset="1600">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_1_G_N_2_T_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="350"
-                    android:pathData="M 206,395C 206,403.5 206,437.5 206,446"
-                    android:propertyName="translateXY"
-                    android:propertyXName="translateX"
-                    android:propertyYName="translateY"
-                    android:startOffset="2083">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.34,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_1_G_N_2_T_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="350"
-                    android:propertyName="scaleX"
-                    android:startOffset="2083"
-                    android:valueFrom="0.6"
-                    android:valueTo="0.72718"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.34,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="350"
-                    android:propertyName="scaleY"
-                    android:startOffset="2083"
-                    android:valueFrom="0.6"
-                    android:valueTo="0.72718"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.34,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="217"
-                    android:propertyName="scaleX"
-                    android:startOffset="2433"
-                    android:valueFrom="0.72718"
-                    android:valueTo="0.72"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0 0.51,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="217"
-                    android:propertyName="scaleY"
-                    android:startOffset="2433"
-                    android:valueFrom="0.72718"
-                    android:valueTo="0.72"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0 0.51,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_1_G_N_2_T_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="1350"
-                    android:valueFrom="0"
-                    android:valueTo="0.6"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_0_G_D_0_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="217"
-                    android:propertyName="fillAlpha"
-                    android:startOffset="0"
-                    android:valueFrom="0"
-                    android:valueTo="0.75"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,0.833 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="1833"
-                    android:propertyName="fillAlpha"
-                    android:startOffset="217"
-                    android:valueFrom="0.75"
-                    android:valueTo="0.75"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0 0.667,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="167"
-                    android:propertyName="fillAlpha"
-                    android:startOffset="2050"
-                    android:valueFrom="0.75"
-                    android:valueTo="0"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_0_G_D_0_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="217"
-                    android:propertyName="pathData"
-                    android:startOffset="0"
-                    android:valueFrom="M0 406 C21.54,406 39,423.46 39,445 C39,466.54 21.54,484 0,484 C-21.54,484 -39,466.54 -39,445 C-39,423.46 -21.54,406 0,406c "
-                    android:valueTo="M0 395 C27.61,395 50,417.39 50,445 C50,472.61 27.61,495 0,495 C-27.61,495 -50,472.61 -50,445 C-50,417.39 -27.61,395 0,395c "
-                    android:valueType="pathType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="1050"
-                    android:propertyName="pathData"
-                    android:startOffset="217"
-                    android:valueFrom="M0 395 C27.61,395 50,417.39 50,445 C50,472.61 27.61,495 0,495 C-27.61,495 -50,472.61 -50,445 C-50,417.39 -27.61,395 0,395c "
-                    android:valueTo="M0 166 C27.61,166 50,188.39 50,216 C50,243.61 27.61,266 0,266 C-27.61,266 -50,243.61 -50,216 C-50,188.39 -27.61,166 0,166c "
-                    android:valueType="pathType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.5,0 0.5,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="783"
-                    android:propertyName="pathData"
-                    android:startOffset="1267"
-                    android:valueFrom="M0 166 C27.61,166 50,188.39 50,216 C50,243.61 27.61,266 0,266 C-27.61,266 -50,243.61 -50,216 C-50,188.39 -27.61,166 0,166c "
-                    android:valueTo="M0 166 C27.61,166 50,188.39 50,216 C50,243.61 27.61,266 0,266 C-27.61,266 -50,243.61 -50,216 C-50,188.39 -27.61,166 0,166c "
-                    android:valueType="pathType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="167"
-                    android:propertyName="pathData"
-                    android:startOffset="2050"
-                    android:valueFrom="M0 166 C27.61,166 50,188.39 50,216 C50,243.61 27.61,266 0,266 C-27.61,266 -50,243.61 -50,216 C-50,188.39 -27.61,166 0,166c "
-                    android:valueTo="M0 180 C19.88,180 36,196.12 36,216 C36,235.88 19.88,252 0,252 C-19.88,252 -36,235.88 -36,216 C-36,196.12 -19.88,180 0,180c "
-                    android:valueType="pathType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="time_group">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="2750"
-                    android:propertyName="translateX"
-                    android:startOffset="0"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <aapt:attr name="android:drawable">
-        <vector
-            android:width="412dp"
-            android:height="892dp"
-            android:viewportHeight="892"
-            android:viewportWidth="412">
-            <group android:name="_R_G">
-                <group
-                    android:name="_R_G_L_5_G"
-                    android:translateX="206"
-                    android:translateY="446">
-                    <path
-                        android:name="_R_G_L_5_G_D_0_P_0"
-                        android:fillAlpha="1"
-                        android:fillColor="@color/fake_wallpaper_color_dark_mode"
-                        android:fillType="nonZero"
-                        android:pathData=" M206 -446 C206,-446 206,446 206,446 C206,446 -206,446 -206,446 C-206,446 -206,-446 -206,-446 C-206,-446 206,-446 206,-446c " />
-                </group>
-                <group
-                    android:name="_R_G_L_4_G_N_3_T_0"
-                    android:scaleX="1"
-                    android:scaleY="1"
-                    android:translateX="206"
-                    android:translateY="446">
-                    <group
-                        android:name="_R_G_L_4_G"
-                        android:translateX="-206"
-                        android:translateY="-446">
-                        <group android:name="_R_G_L_4_G_L_0_G">
-                            <group
-                                android:name="_R_G_L_4_G_L_0_G_L_28_G"
-                                android:translateX="206"
-                                android:translateY="446">
-                                <path
-                                    android:name="_R_G_L_4_G_L_0_G_L_28_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#000000"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M206 -422 C206,-422 206,422 206,422 C206,435.25 195.25,446 182,446 C182,446 -182,446 -182,446 C-195.25,446 -206,435.25 -206,422 C-206,422 -206,-422 -206,-422 C-206,-435.25 -195.25,-446 -182,-446 C-182,-446 182,-446 182,-446 C195.25,-446 206,-435.25 206,-422c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_4_G_L_0_G_L_27_G"
-                                android:translateX="206"
-                                android:translateY="422.5">
-                                <path
-                                    android:name="_R_G_L_4_G_L_0_G_L_27_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#dadce0"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M206 -395.5 C206,-395.5 206,395.5 206,395.5 C206,395.5 -206,395.5 -206,395.5 C-206,395.5 -206,-395.5 -206,-395.5 C-206,-395.5 206,-395.5 206,-395.5c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_4_G_L_0_G_L_26_G"
-                                android:translateX="206"
-                                android:translateY="496.5">
-                                <path
-                                    android:name="_R_G_L_4_G_L_0_G_L_26_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#dadce0"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M206 -377.5 C206,-377.5 206,377.5 206,377.5 C206,387.43 197.93,395.5 188,395.5 C188,395.5 -188,395.5 -188,395.5 C-197.93,395.5 -206,387.43 -206,377.5 C-206,377.5 -206,-377.5 -206,-377.5 C-206,-387.43 -197.93,-395.5 -188,-395.5 C-188,-395.5 188,-395.5 188,-395.5 C197.93,-395.5 206,-387.43 206,-377.5c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_4_G_L_0_G_L_25_G"
-                                android:translateX="206"
-                                android:translateY="50.5">
-                                <path
-                                    android:name="_R_G_L_4_G_L_0_G_L_25_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#e8eaed"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M206 -23.5 C206,-23.5 206,50.5 206,50.5 C206,50.5 -206,50.5 -206,50.5 C-206,50.5 -206,-23.5 -206,-23.5 C-206,-23.5 206,-23.5 206,-23.5c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_4_G_L_0_G_L_24_G"
-                                android:translateX="206"
-                                android:translateY="50.5">
-                                <path
-                                    android:name="_R_G_L_4_G_L_0_G_L_24_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#e8eaed"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M206 -32.5 C206,-32.5 206,32.5 206,32.5 C206,42.43 197.93,50.5 188,50.5 C188,50.5 -188,50.5 -188,50.5 C-197.93,50.5 -206,42.43 -206,32.5 C-206,32.5 -206,-32.5 -206,-32.5 C-206,-42.43 -197.93,-50.5 -188,-50.5 C-188,-50.5 188,-50.5 188,-50.5 C197.93,-50.5 206,-42.43 206,-32.5c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_4_G_L_0_G_L_23_G"
-                                android:translateX="54"
-                                android:translateY="157">
-                                <path
-                                    android:name="_R_G_L_4_G_L_0_G_L_23_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#9aa0a6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_4_G_L_0_G_L_22_G"
-                                android:translateX="54"
-                                android:translateY="157">
-                                <path
-                                    android:name="_R_G_L_4_G_L_0_G_L_22_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#9aa0a6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_4_G_L_0_G_L_21_G"
-                                android:translateX="148.5"
-                                android:translateY="148">
-                                <path
-                                    android:name="_R_G_L_4_G_L_0_G_L_21_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#bdc1c6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M46.5 -5 C46.5,-5 46.5,5 46.5,5 C46.5,7.21 44.71,9 42.5,9 C42.5,9 -42.5,9 -42.5,9 C-44.71,9 -46.5,7.21 -46.5,5 C-46.5,5 -46.5,-5 -46.5,-5 C-46.5,-7.21 -44.71,-9 -42.5,-9 C-42.5,-9 42.5,-9 42.5,-9 C44.71,-9 46.5,-7.21 46.5,-5c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_4_G_L_0_G_L_20_G"
-                                android:translateX="186"
-                                android:translateY="169">
-                                <path
-                                    android:name="_R_G_L_4_G_L_0_G_L_20_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#bdc1c6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M84 -4 C84,-4 84,4 84,4 C84,6.21 82.21,8 80,8 C80,8 -80,8 -80,8 C-82.21,8 -84,6.21 -84,4 C-84,4 -84,-4 -84,-4 C-84,-6.21 -82.21,-8 -80,-8 C-80,-8 80,-8 80,-8 C82.21,-8 84,-6.21 84,-4c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_4_G_L_0_G_L_19_G"
-                                android:translateX="54"
-                                android:translateY="245">
-                                <path
-                                    android:name="_R_G_L_4_G_L_0_G_L_19_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#9aa0a6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_4_G_L_0_G_L_18_G"
-                                android:translateX="162"
-                                android:translateY="236">
-                                <path
-                                    android:name="_R_G_L_4_G_L_0_G_L_18_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#bdc1c6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M60 -5 C60,-5 60,5 60,5 C60,7.21 58.21,9 56,9 C56,9 -56,9 -56,9 C-58.21,9 -60,7.21 -60,5 C-60,5 -60,-5 -60,-5 C-60,-7.21 -58.21,-9 -56,-9 C-56,-9 56,-9 56,-9 C58.21,-9 60,-7.21 60,-5c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_4_G_L_0_G_L_17_G"
-                                android:translateX="171.5"
-                                android:translateY="257">
-                                <path
-                                    android:name="_R_G_L_4_G_L_0_G_L_17_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#bdc1c6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M69.5 -4 C69.5,-4 69.5,4 69.5,4 C69.5,6.21 67.71,8 65.5,8 C65.5,8 -65.5,8 -65.5,8 C-67.71,8 -69.5,6.21 -69.5,4 C-69.5,4 -69.5,-4 -69.5,-4 C-69.5,-6.21 -67.71,-8 -65.5,-8 C-65.5,-8 65.5,-8 65.5,-8 C67.71,-8 69.5,-6.21 69.5,-4c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_4_G_L_0_G_L_16_G"
-                                android:translateX="54"
-                                android:translateY="333">
-                                <path
-                                    android:name="_R_G_L_4_G_L_0_G_L_16_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#9aa0a6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_4_G_L_0_G_L_15_G"
-                                android:translateX="158"
-                                android:translateY="324">
-                                <path
-                                    android:name="_R_G_L_4_G_L_0_G_L_15_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#bdc1c6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M56 -5 C56,-5 56,5 56,5 C56,7.21 54.21,9 52,9 C52,9 -52,9 -52,9 C-54.21,9 -56,7.21 -56,5 C-56,5 -56,-5 -56,-5 C-56,-7.21 -54.21,-9 -52,-9 C-52,-9 52,-9 52,-9 C54.21,-9 56,-7.21 56,-5c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_4_G_L_0_G_L_14_G"
-                                android:translateX="217.5"
-                                android:translateY="345">
-                                <path
-                                    android:name="_R_G_L_4_G_L_0_G_L_14_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#bdc1c6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M115.5 -4 C115.5,-4 115.5,4 115.5,4 C115.5,6.21 113.71,8 111.5,8 C111.5,8 -111.5,8 -111.5,8 C-113.71,8 -115.5,6.21 -115.5,4 C-115.5,4 -115.5,-4 -115.5,-4 C-115.5,-6.21 -113.71,-8 -111.5,-8 C-111.5,-8 111.5,-8 111.5,-8 C113.71,-8 115.5,-6.21 115.5,-4c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_4_G_L_0_G_L_13_G"
-                                android:translateX="54"
-                                android:translateY="421">
-                                <path
-                                    android:name="_R_G_L_4_G_L_0_G_L_13_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#9aa0a6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_4_G_L_0_G_L_12_G"
-                                android:translateX="170"
-                                android:translateY="412">
-                                <path
-                                    android:name="_R_G_L_4_G_L_0_G_L_12_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#bdc1c6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M68 -5 C68,-5 68,5 68,5 C68,7.21 66.21,9 64,9 C64,9 -64,9 -64,9 C-66.21,9 -68,7.21 -68,5 C-68,5 -68,-5 -68,-5 C-68,-7.21 -66.21,-9 -64,-9 C-64,-9 64,-9 64,-9 C66.21,-9 68,-7.21 68,-5c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_4_G_L_0_G_L_11_G"
-                                android:translateX="198.5"
-                                android:translateY="433">
-                                <path
-                                    android:name="_R_G_L_4_G_L_0_G_L_11_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#bdc1c6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M96.5 -4 C96.5,-4 96.5,4 96.5,4 C96.5,6.21 94.71,8 92.5,8 C92.5,8 -92.5,8 -92.5,8 C-94.71,8 -96.5,6.21 -96.5,4 C-96.5,4 -96.5,-4 -96.5,-4 C-96.5,-6.21 -94.71,-8 -92.5,-8 C-92.5,-8 92.5,-8 92.5,-8 C94.71,-8 96.5,-6.21 96.5,-4c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_4_G_L_0_G_L_10_G"
-                                android:translateX="54"
-                                android:translateY="509">
-                                <path
-                                    android:name="_R_G_L_4_G_L_0_G_L_10_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#9aa0a6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_4_G_L_0_G_L_9_G"
-                                android:translateX="135"
-                                android:translateY="500">
-                                <path
-                                    android:name="_R_G_L_4_G_L_0_G_L_9_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#bdc1c6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M33 -5 C33,-5 33,5 33,5 C33,7.21 31.21,9 29,9 C29,9 -29,9 -29,9 C-31.21,9 -33,7.21 -33,5 C-33,5 -33,-5 -33,-5 C-33,-7.21 -31.21,-9 -29,-9 C-29,-9 29,-9 29,-9 C31.21,-9 33,-7.21 33,-5c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_4_G_L_0_G_L_8_G"
-                                android:translateX="185.5"
-                                android:translateY="521">
-                                <path
-                                    android:name="_R_G_L_4_G_L_0_G_L_8_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#bdc1c6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M83.5 -4 C83.5,-4 83.5,4 83.5,4 C83.5,6.21 81.71,8 79.5,8 C79.5,8 -79.5,8 -79.5,8 C-81.71,8 -83.5,6.21 -83.5,4 C-83.5,4 -83.5,-4 -83.5,-4 C-83.5,-6.21 -81.71,-8 -79.5,-8 C-79.5,-8 79.5,-8 79.5,-8 C81.71,-8 83.5,-6.21 83.5,-4c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_4_G_L_0_G_L_7_G"
-                                android:translateX="54"
-                                android:translateY="597">
-                                <path
-                                    android:name="_R_G_L_4_G_L_0_G_L_7_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#9aa0a6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_4_G_L_0_G_L_6_G"
-                                android:translateX="168.5"
-                                android:translateY="588">
-                                <path
-                                    android:name="_R_G_L_4_G_L_0_G_L_6_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#bdc1c6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M66.5 -5 C66.5,-5 66.5,5 66.5,5 C66.5,7.21 64.71,9 62.5,9 C62.5,9 -62.5,9 -62.5,9 C-64.71,9 -66.5,7.21 -66.5,5 C-66.5,5 -66.5,-5 -66.5,-5 C-66.5,-7.21 -64.71,-9 -62.5,-9 C-62.5,-9 62.5,-9 62.5,-9 C64.71,-9 66.5,-7.21 66.5,-5c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_4_G_L_0_G_L_5_G"
-                                android:translateX="198.5"
-                                android:translateY="609">
-                                <path
-                                    android:name="_R_G_L_4_G_L_0_G_L_5_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#bdc1c6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M96.5 -4 C96.5,-4 96.5,4 96.5,4 C96.5,6.21 94.71,8 92.5,8 C92.5,8 -92.5,8 -92.5,8 C-94.71,8 -96.5,6.21 -96.5,4 C-96.5,4 -96.5,-4 -96.5,-4 C-96.5,-6.21 -94.71,-8 -92.5,-8 C-92.5,-8 92.5,-8 92.5,-8 C94.71,-8 96.5,-6.21 96.5,-4c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_4_G_L_0_G_L_4_G"
-                                android:translateX="54"
-                                android:translateY="685">
-                                <path
-                                    android:name="_R_G_L_4_G_L_0_G_L_4_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#9aa0a6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_4_G_L_0_G_L_3_G"
-                                android:translateX="162.5"
-                                android:translateY="676">
-                                <path
-                                    android:name="_R_G_L_4_G_L_0_G_L_3_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#bdc1c6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M60.5 -5 C60.5,-5 60.5,5 60.5,5 C60.5,7.21 58.71,9 56.5,9 C56.5,9 -56.5,9 -56.5,9 C-58.71,9 -60.5,7.21 -60.5,5 C-60.5,5 -60.5,-5 -60.5,-5 C-60.5,-7.21 -58.71,-9 -56.5,-9 C-56.5,-9 56.5,-9 56.5,-9 C58.71,-9 60.5,-7.21 60.5,-5c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_4_G_L_0_G_L_2_G"
-                                android:translateX="174"
-                                android:translateY="697">
-                                <path
-                                    android:name="_R_G_L_4_G_L_0_G_L_2_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#bdc1c6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M72 -4 C72,-4 72,4 72,4 C72,6.21 70.21,8 68,8 C68,8 -68,8 -68,8 C-70.21,8 -72,6.21 -72,4 C-72,4 -72,-4 -72,-4 C-72,-6.21 -70.21,-8 -68,-8 C-68,-8 68,-8 68,-8 C70.21,-8 72,-6.21 72,-4c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_4_G_L_0_G_L_1_G"
-                                android:translateX="313.5"
-                                android:translateY="798">
-                                <path
-                                    android:name="_R_G_L_4_G_L_0_G_L_1_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#bdc1c6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M74.5 0 C74.5,0 74.5,0 74.5,0 C74.5,15.45 61.95,28 46.5,28 C46.5,28 -46.5,28 -46.5,28 C-61.95,28 -74.5,15.45 -74.5,0 C-74.5,0 -74.5,0 -74.5,0 C-74.5,-15.45 -61.95,-28 -46.5,-28 C-46.5,-28 46.5,-28 46.5,-28 C61.95,-28 74.5,-15.45 74.5,0c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_4_G_L_0_G_L_0_G"
-                                android:translateX="205.5"
-                                android:translateY="61">
-                                <path
-                                    android:name="_R_G_L_4_G_L_0_G_L_0_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#f8f9fa"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M171.5 -14 C171.5,-14 171.5,14 171.5,14 C171.5,16.21 169.71,18 167.5,18 C167.5,18 -167.5,18 -167.5,18 C-169.71,18 -171.5,16.21 -171.5,14 C-171.5,14 -171.5,-14 -171.5,-14 C-171.5,-16.21 -169.71,-18 -167.5,-18 C-167.5,-18 167.5,-18 167.5,-18 C169.71,-18 171.5,-16.21 171.5,-14c " />
-                            </group>
-                        </group>
-                    </group>
-                </group>
-                <group
-                    android:name="_R_G_L_3_G_N_2_T_0"
-                    android:scaleX="0.6"
-                    android:scaleY="0"
-                    android:translateX="206"
-                    android:translateY="395">
-                    <group
-                        android:name="_R_G_L_3_G"
-                        android:translateX="-206"
-                        android:translateY="-446">
-                        <group
-                            android:name="_R_G_L_3_G_L_0_G"
-                            android:scaleY="0">
-                            <group
-                                android:name="_R_G_L_3_G_L_0_G_L_28_G"
-                                android:scaleY="0"
-                                android:translateX="206"
-                                android:translateY="446">
-                                <path
-                                    android:name="_R_G_L_3_G_L_0_G_L_28_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#000000"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M206 -422 C206,-422 206,422 206,422 C206,435.25 195.25,446 182,446 C182,446 -182,446 -182,446 C-195.25,446 -206,435.25 -206,422 C-206,422 -206,-422 -206,-422 C-206,-435.25 -195.25,-446 -182,-446 C-182,-446 182,-446 182,-446 C195.25,-446 206,-435.25 206,-422c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_3_G_L_0_G_L_27_G"
-                                android:scaleY="0"
-                                android:translateX="206"
-                                android:translateY="422.5">
-                                <path
-                                    android:name="_R_G_L_3_G_L_0_G_L_27_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#dadce0"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M206 -395.5 C206,-395.5 206,395.5 206,395.5 C206,395.5 -206,395.5 -206,395.5 C-206,395.5 -206,-395.5 -206,-395.5 C-206,-395.5 206,-395.5 206,-395.5c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_3_G_L_0_G_L_26_G"
-                                android:scaleY="0"
-                                android:translateX="206"
-                                android:translateY="496.5">
-                                <path
-                                    android:name="_R_G_L_3_G_L_0_G_L_26_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#dadce0"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M206 -377.5 C206,-377.5 206,377.5 206,377.5 C206,387.43 197.93,395.5 188,395.5 C188,395.5 -188,395.5 -188,395.5 C-197.93,395.5 -206,387.43 -206,377.5 C-206,377.5 -206,-377.5 -206,-377.5 C-206,-387.43 -197.93,-395.5 -188,-395.5 C-188,-395.5 188,-395.5 188,-395.5 C197.93,-395.5 206,-387.43 206,-377.5c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_3_G_L_0_G_L_25_G"
-                                android:scaleY="0"
-                                android:translateX="206"
-                                android:translateY="50.5">
-                                <path
-                                    android:name="_R_G_L_3_G_L_0_G_L_25_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#e8eaed"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M206 -23.5 C206,-23.5 206,50.5 206,50.5 C206,50.5 -206,50.5 -206,50.5 C-206,50.5 -206,-23.5 -206,-23.5 C-206,-23.5 206,-23.5 206,-23.5c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_3_G_L_0_G_L_24_G"
-                                android:scaleY="0"
-                                android:translateX="206"
-                                android:translateY="50.5">
-                                <path
-                                    android:name="_R_G_L_3_G_L_0_G_L_24_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#e8eaed"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M206 -32.5 C206,-32.5 206,32.5 206,32.5 C206,42.43 197.93,50.5 188,50.5 C188,50.5 -188,50.5 -188,50.5 C-197.93,50.5 -206,42.43 -206,32.5 C-206,32.5 -206,-32.5 -206,-32.5 C-206,-42.43 -197.93,-50.5 -188,-50.5 C-188,-50.5 188,-50.5 188,-50.5 C197.93,-50.5 206,-42.43 206,-32.5c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_3_G_L_0_G_L_23_G"
-                                android:scaleY="0"
-                                android:translateX="54"
-                                android:translateY="157">
-                                <path
-                                    android:name="_R_G_L_3_G_L_0_G_L_23_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#9aa0a6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_3_G_L_0_G_L_22_G"
-                                android:scaleY="0"
-                                android:translateX="54"
-                                android:translateY="157">
-                                <path
-                                    android:name="_R_G_L_3_G_L_0_G_L_22_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#9aa0a6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_3_G_L_0_G_L_21_G"
-                                android:scaleY="0"
-                                android:translateX="148.5"
-                                android:translateY="148">
-                                <path
-                                    android:name="_R_G_L_3_G_L_0_G_L_21_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#bdc1c6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M46.5 -5 C46.5,-5 46.5,5 46.5,5 C46.5,7.21 44.71,9 42.5,9 C42.5,9 -42.5,9 -42.5,9 C-44.71,9 -46.5,7.21 -46.5,5 C-46.5,5 -46.5,-5 -46.5,-5 C-46.5,-7.21 -44.71,-9 -42.5,-9 C-42.5,-9 42.5,-9 42.5,-9 C44.71,-9 46.5,-7.21 46.5,-5c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_3_G_L_0_G_L_20_G"
-                                android:scaleY="0"
-                                android:translateX="186"
-                                android:translateY="169">
-                                <path
-                                    android:name="_R_G_L_3_G_L_0_G_L_20_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#bdc1c6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M84 -4 C84,-4 84,4 84,4 C84,6.21 82.21,8 80,8 C80,8 -80,8 -80,8 C-82.21,8 -84,6.21 -84,4 C-84,4 -84,-4 -84,-4 C-84,-6.21 -82.21,-8 -80,-8 C-80,-8 80,-8 80,-8 C82.21,-8 84,-6.21 84,-4c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_3_G_L_0_G_L_19_G"
-                                android:scaleY="0"
-                                android:translateX="54"
-                                android:translateY="245">
-                                <path
-                                    android:name="_R_G_L_3_G_L_0_G_L_19_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#9aa0a6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_3_G_L_0_G_L_18_G"
-                                android:scaleY="0"
-                                android:translateX="162"
-                                android:translateY="236">
-                                <path
-                                    android:name="_R_G_L_3_G_L_0_G_L_18_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#bdc1c6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M60 -5 C60,-5 60,5 60,5 C60,7.21 58.21,9 56,9 C56,9 -56,9 -56,9 C-58.21,9 -60,7.21 -60,5 C-60,5 -60,-5 -60,-5 C-60,-7.21 -58.21,-9 -56,-9 C-56,-9 56,-9 56,-9 C58.21,-9 60,-7.21 60,-5c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_3_G_L_0_G_L_17_G"
-                                android:scaleY="0"
-                                android:translateX="171.5"
-                                android:translateY="257">
-                                <path
-                                    android:name="_R_G_L_3_G_L_0_G_L_17_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#bdc1c6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M69.5 -4 C69.5,-4 69.5,4 69.5,4 C69.5,6.21 67.71,8 65.5,8 C65.5,8 -65.5,8 -65.5,8 C-67.71,8 -69.5,6.21 -69.5,4 C-69.5,4 -69.5,-4 -69.5,-4 C-69.5,-6.21 -67.71,-8 -65.5,-8 C-65.5,-8 65.5,-8 65.5,-8 C67.71,-8 69.5,-6.21 69.5,-4c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_3_G_L_0_G_L_16_G"
-                                android:scaleY="0"
-                                android:translateX="54"
-                                android:translateY="333">
-                                <path
-                                    android:name="_R_G_L_3_G_L_0_G_L_16_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#9aa0a6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_3_G_L_0_G_L_15_G"
-                                android:scaleY="0"
-                                android:translateX="158"
-                                android:translateY="324">
-                                <path
-                                    android:name="_R_G_L_3_G_L_0_G_L_15_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#bdc1c6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M56 -5 C56,-5 56,5 56,5 C56,7.21 54.21,9 52,9 C52,9 -52,9 -52,9 C-54.21,9 -56,7.21 -56,5 C-56,5 -56,-5 -56,-5 C-56,-7.21 -54.21,-9 -52,-9 C-52,-9 52,-9 52,-9 C54.21,-9 56,-7.21 56,-5c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_3_G_L_0_G_L_14_G"
-                                android:scaleY="0"
-                                android:translateX="217.5"
-                                android:translateY="345">
-                                <path
-                                    android:name="_R_G_L_3_G_L_0_G_L_14_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#bdc1c6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M115.5 -4 C115.5,-4 115.5,4 115.5,4 C115.5,6.21 113.71,8 111.5,8 C111.5,8 -111.5,8 -111.5,8 C-113.71,8 -115.5,6.21 -115.5,4 C-115.5,4 -115.5,-4 -115.5,-4 C-115.5,-6.21 -113.71,-8 -111.5,-8 C-111.5,-8 111.5,-8 111.5,-8 C113.71,-8 115.5,-6.21 115.5,-4c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_3_G_L_0_G_L_13_G"
-                                android:scaleY="0"
-                                android:translateX="54"
-                                android:translateY="421">
-                                <path
-                                    android:name="_R_G_L_3_G_L_0_G_L_13_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#9aa0a6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_3_G_L_0_G_L_12_G"
-                                android:scaleY="0"
-                                android:translateX="170"
-                                android:translateY="412">
-                                <path
-                                    android:name="_R_G_L_3_G_L_0_G_L_12_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#bdc1c6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M68 -5 C68,-5 68,5 68,5 C68,7.21 66.21,9 64,9 C64,9 -64,9 -64,9 C-66.21,9 -68,7.21 -68,5 C-68,5 -68,-5 -68,-5 C-68,-7.21 -66.21,-9 -64,-9 C-64,-9 64,-9 64,-9 C66.21,-9 68,-7.21 68,-5c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_3_G_L_0_G_L_11_G"
-                                android:scaleY="0"
-                                android:translateX="198.5"
-                                android:translateY="433">
-                                <path
-                                    android:name="_R_G_L_3_G_L_0_G_L_11_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#bdc1c6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M96.5 -4 C96.5,-4 96.5,4 96.5,4 C96.5,6.21 94.71,8 92.5,8 C92.5,8 -92.5,8 -92.5,8 C-94.71,8 -96.5,6.21 -96.5,4 C-96.5,4 -96.5,-4 -96.5,-4 C-96.5,-6.21 -94.71,-8 -92.5,-8 C-92.5,-8 92.5,-8 92.5,-8 C94.71,-8 96.5,-6.21 96.5,-4c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_3_G_L_0_G_L_10_G"
-                                android:scaleY="0"
-                                android:translateX="54"
-                                android:translateY="509">
-                                <path
-                                    android:name="_R_G_L_3_G_L_0_G_L_10_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#9aa0a6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_3_G_L_0_G_L_9_G"
-                                android:scaleY="0"
-                                android:translateX="135"
-                                android:translateY="500">
-                                <path
-                                    android:name="_R_G_L_3_G_L_0_G_L_9_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#bdc1c6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M33 -5 C33,-5 33,5 33,5 C33,7.21 31.21,9 29,9 C29,9 -29,9 -29,9 C-31.21,9 -33,7.21 -33,5 C-33,5 -33,-5 -33,-5 C-33,-7.21 -31.21,-9 -29,-9 C-29,-9 29,-9 29,-9 C31.21,-9 33,-7.21 33,-5c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_3_G_L_0_G_L_8_G"
-                                android:scaleY="0"
-                                android:translateX="185.5"
-                                android:translateY="521">
-                                <path
-                                    android:name="_R_G_L_3_G_L_0_G_L_8_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#bdc1c6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M83.5 -4 C83.5,-4 83.5,4 83.5,4 C83.5,6.21 81.71,8 79.5,8 C79.5,8 -79.5,8 -79.5,8 C-81.71,8 -83.5,6.21 -83.5,4 C-83.5,4 -83.5,-4 -83.5,-4 C-83.5,-6.21 -81.71,-8 -79.5,-8 C-79.5,-8 79.5,-8 79.5,-8 C81.71,-8 83.5,-6.21 83.5,-4c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_3_G_L_0_G_L_7_G"
-                                android:scaleY="0"
-                                android:translateX="54"
-                                android:translateY="597">
-                                <path
-                                    android:name="_R_G_L_3_G_L_0_G_L_7_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#9aa0a6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_3_G_L_0_G_L_6_G"
-                                android:scaleY="0"
-                                android:translateX="168.5"
-                                android:translateY="588">
-                                <path
-                                    android:name="_R_G_L_3_G_L_0_G_L_6_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#bdc1c6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M66.5 -5 C66.5,-5 66.5,5 66.5,5 C66.5,7.21 64.71,9 62.5,9 C62.5,9 -62.5,9 -62.5,9 C-64.71,9 -66.5,7.21 -66.5,5 C-66.5,5 -66.5,-5 -66.5,-5 C-66.5,-7.21 -64.71,-9 -62.5,-9 C-62.5,-9 62.5,-9 62.5,-9 C64.71,-9 66.5,-7.21 66.5,-5c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_3_G_L_0_G_L_5_G"
-                                android:scaleY="0"
-                                android:translateX="198.5"
-                                android:translateY="609">
-                                <path
-                                    android:name="_R_G_L_3_G_L_0_G_L_5_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#bdc1c6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M96.5 -4 C96.5,-4 96.5,4 96.5,4 C96.5,6.21 94.71,8 92.5,8 C92.5,8 -92.5,8 -92.5,8 C-94.71,8 -96.5,6.21 -96.5,4 C-96.5,4 -96.5,-4 -96.5,-4 C-96.5,-6.21 -94.71,-8 -92.5,-8 C-92.5,-8 92.5,-8 92.5,-8 C94.71,-8 96.5,-6.21 96.5,-4c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_3_G_L_0_G_L_4_G"
-                                android:scaleY="0"
-                                android:translateX="54"
-                                android:translateY="685">
-                                <path
-                                    android:name="_R_G_L_3_G_L_0_G_L_4_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#9aa0a6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_3_G_L_0_G_L_3_G"
-                                android:scaleY="0"
-                                android:translateX="162.5"
-                                android:translateY="676">
-                                <path
-                                    android:name="_R_G_L_3_G_L_0_G_L_3_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#bdc1c6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M60.5 -5 C60.5,-5 60.5,5 60.5,5 C60.5,7.21 58.71,9 56.5,9 C56.5,9 -56.5,9 -56.5,9 C-58.71,9 -60.5,7.21 -60.5,5 C-60.5,5 -60.5,-5 -60.5,-5 C-60.5,-7.21 -58.71,-9 -56.5,-9 C-56.5,-9 56.5,-9 56.5,-9 C58.71,-9 60.5,-7.21 60.5,-5c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_3_G_L_0_G_L_2_G"
-                                android:scaleY="0"
-                                android:translateX="174"
-                                android:translateY="697">
-                                <path
-                                    android:name="_R_G_L_3_G_L_0_G_L_2_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#bdc1c6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M72 -4 C72,-4 72,4 72,4 C72,6.21 70.21,8 68,8 C68,8 -68,8 -68,8 C-70.21,8 -72,6.21 -72,4 C-72,4 -72,-4 -72,-4 C-72,-6.21 -70.21,-8 -68,-8 C-68,-8 68,-8 68,-8 C70.21,-8 72,-6.21 72,-4c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_3_G_L_0_G_L_1_G"
-                                android:scaleY="0"
-                                android:translateX="313.5"
-                                android:translateY="798">
-                                <path
-                                    android:name="_R_G_L_3_G_L_0_G_L_1_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#bdc1c6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M74.5 0 C74.5,0 74.5,0 74.5,0 C74.5,15.45 61.95,28 46.5,28 C46.5,28 -46.5,28 -46.5,28 C-61.95,28 -74.5,15.45 -74.5,0 C-74.5,0 -74.5,0 -74.5,0 C-74.5,-15.45 -61.95,-28 -46.5,-28 C-46.5,-28 46.5,-28 46.5,-28 C61.95,-28 74.5,-15.45 74.5,0c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_3_G_L_0_G_L_0_G"
-                                android:scaleY="0"
-                                android:translateX="205.5"
-                                android:translateY="61">
-                                <path
-                                    android:name="_R_G_L_3_G_L_0_G_L_0_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#f8f9fa"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M171.5 -14 C171.5,-14 171.5,14 171.5,14 C171.5,16.21 169.71,18 167.5,18 C167.5,18 -167.5,18 -167.5,18 C-169.71,18 -171.5,16.21 -171.5,14 C-171.5,14 -171.5,-14 -171.5,-14 C-171.5,-16.21 -169.71,-18 -167.5,-18 C-167.5,-18 167.5,-18 167.5,-18 C169.71,-18 171.5,-16.21 171.5,-14c " />
-                            </group>
-                        </group>
-                    </group>
-                </group>
-                <group
-                    android:name="_R_G_L_2_G_N_2_T_0"
-                    android:scaleX="0.6"
-                    android:scaleY="0"
-                    android:translateX="206"
-                    android:translateY="395">
-                    <group
-                        android:name="_R_G_L_2_G"
-                        android:scaleX="1.3767699999999998"
-                        android:scaleY="1.3767699999999998"
-                        android:translateY="-508.163">
-                        <group
-                            android:name="_R_G_L_2_G_D_0_P_0_G_0_T_0"
-                            android:scaleX="0"
-                            android:scaleY="0">
-                            <path
-                                android:name="_R_G_L_2_G_D_0_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#9aa0a6"
-                                android:fillType="nonZero"
-                                android:pathData=" M0 25 C13.81,25 25,13.81 25,0 C25,-13.81 13.81,-25 0,-25 C-13.81,-25 -25,-13.81 -25,0 C-25,13.81 -13.81,25 0,25c " />
-                        </group>
-                    </group>
-                </group>
-                <group
-                    android:name="_R_G_L_1_G_N_2_T_0"
-                    android:scaleX="0.6"
-                    android:scaleY="0"
-                    android:translateX="206"
-                    android:translateY="395">
-                    <group
-                        android:name="_R_G_L_1_G"
-                        android:scaleX="1.39"
-                        android:scaleY="1.39"
-                        android:translateX="-556.176"
-                        android:translateY="-7.307">
-                        <path
-                            android:name="_R_G_L_1_G_D_0_P_0"
-                            android:fillAlpha="1"
-                            android:fillColor="@color/gesture_tutorial_fake_previous_task_view_color"
-                            android:fillType="nonZero"
-                            android:pathData=" M135 -301 C135,-301 135,311 135,311 C135,319.28 128.28,326 120,326 C120,326 -120,326 -120,326 C-128.28,326 -135,319.28 -135,311 C-135,311 -135,-301 -135,-301 C-135,-309.28 -128.28,-316 -120,-316 C-120,-316 120,-316 120,-316 C128.28,-316 135,-309.28 135,-301c " />
-                    </group>
-                </group>
-                <group
-                    android:name="_R_G_L_0_G"
-                    android:translateX="206"
-                    android:translateY="446">
-                    <path
-                        android:name="_R_G_L_0_G_D_0_P_0"
-                        android:fillAlpha="0"
-                        android:fillColor="@color/gesture_tutorial_primary_color"
-                        android:fillType="nonZero"
-                        android:pathData=" M0 406 C21.54,406 39,423.46 39,445 C39,466.54 21.54,484 0,484 C-21.54,484 -39,466.54 -39,445 C-39,423.46 -21.54,406 0,406c " />
-                </group>
-            </group>
-            <group android:name="time_group" />
-        </vector>
-    </aapt:attr>
-</animated-vector>
\ No newline at end of file
diff --git a/res/drawable/gesture_tutorial_ripple.xml b/quickstep/res/drawable/gesture_tutorial_ripple.xml
similarity index 100%
rename from res/drawable/gesture_tutorial_ripple.xml
rename to quickstep/res/drawable/gesture_tutorial_ripple.xml
diff --git a/quickstep/res/drawable/mock_conversation.xml b/quickstep/res/drawable/mock_conversation.xml
deleted file mode 100644
index 272d9ed..0000000
--- a/quickstep/res/drawable/mock_conversation.xml
+++ /dev/null
@@ -1,212 +0,0 @@
-<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:aapt="http://schemas.android.com/aapt">
-    <target android:name="time_group">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="83"
-                    android:propertyName="translateX"
-                    android:startOffset="0"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <aapt:attr name="android:drawable">
-        <vector
-            android:width="412dp"
-            android:height="892dp"
-            android:viewportHeight="892"
-            android:viewportWidth="412">
-            <group android:name="_R_G">
-                <group
-                    android:name="_R_G_L_1_G"
-                    android:translateX="206"
-                    android:translateY="446">
-                    <path
-                        android:name="_R_G_L_1_G_D_0_P_0"
-                        android:fillAlpha="1"
-                        android:fillColor="#dadce0"
-                        android:fillType="nonZero"
-                        android:pathData=" M206 -446 C206,-446 206,446 206,446 C206,446 -206,446 -206,446 C-206,446 -206,-446 -206,-446 C-206,-446 206,-446 206,-446c " />
-                </group>
-                <group
-                    android:name="_R_G_L_0_G"
-                    android:pivotX="206"
-                    android:pivotY="446"
-                    android:scaleX="1"
-                    android:scaleY="1">
-                    <group android:name="_R_G_L_0_G_L_0_G">
-                        <group
-                            android:name="_R_G_L_0_G_L_0_G_L_14_G"
-                            android:translateX="206"
-                            android:translateY="446">
-                            <path
-                                android:name="_R_G_L_0_G_L_0_G_L_14_G_D_0_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#000000"
-                                android:fillType="nonZero"
-                                android:pathData=" M206 -422 C206,-422 206,422 206,422 C206,435.25 195.25,446 182,446 C182,446 -182,446 -182,446 C-195.25,446 -206,435.25 -206,422 C-206,422 -206,-422 -206,-422 C-206,-435.25 -195.25,-446 -182,-446 C-182,-446 182,-446 182,-446 C195.25,-446 206,-435.25 206,-422c " />
-                        </group>
-                        <group
-                            android:name="_R_G_L_0_G_L_0_G_L_13_G"
-                            android:translateX="206"
-                            android:translateY="496.5">
-                            <path
-                                android:name="_R_G_L_0_G_L_0_G_L_13_G_D_0_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#f1f3f4"
-                                android:fillType="nonZero"
-                                android:pathData=" M206 -395.5 C206,-395.5 206,395.5 206,395.5 C206,395.5 -206,395.5 -206,395.5 C-206,395.5 -206,-395.5 -206,-395.5 C-206,-395.5 206,-395.5 206,-395.5c " />
-                        </group>
-                        <group
-                            android:name="_R_G_L_0_G_L_0_G_L_12_G"
-                            android:translateX="206"
-                            android:translateY="50.5">
-                            <path
-                                android:name="_R_G_L_0_G_L_0_G_L_12_G_D_0_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#e8eaed"
-                                android:fillType="nonZero"
-                                android:pathData=" M206 -50.5 C206,-50.5 206,50.5 206,50.5 C206,50.5 -206,50.5 -206,50.5 C-206,50.5 -206,-50.5 -206,-50.5 C-206,-50.5 206,-50.5 206,-50.5c " />
-                        </group>
-                        <group
-                            android:name="_R_G_L_0_G_L_0_G_L_11_G"
-                            android:translateX="206"
-                            android:translateY="804">
-                            <path
-                                android:name="_R_G_L_0_G_L_0_G_L_11_G_D_0_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#dadce0"
-                                android:fillType="nonZero"
-                                android:pathData=" M177 0 C177,12.15 167.15,22 155,22 C155,22 -155,22 -155,22 C-167.15,22 -177,12.15 -177,0 C-177,-12.15 -167.15,-22 -155,-22 C-155,-22 155,-22 155,-22 C167.15,-22 177,-12.15 177,0c " />
-                        </group>
-                        <group
-                            android:name="_R_G_L_0_G_L_0_G_L_10_G"
-                            android:translateX="117.5"
-                            android:translateY="61">
-                            <path
-                                android:name="_R_G_L_0_G_L_0_G_L_10_G_D_0_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#dadce0"
-                                android:fillType="nonZero"
-                                android:pathData=" M83.5 -14 C83.5,-14 83.5,14 83.5,14 C83.5,16.21 81.71,18 79.5,18 C79.5,18 -79.5,18 -79.5,18 C-81.71,18 -83.5,16.21 -83.5,14 C-83.5,14 -83.5,-14 -83.5,-14 C-83.5,-16.21 -81.71,-18 -79.5,-18 C-79.5,-18 79.5,-18 79.5,-18 C81.71,-18 83.5,-16.21 83.5,-14c " />
-                        </group>
-                        <group
-                            android:name="_R_G_L_0_G_L_0_G_L_9_G"
-                            android:translateX="370"
-                            android:translateY="61">
-                            <path
-                                android:name="_R_G_L_0_G_L_0_G_L_9_G_D_0_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#dadce0"
-                                android:fillType="nonZero"
-                                android:pathData=" M18 -14 C18,-14 18,14 18,14 C18,16.21 16.21,18 14,18 C14,18 -14,18 -14,18 C-16.21,18 -18,16.21 -18,14 C-18,14 -18,-14 -18,-14 C-18,-16.21 -16.21,-18 -14,-18 C-14,-18 14,-18 14,-18 C16.21,-18 18,-16.21 18,-14c " />
-                        </group>
-                        <group
-                            android:name="_R_G_L_0_G_L_0_G_L_8_G"
-                            android:translateX="318"
-                            android:translateY="61">
-                            <path
-                                android:name="_R_G_L_0_G_L_0_G_L_8_G_D_0_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#dadce0"
-                                android:fillType="nonZero"
-                                android:pathData=" M18 -14 C18,-14 18,14 18,14 C18,16.21 16.21,18 14,18 C14,18 -14,18 -14,18 C-16.21,18 -18,16.21 -18,14 C-18,14 -18,-14 -18,-14 C-18,-16.21 -16.21,-18 -14,-18 C-14,-18 14,-18 14,-18 C16.21,-18 18,-16.21 18,-14c " />
-                        </group>
-                        <group
-                            android:name="_R_G_L_0_G_L_0_G_L_7_G"
-                            android:translateX="48"
-                            android:translateY="618">
-                            <path
-                                android:name="_R_G_L_0_G_L_0_G_L_7_G_D_0_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#dadce0"
-                                android:fillType="nonZero"
-                                android:pathData=" M22 0 C22,12.15 12.15,22 0,22 C-12.15,22 -22,12.15 -22,0 C-22,-12.15 -12.15,-22 0,-22 C12.15,-22 22,-12.15 22,0c " />
-                        </group>
-                        <group
-                            android:name="_R_G_L_0_G_L_0_G_L_6_G"
-                            android:translateX="48"
-                            android:translateY="396">
-                            <path
-                                android:name="_R_G_L_0_G_L_0_G_L_6_G_D_0_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#dadce0"
-                                android:fillType="nonZero"
-                                android:pathData=" M22 0 C22,12.15 12.15,22 0,22 C-12.15,22 -22,12.15 -22,0 C-22,-12.15 -12.15,-22 0,-22 C12.15,-22 22,-12.15 22,0c " />
-                        </group>
-                        <group
-                            android:name="_R_G_L_0_G_L_0_G_L_5_G"
-                            android:translateX="259"
-                            android:translateY="286">
-                            <path
-                                android:name="_R_G_L_0_G_L_0_G_L_5_G_D_0_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#bdc1c6"
-                                android:fillType="nonZero"
-                                android:pathData=" M135 -38 C135,-38 135,38 135,38 C135,47.94 126.94,56 117,56 C117,56 -117,56 -117,56 C-126.94,56 -135,47.94 -135,38 C-135,38 -135,-38 -135,-38 C-135,-47.94 -126.94,-56 -117,-56 C-117,-56 117,-56 117,-56 C126.94,-56 135,-47.94 135,-38c " />
-                        </group>
-                        <group
-                            android:name="_R_G_L_0_G_L_0_G_L_4_G"
-                            android:translateX="259"
-                            android:translateY="468">
-                            <path
-                                android:name="_R_G_L_0_G_L_0_G_L_4_G_D_0_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#bdc1c6"
-                                android:fillType="nonZero"
-                                android:pathData=" M134.5 4 C134.5,4 134.5,14 134.5,14 C134.5,16.21 132.71,18 130.5,18 C130.5,18 44.5,18 44.5,18 C42.29,18 40.5,16.21 40.5,14 C40.5,14 40.5,4 40.5,4 C40.5,1.79 42.29,0 44.5,0 C44.5,0 130.5,0 130.5,0 C132.71,0 134.5,1.79 134.5,4c  M135 0 C135,9.66 127.17,17.5 117.5,17.5 C117.5,17.5 31,17.5 31,17.5 C21.34,17.5 13.5,9.66 13.5,0 C13.5,-9.66 21.34,-17.5 31,-17.5 C31,-17.5 117.5,-17.5 117.5,-17.5 C127.17,-17.5 135,-9.66 135,0c " />
-                        </group>
-                        <group
-                            android:name="_R_G_L_0_G_L_0_G_L_3_G"
-                            android:translateX="259"
-                            android:translateY="526.5">
-                            <path
-                                android:name="_R_G_L_0_G_L_0_G_L_3_G_D_0_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#bdc1c6"
-                                android:fillType="nonZero"
-                                android:pathData=" M135 -32.5 C135,-32.5 135,20.5 135,20.5 C135,22.71 133.21,24.5 131,24.5 C131,24.5 -95,24.5 -95,24.5 C-97.21,24.5 -99,22.71 -99,20.5 C-99,20.5 -99,-32.5 -99,-32.5 C-99,-34.71 -97.21,-36.5 -95,-36.5 C-95,-36.5 131,-36.5 131,-36.5 C133.21,-36.5 135,-34.71 135,-32.5c  M135 -18.5 C135,-18.5 135,18.5 135,18.5 C135,28.44 126.94,36.5 117,36.5 C117,36.5 -117,36.5 -117,36.5 C-126.94,36.5 -135,28.44 -135,18.5 C-135,18.5 -135,-18.5 -135,-18.5 C-135,-28.44 -126.94,-36.5 -117,-36.5 C-117,-36.5 117,-36.5 117,-36.5 C126.94,-36.5 135,-28.44 135,-18.5c " />
-                        </group>
-                        <group
-                            android:name="_R_G_L_0_G_L_0_G_L_2_G"
-                            android:translateX="259"
-                            android:translateY="708.5">
-                            <path
-                                android:name="_R_G_L_0_G_L_0_G_L_2_G_D_0_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#bdc1c6"
-                                android:fillType="nonZero"
-                                android:pathData=" M135 -18.5 C135,-18.5 135,18.5 135,18.5 C135,28.44 126.94,36.5 117,36.5 C117,36.5 -117,36.5 -117,36.5 C-126.94,36.5 -135,28.44 -135,18.5 C-135,18.5 -135,-18.5 -135,-18.5 C-135,-28.44 -126.94,-36.5 -117,-36.5 C-117,-36.5 117,-36.5 117,-36.5 C126.94,-36.5 135,-28.44 135,-18.5c " />
-                        </group>
-                        <group
-                            android:name="_R_G_L_0_G_L_0_G_L_1_G"
-                            android:translateX="222"
-                            android:translateY="617">
-                            <path
-                                android:name="_R_G_L_0_G_L_0_G_L_1_G_D_0_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#e8eaed"
-                                android:fillType="nonZero"
-                                android:pathData=" M45.5 0 C45.5,9.66 37.67,17.5 28,17.5 C28,17.5 -117.5,17.5 -117.5,17.5 C-127.16,17.5 -135,9.66 -135,0 C-135,-9.66 -127.16,-17.5 -117.5,-17.5 C-117.5,-17.5 28,-17.5 28,-17.5 C37.67,-17.5 45.5,-9.66 45.5,0c " />
-                        </group>
-                        <group
-                            android:name="_R_G_L_0_G_L_0_G_L_0_G"
-                            android:translateX="222"
-                            android:translateY="395.5">
-                            <path
-                                android:name="_R_G_L_0_G_L_0_G_L_0_G_D_0_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#e8eaed"
-                                android:fillType="nonZero"
-                                android:pathData=" M77 0 C77,9.66 69.16,17.5 59.5,17.5 C59.5,17.5 -117.5,17.5 -117.5,17.5 C-127.16,17.5 -135,9.66 -135,0 C-135,-9.66 -127.16,-17.5 -117.5,-17.5 C-117.5,-17.5 59.5,-17.5 59.5,-17.5 C69.16,-17.5 77,-9.66 77,0c " />
-                        </group>
-                    </group>
-                </group>
-            </group>
-            <group android:name="time_group" />
-        </vector>
-    </aapt:attr>
-</animated-vector>
\ No newline at end of file
diff --git a/quickstep/res/drawable/mock_conversations_list.xml b/quickstep/res/drawable/mock_conversations_list.xml
deleted file mode 100644
index 2dbc88f..0000000
--- a/quickstep/res/drawable/mock_conversations_list.xml
+++ /dev/null
@@ -1,361 +0,0 @@
-<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:aapt="http://schemas.android.com/aapt">
-    <target android:name="time_group">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="83"
-                    android:propertyName="translateX"
-                    android:startOffset="0"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <aapt:attr name="android:drawable">
-        <vector
-            android:width="412dp"
-            android:height="892dp"
-            android:viewportHeight="892"
-            android:viewportWidth="412">
-            <group android:name="_R_G">
-                <group
-                    android:name="_R_G_L_1_G"
-                    android:translateX="206"
-                    android:translateY="446">
-                    <path
-                        android:name="_R_G_L_1_G_D_0_P_0"
-                        android:fillAlpha="1"
-                        android:fillColor="#dadce0"
-                        android:fillType="nonZero"
-                        android:pathData=" M206 -446 C206,-446 206,446 206,446 C206,446 -206,446 -206,446 C-206,446 -206,-446 -206,-446 C-206,-446 206,-446 206,-446c " />
-                </group>
-                <group android:name="_R_G_L_0_G">
-                    <group android:name="_R_G_L_0_G_L_0_G">
-                        <group
-                            android:name="_R_G_L_0_G_L_0_G_L_28_G"
-                            android:translateX="206"
-                            android:translateY="446">
-                            <path
-                                android:name="_R_G_L_0_G_L_0_G_L_28_G_D_0_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#000000"
-                                android:fillType="nonZero"
-                                android:pathData=" M206 -422 C206,-422 206,422 206,422 C206,435.25 195.25,446 182,446 C182,446 -182,446 -182,446 C-195.25,446 -206,435.25 -206,422 C-206,422 -206,-422 -206,-422 C-206,-435.25 -195.25,-446 -182,-446 C-182,-446 182,-446 182,-446 C195.25,-446 206,-435.25 206,-422c " />
-                        </group>
-                        <group
-                            android:name="_R_G_L_0_G_L_0_G_L_27_G"
-                            android:translateX="206"
-                            android:translateY="422.5">
-                            <path
-                                android:name="_R_G_L_0_G_L_0_G_L_27_G_D_0_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#dadce0"
-                                android:fillType="nonZero"
-                                android:pathData=" M206 -395.5 C206,-395.5 206,395.5 206,395.5 C206,395.5 -206,395.5 -206,395.5 C-206,395.5 -206,-395.5 -206,-395.5 C-206,-395.5 206,-395.5 206,-395.5c " />
-                        </group>
-                        <group
-                            android:name="_R_G_L_0_G_L_0_G_L_26_G"
-                            android:translateX="206"
-                            android:translateY="496.5">
-                            <path
-                                android:name="_R_G_L_0_G_L_0_G_L_26_G_D_0_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#dadce0"
-                                android:fillType="nonZero"
-                                android:pathData=" M206 -377.5 C206,-377.5 206,377.5 206,377.5 C206,387.43 197.93,395.5 188,395.5 C188,395.5 -188,395.5 -188,395.5 C-197.93,395.5 -206,387.43 -206,377.5 C-206,377.5 -206,-377.5 -206,-377.5 C-206,-387.43 -197.93,-395.5 -188,-395.5 C-188,-395.5 188,-395.5 188,-395.5 C197.93,-395.5 206,-387.43 206,-377.5c " />
-                        </group>
-                        <group
-                            android:name="_R_G_L_0_G_L_0_G_L_25_G"
-                            android:translateX="206"
-                            android:translateY="50.5">
-                            <path
-                                android:name="_R_G_L_0_G_L_0_G_L_25_G_D_0_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#e8eaed"
-                                android:fillType="nonZero"
-                                android:pathData=" M206 -23.5 C206,-23.5 206,50.5 206,50.5 C206,50.5 -206,50.5 -206,50.5 C-206,50.5 -206,-23.5 -206,-23.5 C-206,-23.5 206,-23.5 206,-23.5c " />
-                        </group>
-                        <group
-                            android:name="_R_G_L_0_G_L_0_G_L_24_G"
-                            android:translateX="206"
-                            android:translateY="50.5">
-                            <path
-                                android:name="_R_G_L_0_G_L_0_G_L_24_G_D_0_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#e8eaed"
-                                android:fillType="nonZero"
-                                android:pathData=" M206 -32.5 C206,-32.5 206,32.5 206,32.5 C206,42.43 197.93,50.5 188,50.5 C188,50.5 -188,50.5 -188,50.5 C-197.93,50.5 -206,42.43 -206,32.5 C-206,32.5 -206,-32.5 -206,-32.5 C-206,-42.43 -197.93,-50.5 -188,-50.5 C-188,-50.5 188,-50.5 188,-50.5 C197.93,-50.5 206,-42.43 206,-32.5c " />
-                        </group>
-                        <group
-                            android:name="_R_G_L_0_G_L_0_G_L_23_G"
-                            android:translateX="54"
-                            android:translateY="157">
-                            <path
-                                android:name="_R_G_L_0_G_L_0_G_L_23_G_D_0_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#9aa0a6"
-                                android:fillType="nonZero"
-                                android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
-                        </group>
-                        <group
-                            android:name="_R_G_L_0_G_L_0_G_L_22_G"
-                            android:translateX="54"
-                            android:translateY="157">
-                            <path
-                                android:name="_R_G_L_0_G_L_0_G_L_22_G_D_0_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#9aa0a6"
-                                android:fillType="nonZero"
-                                android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
-                        </group>
-                        <group
-                            android:name="_R_G_L_0_G_L_0_G_L_21_G"
-                            android:translateX="148.5"
-                            android:translateY="148">
-                            <path
-                                android:name="_R_G_L_0_G_L_0_G_L_21_G_D_0_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#bdc1c6"
-                                android:fillType="nonZero"
-                                android:pathData=" M46.5 -5 C46.5,-5 46.5,5 46.5,5 C46.5,7.21 44.71,9 42.5,9 C42.5,9 -42.5,9 -42.5,9 C-44.71,9 -46.5,7.21 -46.5,5 C-46.5,5 -46.5,-5 -46.5,-5 C-46.5,-7.21 -44.71,-9 -42.5,-9 C-42.5,-9 42.5,-9 42.5,-9 C44.71,-9 46.5,-7.21 46.5,-5c " />
-                        </group>
-                        <group
-                            android:name="_R_G_L_0_G_L_0_G_L_20_G"
-                            android:translateX="186"
-                            android:translateY="169">
-                            <path
-                                android:name="_R_G_L_0_G_L_0_G_L_20_G_D_0_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#bdc1c6"
-                                android:fillType="nonZero"
-                                android:pathData=" M84 -4 C84,-4 84,4 84,4 C84,6.21 82.21,8 80,8 C80,8 -80,8 -80,8 C-82.21,8 -84,6.21 -84,4 C-84,4 -84,-4 -84,-4 C-84,-6.21 -82.21,-8 -80,-8 C-80,-8 80,-8 80,-8 C82.21,-8 84,-6.21 84,-4c " />
-                        </group>
-                        <group
-                            android:name="_R_G_L_0_G_L_0_G_L_19_G"
-                            android:translateX="54"
-                            android:translateY="245">
-                            <path
-                                android:name="_R_G_L_0_G_L_0_G_L_19_G_D_0_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#9aa0a6"
-                                android:fillType="nonZero"
-                                android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
-                        </group>
-                        <group
-                            android:name="_R_G_L_0_G_L_0_G_L_18_G"
-                            android:translateX="162"
-                            android:translateY="236">
-                            <path
-                                android:name="_R_G_L_0_G_L_0_G_L_18_G_D_0_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#bdc1c6"
-                                android:fillType="nonZero"
-                                android:pathData=" M60 -5 C60,-5 60,5 60,5 C60,7.21 58.21,9 56,9 C56,9 -56,9 -56,9 C-58.21,9 -60,7.21 -60,5 C-60,5 -60,-5 -60,-5 C-60,-7.21 -58.21,-9 -56,-9 C-56,-9 56,-9 56,-9 C58.21,-9 60,-7.21 60,-5c " />
-                        </group>
-                        <group
-                            android:name="_R_G_L_0_G_L_0_G_L_17_G"
-                            android:translateX="171.5"
-                            android:translateY="257">
-                            <path
-                                android:name="_R_G_L_0_G_L_0_G_L_17_G_D_0_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#bdc1c6"
-                                android:fillType="nonZero"
-                                android:pathData=" M69.5 -4 C69.5,-4 69.5,4 69.5,4 C69.5,6.21 67.71,8 65.5,8 C65.5,8 -65.5,8 -65.5,8 C-67.71,8 -69.5,6.21 -69.5,4 C-69.5,4 -69.5,-4 -69.5,-4 C-69.5,-6.21 -67.71,-8 -65.5,-8 C-65.5,-8 65.5,-8 65.5,-8 C67.71,-8 69.5,-6.21 69.5,-4c " />
-                        </group>
-                        <group
-                            android:name="_R_G_L_0_G_L_0_G_L_16_G"
-                            android:translateX="54"
-                            android:translateY="333">
-                            <path
-                                android:name="_R_G_L_0_G_L_0_G_L_16_G_D_0_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#9aa0a6"
-                                android:fillType="nonZero"
-                                android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
-                        </group>
-                        <group
-                            android:name="_R_G_L_0_G_L_0_G_L_15_G"
-                            android:translateX="158"
-                            android:translateY="324">
-                            <path
-                                android:name="_R_G_L_0_G_L_0_G_L_15_G_D_0_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#bdc1c6"
-                                android:fillType="nonZero"
-                                android:pathData=" M56 -5 C56,-5 56,5 56,5 C56,7.21 54.21,9 52,9 C52,9 -52,9 -52,9 C-54.21,9 -56,7.21 -56,5 C-56,5 -56,-5 -56,-5 C-56,-7.21 -54.21,-9 -52,-9 C-52,-9 52,-9 52,-9 C54.21,-9 56,-7.21 56,-5c " />
-                        </group>
-                        <group
-                            android:name="_R_G_L_0_G_L_0_G_L_14_G"
-                            android:translateX="217.5"
-                            android:translateY="345">
-                            <path
-                                android:name="_R_G_L_0_G_L_0_G_L_14_G_D_0_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#bdc1c6"
-                                android:fillType="nonZero"
-                                android:pathData=" M115.5 -4 C115.5,-4 115.5,4 115.5,4 C115.5,6.21 113.71,8 111.5,8 C111.5,8 -111.5,8 -111.5,8 C-113.71,8 -115.5,6.21 -115.5,4 C-115.5,4 -115.5,-4 -115.5,-4 C-115.5,-6.21 -113.71,-8 -111.5,-8 C-111.5,-8 111.5,-8 111.5,-8 C113.71,-8 115.5,-6.21 115.5,-4c " />
-                        </group>
-                        <group
-                            android:name="_R_G_L_0_G_L_0_G_L_13_G"
-                            android:translateX="54"
-                            android:translateY="421">
-                            <path
-                                android:name="_R_G_L_0_G_L_0_G_L_13_G_D_0_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#9aa0a6"
-                                android:fillType="nonZero"
-                                android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
-                        </group>
-                        <group
-                            android:name="_R_G_L_0_G_L_0_G_L_12_G"
-                            android:translateX="170"
-                            android:translateY="412">
-                            <path
-                                android:name="_R_G_L_0_G_L_0_G_L_12_G_D_0_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#bdc1c6"
-                                android:fillType="nonZero"
-                                android:pathData=" M68 -5 C68,-5 68,5 68,5 C68,7.21 66.21,9 64,9 C64,9 -64,9 -64,9 C-66.21,9 -68,7.21 -68,5 C-68,5 -68,-5 -68,-5 C-68,-7.21 -66.21,-9 -64,-9 C-64,-9 64,-9 64,-9 C66.21,-9 68,-7.21 68,-5c " />
-                        </group>
-                        <group
-                            android:name="_R_G_L_0_G_L_0_G_L_11_G"
-                            android:translateX="198.5"
-                            android:translateY="433">
-                            <path
-                                android:name="_R_G_L_0_G_L_0_G_L_11_G_D_0_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#bdc1c6"
-                                android:fillType="nonZero"
-                                android:pathData=" M96.5 -4 C96.5,-4 96.5,4 96.5,4 C96.5,6.21 94.71,8 92.5,8 C92.5,8 -92.5,8 -92.5,8 C-94.71,8 -96.5,6.21 -96.5,4 C-96.5,4 -96.5,-4 -96.5,-4 C-96.5,-6.21 -94.71,-8 -92.5,-8 C-92.5,-8 92.5,-8 92.5,-8 C94.71,-8 96.5,-6.21 96.5,-4c " />
-                        </group>
-                        <group
-                            android:name="_R_G_L_0_G_L_0_G_L_10_G"
-                            android:translateX="54"
-                            android:translateY="509">
-                            <path
-                                android:name="_R_G_L_0_G_L_0_G_L_10_G_D_0_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#9aa0a6"
-                                android:fillType="nonZero"
-                                android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
-                        </group>
-                        <group
-                            android:name="_R_G_L_0_G_L_0_G_L_9_G"
-                            android:translateX="135"
-                            android:translateY="500">
-                            <path
-                                android:name="_R_G_L_0_G_L_0_G_L_9_G_D_0_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#bdc1c6"
-                                android:fillType="nonZero"
-                                android:pathData=" M33 -5 C33,-5 33,5 33,5 C33,7.21 31.21,9 29,9 C29,9 -29,9 -29,9 C-31.21,9 -33,7.21 -33,5 C-33,5 -33,-5 -33,-5 C-33,-7.21 -31.21,-9 -29,-9 C-29,-9 29,-9 29,-9 C31.21,-9 33,-7.21 33,-5c " />
-                        </group>
-                        <group
-                            android:name="_R_G_L_0_G_L_0_G_L_8_G"
-                            android:translateX="185.5"
-                            android:translateY="521">
-                            <path
-                                android:name="_R_G_L_0_G_L_0_G_L_8_G_D_0_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#bdc1c6"
-                                android:fillType="nonZero"
-                                android:pathData=" M83.5 -4 C83.5,-4 83.5,4 83.5,4 C83.5,6.21 81.71,8 79.5,8 C79.5,8 -79.5,8 -79.5,8 C-81.71,8 -83.5,6.21 -83.5,4 C-83.5,4 -83.5,-4 -83.5,-4 C-83.5,-6.21 -81.71,-8 -79.5,-8 C-79.5,-8 79.5,-8 79.5,-8 C81.71,-8 83.5,-6.21 83.5,-4c " />
-                        </group>
-                        <group
-                            android:name="_R_G_L_0_G_L_0_G_L_7_G"
-                            android:translateX="54"
-                            android:translateY="597">
-                            <path
-                                android:name="_R_G_L_0_G_L_0_G_L_7_G_D_0_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#9aa0a6"
-                                android:fillType="nonZero"
-                                android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
-                        </group>
-                        <group
-                            android:name="_R_G_L_0_G_L_0_G_L_6_G"
-                            android:translateX="168.5"
-                            android:translateY="588">
-                            <path
-                                android:name="_R_G_L_0_G_L_0_G_L_6_G_D_0_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#bdc1c6"
-                                android:fillType="nonZero"
-                                android:pathData=" M66.5 -5 C66.5,-5 66.5,5 66.5,5 C66.5,7.21 64.71,9 62.5,9 C62.5,9 -62.5,9 -62.5,9 C-64.71,9 -66.5,7.21 -66.5,5 C-66.5,5 -66.5,-5 -66.5,-5 C-66.5,-7.21 -64.71,-9 -62.5,-9 C-62.5,-9 62.5,-9 62.5,-9 C64.71,-9 66.5,-7.21 66.5,-5c " />
-                        </group>
-                        <group
-                            android:name="_R_G_L_0_G_L_0_G_L_5_G"
-                            android:translateX="198.5"
-                            android:translateY="609">
-                            <path
-                                android:name="_R_G_L_0_G_L_0_G_L_5_G_D_0_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#bdc1c6"
-                                android:fillType="nonZero"
-                                android:pathData=" M96.5 -4 C96.5,-4 96.5,4 96.5,4 C96.5,6.21 94.71,8 92.5,8 C92.5,8 -92.5,8 -92.5,8 C-94.71,8 -96.5,6.21 -96.5,4 C-96.5,4 -96.5,-4 -96.5,-4 C-96.5,-6.21 -94.71,-8 -92.5,-8 C-92.5,-8 92.5,-8 92.5,-8 C94.71,-8 96.5,-6.21 96.5,-4c " />
-                        </group>
-                        <group
-                            android:name="_R_G_L_0_G_L_0_G_L_4_G"
-                            android:translateX="54"
-                            android:translateY="685">
-                            <path
-                                android:name="_R_G_L_0_G_L_0_G_L_4_G_D_0_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#9aa0a6"
-                                android:fillType="nonZero"
-                                android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
-                        </group>
-                        <group
-                            android:name="_R_G_L_0_G_L_0_G_L_3_G"
-                            android:translateX="162.5"
-                            android:translateY="676">
-                            <path
-                                android:name="_R_G_L_0_G_L_0_G_L_3_G_D_0_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#bdc1c6"
-                                android:fillType="nonZero"
-                                android:pathData=" M60.5 -5 C60.5,-5 60.5,5 60.5,5 C60.5,7.21 58.71,9 56.5,9 C56.5,9 -56.5,9 -56.5,9 C-58.71,9 -60.5,7.21 -60.5,5 C-60.5,5 -60.5,-5 -60.5,-5 C-60.5,-7.21 -58.71,-9 -56.5,-9 C-56.5,-9 56.5,-9 56.5,-9 C58.71,-9 60.5,-7.21 60.5,-5c " />
-                        </group>
-                        <group
-                            android:name="_R_G_L_0_G_L_0_G_L_2_G"
-                            android:translateX="174"
-                            android:translateY="697">
-                            <path
-                                android:name="_R_G_L_0_G_L_0_G_L_2_G_D_0_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#bdc1c6"
-                                android:fillType="nonZero"
-                                android:pathData=" M72 -4 C72,-4 72,4 72,4 C72,6.21 70.21,8 68,8 C68,8 -68,8 -68,8 C-70.21,8 -72,6.21 -72,4 C-72,4 -72,-4 -72,-4 C-72,-6.21 -70.21,-8 -68,-8 C-68,-8 68,-8 68,-8 C70.21,-8 72,-6.21 72,-4c " />
-                        </group>
-                        <group
-                            android:name="_R_G_L_0_G_L_0_G_L_1_G"
-                            android:translateX="313.5"
-                            android:translateY="798">
-                            <path
-                                android:name="_R_G_L_0_G_L_0_G_L_1_G_D_0_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#bdc1c6"
-                                android:fillType="nonZero"
-                                android:pathData=" M74.5 0 C74.5,0 74.5,0 74.5,0 C74.5,15.45 61.95,28 46.5,28 C46.5,28 -46.5,28 -46.5,28 C-61.95,28 -74.5,15.45 -74.5,0 C-74.5,0 -74.5,0 -74.5,0 C-74.5,-15.45 -61.95,-28 -46.5,-28 C-46.5,-28 46.5,-28 46.5,-28 C61.95,-28 74.5,-15.45 74.5,0c " />
-                        </group>
-                        <group
-                            android:name="_R_G_L_0_G_L_0_G_L_0_G"
-                            android:translateX="205.5"
-                            android:translateY="61">
-                            <path
-                                android:name="_R_G_L_0_G_L_0_G_L_0_G_D_0_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#f8f9fa"
-                                android:fillType="nonZero"
-                                android:pathData=" M171.5 -14 C171.5,-14 171.5,14 171.5,14 C171.5,16.21 169.71,18 167.5,18 C167.5,18 -167.5,18 -167.5,18 C-169.71,18 -171.5,16.21 -171.5,14 C-171.5,14 -171.5,-14 -171.5,-14 C-171.5,-16.21 -169.71,-18 -167.5,-18 C-167.5,-18 167.5,-18 167.5,-18 C169.71,-18 171.5,-16.21 171.5,-14c " />
-                        </group>
-                    </group>
-                </group>
-            </group>
-            <group android:name="time_group" />
-        </vector>
-    </aapt:attr>
-</animated-vector>
\ No newline at end of file
diff --git a/quickstep/res/drawable/mock_webpage_dark_mode.xml b/quickstep/res/drawable/mock_webpage_dark_mode.xml
deleted file mode 100644
index 93b22b7..0000000
--- a/quickstep/res/drawable/mock_webpage_dark_mode.xml
+++ /dev/null
@@ -1,251 +0,0 @@
-<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:aapt="http://schemas.android.com/aapt">
-    <target android:name="time_group">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="83"
-                    android:propertyName="translateX"
-                    android:startOffset="0"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <aapt:attr name="android:drawable">
-        <vector
-            android:width="412dp"
-            android:height="892dp"
-            android:viewportHeight="892"
-            android:viewportWidth="412">
-            <group android:name="_R_G">
-                <group android:name="_R_G_L_0_G">
-                    <group android:name="_R_G_L_0_G_L_3_G">
-                        <group
-                            android:name="_R_G_L_0_G_L_3_G_L_11_G"
-                            android:scaleX="0.87473"
-                            android:scaleY="0.98643"
-                            android:translateX="206"
-                            android:translateY="472.769">
-                            <path
-                                android:name="_R_G_L_0_G_L_3_G_L_11_G_D_0_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#dadce0"
-                                android:fillType="nonZero"
-                                android:pathData=" M235.5 -407 C235.5,-407 235.5,407 235.5,407 C235.5,416.93 227.43,425 217.5,425 C217.5,425 -217.5,425 -217.5,425 C-227.43,425 -235.5,416.93 -235.5,407 C-235.5,407 -235.5,-407 -235.5,-407 C-235.5,-416.93 -227.43,-425 -217.5,-425 C-217.5,-425 217.5,-425 217.5,-425 C227.43,-425 235.5,-416.93 235.5,-407c " />
-                        </group>
-                        <group
-                            android:name="_R_G_L_0_G_L_3_G_L_10_G"
-                            android:translateX="182.5"
-                            android:translateY="831">
-                            <path
-                                android:name="_R_G_L_0_G_L_3_G_L_10_G_D_0_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#bdc1c6"
-                                android:fillType="nonZero"
-                                android:pathData=" M158.5 -3 C158.5,-3 158.5,3 158.5,3 C158.5,7.42 154.92,11 150.5,11 C150.5,11 -150.5,11 -150.5,11 C-154.92,11 -158.5,7.42 -158.5,3 C-158.5,3 -158.5,-3 -158.5,-3 C-158.5,-7.42 -154.92,-11 -150.5,-11 C-150.5,-11 150.5,-11 150.5,-11 C154.92,-11 158.5,-7.42 158.5,-3c " />
-                        </group>
-                        <group
-                            android:name="_R_G_L_0_G_L_3_G_L_9_G"
-                            android:translateX="186"
-                            android:translateY="801">
-                            <path
-                                android:name="_R_G_L_0_G_L_3_G_L_9_G_D_0_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#bdc1c6"
-                                android:fillType="nonZero"
-                                android:pathData=" M162 -3 C162,-3 162,3 162,3 C162,7.42 158.42,11 154,11 C154,11 -154,11 -154,11 C-158.42,11 -162,7.42 -162,3 C-162,3 -162,-3 -162,-3 C-162,-7.42 -158.42,-11 -154,-11 C-154,-11 154,-11 154,-11 C158.42,-11 162,-7.42 162,-3c " />
-                        </group>
-                        <group
-                            android:name="_R_G_L_0_G_L_3_G_L_8_G"
-                            android:translateX="119"
-                            android:translateY="755">
-                            <path
-                                android:name="_R_G_L_0_G_L_3_G_L_8_G_D_0_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#bdc1c6"
-                                android:fillType="nonZero"
-                                android:pathData=" M95 -3 C95,-3 95,3 95,3 C95,7.42 91.42,11 87,11 C87,11 -87,11 -87,11 C-91.42,11 -95,7.42 -95,3 C-95,3 -95,-3 -95,-3 C-95,-7.42 -91.42,-11 -87,-11 C-87,-11 87,-11 87,-11 C91.42,-11 95,-7.42 95,-3c " />
-                        </group>
-                        <group
-                            android:name="_R_G_L_0_G_L_3_G_L_7_G"
-                            android:translateX="182.5"
-                            android:translateY="725">
-                            <path
-                                android:name="_R_G_L_0_G_L_3_G_L_7_G_D_0_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#bdc1c6"
-                                android:fillType="nonZero"
-                                android:pathData=" M158.5 -3 C158.5,-3 158.5,3 158.5,3 C158.5,7.42 154.92,11 150.5,11 C150.5,11 -150.5,11 -150.5,11 C-154.92,11 -158.5,7.42 -158.5,3 C-158.5,3 -158.5,-3 -158.5,-3 C-158.5,-7.42 -154.92,-11 -150.5,-11 C-150.5,-11 150.5,-11 150.5,-11 C154.92,-11 158.5,-7.42 158.5,-3c " />
-                        </group>
-                        <group
-                            android:name="_R_G_L_0_G_L_3_G_L_6_G"
-                            android:translateX="197.5"
-                            android:translateY="695">
-                            <path
-                                android:name="_R_G_L_0_G_L_3_G_L_6_G_D_0_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#bdc1c6"
-                                android:fillType="nonZero"
-                                android:pathData=" M173.5 -3 C173.5,-3 173.5,3 173.5,3 C173.5,7.42 169.92,11 165.5,11 C165.5,11 -165.5,11 -165.5,11 C-169.92,11 -173.5,7.42 -173.5,3 C-173.5,3 -173.5,-3 -173.5,-3 C-173.5,-7.42 -169.92,-11 -165.5,-11 C-165.5,-11 165.5,-11 165.5,-11 C169.92,-11 173.5,-7.42 173.5,-3c " />
-                        </group>
-                        <group
-                            android:name="_R_G_L_0_G_L_3_G_L_5_G"
-                            android:translateX="192"
-                            android:translateY="665">
-                            <path
-                                android:name="_R_G_L_0_G_L_3_G_L_5_G_D_0_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#bdc1c6"
-                                android:fillType="nonZero"
-                                android:pathData=" M168 -3 C168,-3 168,3 168,3 C168,7.42 164.42,11 160,11 C160,11 -160,11 -160,11 C-164.42,11 -168,7.42 -168,3 C-168,3 -168,-3 -168,-3 C-168,-7.42 -164.42,-11 -160,-11 C-160,-11 160,-11 160,-11 C164.42,-11 168,-7.42 168,-3c " />
-                        </group>
-                        <group
-                            android:name="_R_G_L_0_G_L_3_G_L_4_G"
-                            android:translateX="105.5"
-                            android:translateY="360">
-                            <path
-                                android:name="_R_G_L_0_G_L_3_G_L_4_G_D_0_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#bdc1c6"
-                                android:fillType="nonZero"
-                                android:pathData=" M23.5 -2 C23.5,-2 23.5,2 23.5,2 C23.5,4.21 21.71,6 19.5,6 C19.5,6 -19.5,6 -19.5,6 C-21.71,6 -23.5,4.21 -23.5,2 C-23.5,2 -23.5,-2 -23.5,-2 C-23.5,-4.21 -21.71,-6 -19.5,-6 C-19.5,-6 19.5,-6 19.5,-6 C21.71,-6 23.5,-4.21 23.5,-2c " />
-                        </group>
-                        <group
-                            android:name="_R_G_L_0_G_L_3_G_L_3_G"
-                            android:translateX="47.5"
-                            android:translateY="360">
-                            <path
-                                android:name="_R_G_L_0_G_L_3_G_L_3_G_D_0_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#bdc1c6"
-                                android:fillType="nonZero"
-                                android:pathData=" M23.5 -2 C23.5,-2 23.5,2 23.5,2 C23.5,4.21 21.71,6 19.5,6 C19.5,6 -19.5,6 -19.5,6 C-21.71,6 -23.5,4.21 -23.5,2 C-23.5,2 -23.5,-2 -23.5,-2 C-23.5,-4.21 -21.71,-6 -19.5,-6 C-19.5,-6 19.5,-6 19.5,-6 C21.71,-6 23.5,-4.21 23.5,-2c " />
-                        </group>
-                        <group
-                            android:name="_R_G_L_0_G_L_3_G_L_2_G"
-                            android:translateX="142.5"
-                            android:translateY="328">
-                            <path
-                                android:name="_R_G_L_0_G_L_3_G_L_2_G_D_0_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#bdc1c6"
-                                android:fillType="nonZero"
-                                android:pathData=" M118.5 -10 C118.5,-10 118.5,10 118.5,10 C118.5,14.42 114.92,18 110.5,18 C110.5,18 -110.5,18 -110.5,18 C-114.92,18 -118.5,14.42 -118.5,10 C-118.5,10 -118.5,-10 -118.5,-10 C-118.5,-14.42 -114.92,-18 -110.5,-18 C-110.5,-18 110.5,-18 110.5,-18 C114.92,-18 118.5,-14.42 118.5,-10c " />
-                        </group>
-                        <group
-                            android:name="_R_G_L_0_G_L_3_G_L_1_G"
-                            android:translateX="186"
-                            android:translateY="284">
-                            <path
-                                android:name="_R_G_L_0_G_L_3_G_L_1_G_D_0_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#bdc1c6"
-                                android:fillType="nonZero"
-                                android:pathData=" M162 -10 C162,-10 162,10 162,10 C162,14.42 158.42,18 154,18 C154,18 -154,18 -154,18 C-158.42,18 -162,14.42 -162,10 C-162,10 -162,-10 -162,-10 C-162,-14.42 -158.42,-18 -154,-18 C-154,-18 154,-18 154,-18 C158.42,-18 162,-14.42 162,-10c " />
-                        </group>
-                        <group
-                            android:name="_R_G_L_0_G_L_3_G_L_0_G"
-                            android:translateX="155"
-                            android:translateY="240">
-                            <path
-                                android:name="_R_G_L_0_G_L_3_G_L_0_G_D_0_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#bdc1c6"
-                                android:fillType="nonZero"
-                                android:pathData=" M131 -10 C131,-10 131,10 131,10 C131,14.42 127.42,18 123,18 C123,18 -123,18 -123,18 C-127.42,18 -131,14.42 -131,10 C-131,10 -131,-10 -131,-10 C-131,-14.42 -127.42,-18 -123,-18 C-123,-18 123,-18 123,-18 C127.42,-18 131,-14.42 131,-10c " />
-                        </group>
-                    </group>
-                    <group
-                        android:name="_R_G_L_0_G_L_2_G"
-                        android:translateX="24"
-                        android:translateY="390">
-                        <group
-                            android:name="_R_G_L_0_G_L_2_G_L_0_G"
-                            android:translateX="182"
-                            android:translateY="120">
-                            <path
-                                android:name="_R_G_L_0_G_L_2_G_L_0_G_D_0_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#bdc1c6"
-                                android:fillType="nonZero"
-                                android:pathData=" M182 -98 C182,-98 182,98 182,98 C182,110.14 172.14,120 160,120 C160,120 -160,120 -160,120 C-172.14,120 -182,110.14 -182,98 C-182,98 -182,-98 -182,-98 C-182,-110.14 -172.14,-120 -160,-120 C-160,-120 160,-120 160,-120 C172.14,-120 182,-110.14 182,-98c " />
-                        </group>
-                    </group>
-                    <group android:name="_R_G_L_0_G_L_1_G">
-                        <group
-                            android:name="_R_G_L_0_G_L_1_G_L_2_G"
-                            android:translateX="206"
-                            android:translateY="145">
-                            <path
-                                android:name="_R_G_L_0_G_L_1_G_L_2_G_D_0_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#e8eaed"
-                                android:fillType="nonZero"
-                                android:pathData=" M206 -95.63 C206,-95.63 206,42.37 206,42.37 C206,43.47 205.1,44.37 204,44.37 C204,44.37 -204,44.37 -204,44.37 C-205.1,44.37 -206,43.47 -206,42.37 C-206,42.37 -206,-95.63 -206,-95.63 C-206,-96.73 -205.1,-97.63 -204,-97.63 C-204,-97.63 204,-97.63 204,-97.63 C205.1,-97.63 206,-96.73 206,-95.63c " />
-                        </group>
-                        <group
-                            android:name="_R_G_L_0_G_L_1_G_L_1_G"
-                            android:translateX="206"
-                            android:translateY="145">
-                            <path
-                                android:name="_R_G_L_0_G_L_1_G_L_1_G_D_0_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#80868b"
-                                android:fillType="nonZero"
-                                android:pathData=" M109 -14 C109,-14 109,14 109,14 C109,15.1 108.1,16 107,16 C107,16 -107,16 -107,16 C-108.1,16 -109,15.1 -109,14 C-109,14 -109,-14 -109,-14 C-109,-15.1 -108.1,-16 -107,-16 C-107,-16 107,-16 107,-16 C108.1,-16 109,-15.1 109,-14c " />
-                        </group>
-                        <group
-                            android:name="_R_G_L_0_G_L_1_G_L_0_G"
-                            android:translateX="46"
-                            android:translateY="145">
-                            <path
-                                android:name="_R_G_L_0_G_L_1_G_L_0_G_D_0_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#80868b"
-                                android:fillType="nonZero"
-                                android:pathData=" M22 -14 C22,-14 22,14 22,14 C22,18.42 18.42,22 14,22 C14,22 -14,22 -14,22 C-18.42,22 -22,18.42 -22,14 C-22,14 -22,-14 -22,-14 C-22,-18.42 -18.42,-22 -14,-22 C-14,-22 14,-22 14,-22 C18.42,-22 22,-18.42 22,-14c " />
-                        </group>
-                    </group>
-                    <group android:name="_R_G_L_0_G_L_0_G">
-                        <group
-                            android:name="_R_G_L_0_G_L_0_G_L_2_G"
-                            android:translateX="206"
-                            android:translateY="51">
-                            <path
-                                android:name="_R_G_L_0_G_L_0_G_L_2_G_D_0_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#202124"
-                                android:fillType="nonZero"
-                                android:pathData=" M206 -0.27 C206,-0.27 206,49.73 206,49.73 C206,49.73 -206,49.73 -206,49.73 C-206,49.73 -206,-0.27 -206,-0.27 C-206,-0.27 206,-0.27 206,-0.27c " />
-                        </group>
-                        <group
-                            android:name="_R_G_L_0_G_L_0_G_L_1_G"
-                            android:translateX="206"
-                            android:translateY="50.5">
-                            <path
-                                android:name="_R_G_L_0_G_L_0_G_L_1_G_D_0_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#202124"
-                                android:fillType="nonZero"
-                                android:pathData=" M206 -32.5 C206,-32.5 206,32.5 206,32.5 C206,42.43 197.93,50.5 188,50.5 C188,50.5 -188,50.5 -188,50.5 C-197.93,50.5 -206,42.43 -206,32.5 C-206,32.5 -206,-32.5 -206,-32.5 C-206,-42.43 -197.93,-50.5 -188,-50.5 C-188,-50.5 188,-50.5 188,-50.5 C197.93,-50.5 206,-42.43 206,-32.5c " />
-                        </group>
-                        <group
-                            android:name="_R_G_L_0_G_L_0_G_L_0_G"
-                            android:translateX="206"
-                            android:translateY="66.5">
-                            <path
-                                android:name="_R_G_L_0_G_L_0_G_L_0_G_D_0_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#3c4043"
-                                android:fillType="nonZero"
-                                android:pathData=" M190 0 C190,0 190,0 190,0 C190,10.21 181.71,18.5 171.5,18.5 C171.5,18.5 -171.5,18.5 -171.5,18.5 C-181.71,18.5 -190,10.21 -190,0 C-190,0 -190,0 -190,0 C-190,-10.21 -181.71,-18.5 -171.5,-18.5 C-171.5,-18.5 171.5,-18.5 171.5,-18.5 C181.71,-18.5 190,-10.21 190,0c " />
-                        </group>
-                    </group>
-                </group>
-            </group>
-            <group android:name="time_group" />
-        </vector>
-    </aapt:attr>
-</animated-vector>
\ No newline at end of file
diff --git a/quickstep/res/drawable/mock_webpage_light_mode.xml b/quickstep/res/drawable/mock_webpage_light_mode.xml
deleted file mode 100644
index 98abb92..0000000
--- a/quickstep/res/drawable/mock_webpage_light_mode.xml
+++ /dev/null
@@ -1,263 +0,0 @@
-<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:aapt="http://schemas.android.com/aapt">
-    <target android:name="time_group">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="83"
-                    android:propertyName="translateX"
-                    android:startOffset="0"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <aapt:attr name="android:drawable">
-        <vector
-            android:width="412dp"
-            android:height="892dp"
-            android:viewportHeight="892"
-            android:viewportWidth="412">
-            <group android:name="_R_G">
-                <group android:name="_R_G_L_0_G">
-                    <group android:name="_R_G_L_0_G_L_4_G">
-                        <group
-                            android:name="_R_G_L_0_G_L_4_G_L_11_G"
-                            android:scaleX="0.87473"
-                            android:scaleY="0.98643"
-                            android:translateX="206"
-                            android:translateY="472.769">
-                            <path
-                                android:name="_R_G_L_0_G_L_4_G_L_11_G_D_0_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#dadce0"
-                                android:fillType="nonZero"
-                                android:pathData=" M235.5 -407 C235.5,-407 235.5,407 235.5,407 C235.5,416.93 227.43,425 217.5,425 C217.5,425 -217.5,425 -217.5,425 C-227.43,425 -235.5,416.93 -235.5,407 C-235.5,407 -235.5,-407 -235.5,-407 C-235.5,-416.93 -227.43,-425 -217.5,-425 C-217.5,-425 217.5,-425 217.5,-425 C227.43,-425 235.5,-416.93 235.5,-407c " />
-                        </group>
-                        <group
-                            android:name="_R_G_L_0_G_L_4_G_L_10_G"
-                            android:translateX="182.5"
-                            android:translateY="831">
-                            <path
-                                android:name="_R_G_L_0_G_L_4_G_L_10_G_D_0_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#bdc1c6"
-                                android:fillType="nonZero"
-                                android:pathData=" M158.5 -3 C158.5,-3 158.5,3 158.5,3 C158.5,7.42 154.92,11 150.5,11 C150.5,11 -150.5,11 -150.5,11 C-154.92,11 -158.5,7.42 -158.5,3 C-158.5,3 -158.5,-3 -158.5,-3 C-158.5,-7.42 -154.92,-11 -150.5,-11 C-150.5,-11 150.5,-11 150.5,-11 C154.92,-11 158.5,-7.42 158.5,-3c " />
-                        </group>
-                        <group
-                            android:name="_R_G_L_0_G_L_4_G_L_9_G"
-                            android:translateX="186"
-                            android:translateY="801">
-                            <path
-                                android:name="_R_G_L_0_G_L_4_G_L_9_G_D_0_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#bdc1c6"
-                                android:fillType="nonZero"
-                                android:pathData=" M162 -3 C162,-3 162,3 162,3 C162,7.42 158.42,11 154,11 C154,11 -154,11 -154,11 C-158.42,11 -162,7.42 -162,3 C-162,3 -162,-3 -162,-3 C-162,-7.42 -158.42,-11 -154,-11 C-154,-11 154,-11 154,-11 C158.42,-11 162,-7.42 162,-3c " />
-                        </group>
-                        <group
-                            android:name="_R_G_L_0_G_L_4_G_L_8_G"
-                            android:translateX="119"
-                            android:translateY="755">
-                            <path
-                                android:name="_R_G_L_0_G_L_4_G_L_8_G_D_0_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#bdc1c6"
-                                android:fillType="nonZero"
-                                android:pathData=" M95 -3 C95,-3 95,3 95,3 C95,7.42 91.42,11 87,11 C87,11 -87,11 -87,11 C-91.42,11 -95,7.42 -95,3 C-95,3 -95,-3 -95,-3 C-95,-7.42 -91.42,-11 -87,-11 C-87,-11 87,-11 87,-11 C91.42,-11 95,-7.42 95,-3c " />
-                        </group>
-                        <group
-                            android:name="_R_G_L_0_G_L_4_G_L_7_G"
-                            android:translateX="182.5"
-                            android:translateY="725">
-                            <path
-                                android:name="_R_G_L_0_G_L_4_G_L_7_G_D_0_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#bdc1c6"
-                                android:fillType="nonZero"
-                                android:pathData=" M158.5 -3 C158.5,-3 158.5,3 158.5,3 C158.5,7.42 154.92,11 150.5,11 C150.5,11 -150.5,11 -150.5,11 C-154.92,11 -158.5,7.42 -158.5,3 C-158.5,3 -158.5,-3 -158.5,-3 C-158.5,-7.42 -154.92,-11 -150.5,-11 C-150.5,-11 150.5,-11 150.5,-11 C154.92,-11 158.5,-7.42 158.5,-3c " />
-                        </group>
-                        <group
-                            android:name="_R_G_L_0_G_L_4_G_L_6_G"
-                            android:translateX="197.5"
-                            android:translateY="695">
-                            <path
-                                android:name="_R_G_L_0_G_L_4_G_L_6_G_D_0_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#bdc1c6"
-                                android:fillType="nonZero"
-                                android:pathData=" M173.5 -3 C173.5,-3 173.5,3 173.5,3 C173.5,7.42 169.92,11 165.5,11 C165.5,11 -165.5,11 -165.5,11 C-169.92,11 -173.5,7.42 -173.5,3 C-173.5,3 -173.5,-3 -173.5,-3 C-173.5,-7.42 -169.92,-11 -165.5,-11 C-165.5,-11 165.5,-11 165.5,-11 C169.92,-11 173.5,-7.42 173.5,-3c " />
-                        </group>
-                        <group
-                            android:name="_R_G_L_0_G_L_4_G_L_5_G"
-                            android:translateX="192"
-                            android:translateY="665">
-                            <path
-                                android:name="_R_G_L_0_G_L_4_G_L_5_G_D_0_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#bdc1c6"
-                                android:fillType="nonZero"
-                                android:pathData=" M168 -3 C168,-3 168,3 168,3 C168,7.42 164.42,11 160,11 C160,11 -160,11 -160,11 C-164.42,11 -168,7.42 -168,3 C-168,3 -168,-3 -168,-3 C-168,-7.42 -164.42,-11 -160,-11 C-160,-11 160,-11 160,-11 C164.42,-11 168,-7.42 168,-3c " />
-                        </group>
-                        <group
-                            android:name="_R_G_L_0_G_L_4_G_L_4_G"
-                            android:translateX="105.5"
-                            android:translateY="360">
-                            <path
-                                android:name="_R_G_L_0_G_L_4_G_L_4_G_D_0_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#bdc1c6"
-                                android:fillType="nonZero"
-                                android:pathData=" M23.5 -2 C23.5,-2 23.5,2 23.5,2 C23.5,4.21 21.71,6 19.5,6 C19.5,6 -19.5,6 -19.5,6 C-21.71,6 -23.5,4.21 -23.5,2 C-23.5,2 -23.5,-2 -23.5,-2 C-23.5,-4.21 -21.71,-6 -19.5,-6 C-19.5,-6 19.5,-6 19.5,-6 C21.71,-6 23.5,-4.21 23.5,-2c " />
-                        </group>
-                        <group
-                            android:name="_R_G_L_0_G_L_4_G_L_3_G"
-                            android:translateX="47.5"
-                            android:translateY="360">
-                            <path
-                                android:name="_R_G_L_0_G_L_4_G_L_3_G_D_0_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#bdc1c6"
-                                android:fillType="nonZero"
-                                android:pathData=" M23.5 -2 C23.5,-2 23.5,2 23.5,2 C23.5,4.21 21.71,6 19.5,6 C19.5,6 -19.5,6 -19.5,6 C-21.71,6 -23.5,4.21 -23.5,2 C-23.5,2 -23.5,-2 -23.5,-2 C-23.5,-4.21 -21.71,-6 -19.5,-6 C-19.5,-6 19.5,-6 19.5,-6 C21.71,-6 23.5,-4.21 23.5,-2c " />
-                        </group>
-                        <group
-                            android:name="_R_G_L_0_G_L_4_G_L_2_G"
-                            android:translateX="142.5"
-                            android:translateY="328">
-                            <path
-                                android:name="_R_G_L_0_G_L_4_G_L_2_G_D_0_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#bdc1c6"
-                                android:fillType="nonZero"
-                                android:pathData=" M118.5 -10 C118.5,-10 118.5,10 118.5,10 C118.5,14.42 114.92,18 110.5,18 C110.5,18 -110.5,18 -110.5,18 C-114.92,18 -118.5,14.42 -118.5,10 C-118.5,10 -118.5,-10 -118.5,-10 C-118.5,-14.42 -114.92,-18 -110.5,-18 C-110.5,-18 110.5,-18 110.5,-18 C114.92,-18 118.5,-14.42 118.5,-10c " />
-                        </group>
-                        <group
-                            android:name="_R_G_L_0_G_L_4_G_L_1_G"
-                            android:translateX="186"
-                            android:translateY="284">
-                            <path
-                                android:name="_R_G_L_0_G_L_4_G_L_1_G_D_0_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#bdc1c6"
-                                android:fillType="nonZero"
-                                android:pathData=" M162 -10 C162,-10 162,10 162,10 C162,14.42 158.42,18 154,18 C154,18 -154,18 -154,18 C-158.42,18 -162,14.42 -162,10 C-162,10 -162,-10 -162,-10 C-162,-14.42 -158.42,-18 -154,-18 C-154,-18 154,-18 154,-18 C158.42,-18 162,-14.42 162,-10c " />
-                        </group>
-                        <group
-                            android:name="_R_G_L_0_G_L_4_G_L_0_G"
-                            android:translateX="155"
-                            android:translateY="240">
-                            <path
-                                android:name="_R_G_L_0_G_L_4_G_L_0_G_D_0_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#bdc1c6"
-                                android:fillType="nonZero"
-                                android:pathData=" M131 -10 C131,-10 131,10 131,10 C131,14.42 127.42,18 123,18 C123,18 -123,18 -123,18 C-127.42,18 -131,14.42 -131,10 C-131,10 -131,-10 -131,-10 C-131,-14.42 -127.42,-18 -123,-18 C-123,-18 123,-18 123,-18 C127.42,-18 131,-14.42 131,-10c " />
-                        </group>
-                    </group>
-                    <group
-                        android:name="_R_G_L_0_G_L_3_G"
-                        android:translateX="24"
-                        android:translateY="390">
-                        <group
-                            android:name="_R_G_L_0_G_L_3_G_L_0_G"
-                            android:translateX="182"
-                            android:translateY="120">
-                            <path
-                                android:name="_R_G_L_0_G_L_3_G_L_0_G_D_0_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#bdc1c6"
-                                android:fillType="nonZero"
-                                android:pathData=" M182 -98 C182,-98 182,98 182,98 C182,110.14 172.14,120 160,120 C160,120 -160,120 -160,120 C-172.14,120 -182,110.14 -182,98 C-182,98 -182,-98 -182,-98 C-182,-110.14 -172.14,-120 -160,-120 C-160,-120 160,-120 160,-120 C172.14,-120 182,-110.14 182,-98c " />
-                        </group>
-                    </group>
-                    <group android:name="_R_G_L_0_G_L_2_G">
-                        <group
-                            android:name="_R_G_L_0_G_L_2_G_L_2_G"
-                            android:translateX="206"
-                            android:translateY="145">
-                            <path
-                                android:name="_R_G_L_0_G_L_2_G_L_2_G_D_0_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#e8eaed"
-                                android:fillType="nonZero"
-                                android:pathData=" M206 -95.63 C206,-95.63 206,42.37 206,42.37 C206,43.47 205.1,44.37 204,44.37 C204,44.37 -204,44.37 -204,44.37 C-205.1,44.37 -206,43.47 -206,42.37 C-206,42.37 -206,-95.63 -206,-95.63 C-206,-96.73 -205.1,-97.63 -204,-97.63 C-204,-97.63 204,-97.63 204,-97.63 C205.1,-97.63 206,-96.73 206,-95.63c " />
-                        </group>
-                        <group
-                            android:name="_R_G_L_0_G_L_2_G_L_1_G"
-                            android:translateX="206"
-                            android:translateY="145">
-                            <path
-                                android:name="_R_G_L_0_G_L_2_G_L_1_G_D_0_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#80868b"
-                                android:fillType="nonZero"
-                                android:pathData=" M109 -14 C109,-14 109,14 109,14 C109,15.1 108.1,16 107,16 C107,16 -107,16 -107,16 C-108.1,16 -109,15.1 -109,14 C-109,14 -109,-14 -109,-14 C-109,-15.1 -108.1,-16 -107,-16 C-107,-16 107,-16 107,-16 C108.1,-16 109,-15.1 109,-14c " />
-                        </group>
-                        <group
-                            android:name="_R_G_L_0_G_L_2_G_L_0_G"
-                            android:translateX="46"
-                            android:translateY="145">
-                            <path
-                                android:name="_R_G_L_0_G_L_2_G_L_0_G_D_0_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#80868b"
-                                android:fillType="nonZero"
-                                android:pathData=" M22 -14 C22,-14 22,14 22,14 C22,18.42 18.42,22 14,22 C14,22 -14,22 -14,22 C-18.42,22 -22,18.42 -22,14 C-22,14 -22,-14 -22,-14 C-22,-18.42 -18.42,-22 -14,-22 C-14,-22 14,-22 14,-22 C18.42,-22 22,-18.42 22,-14c " />
-                        </group>
-                    </group>
-                    <group android:name="_R_G_L_0_G_L_1_G">
-                        <group
-                            android:name="_R_G_L_0_G_L_1_G_L_2_G"
-                            android:translateX="206"
-                            android:translateY="51">
-                            <path
-                                android:name="_R_G_L_0_G_L_1_G_L_2_G_D_0_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#6e7175"
-                                android:fillType="nonZero"
-                                android:pathData=" M206 -0.27 C206,-0.27 206,49.73 206,49.73 C206,49.73 -206,49.73 -206,49.73 C-206,49.73 -206,-0.27 -206,-0.27 C-206,-0.27 206,-0.27 206,-0.27c " />
-                        </group>
-                        <group
-                            android:name="_R_G_L_0_G_L_1_G_L_1_G"
-                            android:translateX="206"
-                            android:translateY="50.5">
-                            <path
-                                android:name="_R_G_L_0_G_L_1_G_L_1_G_D_0_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#6e7175"
-                                android:fillType="nonZero"
-                                android:pathData=" M206 -32.5 C206,-32.5 206,32.5 206,32.5 C206,42.43 197.93,50.5 188,50.5 C188,50.5 -188,50.5 -188,50.5 C-197.93,50.5 -206,42.43 -206,32.5 C-206,32.5 -206,-32.5 -206,-32.5 C-206,-42.43 -197.93,-50.5 -188,-50.5 C-188,-50.5 188,-50.5 188,-50.5 C197.93,-50.5 206,-42.43 206,-32.5c " />
-                        </group>
-                        <group
-                            android:name="_R_G_L_0_G_L_1_G_L_0_G"
-                            android:translateX="206"
-                            android:translateY="66.5">
-                            <path
-                                android:name="_R_G_L_0_G_L_1_G_L_0_G_D_0_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#9a9a9a"
-                                android:fillType="nonZero"
-                                android:pathData=" M190 0 C190,0 190,0 190,0 C190,10.21 181.71,18.5 171.5,18.5 C171.5,18.5 -171.5,18.5 -171.5,18.5 C-181.71,18.5 -190,10.21 -190,0 C-190,0 -190,0 -190,0 C-190,-10.21 -181.71,-18.5 -171.5,-18.5 C-171.5,-18.5 171.5,-18.5 171.5,-18.5 C181.71,-18.5 190,-10.21 190,0c " />
-                        </group>
-                    </group>
-                    <group
-                        android:name="_R_G_L_0_G_L_0_G"
-                        android:scaleY="0"
-                        android:translateX="206"
-                        android:translateY="446">
-                        <path
-                            android:name="_R_G_L_0_G_L_0_G_D_0_P_0"
-                            android:fillAlpha="1"
-                            android:fillColor="#bac4d6"
-                            android:fillType="nonZero"
-                            android:pathData=" M206.06 -430.06 C206.06,-430.06 206,431 206,431 C206,446 189.75,446 189.79,446 C189.79,446 -189.98,446 -189.98,446 C-189.94,446 -206,446 -206,431 C-206,431 -206,-430 -206,-430 C-206,-446 -189.97,-446 -190.01,-446 C-190.01,-446 188.98,-446.06 188.98,-446.06 C188.94,-446.06 206,-446 206.06,-430.06c " />
-                    </group>
-                </group>
-            </group>
-            <group android:name="time_group" />
-        </vector>
-    </aapt:attr>
-</animated-vector>
\ No newline at end of file
diff --git a/quickstep/res/drawable/taskbar_edu_splitscreen.webp b/quickstep/res/drawable/taskbar_edu_splitscreen.webp
new file mode 100644
index 0000000..2f4402f
--- /dev/null
+++ b/quickstep/res/drawable/taskbar_edu_splitscreen.webp
Binary files differ
diff --git a/quickstep/res/interpolator/app_open_x.xml b/quickstep/res/interpolator/app_open_x.xml
new file mode 100644
index 0000000..5fa0bcb
--- /dev/null
+++ b/quickstep/res/interpolator/app_open_x.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 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.
+*/
+-->
+
+<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
+    android:pathData="M 0, 0 C 0.1217, 0.0462, 0.15, 0.4686, 0.1667, 0.66 C 0.1834, 0.8878, 0.1667, 1, 1, 1"/>
diff --git a/quickstep/res/interpolator/three_point_fast_out_extra_slow_in.xml b/quickstep/res/interpolator/three_point_fast_out_extra_slow_in.xml
new file mode 100644
index 0000000..70c4231
--- /dev/null
+++ b/quickstep/res/interpolator/three_point_fast_out_extra_slow_in.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 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.
+*/
+-->
+
+<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
+    android:pathData="M 0,0 C 0.05, 0, 0.133333, 0.06, 0.166666, 0.4 C 0.208333, 0.82, 0.25, 1, 1, 1"/>
diff --git a/quickstep/res/layout/gesture_tutorial_dialog.xml b/quickstep/res/layout/gesture_tutorial_dialog.xml
index 59bf7b9..db6ec85 100644
--- a/quickstep/res/layout/gesture_tutorial_dialog.xml
+++ b/quickstep/res/layout/gesture_tutorial_dialog.xml
@@ -1,4 +1,18 @@
 <?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
 <androidx.constraintlayout.widget.ConstraintLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto"
diff --git a/quickstep/res/layout/gesture_tutorial_fragment.xml b/quickstep/res/layout/gesture_tutorial_fragment.xml
index cdda43c..cfb3eb0 100644
--- a/quickstep/res/layout/gesture_tutorial_fragment.xml
+++ b/quickstep/res/layout/gesture_tutorial_fragment.xml
@@ -49,7 +49,7 @@
         android:scaleY="0.98"
         android:visibility="invisible" />
 
-    <View
+    <FrameLayout
         android:id="@+id/gesture_tutorial_fake_task_view"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
@@ -62,7 +62,7 @@
         android:background="@drawable/gesture_tutorial_ripple"/>
 
     <ImageView
-        android:id="@+id/gesture_tutorial_feedback_video"
+        android:id="@+id/gesture_tutorial_edge_gesture_video"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:layout_alignParentTop="true"
@@ -73,14 +73,12 @@
         android:visibility="gone"/>
 
     <ImageView
-        android:id="@+id/gesture_tutorial_gesture_video"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:layout_alignParentTop="true"
-        android:layout_alignParentBottom="true"
-        android:layout_alignParentStart="true"
-        android:layout_alignParentEnd="true"
-        android:scaleType="fitXY"
+        android:id="@+id/gesture_tutorial_finger_dot"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:src="@drawable/gesture_tutorial_finger_dot"
+        android:layout_centerHorizontal="true"
+        android:layout_centerVertical="true"
         android:visibility="gone"/>
 
     <androidx.constraintlayout.widget.ConstraintLayout
diff --git a/quickstep/res/layout/gesture_tutorial_mock_conversation.xml b/quickstep/res/layout/gesture_tutorial_mock_conversation.xml
new file mode 100644
index 0000000..89973d3
--- /dev/null
+++ b/quickstep/res/layout/gesture_tutorial_mock_conversation.xml
@@ -0,0 +1,242 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<androidx.constraintlayout.widget.ConstraintLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:id="@+id/top_bar"
+        android:layout_width="match_parent"
+        android:layout_height="101dp"
+        android:background="@color/mock_conversation_top_bar"
+
+        app:layout_constraintTop_toTopOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintEnd_toEndOf="parent">
+
+        <androidx.cardview.widget.CardView
+            android:layout_width="0dp"
+            android:layout_height="0dp"
+            android:layout_marginTop="43dp"
+            android:layout_marginBottom="22dp"
+            android:layout_marginStart="34dp"
+            android:layout_marginEnd="211dp"
+
+            app:cardElevation="0dp"
+            app:cardCornerRadius="4dp"
+            app:cardBackgroundColor="@color/mock_conversation_top_bar_item"
+            app:layout_constraintTop_toTopOf="parent"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"/>
+
+        <androidx.cardview.widget.CardView
+            android:layout_width="0dp"
+            android:layout_height="0dp"
+            android:layout_marginTop="43dp"
+            android:layout_marginBottom="22dp"
+            android:layout_marginStart="300dp"
+            android:layout_marginEnd="16dp"
+
+            app:cardElevation="0dp"
+            app:cardCornerRadius="4dp"
+            app:cardBackgroundColor="@color/mock_conversation_top_bar_item"
+            app:layout_constraintDimensionRatio="1:1"
+            app:layout_constraintTop_toTopOf="parent"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintEnd_toStartOf="@id/top_bar_button"/>
+
+        <androidx.cardview.widget.CardView
+            android:id="@+id/top_bar_button"
+            android:layout_width="0dp"
+            android:layout_height="0dp"
+            android:layout_marginTop="43dp"
+            android:layout_marginBottom="22dp"
+            android:layout_marginStart="300dp"
+            android:layout_marginEnd="24dp"
+
+            app:cardElevation="0dp"
+            app:cardCornerRadius="4dp"
+            app:cardBackgroundColor="@color/mock_conversation_top_bar_item"
+            app:layout_constraintDimensionRatio="1:1"
+            app:layout_constraintTop_toTopOf="parent"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"/>
+
+    </androidx.constraintlayout.widget.ConstraintLayout>
+
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:layout_width="match_parent"
+        android:layout_height="0dp"
+        android:background="@color/mock_conversation_background"
+        android:paddingBottom="66dp"
+
+        app:layout_constraintTop_toBottomOf="@id/top_bar"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintEnd_toEndOf="parent">
+
+        <androidx.constraintlayout.widget.ConstraintLayout
+            android:layout_width="match_parent"
+            android:layout_height="0dp"
+            android:paddingBottom="36dp"
+
+            app:layout_constraintTop_toTopOf="parent"
+            app:layout_constraintBottom_toTopOf="@id/message_bar"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintEnd_toEndOf="parent">
+
+            <androidx.cardview.widget.CardView
+                android:id="@+id/message_1"
+                android:layout_width="0dp"
+                android:layout_height="112dp"
+                android:layout_marginBottom="32dp"
+                android:layout_marginStart="124dp"
+                android:layout_marginEnd="18dp"
+
+                app:cardElevation="0dp"
+                app:cardCornerRadius="18dp"
+                app:cardBackgroundColor="@color/mock_conversation_sent_message"
+                app:layout_constraintBottom_toTopOf="@id/reply_icon_1"
+                app:layout_constraintStart_toStartOf="parent"
+                app:layout_constraintEnd_toEndOf="parent"/>
+
+            <androidx.cardview.widget.CardView
+                android:id="@+id/reply_icon_1"
+                android:layout_width="0dp"
+                android:layout_height="0dp"
+                android:layout_marginBottom="32dp"
+                android:layout_marginStart="26dp"
+                android:layout_marginEnd="342dp"
+
+                app:cardElevation="0dp"
+                app:cardCornerRadius="100dp"
+                app:cardBackgroundColor="@color/mock_conversation_profile_icon"
+                app:layout_constraintDimensionRatio="1:1"
+                app:layout_constraintBottom_toTopOf="@id/message_2"
+                app:layout_constraintStart_toStartOf="parent"
+                app:layout_constraintEnd_toEndOf="parent"/>
+
+            <androidx.cardview.widget.CardView
+                android:layout_width="0dp"
+                android:layout_height="36dp"
+                android:layout_marginStart="17dp"
+                android:layout_marginEnd="112dp"
+
+                app:cardElevation="0dp"
+                app:cardCornerRadius="18dp"
+                app:cardBackgroundColor="@color/mock_conversation_received_message"
+                app:layout_constraintTop_toTopOf="@id/reply_icon_1"
+                app:layout_constraintBottom_toBottomOf="@id/reply_icon_1"
+                app:layout_constraintStart_toEndOf="@id/reply_icon_1"
+                app:layout_constraintEnd_toEndOf="parent"/>
+
+            <androidx.cardview.widget.CardView
+                android:id="@+id/message_2"
+                android:layout_width="0dp"
+                android:layout_height="36dp"
+                android:layout_marginBottom="4dp"
+                android:layout_marginStart="280dp"
+                android:layout_marginEnd="18dp"
+
+                app:cardElevation="0dp"
+                app:cardCornerRadius="18dp"
+                app:cardBackgroundColor="@color/mock_conversation_sent_message"
+                app:layout_constraintBottom_toTopOf="@id/message_3"
+                app:layout_constraintStart_toStartOf="parent"
+                app:layout_constraintEnd_toEndOf="parent"/>
+
+            <androidx.cardview.widget.CardView
+                android:id="@+id/message_3"
+                android:layout_width="0dp"
+                android:layout_height="74dp"
+                android:layout_marginBottom="32dp"
+                android:layout_marginStart="124dp"
+                android:layout_marginEnd="18dp"
+
+                app:cardElevation="0dp"
+                app:cardCornerRadius="18dp"
+                app:cardBackgroundColor="@color/mock_conversation_sent_message"
+                app:layout_constraintBottom_toTopOf="@id/reply_icon_2"
+                app:layout_constraintStart_toStartOf="parent"
+                app:layout_constraintEnd_toEndOf="parent"/>
+
+            <androidx.cardview.widget.CardView
+                android:id="@+id/reply_icon_2"
+                android:layout_width="0dp"
+                android:layout_height="0dp"
+                android:layout_marginBottom="32dp"
+                android:layout_marginStart="26dp"
+                android:layout_marginEnd="342dp"
+
+                app:cardElevation="0dp"
+                app:cardCornerRadius="100dp"
+                app:cardBackgroundColor="@color/mock_conversation_profile_icon"
+                app:layout_constraintDimensionRatio="1:1"
+                app:layout_constraintBottom_toTopOf="@id/message_4"
+                app:layout_constraintStart_toStartOf="parent"
+                app:layout_constraintEnd_toEndOf="parent"/>
+
+            <androidx.cardview.widget.CardView
+                android:layout_width="0dp"
+                android:layout_height="36dp"
+                android:layout_marginStart="17dp"
+                android:layout_marginEnd="144dp"
+
+                app:cardElevation="0dp"
+                app:cardCornerRadius="18dp"
+                app:cardBackgroundColor="@color/mock_conversation_received_message"
+                app:layout_constraintTop_toTopOf="@id/reply_icon_2"
+                app:layout_constraintBottom_toBottomOf="@id/reply_icon_2"
+                app:layout_constraintStart_toEndOf="@id/reply_icon_2"
+                app:layout_constraintEnd_toEndOf="parent"/>
+
+            <androidx.cardview.widget.CardView
+                android:id="@+id/message_4"
+                android:layout_width="0dp"
+                android:layout_height="74dp"
+                android:layout_marginStart="124dp"
+                android:layout_marginEnd="18dp"
+
+                app:cardElevation="0dp"
+                app:cardCornerRadius="18dp"
+                app:cardBackgroundColor="@color/mock_conversation_sent_message"
+                app:layout_constraintBottom_toBottomOf="parent"
+                app:layout_constraintStart_toStartOf="parent"
+                app:layout_constraintEnd_toEndOf="parent"/>
+
+        </androidx.constraintlayout.widget.ConstraintLayout>
+
+        <androidx.cardview.widget.CardView
+            android:id="@+id/message_bar"
+            android:layout_width="0dp"
+            android:layout_height="44dp"
+            android:layout_marginTop="36dp"
+            android:layout_marginStart="34dp"
+            android:layout_marginEnd="24dp"
+
+            app:cardElevation="0dp"
+            app:cardCornerRadius="164dp"
+            app:cardBackgroundColor="@color/mock_conversation_message_input"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintEnd_toEndOf="parent" />
+
+    </androidx.constraintlayout.widget.ConstraintLayout>
+
+</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
diff --git a/quickstep/res/layout/gesture_tutorial_mock_conversation_list.xml b/quickstep/res/layout/gesture_tutorial_mock_conversation_list.xml
new file mode 100644
index 0000000..ad6b165
--- /dev/null
+++ b/quickstep/res/layout/gesture_tutorial_mock_conversation_list.xml
@@ -0,0 +1,394 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<androidx.constraintlayout.widget.ConstraintLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:id="@+id/top_bar"
+        android:layout_width="match_parent"
+        android:layout_height="101dp"
+        android:background="@color/mock_list_top_bar"
+
+        app:layout_constraintTop_toTopOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintEnd_toEndOf="parent">
+
+        <androidx.cardview.widget.CardView
+            android:layout_width="0dp"
+            android:layout_height="0dp"
+            android:layout_marginTop="43dp"
+            android:layout_marginBottom="22dp"
+            android:layout_marginStart="34dp"
+            android:layout_marginEnd="35dp"
+
+            app:cardElevation="0dp"
+            app:cardCornerRadius="4dp"
+            app:cardBackgroundColor="@color/mock_list_top_bar_item"
+            app:layout_constraintTop_toTopOf="parent"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"/>
+
+    </androidx.constraintlayout.widget.ConstraintLayout>
+
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:layout_width="match_parent"
+        android:layout_height="0dp"
+        android:background="@color/mock_list_background"
+        android:paddingBottom="66dp"
+
+        app:layout_constraintTop_toBottomOf="@id/top_bar"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintEnd_toEndOf="parent">
+
+        <androidx.constraintlayout.widget.ConstraintLayout
+            android:layout_width="match_parent"
+            android:layout_height="0dp"
+            android:paddingTop="28dp"
+            android:paddingStart="26dp"
+            android:paddingBottom="14dp"
+
+            app:layout_constraintTop_toTopOf="parent"
+            app:layout_constraintBottom_toTopOf="@id/mock_button">
+
+            <androidx.cardview.widget.CardView
+                android:id="@+id/conversation_icon_1"
+                android:layout_width="56dp"
+                android:layout_height="56dp"
+
+                app:cardElevation="0dp"
+                app:cardCornerRadius="100dp"
+                app:cardBackgroundColor="@color/mock_list_profile_icon"
+                app:layout_constraintTop_toTopOf="parent"
+                app:layout_constraintStart_toStartOf="parent"/>
+
+            <androidx.cardview.widget.CardView
+                android:id="@+id/conversation_line_1"
+                android:layout_width="0dp"
+                android:layout_height="18dp"
+                android:layout_marginStart="20dp"
+                android:layout_marginEnd="217dp"
+
+                app:cardElevation="0dp"
+                app:cardCornerRadius="4dp"
+                app:cardBackgroundColor="@color/mock_list_preview_message"
+                app:layout_constraintVertical_chainStyle="packed"
+                app:layout_constraintTop_toTopOf="@id/conversation_icon_1"
+                app:layout_constraintStart_toEndOf="@id/conversation_icon_1"
+                app:layout_constraintEnd_toEndOf="parent"
+                app:layout_constraintBottom_toTopOf="@id/conversation_line_2"/>
+
+            <androidx.cardview.widget.CardView
+                android:id="@+id/conversation_line_2"
+                android:layout_width="0dp"
+                android:layout_height="16dp"
+                android:layout_marginStart="20dp"
+                android:layout_marginEnd="142dp"
+                android:layout_marginTop="4dp"
+
+                app:cardElevation="0dp"
+                app:cardCornerRadius="4dp"
+                app:cardBackgroundColor="@color/mock_list_preview_message"
+                app:layout_constraintTop_toBottomOf="@id/conversation_line_1"
+                app:layout_constraintStart_toEndOf="@id/conversation_icon_1"
+                app:layout_constraintEnd_toEndOf="parent"
+                app:layout_constraintBottom_toBottomOf="@id/conversation_icon_1"/>
+
+            <androidx.cardview.widget.CardView
+                android:id="@+id/conversation_icon_2"
+                android:layout_width="56dp"
+                android:layout_height="56dp"
+                android:layout_marginTop="32dp"
+
+                app:cardElevation="0dp"
+                app:cardCornerRadius="100dp"
+                app:cardBackgroundColor="@color/mock_list_profile_icon"
+                app:layout_constraintTop_toBottomOf="@id/conversation_icon_1"
+                app:layout_constraintStart_toStartOf="parent"/>
+
+            <androidx.cardview.widget.CardView
+                android:id="@+id/conversation_line_3"
+                android:layout_width="0dp"
+                android:layout_height="18dp"
+                android:layout_marginStart="20dp"
+                android:layout_marginEnd="190dp"
+
+                app:cardElevation="0dp"
+                app:cardCornerRadius="4dp"
+                app:cardBackgroundColor="@color/mock_list_preview_message"
+                app:layout_constraintVertical_chainStyle="packed"
+                app:layout_constraintTop_toTopOf="@id/conversation_icon_2"
+                app:layout_constraintStart_toEndOf="@id/conversation_icon_2"
+                app:layout_constraintEnd_toEndOf="parent"
+                app:layout_constraintBottom_toTopOf="@id/conversation_line_4"/>
+
+            <androidx.cardview.widget.CardView
+                android:id="@+id/conversation_line_4"
+                android:layout_width="0dp"
+                android:layout_height="16dp"
+                android:layout_marginStart="20dp"
+                android:layout_marginEnd="171dp"
+                android:layout_marginTop="4dp"
+
+                app:cardElevation="0dp"
+                app:cardCornerRadius="4dp"
+                app:cardBackgroundColor="@color/mock_list_preview_message"
+                app:layout_constraintTop_toBottomOf="@id/conversation_line_3"
+                app:layout_constraintStart_toEndOf="@id/conversation_icon_2"
+                app:layout_constraintEnd_toEndOf="parent"
+                app:layout_constraintBottom_toBottomOf="@id/conversation_icon_2"/>
+
+            <androidx.cardview.widget.CardView
+                android:id="@+id/conversation_icon_3"
+                android:layout_width="56dp"
+                android:layout_height="56dp"
+                android:layout_marginTop="32dp"
+
+                app:cardElevation="0dp"
+                app:cardCornerRadius="100dp"
+                app:cardBackgroundColor="@color/mock_list_profile_icon"
+                app:layout_constraintTop_toBottomOf="@id/conversation_icon_2"
+                app:layout_constraintStart_toStartOf="parent"/>
+
+            <androidx.cardview.widget.CardView
+                android:id="@+id/conversation_line_5"
+                android:layout_width="0dp"
+                android:layout_height="18dp"
+                android:layout_marginStart="20dp"
+                android:layout_marginEnd="198dp"
+
+                app:cardElevation="0dp"
+                app:cardCornerRadius="4dp"
+                app:cardBackgroundColor="@color/mock_list_preview_message"
+                app:layout_constraintVertical_chainStyle="packed"
+                app:layout_constraintTop_toTopOf="@id/conversation_icon_3"
+                app:layout_constraintStart_toEndOf="@id/conversation_icon_3"
+                app:layout_constraintEnd_toEndOf="parent"
+                app:layout_constraintBottom_toTopOf="@id/conversation_line_6"/>
+
+            <androidx.cardview.widget.CardView
+                android:id="@+id/conversation_line_6"
+                android:layout_width="0dp"
+                android:layout_height="16dp"
+                android:layout_marginStart="20dp"
+                android:layout_marginEnd="79dp"
+                android:layout_marginTop="4dp"
+
+                app:cardElevation="0dp"
+                app:cardCornerRadius="4dp"
+                app:cardBackgroundColor="@color/mock_list_preview_message"
+                app:layout_constraintTop_toBottomOf="@id/conversation_line_5"
+                app:layout_constraintStart_toEndOf="@id/conversation_icon_3"
+                app:layout_constraintEnd_toEndOf="parent"
+                app:layout_constraintBottom_toBottomOf="@id/conversation_icon_3"/>
+
+            <androidx.cardview.widget.CardView
+                android:id="@+id/conversation_icon_4"
+                android:layout_width="56dp"
+                android:layout_height="56dp"
+                android:layout_marginTop="32dp"
+
+                app:cardElevation="0dp"
+                app:cardCornerRadius="100dp"
+                app:cardBackgroundColor="@color/mock_list_profile_icon"
+                app:layout_constraintTop_toBottomOf="@id/conversation_icon_3"
+                app:layout_constraintStart_toStartOf="parent"/>
+
+            <androidx.cardview.widget.CardView
+                android:id="@+id/conversation_line_7"
+                android:layout_width="0dp"
+                android:layout_height="18dp"
+                android:layout_marginStart="20dp"
+                android:layout_marginEnd="174dp"
+
+                app:cardElevation="0dp"
+                app:cardCornerRadius="4dp"
+                app:cardBackgroundColor="@color/mock_list_preview_message"
+                app:layout_constraintVertical_chainStyle="packed"
+                app:layout_constraintTop_toTopOf="@id/conversation_icon_4"
+                app:layout_constraintStart_toEndOf="@id/conversation_icon_4"
+                app:layout_constraintEnd_toEndOf="parent"
+                app:layout_constraintBottom_toTopOf="@id/conversation_line_8"/>
+
+            <androidx.cardview.widget.CardView
+                android:id="@+id/conversation_line_8"
+                android:layout_width="0dp"
+                android:layout_height="16dp"
+                android:layout_marginStart="20dp"
+                android:layout_marginEnd="117dp"
+                android:layout_marginTop="4dp"
+
+                app:cardElevation="0dp"
+                app:cardCornerRadius="4dp"
+                app:cardBackgroundColor="@color/mock_list_preview_message"
+                app:layout_constraintTop_toBottomOf="@id/conversation_line_7"
+                app:layout_constraintStart_toEndOf="@id/conversation_icon_4"
+                app:layout_constraintEnd_toEndOf="parent"
+                app:layout_constraintBottom_toBottomOf="@id/conversation_icon_4"/>
+
+            <androidx.cardview.widget.CardView
+                android:id="@+id/conversation_icon_5"
+                android:layout_width="56dp"
+                android:layout_height="56dp"
+                android:layout_marginTop="32dp"
+
+                app:cardElevation="0dp"
+                app:cardCornerRadius="100dp"
+                app:cardBackgroundColor="@color/mock_list_profile_icon"
+                app:layout_constraintTop_toBottomOf="@id/conversation_icon_4"
+                app:layout_constraintStart_toStartOf="parent"/>
+
+            <androidx.cardview.widget.CardView
+                android:id="@+id/conversation_line_9"
+                android:layout_width="0dp"
+                android:layout_height="18dp"
+                android:layout_marginStart="20dp"
+                android:layout_marginEnd="244dp"
+
+                app:cardElevation="0dp"
+                app:cardCornerRadius="4dp"
+                app:cardBackgroundColor="@color/mock_list_preview_message"
+                app:layout_constraintVertical_chainStyle="packed"
+                app:layout_constraintTop_toTopOf="@id/conversation_icon_5"
+                app:layout_constraintStart_toEndOf="@id/conversation_icon_5"
+                app:layout_constraintEnd_toEndOf="parent"
+                app:layout_constraintBottom_toTopOf="@id/conversation_line_10"/>
+
+            <androidx.cardview.widget.CardView
+                android:id="@+id/conversation_line_10"
+                android:layout_width="0dp"
+                android:layout_height="16dp"
+                android:layout_marginStart="20dp"
+                android:layout_marginEnd="143dp"
+                android:layout_marginTop="4dp"
+
+                app:cardElevation="0dp"
+                app:cardCornerRadius="4dp"
+                app:cardBackgroundColor="@color/mock_list_preview_message"
+                app:layout_constraintTop_toBottomOf="@id/conversation_line_9"
+                app:layout_constraintStart_toEndOf="@id/conversation_icon_5"
+                app:layout_constraintEnd_toEndOf="parent"
+                app:layout_constraintBottom_toBottomOf="@id/conversation_icon_5"/>
+
+            <androidx.cardview.widget.CardView
+                android:id="@+id/conversation_icon_6"
+                android:layout_width="56dp"
+                android:layout_height="56dp"
+                android:layout_marginTop="32dp"
+
+                app:cardElevation="0dp"
+                app:cardCornerRadius="100dp"
+                app:cardBackgroundColor="@color/mock_list_profile_icon"
+                app:layout_constraintTop_toBottomOf="@id/conversation_icon_5"
+                app:layout_constraintStart_toStartOf="parent"/>
+
+            <androidx.cardview.widget.CardView
+                android:id="@+id/conversation_line_11"
+                android:layout_width="0dp"
+                android:layout_height="18dp"
+                android:layout_marginStart="20dp"
+                android:layout_marginEnd="177dp"
+
+                app:cardElevation="0dp"
+                app:cardCornerRadius="4dp"
+                app:cardBackgroundColor="@color/mock_list_preview_message"
+                app:layout_constraintVertical_chainStyle="packed"
+                app:layout_constraintTop_toTopOf="@id/conversation_icon_6"
+                app:layout_constraintStart_toEndOf="@id/conversation_icon_6"
+                app:layout_constraintEnd_toEndOf="parent"
+                app:layout_constraintBottom_toTopOf="@id/conversation_line_12"/>
+
+            <androidx.cardview.widget.CardView
+                android:id="@+id/conversation_line_12"
+                android:layout_width="0dp"
+                android:layout_height="16dp"
+                android:layout_marginStart="20dp"
+                android:layout_marginEnd="117dp"
+                android:layout_marginTop="4dp"
+
+                app:cardElevation="0dp"
+                app:cardCornerRadius="4dp"
+                app:cardBackgroundColor="@color/mock_list_preview_message"
+                app:layout_constraintTop_toBottomOf="@id/conversation_line_11"
+                app:layout_constraintStart_toEndOf="@id/conversation_icon_6"
+                app:layout_constraintEnd_toEndOf="parent"
+                app:layout_constraintBottom_toBottomOf="@id/conversation_icon_6"/>
+
+            <androidx.cardview.widget.CardView
+                android:id="@+id/conversation_icon_7"
+                android:layout_width="56dp"
+                android:layout_height="56dp"
+                android:layout_marginTop="32dp"
+
+                app:cardElevation="0dp"
+                app:cardCornerRadius="100dp"
+                app:cardBackgroundColor="@color/mock_list_profile_icon"
+                app:layout_constraintTop_toBottomOf="@id/conversation_icon_6"
+                app:layout_constraintStart_toStartOf="parent"/>
+
+            <androidx.cardview.widget.CardView
+                android:id="@+id/conversation_line_13"
+                android:layout_width="0dp"
+                android:layout_height="18dp"
+                android:layout_marginStart="20dp"
+                android:layout_marginEnd="189dp"
+
+                app:cardElevation="0dp"
+                app:cardCornerRadius="4dp"
+                app:cardBackgroundColor="@color/mock_list_preview_message"
+                app:layout_constraintVertical_chainStyle="packed"
+                app:layout_constraintTop_toTopOf="@id/conversation_icon_7"
+                app:layout_constraintStart_toEndOf="@id/conversation_icon_7"
+                app:layout_constraintEnd_toEndOf="parent"
+                app:layout_constraintBottom_toTopOf="@id/conversation_line_14"/>
+
+            <androidx.cardview.widget.CardView
+                android:id="@+id/conversation_line_14"
+                android:layout_width="0dp"
+                android:layout_height="16dp"
+                android:layout_marginStart="20dp"
+                android:layout_marginEnd="166dp"
+                android:layout_marginTop="4dp"
+
+                app:cardElevation="0dp"
+                app:cardCornerRadius="4dp"
+                app:cardBackgroundColor="@color/mock_list_preview_message"
+                app:layout_constraintTop_toBottomOf="@id/conversation_line_13"
+                app:layout_constraintStart_toEndOf="@id/conversation_icon_7"
+                app:layout_constraintEnd_toEndOf="parent"
+                app:layout_constraintBottom_toBottomOf="@id/conversation_icon_7"/>
+
+        </androidx.constraintlayout.widget.ConstraintLayout>
+
+        <androidx.cardview.widget.CardView
+            android:id="@+id/mock_button"
+            android:layout_width="149dp"
+            android:layout_height="56dp"
+            android:layout_marginEnd="24dp"
+
+            app:cardElevation="0dp"
+            app:cardCornerRadius="164dp"
+            app:cardBackgroundColor="@color/mock_list_button"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"/>
+
+    </androidx.constraintlayout.widget.ConstraintLayout>
+
+</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
diff --git a/quickstep/res/layout/gesture_tutorial_mock_webpage.xml b/quickstep/res/layout/gesture_tutorial_mock_webpage.xml
new file mode 100644
index 0000000..ab00a11
--- /dev/null
+++ b/quickstep/res/layout/gesture_tutorial_mock_webpage.xml
@@ -0,0 +1,274 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<androidx.constraintlayout.widget.ConstraintLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:id="@+id/url_bar"
+        android:layout_width="match_parent"
+        android:layout_height="101dp"
+        android:background="@color/mock_webpage_url_bar"
+
+        app:layout_constraintTop_toTopOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintEnd_toEndOf="parent">
+
+        <androidx.cardview.widget.CardView
+            android:layout_width="0dp"
+            android:layout_height="0dp"
+            android:layout_marginTop="48dp"
+            android:layout_marginBottom="16dp"
+            android:layout_marginStart="16dp"
+            android:layout_marginEnd="16dp"
+
+            app:cardElevation="0dp"
+            app:cardCornerRadius="100dp"
+            app:cardBackgroundColor="@color/mock_webpage_url_bar_item"
+            app:layout_constraintTop_toTopOf="parent"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"/>
+
+    </androidx.constraintlayout.widget.ConstraintLayout>
+
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:id="@+id/top_bar"
+        android:layout_width="match_parent"
+        android:layout_height="88dp"
+        android:background="@color/mock_webpage_top_bar"
+
+        app:layout_constraintTop_toBottomOf="@id/url_bar"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintEnd_toEndOf="parent">
+
+        <androidx.cardview.widget.CardView
+            android:id="@+id/top_bar_button"
+            android:layout_width="0dp"
+            android:layout_height="0dp"
+            android:layout_marginTop="22dp"
+            android:layout_marginBottom="22dp"
+            android:layout_marginStart="24dp"
+            android:layout_marginEnd="344dp"
+
+            app:cardElevation="0dp"
+            app:cardCornerRadius="8dp"
+            app:cardBackgroundColor="@color/mock_webpage_top_bar_item"
+            app:layout_constraintDimensionRatio="1:1"
+            app:layout_constraintTop_toTopOf="parent"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"/>
+
+        <androidx.cardview.widget.CardView
+            android:layout_width="0dp"
+            android:layout_height="0dp"
+            android:layout_marginTop="28dp"
+            android:layout_marginBottom="28dp"
+            android:layout_marginStart="97dp"
+            android:layout_marginEnd="97dp"
+
+            app:cardElevation="0dp"
+            app:cardCornerRadius="2dp"
+            app:cardBackgroundColor="@color/mock_webpage_top_bar_item"
+            app:layout_constraintTop_toTopOf="parent"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"/>
+
+    </androidx.constraintlayout.widget.ConstraintLayout>
+
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:layout_width="match_parent"
+        android:layout_height="0dp"
+        android:background="@color/mock_webpage_background"
+        android:paddingTop="32dp"
+        android:paddingStart="24dp"
+        android:paddingBottom="50dp"
+
+        app:layout_constraintTop_toBottomOf="@id/top_bar"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintEnd_toEndOf="parent">
+
+        <androidx.cardview.widget.CardView
+            android:id="@+id/mock_line_1"
+            android:layout_width="0dp"
+            android:layout_height="36dp"
+            android:layout_marginEnd="126dp"
+
+            app:cardElevation="0dp"
+            app:cardCornerRadius="4dp"
+            app:cardBackgroundColor="@color/mock_webpage_page_text"
+            app:layout_constraintTop_toTopOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"/>
+
+        <androidx.cardview.widget.CardView
+            android:id="@+id/mock_line_2"
+            android:layout_width="0dp"
+            android:layout_height="36dp"
+            android:layout_marginTop="8dp"
+            android:layout_marginEnd="64dp"
+
+            app:cardElevation="0dp"
+            app:cardCornerRadius="4dp"
+            app:cardBackgroundColor="@color/mock_webpage_page_text"
+            app:layout_constraintTop_toBottomOf="@id/mock_line_1"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"/>
+
+        <androidx.cardview.widget.CardView
+            android:id="@+id/mock_line_3"
+            android:layout_width="0dp"
+            android:layout_height="36dp"
+            android:layout_marginTop="8dp"
+            android:layout_marginEnd="151dp"
+
+            app:cardElevation="0dp"
+            app:cardCornerRadius="4dp"
+            app:cardBackgroundColor="@color/mock_webpage_page_text"
+            app:layout_constraintTop_toBottomOf="@id/mock_line_2"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"/>
+
+        <androidx.cardview.widget.CardView
+            android:id="@+id/mock_button"
+            android:layout_width="47dp"
+            android:layout_height="12dp"
+            android:layout_marginTop="8dp"
+
+            app:cardElevation="0dp"
+            app:cardCornerRadius="4dp"
+            app:cardBackgroundColor="@color/mock_webpage_page_text"
+            app:layout_constraintTop_toBottomOf="@id/mock_line_3"
+            app:layout_constraintStart_toStartOf="parent"/>
+
+        <androidx.cardview.widget.CardView
+            android:layout_width="47dp"
+            android:layout_height="12dp"
+            android:background="@color/mock_webpage_page_text"
+            android:layout_marginStart="11dp"
+            android:layout_marginTop="8dp"
+
+            app:cardElevation="0dp"
+            app:cardCornerRadius="4dp"
+            app:cardBackgroundColor="@color/mock_webpage_page_text"
+            app:layout_constraintTop_toBottomOf="@id/mock_line_3"
+            app:layout_constraintStart_toEndOf="@id/mock_button"/>
+
+        <androidx.cardview.widget.CardView
+            android:id="@+id/mock_block"
+            android:layout_width="0dp"
+            android:layout_height="240dp"
+            android:layout_marginTop="24dp"
+            android:layout_marginEnd="24dp"
+
+            app:cardElevation="0dp"
+            app:cardCornerRadius="22dp"
+            app:cardBackgroundColor="@color/mock_webpage_page_text"
+            app:layout_constraintTop_toBottomOf="@id/mock_button"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"/>
+
+        <androidx.cardview.widget.CardView
+            android:id="@+id/mock_line_4"
+            android:layout_width="0dp"
+            android:layout_height="22dp"
+            android:layout_marginTop="24dp"
+            android:layout_marginEnd="52dp"
+
+            app:cardElevation="0dp"
+            app:cardCornerRadius="8dp"
+            app:cardBackgroundColor="@color/mock_webpage_page_text"
+            app:layout_constraintTop_toBottomOf="@id/mock_block"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"/>
+
+        <androidx.cardview.widget.CardView
+            android:id="@+id/mock_line_5"
+            android:layout_width="0dp"
+            android:layout_height="22dp"
+            android:layout_marginTop="8dp"
+            android:layout_marginEnd="41dp"
+
+            app:cardElevation="0dp"
+            app:cardCornerRadius="8dp"
+            app:cardBackgroundColor="@color/mock_webpage_page_text"
+            app:layout_constraintTop_toBottomOf="@id/mock_line_4"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"/>
+
+        <androidx.cardview.widget.CardView
+            android:id="@+id/mock_line_6"
+            android:layout_width="0dp"
+            android:layout_height="22dp"
+            android:layout_marginTop="8dp"
+            android:layout_marginEnd="71dp"
+
+            app:cardElevation="0dp"
+            app:cardCornerRadius="8dp"
+            app:cardBackgroundColor="@color/mock_webpage_page_text"
+            app:layout_constraintTop_toBottomOf="@id/mock_line_5"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"/>
+
+        <androidx.cardview.widget.CardView
+            android:id="@+id/mock_line_7"
+            android:layout_width="0dp"
+            android:layout_height="22dp"
+            android:layout_marginTop="8dp"
+            android:layout_marginEnd="198dp"
+
+            app:cardElevation="0dp"
+            app:cardCornerRadius="8dp"
+            app:cardBackgroundColor="@color/mock_webpage_page_text"
+            app:layout_constraintTop_toBottomOf="@id/mock_line_6"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"/>
+
+        <androidx.cardview.widget.CardView
+            android:id="@+id/mock_line_8"
+            android:layout_width="0dp"
+            android:layout_height="22dp"
+            android:layout_marginTop="24dp"
+            android:layout_marginEnd="64dp"
+
+            app:cardElevation="0dp"
+            app:cardCornerRadius="8dp"
+            app:cardBackgroundColor="@color/mock_webpage_page_text"
+            app:layout_constraintTop_toBottomOf="@id/mock_line_7"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"/>
+
+        <androidx.cardview.widget.CardView
+            android:layout_width="0dp"
+            android:layout_height="22dp"
+            android:layout_marginTop="8dp"
+            android:layout_marginEnd="71dp"
+
+            app:cardElevation="0dp"
+            app:cardCornerRadius="8dp"
+            app:cardBackgroundColor="@color/mock_webpage_page_text"
+            app:layout_constraintTop_toBottomOf="@id/mock_line_8"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"/>
+
+    </androidx.constraintlayout.widget.ConstraintLayout>
+
+</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
diff --git a/quickstep/res/layout/task_grouped.xml b/quickstep/res/layout/task_grouped.xml
new file mode 100644
index 0000000..069ff86
--- /dev/null
+++ b/quickstep/res/layout/task_grouped.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+     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.
+-->
+<!-- NOTE! don't add dimensions for margins / paddings / sizes that change per orientation to this
+     file, they need to be loaded at runtime. -->
+
+<!-- DOUBLE NOTE! Don't deviate IDs from task.xml since this layout acts as a "subclass" (read as
+     "bad code"). How can we use the view pool in RecentsView to use task.xml layout with using
+     GroupedTaskView.java class? Is that possible (while still keeping code in separate class) ? -->
+
+<com.android.quickstep.views.GroupedTaskView
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:clipChildren="false"
+    android:defaultFocusHighlightEnabled="false"
+    android:focusable="true">
+
+    <com.android.quickstep.views.TaskThumbnailView
+        android:id="@+id/snapshot"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"/>
+
+    <com.android.quickstep.views.TaskThumbnailView
+        android:id="@+id/bottomright_snapshot"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"/>
+
+    <com.android.quickstep.views.IconView
+        android:id="@+id/icon"
+        android:layout_width="@dimen/task_thumbnail_icon_size"
+        android:layout_height="@dimen/task_thumbnail_icon_size"
+        android:focusable="false"
+        android:importantForAccessibility="no"/>
+</com.android.quickstep.views.GroupedTaskView>
\ No newline at end of file
diff --git a/quickstep/res/layout/taskbar.xml b/quickstep/res/layout/taskbar.xml
index c0e0862..b4c168c 100644
--- a/quickstep/res/layout/taskbar.xml
+++ b/quickstep/res/layout/taskbar.xml
@@ -65,13 +65,12 @@
             android:layout_gravity="end"/>
     </FrameLayout>
 
-    <View
+    <com.android.launcher3.taskbar.StashedHandleView
         android:id="@+id/stashed_handle"
         tools:comment1="The actual size and shape will be set as a ViewOutlineProvider at runtime"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        tools:comment2="TODO: Tint dynamically"
-        android:background="?android:attr/textColorPrimary"
+        android:background="@color/taskbar_stashed_handle_dark_color"
         android:clipToOutline="true"
         android:layout_gravity="bottom"/>
 
diff --git a/quickstep/res/layout/taskbar_edu.xml b/quickstep/res/layout/taskbar_edu.xml
new file mode 100644
index 0000000..ef57a53
--- /dev/null
+++ b/quickstep/res/layout/taskbar_edu.xml
@@ -0,0 +1,158 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<com.android.launcher3.taskbar.TaskbarEduView xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:launcher="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:layout_gravity="bottom"
+    android:gravity="bottom"
+    android:orientation="vertical"
+    android:layout_marginHorizontal="108dp">
+
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:id="@+id/edu_view"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:background="@drawable/bg_rounded_corner_bottom_sheet"
+        android:gravity="center_horizontal"
+        android:paddingHorizontal="36dp"
+        android:paddingTop="64dp">
+
+        <com.android.launcher3.taskbar.TaskbarEduPagedView
+            android:id="@+id/content"
+            android:clipToPadding="false"
+            android:layout_width="match_parent"
+            android:layout_height="378dp"
+            app:layout_constraintTop_toTopOf="parent"
+            launcher:pageIndicator="@+id/content_page_indicator">
+
+            <LinearLayout
+                android:id="@+id/page_splitscreen"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:orientation="vertical"
+                android:gravity="center_horizontal">
+
+                <TextView
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:layout_marginHorizontal="16dp"
+                    android:gravity="center_horizontal"
+                    style="@style/TextHeadline"
+                    android:text="@string/taskbar_edu_splitscreen"
+                    android:fontFamily="google-sans"
+                    android:textColor="?android:attr/textColorPrimary"
+                    android:textSize="24sp"
+                    android:maxLines="2"/>
+
+                <ImageView
+                    android:layout_width="322dp"
+                    android:layout_height="282dp"
+                    android:layout_marginTop="16dp"
+                    android:src="@drawable/taskbar_edu_splitscreen"/>
+            </LinearLayout>
+
+            <LinearLayout
+                android:id="@+id/page_customize"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:orientation="vertical"
+                android:gravity="center_horizontal">
+
+                <TextView
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:layout_marginHorizontal="16dp"
+                    android:gravity="center_horizontal"
+                    style="@style/TextHeadline"
+                    android:text="@string/taskbar_edu_customize"
+                    android:fontFamily="google-sans"
+                    android:textColor="?android:attr/textColorPrimary"
+                    android:textSize="24sp"
+                    android:maxLines="2"/>
+
+                <ImageView
+                    android:layout_width="322dp"
+                    android:layout_height="282dp"
+                    android:layout_marginTop="16dp"
+                    android:src="@drawable/taskbar_edu_splitscreen"/>
+            </LinearLayout>
+
+            <LinearLayout
+                android:id="@+id/page_dock"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:orientation="vertical"
+                android:gravity="center_horizontal">
+
+                <TextView
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:layout_marginHorizontal="16dp"
+                    android:gravity="center_horizontal"
+                    style="@style/TextHeadline"
+                    android:text="@string/taskbar_edu_dock"
+                    android:fontFamily="google-sans"
+                    android:textColor="?android:attr/textColorPrimary"
+                    android:textSize="24sp"
+                    android:maxLines="2"/>
+
+                <ImageView
+                    android:layout_width="322dp"
+                    android:layout_height="282dp"
+                    android:layout_marginTop="16dp"
+                    android:src="@drawable/taskbar_edu_splitscreen"/>
+            </LinearLayout>
+        </com.android.launcher3.taskbar.TaskbarEduPagedView>
+
+        <Button
+            android:id="@+id/edu_start_button"
+            android:layout_width="wrap_content"
+            android:layout_height="36dp"
+            android:layout_marginBottom="92dp"
+            app:layout_constraintTop_toBottomOf="@id/content"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            android:text="@string/taskbar_edu_close"
+            style="@style/TaskbarEdu.Button.Close"
+            android:textColor="?android:attr/textColorPrimary"/>
+
+        <com.android.launcher3.pageindicators.PageIndicatorDots
+            android:id="@+id/content_page_indicator"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            app:layout_constraintTop_toTopOf="@id/edu_start_button"
+            app:layout_constraintBottom_toBottomOf="@id/edu_start_button"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            android:elevation="1dp" />
+
+        <Button
+            android:id="@+id/edu_end_button"
+            android:layout_width="wrap_content"
+            android:layout_height="36dp"
+            android:layout_marginBottom="92dp"
+            app:layout_constraintTop_toBottomOf="@id/content"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            android:text="@string/taskbar_edu_next"
+            style="@style/TaskbarEdu.Button.Next"
+            android:textColor="?androidprv:attr/textColorOnAccent"/>
+    </androidx.constraintlayout.widget.ConstraintLayout>
+</com.android.launcher3.taskbar.TaskbarEduView>
\ No newline at end of file
diff --git a/quickstep/res/values-af/strings.xml b/quickstep/res/values-af/strings.xml
index 433ef86..4a83a4b 100644
--- a/quickstep/res/values-af/strings.xml
+++ b/quickstep/res/values-af/strings.xml
@@ -84,4 +84,7 @@
     <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Jy kan dit later in die <xliff:g id="NAME">%1$s</xliff:g>-program kry"</string>
     <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Kanselleer"</string>
     <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Slaan oor"</string>
+    <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Gebruik 2 programme tegelyk en wissel programme met die taakbalk"</string>
+    <string name="taskbar_edu_next" msgid="4007618274426775841">"Volgende"</string>
+    <string name="taskbar_edu_close" msgid="887022990168191073">"Maak toe"</string>
 </resources>
diff --git a/quickstep/res/values-am/strings.xml b/quickstep/res/values-am/strings.xml
index 838dd60..4bb9c15 100644
--- a/quickstep/res/values-am/strings.xml
+++ b/quickstep/res/values-am/strings.xml
@@ -84,4 +84,7 @@
     <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"ይህን በኋላ በ<xliff:g id="NAME">%1$s</xliff:g> መተግበሪያው ውስጥ ማግኘት ይችላሉ"</string>
     <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"ይቅር"</string>
     <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"ዝለል"</string>
+    <string name="taskbar_edu_header_1" msgid="5323217563328273689">"በአንድ ጊዜ 2 መተግበሪያዎችን ይጠቀሙ እና በተግባር አሞሌው አማካኝነት መተግበሪያዎችን ይቀያይሩ"</string>
+    <string name="taskbar_edu_next" msgid="4007618274426775841">"ቀጣይ"</string>
+    <string name="taskbar_edu_close" msgid="887022990168191073">"ዝጋ"</string>
 </resources>
diff --git a/quickstep/res/values-ar/strings.xml b/quickstep/res/values-ar/strings.xml
index 3f26977..6557abb 100644
--- a/quickstep/res/values-ar/strings.xml
+++ b/quickstep/res/values-ar/strings.xml
@@ -84,4 +84,7 @@
     <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"يمكنك العثور على هذا الدليل التوجيهي لاحقًا في التطبيق \"<xliff:g id="NAME">%1$s</xliff:g>\""</string>
     <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"إلغاء"</string>
     <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"التخطي"</string>
+    <string name="taskbar_edu_header_1" msgid="5323217563328273689">"يمكنك استخدام تطبيقين في الوقت نفسه والتبديل بينهما من شريط المهام."</string>
+    <string name="taskbar_edu_next" msgid="4007618274426775841">"الشاشة التالية"</string>
+    <string name="taskbar_edu_close" msgid="887022990168191073">"إغلاق"</string>
 </resources>
diff --git a/quickstep/res/values-as/strings.xml b/quickstep/res/values-as/strings.xml
index 2551fc4..a506618 100644
--- a/quickstep/res/values-as/strings.xml
+++ b/quickstep/res/values-as/strings.xml
@@ -84,4 +84,7 @@
     <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"আপুনি এয়া পাছত <xliff:g id="NAME">%1$s</xliff:g> এপ্‌টোত বিচাৰিব পাৰিব"</string>
     <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"বাতিল কৰক"</string>
     <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"এৰি যাওক"</string>
+    <string name="taskbar_edu_header_1" msgid="5323217563328273689">"এবাৰতে ২ টা এপ্‌ ব্যৱহাৰ কৰক আৰু টাস্কবাৰ ব্যৱহাৰ কৰি এপ্‌ সলনি কৰক"</string>
+    <string name="taskbar_edu_next" msgid="4007618274426775841">"পৰৱৰ্তী"</string>
+    <string name="taskbar_edu_close" msgid="887022990168191073">"বন্ধ কৰক"</string>
 </resources>
diff --git a/quickstep/res/values-az/strings.xml b/quickstep/res/values-az/strings.xml
index d01bf3f..ba235f4 100644
--- a/quickstep/res/values-az/strings.xml
+++ b/quickstep/res/values-az/strings.xml
@@ -84,4 +84,7 @@
     <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Bunu sonra <xliff:g id="NAME">%1$s</xliff:g> tətbiqində tapa bilərsiniz"</string>
     <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Ləğv edin"</string>
     <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Ötürün"</string>
+    <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Eyni anda 2 tətbiqdən istifadə edin və tapşırıq paneli ilə tətbiqlər arasında keçid edin"</string>
+    <string name="taskbar_edu_next" msgid="4007618274426775841">"Sonra"</string>
+    <string name="taskbar_edu_close" msgid="887022990168191073">"Bağlayın"</string>
 </resources>
diff --git a/quickstep/res/values-b+sr+Latn/strings.xml b/quickstep/res/values-b+sr+Latn/strings.xml
index bde409f..5001491 100644
--- a/quickstep/res/values-b+sr+Latn/strings.xml
+++ b/quickstep/res/values-b+sr+Latn/strings.xml
@@ -84,4 +84,7 @@
     <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Možete da pronađete ovo kasnije u aplikaciji <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Otkaži"</string>
     <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Preskoči"</string>
+    <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Koristite 2 aplikacije odjednom i menjajte aplikacije pomoću trake zadataka"</string>
+    <string name="taskbar_edu_next" msgid="4007618274426775841">"Dalje"</string>
+    <string name="taskbar_edu_close" msgid="887022990168191073">"Zatvori"</string>
 </resources>
diff --git a/quickstep/res/values-be/strings.xml b/quickstep/res/values-be/strings.xml
index 8e57bd8..1662423 100644
--- a/quickstep/res/values-be/strings.xml
+++ b/quickstep/res/values-be/strings.xml
@@ -84,4 +84,7 @@
     <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Знайсці дапаможнік можна ў праграме \"<xliff:g id="NAME">%1$s</xliff:g>\""</string>
     <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Скасаваць"</string>
     <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Прапусціць"</string>
+    <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Адначасова выкарыстоўвайце 2 праграмы і пераключайцеся паміж імі на панэлі задач"</string>
+    <string name="taskbar_edu_next" msgid="4007618274426775841">"Далей"</string>
+    <string name="taskbar_edu_close" msgid="887022990168191073">"Закрыць"</string>
 </resources>
diff --git a/quickstep/res/values-bg/strings.xml b/quickstep/res/values-bg/strings.xml
index 7305d9d..7712020 100644
--- a/quickstep/res/values-bg/strings.xml
+++ b/quickstep/res/values-bg/strings.xml
@@ -84,4 +84,7 @@
     <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Урокът е налице в приложението <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Отказ"</string>
     <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Пропускане"</string>
+    <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Използвайте две приложения едновременно и превключвайте между приложенията посредством лентата на задачите"</string>
+    <string name="taskbar_edu_next" msgid="4007618274426775841">"Напред"</string>
+    <string name="taskbar_edu_close" msgid="887022990168191073">"Затваряне"</string>
 </resources>
diff --git a/quickstep/res/values-bn/strings.xml b/quickstep/res/values-bn/strings.xml
index 1d0b45f..83f6656 100644
--- a/quickstep/res/values-bn/strings.xml
+++ b/quickstep/res/values-bn/strings.xml
@@ -84,4 +84,10 @@
     <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"আপনি <xliff:g id="NAME">%1$s</xliff:g> অ্যাপে পরে এটি খুঁজে পাবেন"</string>
     <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"বাতিল করুন"</string>
     <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"এড়িয়ে যান"</string>
+    <!-- no translation found for taskbar_edu_header_1 (5323217563328273689) -->
+    <skip />
+    <!-- no translation found for taskbar_edu_next (4007618274426775841) -->
+    <skip />
+    <!-- no translation found for taskbar_edu_close (887022990168191073) -->
+    <skip />
 </resources>
diff --git a/quickstep/res/values-bs/strings.xml b/quickstep/res/values-bs/strings.xml
index acd7b10..eba8275 100644
--- a/quickstep/res/values-bs/strings.xml
+++ b/quickstep/res/values-bs/strings.xml
@@ -84,4 +84,7 @@
     <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"To možete pronaći kasnije u aplikaciji <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Otkaži"</string>
     <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Preskoči"</string>
+    <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Koristite 2 aplikacije odjednom i prebacujte između aplikacija putem programske trake"</string>
+    <string name="taskbar_edu_next" msgid="4007618274426775841">"Naprijed"</string>
+    <string name="taskbar_edu_close" msgid="887022990168191073">"Zatvori"</string>
 </resources>
diff --git a/quickstep/res/values-ca/strings.xml b/quickstep/res/values-ca/strings.xml
index a0d6aee..62d1ed0 100644
--- a/quickstep/res/values-ca/strings.xml
+++ b/quickstep/res/values-ca/strings.xml
@@ -84,4 +84,7 @@
     <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Pots trobar-lo més tard a l\'aplicació <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Cancel·la"</string>
     <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Omet"</string>
+    <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Utilitza 2 aplicacions alhora i canvia d\'aplicació amb la barra de tasques"</string>
+    <string name="taskbar_edu_next" msgid="4007618274426775841">"Següent"</string>
+    <string name="taskbar_edu_close" msgid="887022990168191073">"Tanca"</string>
 </resources>
diff --git a/quickstep/res/values-cs/strings.xml b/quickstep/res/values-cs/strings.xml
index b2d092e..c4e632c 100644
--- a/quickstep/res/values-cs/strings.xml
+++ b/quickstep/res/values-cs/strings.xml
@@ -84,4 +84,7 @@
     <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Program později najdete v aplikaci <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Zrušit"</string>
     <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Přeskočit"</string>
+    <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Používejte 2 aplikace naráz a přepínejte mezi aplikacemi pomocí hlavního panelu"</string>
+    <string name="taskbar_edu_next" msgid="4007618274426775841">"Další"</string>
+    <string name="taskbar_edu_close" msgid="887022990168191073">"Zavřít"</string>
 </resources>
diff --git a/quickstep/res/values-da/strings.xml b/quickstep/res/values-da/strings.xml
index f2e2df0..ed63f40 100644
--- a/quickstep/res/values-da/strings.xml
+++ b/quickstep/res/values-da/strings.xml
@@ -84,4 +84,7 @@
     <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Du kan finde dette senere i appen <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Annuller"</string>
     <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Spring over"</string>
+    <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Brug to apps på samme tid, og skift mellem dem via proceslinjen"</string>
+    <string name="taskbar_edu_next" msgid="4007618274426775841">"Næste"</string>
+    <string name="taskbar_edu_close" msgid="887022990168191073">"Luk"</string>
 </resources>
diff --git a/quickstep/res/values-de/strings.xml b/quickstep/res/values-de/strings.xml
index 4a023e3..0ff759e 100644
--- a/quickstep/res/values-de/strings.xml
+++ b/quickstep/res/values-de/strings.xml
@@ -84,4 +84,7 @@
     <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Du findest es später auch in der <xliff:g id="NAME">%1$s</xliff:g> App"</string>
     <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Abbrechen"</string>
     <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Überspringen"</string>
+    <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Du kannst 2 Apps auf einmal verwenden und über die Taskleiste zwischen ihnen wechseln"</string>
+    <string name="taskbar_edu_next" msgid="4007618274426775841">"Weiter"</string>
+    <string name="taskbar_edu_close" msgid="887022990168191073">"Schließen"</string>
 </resources>
diff --git a/quickstep/res/values-el/strings.xml b/quickstep/res/values-el/strings.xml
index 7243e03..1c5e24a 100644
--- a/quickstep/res/values-el/strings.xml
+++ b/quickstep/res/values-el/strings.xml
@@ -84,4 +84,7 @@
     <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Βρείτε τον αργότερα στην εφαρμογή <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Ακύρωση"</string>
     <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Παράβλεψη"</string>
+    <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Χρησιμοποιήστε 2 εφαρμογές ταυτόχρονα και κάντε εναλλαγή εφαρμογών με τη γραμμή εργασιών"</string>
+    <string name="taskbar_edu_next" msgid="4007618274426775841">"Επόμενο"</string>
+    <string name="taskbar_edu_close" msgid="887022990168191073">"Κλείσιμο"</string>
 </resources>
diff --git a/quickstep/res/values-en-rAU/strings.xml b/quickstep/res/values-en-rAU/strings.xml
index 7b42aac..c045bcd 100644
--- a/quickstep/res/values-en-rAU/strings.xml
+++ b/quickstep/res/values-en-rAU/strings.xml
@@ -84,4 +84,7 @@
     <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"You can find this later in the <xliff:g id="NAME">%1$s</xliff:g> app"</string>
     <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Cancel"</string>
     <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Skip"</string>
+    <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Use two apps at once and switch apps with the taskbar"</string>
+    <string name="taskbar_edu_next" msgid="4007618274426775841">"Next"</string>
+    <string name="taskbar_edu_close" msgid="887022990168191073">"Close"</string>
 </resources>
diff --git a/quickstep/res/values-en-rCA/strings.xml b/quickstep/res/values-en-rCA/strings.xml
index 7b42aac..c045bcd 100644
--- a/quickstep/res/values-en-rCA/strings.xml
+++ b/quickstep/res/values-en-rCA/strings.xml
@@ -84,4 +84,7 @@
     <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"You can find this later in the <xliff:g id="NAME">%1$s</xliff:g> app"</string>
     <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Cancel"</string>
     <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Skip"</string>
+    <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Use two apps at once and switch apps with the taskbar"</string>
+    <string name="taskbar_edu_next" msgid="4007618274426775841">"Next"</string>
+    <string name="taskbar_edu_close" msgid="887022990168191073">"Close"</string>
 </resources>
diff --git a/quickstep/res/values-en-rGB/strings.xml b/quickstep/res/values-en-rGB/strings.xml
index 7b42aac..c045bcd 100644
--- a/quickstep/res/values-en-rGB/strings.xml
+++ b/quickstep/res/values-en-rGB/strings.xml
@@ -84,4 +84,7 @@
     <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"You can find this later in the <xliff:g id="NAME">%1$s</xliff:g> app"</string>
     <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Cancel"</string>
     <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Skip"</string>
+    <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Use two apps at once and switch apps with the taskbar"</string>
+    <string name="taskbar_edu_next" msgid="4007618274426775841">"Next"</string>
+    <string name="taskbar_edu_close" msgid="887022990168191073">"Close"</string>
 </resources>
diff --git a/quickstep/res/values-en-rIN/strings.xml b/quickstep/res/values-en-rIN/strings.xml
index 7b42aac..c045bcd 100644
--- a/quickstep/res/values-en-rIN/strings.xml
+++ b/quickstep/res/values-en-rIN/strings.xml
@@ -84,4 +84,7 @@
     <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"You can find this later in the <xliff:g id="NAME">%1$s</xliff:g> app"</string>
     <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Cancel"</string>
     <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Skip"</string>
+    <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Use two apps at once and switch apps with the taskbar"</string>
+    <string name="taskbar_edu_next" msgid="4007618274426775841">"Next"</string>
+    <string name="taskbar_edu_close" msgid="887022990168191073">"Close"</string>
 </resources>
diff --git a/quickstep/res/values-en-rXC/strings.xml b/quickstep/res/values-en-rXC/strings.xml
index 35ec6bb..1550285 100644
--- a/quickstep/res/values-en-rXC/strings.xml
+++ b/quickstep/res/values-en-rXC/strings.xml
@@ -84,4 +84,7 @@
     <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‎‏‏‏‏‏‏‎‎‎‏‏‎‎‏‏‏‎‎‏‏‎‏‎‏‏‎‏‏‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‎‎‎‎‎‏‏‏‏‏‎‏‎‎‏‏‏‎‎You can find this later in the ‎‏‎‎‏‏‎<xliff:g id="NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ app‎‏‎‎‏‎"</string>
     <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‏‎‏‎‎‏‏‎‏‏‏‏‏‎‏‎‎‎‏‏‏‏‎‏‎‎‎‎‏‏‎‏‎‎‏‎‎‎‏‎‏‎‏‏‏‏‏‏‏‎‏‏‏‎‏‏‎‏‏‎‎‎Cancel‎‏‎‎‏‎"</string>
     <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‎‏‏‏‎‏‎‏‏‏‏‎‎‏‎‏‏‎‎‎‎‎‏‎‏‏‎‎‏‏‎‎‏‎‏‎‎‏‏‏‏‎‎‎‏‎‏‎‎‎‎‎‏‎‏‎‎‏‏‎‎‎‎Skip‎‏‎‎‏‎"</string>
+    <string name="taskbar_edu_header_1" msgid="5323217563328273689">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‎‏‎‎‏‏‏‎‏‏‏‏‏‏‏‎‏‏‏‏‎‎‎‏‎‏‎‏‏‏‎‎‏‎‏‎‎‎‏‎‎‏‏‎‏‎‏‎‏‏‏‎‏‎‎‎‏‏‎‎‏‎Use 2 apps at once and switch apps with the taskbar‎‏‎‎‏‎"</string>
+    <string name="taskbar_edu_next" msgid="4007618274426775841">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‏‎‏‏‏‏‎‎‏‏‏‎‏‏‏‏‎‏‎‏‏‏‎‎‏‎‏‏‎‎‏‎‏‏‎‏‎‏‎‎‏‎‎‏‎‎‏‏‎‏‎‎‏‎‎‏‎‎‎‎‏‎Next‎‏‎‎‏‎"</string>
+    <string name="taskbar_edu_close" msgid="887022990168191073">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‎‎‏‏‎‎‎‏‎‎‏‏‏‏‎‏‎‏‎‏‏‎‏‎‏‏‎‏‎‏‏‎‏‏‏‏‎‎‏‎‎‏‎‏‎‎‎‏‏‏‎‎‎‎‎‏‏‎‎‎‎‏‎Close‎‏‎‎‏‎"</string>
 </resources>
diff --git a/quickstep/res/values-es-rUS/strings.xml b/quickstep/res/values-es-rUS/strings.xml
index e61fd91..02f6ea6 100644
--- a/quickstep/res/values-es-rUS/strings.xml
+++ b/quickstep/res/values-es-rUS/strings.xml
@@ -84,4 +84,7 @@
     <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Puedes encontrarlo en la app de <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Cancelar"</string>
     <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Omitir"</string>
+    <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Usa 2 apps a la vez e intercámbialas con la barra de tareas"</string>
+    <string name="taskbar_edu_next" msgid="4007618274426775841">"Siguiente"</string>
+    <string name="taskbar_edu_close" msgid="887022990168191073">"Cerrar"</string>
 </resources>
diff --git a/quickstep/res/values-es/strings.xml b/quickstep/res/values-es/strings.xml
index 8e8829e..b4fee8b 100644
--- a/quickstep/res/values-es/strings.xml
+++ b/quickstep/res/values-es/strings.xml
@@ -84,4 +84,7 @@
     <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Puedes consultarlo en otro momento en la aplicación <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Cancelar"</string>
     <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Saltar"</string>
+    <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Usa dos aplicaciones a la vez y cambia de aplicación con la barra de tareas"</string>
+    <string name="taskbar_edu_next" msgid="4007618274426775841">"Siguiente"</string>
+    <string name="taskbar_edu_close" msgid="887022990168191073">"Cerrar"</string>
 </resources>
diff --git a/quickstep/res/values-et/strings.xml b/quickstep/res/values-et/strings.xml
index 74b7528..9f8737c 100644
--- a/quickstep/res/values-et/strings.xml
+++ b/quickstep/res/values-et/strings.xml
@@ -84,4 +84,7 @@
     <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Leiate selle hiljem rakendusest <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Tühista"</string>
     <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Jäta vahele"</string>
+    <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Tegumiribal kahe rakenduse korraga kasutamine ja rakenduste vahel vahetamine"</string>
+    <string name="taskbar_edu_next" msgid="4007618274426775841">"Järgmine"</string>
+    <string name="taskbar_edu_close" msgid="887022990168191073">"Sule"</string>
 </resources>
diff --git a/quickstep/res/values-eu/strings.xml b/quickstep/res/values-eu/strings.xml
index bd016e9..e4186a4 100644
--- a/quickstep/res/values-eu/strings.xml
+++ b/quickstep/res/values-eu/strings.xml
@@ -84,4 +84,7 @@
     <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"<xliff:g id="NAME">%1$s</xliff:g> aplikazioan dago eskuragarri tutoriala"</string>
     <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Utzi"</string>
     <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Saltatu"</string>
+    <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Erabili bi aplikazio aldi berean eta aldatu aplikazioz zereginen barra erabilita"</string>
+    <string name="taskbar_edu_next" msgid="4007618274426775841">"Hurrengoa"</string>
+    <string name="taskbar_edu_close" msgid="887022990168191073">"Itxi"</string>
 </resources>
diff --git a/quickstep/res/values-fa/strings.xml b/quickstep/res/values-fa/strings.xml
index ae260ed..0a27952 100644
--- a/quickstep/res/values-fa/strings.xml
+++ b/quickstep/res/values-fa/strings.xml
@@ -84,4 +84,7 @@
     <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"می‌توانید آن را بعداً در برنامه <xliff:g id="NAME">%1$s</xliff:g> پیدا کنید"</string>
     <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"لغو"</string>
     <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"رد شدن"</string>
+    <string name="taskbar_edu_header_1" msgid="5323217563328273689">"هم‌زمان از ۲ برنامه استفاده کنید و ازطریق نوار وظیفه بین برنامه‌ها جابه‌جا شوید"</string>
+    <string name="taskbar_edu_next" msgid="4007618274426775841">"بعدی"</string>
+    <string name="taskbar_edu_close" msgid="887022990168191073">"بستن"</string>
 </resources>
diff --git a/quickstep/res/values-fi/strings.xml b/quickstep/res/values-fi/strings.xml
index 8762feb..fc19646 100644
--- a/quickstep/res/values-fi/strings.xml
+++ b/quickstep/res/values-fi/strings.xml
@@ -84,4 +84,7 @@
     <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Löydät tämän myöhemmin sovelluksesta: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Peru"</string>
     <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Ohita"</string>
+    <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Voit käyttää kahta sovellusta samaan aikaan ja vaihtaa sovelluksesta toiseen tehtäväpalkin kautta"</string>
+    <string name="taskbar_edu_next" msgid="4007618274426775841">"Seuraava"</string>
+    <string name="taskbar_edu_close" msgid="887022990168191073">"Sulje"</string>
 </resources>
diff --git a/quickstep/res/values-fr-rCA/strings.xml b/quickstep/res/values-fr-rCA/strings.xml
index a3c9393..cb1eff6 100644
--- a/quickstep/res/values-fr-rCA/strings.xml
+++ b/quickstep/res/values-fr-rCA/strings.xml
@@ -84,4 +84,10 @@
     <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Vous trouverez le tutoriel dans l\'application <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Annuler"</string>
     <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Ignorer"</string>
+    <!-- no translation found for taskbar_edu_header_1 (5323217563328273689) -->
+    <skip />
+    <!-- no translation found for taskbar_edu_next (4007618274426775841) -->
+    <skip />
+    <!-- no translation found for taskbar_edu_close (887022990168191073) -->
+    <skip />
 </resources>
diff --git a/quickstep/res/values-fr/strings.xml b/quickstep/res/values-fr/strings.xml
index 5164792..67106b8 100644
--- a/quickstep/res/values-fr/strings.xml
+++ b/quickstep/res/values-fr/strings.xml
@@ -84,4 +84,7 @@
     <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Vous le retrouverez dans l\'appli <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Annuler"</string>
     <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Passer"</string>
+    <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Utilisez deux applis à la fois et changez d\'appli avec la barre des tâches"</string>
+    <string name="taskbar_edu_next" msgid="4007618274426775841">"Suivant"</string>
+    <string name="taskbar_edu_close" msgid="887022990168191073">"Fermer"</string>
 </resources>
diff --git a/quickstep/res/values-gl/strings.xml b/quickstep/res/values-gl/strings.xml
index baa87e7..8600412 100644
--- a/quickstep/res/values-gl/strings.xml
+++ b/quickstep/res/values-gl/strings.xml
@@ -84,4 +84,7 @@
     <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Podes atopar isto máis tarde na aplicación <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Cancelar"</string>
     <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Omitir"</string>
+    <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Usa dúas aplicacións á vez e alterna unha coa outra mediante a barra de ferramentas"</string>
+    <string name="taskbar_edu_next" msgid="4007618274426775841">"Seguinte"</string>
+    <string name="taskbar_edu_close" msgid="887022990168191073">"Pechar"</string>
 </resources>
diff --git a/quickstep/res/values-gu/strings.xml b/quickstep/res/values-gu/strings.xml
index 33e8617..cf5e464 100644
--- a/quickstep/res/values-gu/strings.xml
+++ b/quickstep/res/values-gu/strings.xml
@@ -84,4 +84,10 @@
     <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"તમે આને પછીથી <xliff:g id="NAME">%1$s</xliff:g> ઍપમાં જોઈ શકો છો"</string>
     <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"રદ કરો"</string>
     <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"છોડો"</string>
+    <!-- no translation found for taskbar_edu_header_1 (5323217563328273689) -->
+    <skip />
+    <!-- no translation found for taskbar_edu_next (4007618274426775841) -->
+    <skip />
+    <!-- no translation found for taskbar_edu_close (887022990168191073) -->
+    <skip />
 </resources>
diff --git a/quickstep/res/values-hi/strings.xml b/quickstep/res/values-hi/strings.xml
index 50ebb27..2c7a5ac 100644
--- a/quickstep/res/values-hi/strings.xml
+++ b/quickstep/res/values-hi/strings.xml
@@ -84,4 +84,7 @@
     <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"आप बाद में <xliff:g id="NAME">%1$s</xliff:g> ऐप्लिकेशन पर इसे देख सकते हैं"</string>
     <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"अभी नहीं"</string>
     <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"अभी नहीं"</string>
+    <string name="taskbar_edu_header_1" msgid="5323217563328273689">"एक साथ दो ऐप्लिकेशन इस्तेमाल करें और टास्कबार से एक से दूसरे ऐप्लिकेशन पर जाएं"</string>
+    <string name="taskbar_edu_next" msgid="4007618274426775841">"आगे बढ़ें"</string>
+    <string name="taskbar_edu_close" msgid="887022990168191073">"बंद करें"</string>
 </resources>
diff --git a/quickstep/res/values-hr/strings.xml b/quickstep/res/values-hr/strings.xml
index 50efb74..b8d4e4f 100644
--- a/quickstep/res/values-hr/strings.xml
+++ b/quickstep/res/values-hr/strings.xml
@@ -84,4 +84,7 @@
     <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Kasnije ga možete pronaći u aplikaciji <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Odustani"</string>
     <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Preskoči"</string>
+    <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Upotrebljavajte dvije aplikacije odjednom i prebacujte se između aplikacija i programske trake"</string>
+    <string name="taskbar_edu_next" msgid="4007618274426775841">"Dalje"</string>
+    <string name="taskbar_edu_close" msgid="887022990168191073">"Zatvori"</string>
 </resources>
diff --git a/quickstep/res/values-hu/strings.xml b/quickstep/res/values-hu/strings.xml
index e9bd2bf..429b364 100644
--- a/quickstep/res/values-hu/strings.xml
+++ b/quickstep/res/values-hu/strings.xml
@@ -84,4 +84,7 @@
     <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Ezt később megtalálhatja a(z) <xliff:g id="NAME">%1$s</xliff:g> alkalmazásban"</string>
     <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Mégse"</string>
     <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Kihagyás"</string>
+    <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Két alkalmazást használhat egyszerre, és az eszköztárral válthat az alkalmazások között"</string>
+    <string name="taskbar_edu_next" msgid="4007618274426775841">"Tovább"</string>
+    <string name="taskbar_edu_close" msgid="887022990168191073">"Bezárás"</string>
 </resources>
diff --git a/quickstep/res/values-hy/strings.xml b/quickstep/res/values-hy/strings.xml
index e2c0af3..0a18ae9 100644
--- a/quickstep/res/values-hy/strings.xml
+++ b/quickstep/res/values-hy/strings.xml
@@ -84,4 +84,7 @@
     <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Հետագայում սա կարող եք գտնել «<xliff:g id="NAME">%1$s</xliff:g>» հավելվածում"</string>
     <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Չեղարկել"</string>
     <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Բաց թողնել"</string>
+    <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Միաժամանակ օգտագործեք 2 հավելված և խնդրագոտու միջոցով անցեք մեկից մյուսը։"</string>
+    <string name="taskbar_edu_next" msgid="4007618274426775841">"Առաջ"</string>
+    <string name="taskbar_edu_close" msgid="887022990168191073">"Փակել"</string>
 </resources>
diff --git a/quickstep/res/values-in/strings.xml b/quickstep/res/values-in/strings.xml
index 3e24fcb..8ef7355 100644
--- a/quickstep/res/values-in/strings.xml
+++ b/quickstep/res/values-in/strings.xml
@@ -84,4 +84,7 @@
     <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Anda dapat menemukan tutorial ini di lain waktu di aplikasi <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Batal"</string>
     <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Lewati"</string>
+    <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Gunakan 2 aplikasi sekaligus dan beralihlah antar-aplikasi dengan taskbar"</string>
+    <string name="taskbar_edu_next" msgid="4007618274426775841">"Berikutnya"</string>
+    <string name="taskbar_edu_close" msgid="887022990168191073">"Tutup"</string>
 </resources>
diff --git a/quickstep/res/values-is/strings.xml b/quickstep/res/values-is/strings.xml
index eeebc71..5bcc545 100644
--- a/quickstep/res/values-is/strings.xml
+++ b/quickstep/res/values-is/strings.xml
@@ -84,4 +84,7 @@
     <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Þú getur fundið þetta síðar í forritinu <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Hætta við"</string>
     <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Sleppa"</string>
+    <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Notaðu 2 forrit í einu og skiptu á milli forrita á verkefnastikunni"</string>
+    <string name="taskbar_edu_next" msgid="4007618274426775841">"Áfram"</string>
+    <string name="taskbar_edu_close" msgid="887022990168191073">"Loka"</string>
 </resources>
diff --git a/quickstep/res/values-it/strings.xml b/quickstep/res/values-it/strings.xml
index 5a33a38..5633381 100644
--- a/quickstep/res/values-it/strings.xml
+++ b/quickstep/res/values-it/strings.xml
@@ -84,4 +84,7 @@
     <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Puoi trovarlo in un secondo momento nell\'app <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Annulla"</string>
     <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Salta"</string>
+    <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Usa 2 app contemporaneamente e passa dall\'una all\'altra tramite la barra delle applicazioni"</string>
+    <string name="taskbar_edu_next" msgid="4007618274426775841">"Avanti"</string>
+    <string name="taskbar_edu_close" msgid="887022990168191073">"Chiudi"</string>
 </resources>
diff --git a/quickstep/res/values-iw/strings.xml b/quickstep/res/values-iw/strings.xml
index 2677690..e687d88 100644
--- a/quickstep/res/values-iw/strings.xml
+++ b/quickstep/res/values-iw/strings.xml
@@ -84,4 +84,10 @@
     <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"ניתן למצוא את המדריך מאוחר יותר באפליקציה <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"ביטול"</string>
     <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"דילוג"</string>
+    <!-- no translation found for taskbar_edu_header_1 (5323217563328273689) -->
+    <skip />
+    <!-- no translation found for taskbar_edu_next (4007618274426775841) -->
+    <skip />
+    <!-- no translation found for taskbar_edu_close (887022990168191073) -->
+    <skip />
 </resources>
diff --git a/quickstep/res/values-ja/strings.xml b/quickstep/res/values-ja/strings.xml
index 9c2adef..a0b25a9 100644
--- a/quickstep/res/values-ja/strings.xml
+++ b/quickstep/res/values-ja/strings.xml
@@ -84,4 +84,7 @@
     <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"チュートリアルは後から <xliff:g id="NAME">%1$s</xliff:g> アプリで確認できます"</string>
     <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"キャンセル"</string>
     <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"スキップ"</string>
+    <string name="taskbar_edu_header_1" msgid="5323217563328273689">"2 つのアプリを同時に使用し、タスクバーでアプリを切り替えます"</string>
+    <string name="taskbar_edu_next" msgid="4007618274426775841">"次へ"</string>
+    <string name="taskbar_edu_close" msgid="887022990168191073">"閉じる"</string>
 </resources>
diff --git a/quickstep/res/values-ka/strings.xml b/quickstep/res/values-ka/strings.xml
index ab3715a..fec33cf 100644
--- a/quickstep/res/values-ka/strings.xml
+++ b/quickstep/res/values-ka/strings.xml
@@ -84,4 +84,7 @@
     <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"ამის მოგვიანებით პოვნა <xliff:g id="NAME">%1$s</xliff:g> აპში შეგიძლიათ"</string>
     <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"გაუქმება"</string>
     <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"გამოტოვება"</string>
+    <string name="taskbar_edu_header_1" msgid="5323217563328273689">"გამოიყენეთ ერთდროულად 2 აპი და გადართეთ აპები ამოცანების ზოლის მეშვეობით"</string>
+    <string name="taskbar_edu_next" msgid="4007618274426775841">"შემდეგი"</string>
+    <string name="taskbar_edu_close" msgid="887022990168191073">"დახურვა"</string>
 </resources>
diff --git a/quickstep/res/values-kk/strings.xml b/quickstep/res/values-kk/strings.xml
index d762bd8..dd337fc 100644
--- a/quickstep/res/values-kk/strings.xml
+++ b/quickstep/res/values-kk/strings.xml
@@ -84,4 +84,7 @@
     <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Мұны кейін <xliff:g id="NAME">%1$s</xliff:g> қолданбасынан таба аласыз."</string>
     <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Бас тарту"</string>
     <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Өткізіп жіберу"</string>
+    <string name="taskbar_edu_header_1" msgid="5323217563328273689">"2 қолданбаны қатар қолданыңыз және оларды тапсырмалар тақтасы арқылы ауыстырыңыз."</string>
+    <string name="taskbar_edu_next" msgid="4007618274426775841">"Келесі"</string>
+    <string name="taskbar_edu_close" msgid="887022990168191073">"Жабу"</string>
 </resources>
diff --git a/quickstep/res/values-km/strings.xml b/quickstep/res/values-km/strings.xml
index 2700b83..9f90d06 100644
--- a/quickstep/res/values-km/strings.xml
+++ b/quickstep/res/values-km/strings.xml
@@ -84,4 +84,7 @@
     <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"អ្នកអាចស្វែងរកមេរៀននេះនៅពេលក្រោយក្នុងកម្មវិធី <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"បោះបង់"</string>
     <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"រំលង"</string>
+    <string name="taskbar_edu_header_1" msgid="5323217563328273689">"ប្រើ​កម្មវិធី 2 ក្នុងពេលតែមួយ ហើយប្ដូរ​កម្មវិធី​ដោយប្រើ​របារ​កិច្ចការ"</string>
+    <string name="taskbar_edu_next" msgid="4007618274426775841">"បន្ទាប់"</string>
+    <string name="taskbar_edu_close" msgid="887022990168191073">"បិទ"</string>
 </resources>
diff --git a/quickstep/res/values-kn/strings.xml b/quickstep/res/values-kn/strings.xml
index 9b981c2..1a83864 100644
--- a/quickstep/res/values-kn/strings.xml
+++ b/quickstep/res/values-kn/strings.xml
@@ -84,4 +84,10 @@
     <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"<xliff:g id="NAME">%1$s</xliff:g> ಆ್ಯಪ್‌ನಲ್ಲಿ ಇದನ್ನು ನಂತರ ಕಾಣಬಹುದು"</string>
     <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"ರದ್ದುಮಾಡಿ"</string>
     <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"ಸ್ಕಿಪ್ ಮಾಡಿ"</string>
+    <!-- no translation found for taskbar_edu_header_1 (5323217563328273689) -->
+    <skip />
+    <!-- no translation found for taskbar_edu_next (4007618274426775841) -->
+    <skip />
+    <!-- no translation found for taskbar_edu_close (887022990168191073) -->
+    <skip />
 </resources>
diff --git a/quickstep/res/values-ko/strings.xml b/quickstep/res/values-ko/strings.xml
index ba564a7..e5341f4 100644
--- a/quickstep/res/values-ko/strings.xml
+++ b/quickstep/res/values-ko/strings.xml
@@ -84,4 +84,7 @@
     <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"이 튜토리얼은 <xliff:g id="NAME">%1$s</xliff:g> 앱에서 다시 볼 수 있습니다"</string>
     <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"취소"</string>
     <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"건너뛰기"</string>
+    <string name="taskbar_edu_header_1" msgid="5323217563328273689">"작업 표시줄을 통해 앱 2개를 동시에 사용하고 앱 간에 전환"</string>
+    <string name="taskbar_edu_next" msgid="4007618274426775841">"다음"</string>
+    <string name="taskbar_edu_close" msgid="887022990168191073">"닫기"</string>
 </resources>
diff --git a/quickstep/res/values-ky/strings.xml b/quickstep/res/values-ky/strings.xml
index 8be5c53..b2e2ec2 100644
--- a/quickstep/res/values-ky/strings.xml
+++ b/quickstep/res/values-ky/strings.xml
@@ -84,4 +84,7 @@
     <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Аны кийин <xliff:g id="NAME">%1$s</xliff:g> колдонмосунан табасыз"</string>
     <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Жокко чыгаруу"</string>
     <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Өткрп жиберүү"</string>
+    <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Бир убакта 2 колдонмону пайдаланып, колдонмолорду тапшырмалар тактасы аркылуу которуштуруу"</string>
+    <string name="taskbar_edu_next" msgid="4007618274426775841">"Кийинки"</string>
+    <string name="taskbar_edu_close" msgid="887022990168191073">"Жабуу"</string>
 </resources>
diff --git a/quickstep/res/values-lo/strings.xml b/quickstep/res/values-lo/strings.xml
index 915578b..699cafa 100644
--- a/quickstep/res/values-lo/strings.xml
+++ b/quickstep/res/values-lo/strings.xml
@@ -84,4 +84,7 @@
     <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"ທ່ານສາມາດຊອກສ່ວນນີ້ພາຍຫຼັງໄດ້ໃນແອັບ <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"ຍົກເລີກ"</string>
     <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"ຂ້າມ"</string>
+    <string name="taskbar_edu_header_1" msgid="5323217563328273689">"ໃຊ້ 2 ແອັບພ້ອມກັບ ແລະ ສະຫຼັບແອັບດ້ວຍແຖບໜ້າວຽກ"</string>
+    <string name="taskbar_edu_next" msgid="4007618274426775841">"ຕໍ່ໄປ"</string>
+    <string name="taskbar_edu_close" msgid="887022990168191073">"ປິດ"</string>
 </resources>
diff --git a/quickstep/res/values-lt/strings.xml b/quickstep/res/values-lt/strings.xml
index b0c679c..f8c7bc7 100644
--- a/quickstep/res/values-lt/strings.xml
+++ b/quickstep/res/values-lt/strings.xml
@@ -84,4 +84,7 @@
     <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Tai galėsite rasti vėliau programoje „<xliff:g id="NAME">%1$s</xliff:g>“"</string>
     <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Atšaukti"</string>
     <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Praleisti"</string>
+    <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Užduočių juostoje vienu metu naudokite dvi programas ir jas perjunkite"</string>
+    <string name="taskbar_edu_next" msgid="4007618274426775841">"Kitas"</string>
+    <string name="taskbar_edu_close" msgid="887022990168191073">"Uždaryti"</string>
 </resources>
diff --git a/quickstep/res/values-lv/strings.xml b/quickstep/res/values-lv/strings.xml
index df1c3e9..0e44d77 100644
--- a/quickstep/res/values-lv/strings.xml
+++ b/quickstep/res/values-lv/strings.xml
@@ -84,4 +84,7 @@
     <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Varēsiet to vēlāk atrast lietotnē <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Atcelt"</string>
     <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Izlaist"</string>
+    <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Varat izmantot divas lietotnes reizē un pāriet no vienas uz otru, izmantojot rīkjoslu"</string>
+    <string name="taskbar_edu_next" msgid="4007618274426775841">"Tālāk"</string>
+    <string name="taskbar_edu_close" msgid="887022990168191073">"Aizvērt"</string>
 </resources>
diff --git a/quickstep/res/values-mk/strings.xml b/quickstep/res/values-mk/strings.xml
index 98307da..b3e08f5 100644
--- a/quickstep/res/values-mk/strings.xml
+++ b/quickstep/res/values-mk/strings.xml
@@ -84,4 +84,7 @@
     <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Ова може да го најдете подоцна во апликацијата <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Откажи"</string>
     <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Прескокни"</string>
+    <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Користете 2 апликации одеднаш и префрлувајте се меѓу нив со лентата за задачи"</string>
+    <string name="taskbar_edu_next" msgid="4007618274426775841">"Следна"</string>
+    <string name="taskbar_edu_close" msgid="887022990168191073">"Затвори"</string>
 </resources>
diff --git a/quickstep/res/values-ml/strings.xml b/quickstep/res/values-ml/strings.xml
index 52be3ac..9291259 100644
--- a/quickstep/res/values-ml/strings.xml
+++ b/quickstep/res/values-ml/strings.xml
@@ -84,4 +84,7 @@
     <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"<xliff:g id="NAME">%1$s</xliff:g> ആപ്പിൽ നിങ്ങൾക്ക് ഇത് പിന്നീട് കാണാനാകും"</string>
     <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"റദ്ദാക്കുക"</string>
     <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"ഒഴിവാക്കുക"</string>
+    <string name="taskbar_edu_header_1" msgid="5323217563328273689">"ടാസ്‌ക്‌ബാറിന്റെ സഹായത്തോടെ ഒരേ സമയം 2 ആപ്പുകൾ ഉപയോഗിക്കുകയും ആപ്പുകൾ പരസ്പരം മാറുകയും ചെയ്യൂ"</string>
+    <string name="taskbar_edu_next" msgid="4007618274426775841">"അടുത്തത്"</string>
+    <string name="taskbar_edu_close" msgid="887022990168191073">"അടയ്ക്കുക"</string>
 </resources>
diff --git a/quickstep/res/values-mn/strings.xml b/quickstep/res/values-mn/strings.xml
index 79fbca6..65023d6 100644
--- a/quickstep/res/values-mn/strings.xml
+++ b/quickstep/res/values-mn/strings.xml
@@ -84,4 +84,7 @@
     <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Та үүнийг дараа нь <xliff:g id="NAME">%1$s</xliff:g> аппаас олох боломжтой"</string>
     <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Цуцлах"</string>
     <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Алгасах"</string>
+    <string name="taskbar_edu_header_1" msgid="5323217563328273689">"2 аппыг нэг дор ашиглан талбарын тусламжтайгаар аппуудыг сэлгэнэ үү"</string>
+    <string name="taskbar_edu_next" msgid="4007618274426775841">"Дараах"</string>
+    <string name="taskbar_edu_close" msgid="887022990168191073">"Хаах"</string>
 </resources>
diff --git a/quickstep/res/values-mr/strings.xml b/quickstep/res/values-mr/strings.xml
index 8618f85..40c88a4 100644
--- a/quickstep/res/values-mr/strings.xml
+++ b/quickstep/res/values-mr/strings.xml
@@ -84,4 +84,10 @@
     <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"तुम्हाला हे नंतर <xliff:g id="NAME">%1$s</xliff:g> ॲपमध्ये मिळेल"</string>
     <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"रद्द करा"</string>
     <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"वगळा"</string>
+    <!-- no translation found for taskbar_edu_header_1 (5323217563328273689) -->
+    <skip />
+    <!-- no translation found for taskbar_edu_next (4007618274426775841) -->
+    <skip />
+    <!-- no translation found for taskbar_edu_close (887022990168191073) -->
+    <skip />
 </resources>
diff --git a/quickstep/res/values-ms/strings.xml b/quickstep/res/values-ms/strings.xml
index 1e2d43d..886f3b6 100644
--- a/quickstep/res/values-ms/strings.xml
+++ b/quickstep/res/values-ms/strings.xml
@@ -84,4 +84,7 @@
     <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Anda boleh mendapatkan tutorial ini kemudian dalam apl <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Batal"</string>
     <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Langkau"</string>
+    <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Gunakan 2 apl pada satu masa dan tukar apl dengan bar tugas"</string>
+    <string name="taskbar_edu_next" msgid="4007618274426775841">"Seterusnya"</string>
+    <string name="taskbar_edu_close" msgid="887022990168191073">"Tutup"</string>
 </resources>
diff --git a/quickstep/res/values-my/strings.xml b/quickstep/res/values-my/strings.xml
index b07bbfa..0d38c84 100644
--- a/quickstep/res/values-my/strings.xml
+++ b/quickstep/res/values-my/strings.xml
@@ -84,4 +84,7 @@
     <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"၎င်းကို နောက်မှ <xliff:g id="NAME">%1$s</xliff:g> အက်ပ်တွင် ရှာနိုင်သည်"</string>
     <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"မလုပ်တော့"</string>
     <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"ကျော်ရန်"</string>
+    <string name="taskbar_edu_header_1" msgid="5323217563328273689">"အက်ပ် ၂ ခုကို တစ်ပြိုင်ထဲသုံးပြီး လုပ်ဆောင်စရာဘားဖြင့် အက်ပ်များပြောင်းလိုက်ပါ"</string>
+    <string name="taskbar_edu_next" msgid="4007618274426775841">"ရှေ့သို့"</string>
+    <string name="taskbar_edu_close" msgid="887022990168191073">"ပိတ်ရန်"</string>
 </resources>
diff --git a/quickstep/res/values-nb/strings.xml b/quickstep/res/values-nb/strings.xml
index 16988c5..8ad72cd 100644
--- a/quickstep/res/values-nb/strings.xml
+++ b/quickstep/res/values-nb/strings.xml
@@ -84,4 +84,7 @@
     <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Du kan finne dette i <xliff:g id="NAME">%1$s</xliff:g>-appen senere"</string>
     <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Avbryt"</string>
     <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Hopp over"</string>
+    <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Bruk to apper samtidig og bytt app med oppgavelinjen"</string>
+    <string name="taskbar_edu_next" msgid="4007618274426775841">"Neste"</string>
+    <string name="taskbar_edu_close" msgid="887022990168191073">"Lukk"</string>
 </resources>
diff --git a/quickstep/res/values-ne/strings.xml b/quickstep/res/values-ne/strings.xml
index 91cae47..89ef427 100644
--- a/quickstep/res/values-ne/strings.xml
+++ b/quickstep/res/values-ne/strings.xml
@@ -84,4 +84,10 @@
     <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"तपाईं पछि <xliff:g id="NAME">%1$s</xliff:g> नामक एपमा गई यो ट्युटोरियल भेट्टाउन सक्नुहुन्छ"</string>
     <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"रद्द गर्नुहोस्"</string>
     <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"स्किप गर्नु…"</string>
+    <!-- no translation found for taskbar_edu_header_1 (5323217563328273689) -->
+    <skip />
+    <!-- no translation found for taskbar_edu_next (4007618274426775841) -->
+    <skip />
+    <!-- no translation found for taskbar_edu_close (887022990168191073) -->
+    <skip />
 </resources>
diff --git a/quickstep/res/values-night/colors.xml b/quickstep/res/values-night/colors.xml
new file mode 100644
index 0000000..c3b2536
--- /dev/null
+++ b/quickstep/res/values-night/colors.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<resources>
+
+    <color name="gesture_tutorial_back_arrow_color">#99000000</color>
+
+    <color name="gesture_tutorial_fake_wallpaper_color">#000000</color> <!-- Black -->
+
+    <color name="mock_webpage_url_bar">#202124</color>
+    <color name="mock_webpage_url_bar_item">#3c4043</color>
+
+</resources>
\ No newline at end of file
diff --git a/quickstep/res/values-nl/strings.xml b/quickstep/res/values-nl/strings.xml
index 96da966..faed85b 100644
--- a/quickstep/res/values-nl/strings.xml
+++ b/quickstep/res/values-nl/strings.xml
@@ -84,4 +84,7 @@
     <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Je vindt dit later terug in de app <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Annuleren"</string>
     <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Overslaan"</string>
+    <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Gebruik 2 apps tegelijk en schakel tussen apps via de taakbalk"</string>
+    <string name="taskbar_edu_next" msgid="4007618274426775841">"Volgende"</string>
+    <string name="taskbar_edu_close" msgid="887022990168191073">"Sluiten"</string>
 </resources>
diff --git a/quickstep/res/values-or/strings.xml b/quickstep/res/values-or/strings.xml
index 9488021..b6281c3 100644
--- a/quickstep/res/values-or/strings.xml
+++ b/quickstep/res/values-or/strings.xml
@@ -84,4 +84,10 @@
     <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"ଆପଣ ପରେ ଏହାକୁ <xliff:g id="NAME">%1$s</xliff:g> ଆପରେ ପାଇପାରିବେ"</string>
     <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"ବାତିଲ୍ କରନ୍ତୁ"</string>
     <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"ବାଦ୍ ଦିଅନ୍ତୁ"</string>
+    <!-- no translation found for taskbar_edu_header_1 (5323217563328273689) -->
+    <skip />
+    <!-- no translation found for taskbar_edu_next (4007618274426775841) -->
+    <skip />
+    <!-- no translation found for taskbar_edu_close (887022990168191073) -->
+    <skip />
 </resources>
diff --git a/quickstep/res/values-pa/strings.xml b/quickstep/res/values-pa/strings.xml
index 89b2119..bdfc867 100644
--- a/quickstep/res/values-pa/strings.xml
+++ b/quickstep/res/values-pa/strings.xml
@@ -84,4 +84,10 @@
     <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"ਤੁਸੀਂ ਇਸਨੂੰ ਬਾਅਦ ਵਿੱਚ <xliff:g id="NAME">%1$s</xliff:g> ਐਪ ਵਿੱਚ ਲੱਭ ਸਕਦੇ ਹੋ"</string>
     <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"ਰੱਦ ਕਰੋ"</string>
     <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"ਛੱਡੋ"</string>
+    <!-- no translation found for taskbar_edu_header_1 (5323217563328273689) -->
+    <skip />
+    <!-- no translation found for taskbar_edu_next (4007618274426775841) -->
+    <skip />
+    <!-- no translation found for taskbar_edu_close (887022990168191073) -->
+    <skip />
 </resources>
diff --git a/quickstep/res/values-pl/strings.xml b/quickstep/res/values-pl/strings.xml
index 893db91..57c9e4c 100644
--- a/quickstep/res/values-pl/strings.xml
+++ b/quickstep/res/values-pl/strings.xml
@@ -84,4 +84,7 @@
     <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Znajdziesz to później w aplikacji <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Anuluj"</string>
     <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Pomiń"</string>
+    <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Używaj 2 aplikacji jednocześnie i przełączaj je za pomocą paska zadań"</string>
+    <string name="taskbar_edu_next" msgid="4007618274426775841">"Dalej"</string>
+    <string name="taskbar_edu_close" msgid="887022990168191073">"Zamknij"</string>
 </resources>
diff --git a/quickstep/res/values-pt-rPT/strings.xml b/quickstep/res/values-pt-rPT/strings.xml
index c1cd2bb..40bb8a1 100644
--- a/quickstep/res/values-pt-rPT/strings.xml
+++ b/quickstep/res/values-pt-rPT/strings.xml
@@ -84,4 +84,7 @@
     <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Pode encontrar isto mais tarde na app <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Cancelar"</string>
     <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Ignorar"</string>
+    <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Utilize 2 apps em simultâneo e alterne entre as apps com a barra de tarefas"</string>
+    <string name="taskbar_edu_next" msgid="4007618274426775841">"Seguinte"</string>
+    <string name="taskbar_edu_close" msgid="887022990168191073">"Fechar"</string>
 </resources>
diff --git a/quickstep/res/values-pt/strings.xml b/quickstep/res/values-pt/strings.xml
index 422d13a..144bbf6 100644
--- a/quickstep/res/values-pt/strings.xml
+++ b/quickstep/res/values-pt/strings.xml
@@ -84,4 +84,7 @@
     <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Veja o tutorial mais tarde no app <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Cancelar"</string>
     <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Pular"</string>
+    <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Use dois apps ao mesmo tempo e alterne entre eles usando a barra de tarefas"</string>
+    <string name="taskbar_edu_next" msgid="4007618274426775841">"Próxima"</string>
+    <string name="taskbar_edu_close" msgid="887022990168191073">"Fechar"</string>
 </resources>
diff --git a/quickstep/res/values-ro/strings.xml b/quickstep/res/values-ro/strings.xml
index a5e97e0..2231522 100644
--- a/quickstep/res/values-ro/strings.xml
+++ b/quickstep/res/values-ro/strings.xml
@@ -84,4 +84,7 @@
     <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Îl puteți găsi mai târziu în aplicația <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Anulați"</string>
     <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Omiteți"</string>
+    <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Folosiți două aplicații simultan și comutați între aplicații folosind bara de activități"</string>
+    <string name="taskbar_edu_next" msgid="4007618274426775841">"Înainte"</string>
+    <string name="taskbar_edu_close" msgid="887022990168191073">"Închideți"</string>
 </resources>
diff --git a/quickstep/res/values-ru/strings.xml b/quickstep/res/values-ru/strings.xml
index 7c4d485..9087da9 100644
--- a/quickstep/res/values-ru/strings.xml
+++ b/quickstep/res/values-ru/strings.xml
@@ -84,4 +84,7 @@
     <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Его можно найти в приложении \"<xliff:g id="NAME">%1$s</xliff:g>\"."</string>
     <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Отмена"</string>
     <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Пропустить"</string>
+    <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Пользуйтесь двумя приложениями одновременно и переключайтесь между ними с помощью панели задач"</string>
+    <string name="taskbar_edu_next" msgid="4007618274426775841">"Далее"</string>
+    <string name="taskbar_edu_close" msgid="887022990168191073">"Закрыть"</string>
 </resources>
diff --git a/quickstep/res/values-si/strings.xml b/quickstep/res/values-si/strings.xml
index 5f322e6..b3d88c0 100644
--- a/quickstep/res/values-si/strings.xml
+++ b/quickstep/res/values-si/strings.xml
@@ -84,4 +84,7 @@
     <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"ඔබට මෙය පසුව <xliff:g id="NAME">%1$s</xliff:g> යෙදුම තුළ සොයා ගත හැකිය"</string>
     <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"අවලංගු කරන්න"</string>
     <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"මඟ හරින්න"</string>
+    <string name="taskbar_edu_header_1" msgid="5323217563328273689">"එකවර යෙදුම් 2ක් භාවිත කර කාර්ය තීරුව සමඟින් යෙදුම් මාරු කරන්න"</string>
+    <string name="taskbar_edu_next" msgid="4007618274426775841">"ඊළඟ"</string>
+    <string name="taskbar_edu_close" msgid="887022990168191073">"වසන්න"</string>
 </resources>
diff --git a/quickstep/res/values-sk/strings.xml b/quickstep/res/values-sk/strings.xml
index 799e941..0b0082c 100644
--- a/quickstep/res/values-sk/strings.xml
+++ b/quickstep/res/values-sk/strings.xml
@@ -84,4 +84,7 @@
     <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Tento návod nájdete v aplikácii <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Zrušiť"</string>
     <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Preskočiť"</string>
+    <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Používajte dve aplikácie naraz a prepínajte ich pomocou panela úloh"</string>
+    <string name="taskbar_edu_next" msgid="4007618274426775841">"Ďalej"</string>
+    <string name="taskbar_edu_close" msgid="887022990168191073">"Zavrieť"</string>
 </resources>
diff --git a/quickstep/res/values-sl/strings.xml b/quickstep/res/values-sl/strings.xml
index 7e40277..a2b1363 100644
--- a/quickstep/res/values-sl/strings.xml
+++ b/quickstep/res/values-sl/strings.xml
@@ -84,4 +84,7 @@
     <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"To lahko pozneje najdete v aplikaciji <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Prekliči"</string>
     <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Preskoči"</string>
+    <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Sočasno uporabite dve aplikaciji in preklopite med njima z orodno vrstico."</string>
+    <string name="taskbar_edu_next" msgid="4007618274426775841">"Naprej"</string>
+    <string name="taskbar_edu_close" msgid="887022990168191073">"Zapri"</string>
 </resources>
diff --git a/quickstep/res/values-sq/strings.xml b/quickstep/res/values-sq/strings.xml
index 86528d2..f259f3c 100644
--- a/quickstep/res/values-sq/strings.xml
+++ b/quickstep/res/values-sq/strings.xml
@@ -84,4 +84,10 @@
     <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Këtë mund ta gjesh më vonë tek aplikacioni <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Anulo"</string>
     <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Kapërce"</string>
+    <!-- no translation found for taskbar_edu_header_1 (5323217563328273689) -->
+    <skip />
+    <!-- no translation found for taskbar_edu_next (4007618274426775841) -->
+    <skip />
+    <!-- no translation found for taskbar_edu_close (887022990168191073) -->
+    <skip />
 </resources>
diff --git a/quickstep/res/values-sr/strings.xml b/quickstep/res/values-sr/strings.xml
index f2ffa0a..0d6d4d6 100644
--- a/quickstep/res/values-sr/strings.xml
+++ b/quickstep/res/values-sr/strings.xml
@@ -84,4 +84,7 @@
     <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Можете да пронађете ово касније у апликацији <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Откажи"</string>
     <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Прескочи"</string>
+    <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Користите 2 апликације одједном и мењајте апликације помоћу траке задатака"</string>
+    <string name="taskbar_edu_next" msgid="4007618274426775841">"Даље"</string>
+    <string name="taskbar_edu_close" msgid="887022990168191073">"Затвори"</string>
 </resources>
diff --git a/quickstep/res/values-sv/strings.xml b/quickstep/res/values-sv/strings.xml
index 931e458..acb8014 100644
--- a/quickstep/res/values-sv/strings.xml
+++ b/quickstep/res/values-sv/strings.xml
@@ -84,4 +84,7 @@
     <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Du hittar det här igen i <xliff:g id="NAME">%1$s</xliff:g>-appen"</string>
     <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Avbryt"</string>
     <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Hoppa över"</string>
+    <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Använd två appar samtidigt och byt mellan appar via aktivitetsfältet"</string>
+    <string name="taskbar_edu_next" msgid="4007618274426775841">"Nästa"</string>
+    <string name="taskbar_edu_close" msgid="887022990168191073">"Stäng"</string>
 </resources>
diff --git a/quickstep/res/values-sw/strings.xml b/quickstep/res/values-sw/strings.xml
index 22aa3ef..f49ef9b 100644
--- a/quickstep/res/values-sw/strings.xml
+++ b/quickstep/res/values-sw/strings.xml
@@ -84,4 +84,7 @@
     <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Utapata mafunzo haya baadaye katika programu ya <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Ghairi"</string>
     <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Ruka"</string>
+    <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Tumia programu mbili kwa wakati mmoja na ubadilishe programu ukitumia upau wa shughuli"</string>
+    <string name="taskbar_edu_next" msgid="4007618274426775841">"Endelea"</string>
+    <string name="taskbar_edu_close" msgid="887022990168191073">"Funga"</string>
 </resources>
diff --git a/quickstep/res/values-ta/strings.xml b/quickstep/res/values-ta/strings.xml
index de7c26d..321555f 100644
--- a/quickstep/res/values-ta/strings.xml
+++ b/quickstep/res/values-ta/strings.xml
@@ -84,4 +84,7 @@
     <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"<xliff:g id="NAME">%1$s</xliff:g> ஆப்ஸில் பிறகு இதைக் கண்டறியலாம்"</string>
     <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"ரத்துசெய்"</string>
     <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"தவிர்"</string>
+    <string name="taskbar_edu_header_1" msgid="5323217563328273689">"ஒரே நேரத்தில் 2 ஆப்ஸைப் பயன்படுத்தலாம், பணிப்பட்டி மூலம் ஆப்ஸுக்கிடையே மாறலாம்"</string>
+    <string name="taskbar_edu_next" msgid="4007618274426775841">"அடுத்து"</string>
+    <string name="taskbar_edu_close" msgid="887022990168191073">"மூடுக"</string>
 </resources>
diff --git a/quickstep/res/values-te/strings.xml b/quickstep/res/values-te/strings.xml
index 73e4e0c..b8f3b04 100644
--- a/quickstep/res/values-te/strings.xml
+++ b/quickstep/res/values-te/strings.xml
@@ -33,13 +33,13 @@
     <string name="all_apps_prediction_tip" msgid="2672336544844936186">"మీ సూచించబడిన యాప్‌లు"</string>
     <string name="hotseat_edu_title_migrate" msgid="306578144424489980">"మీ మొదటి స్క్రీన్‌ దిగువ వరుసలో యాప్ సలహాలను పొందండి"</string>
     <string name="hotseat_edu_title_migrate_landscape" msgid="3633942953997845243">"మీ హోమ్ స్క్రీన్‌లోని ఇష్టమైన వాటి వరుసలో యాప్ సూచ‌న‌లు పొందండి"</string>
-    <string name="hotseat_edu_message_migrate" msgid="8927179260533775320">"మీరు ఎక్కువగా ఉపయోగించే యాప్‌లను నేరుగా మొదటి స్క్రీన్‌లోనే సులభంగా యాక్సెస్ చేయండి. మీ రోజువారీ కార్యకలాపాలను బట్టి సూచనలు మారతాయి. దిగువ వరుసలోని యాప్‌లు మీ మొదటి స్క్రీన్ పైకి చేరుకుంటాయి."</string>
-    <string name="hotseat_edu_message_migrate_landscape" msgid="4248943380443387697">"మీరు ఎక్కువగా ఉపయోగించే యాప్‌లను నేరుగా మొదటి స్క్రీన్‌లోనే సులభంగా యాక్సెస్ చేయండి. మీ రోజువారీ కార్యకలాపాలను బట్టి సూచనలు మారతాయి. ఇష్టమైన వాటి వరుసలోని యాప్‌లు మీ మొదటి స్క్రీన్‌కు చేరుకుంటాయి."</string>
-    <string name="hotseat_edu_message_migrate_alt" msgid="3042360119039646356">"మీరు ఎక్కువగా ఉపయోగించే యాప్‌లను నేరుగా మొదటి స్క్రీన్‌లోనే సులభంగా యాక్సెస్ చేయండి. మీ రోజువారీ కార్యకలాపాలను బట్టి సూచనలు మారతాయి. దిగువ వరుసలోని యాప్‌లు కొత్త ఫోల్డర్‌కు తరలించబడతాయి."</string>
+    <string name="hotseat_edu_message_migrate" msgid="8927179260533775320">"మీరు ఎక్కువగా ఉపయోగించే యాప్‌లను నేరుగా మొదటి స్క్రీన్‌లోనే సులభంగా యాక్సెస్ చేయండి. మీ రోజువారీ యాక్టివిటీలను బట్టి సూచనలు మారతాయి. దిగువ వరుసలోని యాప్‌లు మీ మొదటి స్క్రీన్ పైకి చేరుకుంటాయి."</string>
+    <string name="hotseat_edu_message_migrate_landscape" msgid="4248943380443387697">"మీరు ఎక్కువగా ఉపయోగించే యాప్‌లను నేరుగా మొదటి స్క్రీన్‌లోనే సులభంగా యాక్సెస్ చేయండి. మీ రోజువారీ యాక్టివిటీలను బట్టి సూచనలు మారతాయి. ఇష్టమైన వాటి వరుసలోని యాప్‌లు మీ మొదటి స్క్రీన్‌కు చేరుకుంటాయి."</string>
+    <string name="hotseat_edu_message_migrate_alt" msgid="3042360119039646356">"మీరు ఎక్కువగా ఉపయోగించే యాప్‌లను నేరుగా మొదటి స్క్రీన్‌లోనే సులభంగా యాక్సెస్ చేయండి. మీ రోజువారీ యాక్టివిటీలను బట్టి సూచనలు మారతాయి. దిగువ వరుసలోని యాప్‌లు కొత్త ఫోల్డర్‌కు తరలించబడతాయి."</string>
     <string name="hotseat_edu_accept" msgid="1611544083278999837">"యాప్ సూచ‌న‌లను పొందండి"</string>
     <string name="hotseat_edu_dismiss" msgid="2781161822780201689">"వద్దు"</string>
     <string name="hotseat_prediction_settings" msgid="6246554993566070818">"సెట్టింగ్‌లు"</string>
-    <string name="hotseat_auto_enrolled" msgid="522100018967146807">"ఎక్కువగా ఉపయోగించిన యాప్‌లు ఇక్కడ కనిపిస్తాయి, అవి రోజువారీ కార్యకలాపాలను బట్టి మారుతూ ఉంటాయి"</string>
+    <string name="hotseat_auto_enrolled" msgid="522100018967146807">"ఎక్కువగా ఉపయోగించిన యాప్‌లు ఇక్కడ కనిపిస్తాయి, అవి రోజువారీ యాక్టివిటీలను బట్టి మారుతూ ఉంటాయి"</string>
     <string name="hotseat_tip_no_empty_slots" msgid="1325212677738179185">"యాప్ సలహాలను పొందడానికి దిగువ వరుస నుండి యాప్‌లను లాగండి"</string>
     <string name="hotseat_tip_gaps_filled" msgid="3035673010274223538">"యాప్ సూచ‌న‌లు ఖాళీ స్పేస్‌కు జోడించబడ్డాయి"</string>
     <string name="hotsaet_tip_prediction_enabled" msgid="2233554377501347650">"యాప్ సలహాలు ఎనేబుల్ చేయబడ్డాయి"</string>
@@ -84,4 +84,10 @@
     <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"<xliff:g id="NAME">%1$s</xliff:g> యాప్‌లో మీరు తర్వాత కనుగొనవచ్చు"</string>
     <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"రద్దు చేయి"</string>
     <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"స్కిప్ చేయి"</string>
+    <!-- no translation found for taskbar_edu_header_1 (5323217563328273689) -->
+    <skip />
+    <!-- no translation found for taskbar_edu_next (4007618274426775841) -->
+    <skip />
+    <!-- no translation found for taskbar_edu_close (887022990168191073) -->
+    <skip />
 </resources>
diff --git a/quickstep/res/values-th/strings.xml b/quickstep/res/values-th/strings.xml
index 52b2878..6839fef 100644
--- a/quickstep/res/values-th/strings.xml
+++ b/quickstep/res/values-th/strings.xml
@@ -84,4 +84,7 @@
     <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"คุณดูบทแนะนำนี้ได้ภายหลังในแอป \"<xliff:g id="NAME">%1$s</xliff:g>\""</string>
     <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"ยกเลิก"</string>
     <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"ข้าม"</string>
+    <string name="taskbar_edu_header_1" msgid="5323217563328273689">"ใช้แอป 2 แอปพร้อมกันและสลับแอปด้วยแถบงาน"</string>
+    <string name="taskbar_edu_next" msgid="4007618274426775841">"ถัดไป"</string>
+    <string name="taskbar_edu_close" msgid="887022990168191073">"ปิด"</string>
 </resources>
diff --git a/quickstep/res/values-tl/strings.xml b/quickstep/res/values-tl/strings.xml
index 412449b..a7a0d81 100644
--- a/quickstep/res/values-tl/strings.xml
+++ b/quickstep/res/values-tl/strings.xml
@@ -84,4 +84,7 @@
     <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Makikita mo ito sa <xliff:g id="NAME">%1$s</xliff:g> app sa ibang pagkakataon"</string>
     <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Kanselahin"</string>
     <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Laktawan"</string>
+    <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Gumamit ng 2 app nang sabay at magpalipat-lipat ng app gamit ang taskbar"</string>
+    <string name="taskbar_edu_next" msgid="4007618274426775841">"Susunod"</string>
+    <string name="taskbar_edu_close" msgid="887022990168191073">"Isara"</string>
 </resources>
diff --git a/quickstep/res/values-tr/strings.xml b/quickstep/res/values-tr/strings.xml
index 58d78e0..7ea58a0 100644
--- a/quickstep/res/values-tr/strings.xml
+++ b/quickstep/res/values-tr/strings.xml
@@ -84,4 +84,7 @@
     <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Bunu daha sonra <xliff:g id="NAME">%1$s</xliff:g> uygulamasında bulabilirsiniz"</string>
     <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"İptal"</string>
     <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Atla"</string>
+    <string name="taskbar_edu_header_1" msgid="5323217563328273689">"2 uygulamayı aynı anda kullanıp görev çubuğuyla uygulamalar arasında geçiş yapın"</string>
+    <string name="taskbar_edu_next" msgid="4007618274426775841">"İleri"</string>
+    <string name="taskbar_edu_close" msgid="887022990168191073">"Kapat"</string>
 </resources>
diff --git a/quickstep/res/values-uk/strings.xml b/quickstep/res/values-uk/strings.xml
index 544cec7..4127b75 100644
--- a/quickstep/res/values-uk/strings.xml
+++ b/quickstep/res/values-uk/strings.xml
@@ -84,4 +84,7 @@
     <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Ви знайдете його пізніше в додатку <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Скасувати"</string>
     <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Пропустити"</string>
+    <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Користуйтеся двома додатками одночасно й перемикайтеся між ними за допомогою панелі завдань"</string>
+    <string name="taskbar_edu_next" msgid="4007618274426775841">"Далі"</string>
+    <string name="taskbar_edu_close" msgid="887022990168191073">"Закрити"</string>
 </resources>
diff --git a/quickstep/res/values-ur/strings.xml b/quickstep/res/values-ur/strings.xml
index 2e8bde9..0af4328 100644
--- a/quickstep/res/values-ur/strings.xml
+++ b/quickstep/res/values-ur/strings.xml
@@ -84,4 +84,7 @@
     <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"آپ اسے بعد میں <xliff:g id="NAME">%1$s</xliff:g> ایپ میں تلاش کر سکتے ہیں"</string>
     <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"منسوخ کریں"</string>
     <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"نظر انداز کریں"</string>
+    <string name="taskbar_edu_header_1" msgid="5323217563328273689">"ایک وقت میں 2 ایپس استعمال کریں اور ٹاسک بار کے ساتھ ایپس پر سوئچ کریں"</string>
+    <string name="taskbar_edu_next" msgid="4007618274426775841">"آگے"</string>
+    <string name="taskbar_edu_close" msgid="887022990168191073">"بند کریں"</string>
 </resources>
diff --git a/quickstep/res/values-uz/strings.xml b/quickstep/res/values-uz/strings.xml
index 8b194de..c77a6c7 100644
--- a/quickstep/res/values-uz/strings.xml
+++ b/quickstep/res/values-uz/strings.xml
@@ -84,4 +84,7 @@
     <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Bu darslar <xliff:g id="NAME">%1$s</xliff:g> ilovasida chiqadi"</string>
     <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Bekor qilish"</string>
     <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Tashlab ketish"</string>
+    <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Vazifalar panelidan almashtirish uchun birdaniga 2 ta ilovadan foydalanish"</string>
+    <string name="taskbar_edu_next" msgid="4007618274426775841">"Keyingisi"</string>
+    <string name="taskbar_edu_close" msgid="887022990168191073">"Yopish"</string>
 </resources>
diff --git a/quickstep/res/values-vi/strings.xml b/quickstep/res/values-vi/strings.xml
index 7bd0c70..0261368 100644
--- a/quickstep/res/values-vi/strings.xml
+++ b/quickstep/res/values-vi/strings.xml
@@ -84,4 +84,7 @@
     <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Bạn có thể tìm lại phần hướng dẫn này trong ứng dụng <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Hủy"</string>
     <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Bỏ qua"</string>
+    <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Dùng 2 ứng dụng một lúc và chuyển đổi ứng dụng thông qua thanh tác vụ"</string>
+    <string name="taskbar_edu_next" msgid="4007618274426775841">"Tiếp theo"</string>
+    <string name="taskbar_edu_close" msgid="887022990168191073">"Đóng"</string>
 </resources>
diff --git a/quickstep/res/values-zh-rCN/strings.xml b/quickstep/res/values-zh-rCN/strings.xml
index 9e641de..8d97e7a 100644
--- a/quickstep/res/values-zh-rCN/strings.xml
+++ b/quickstep/res/values-zh-rCN/strings.xml
@@ -84,4 +84,7 @@
     <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"您之后可以在“<xliff:g id="NAME">%1$s</xliff:g>”应用中找到此教程"</string>
     <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"取消"</string>
     <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"跳过"</string>
+    <string name="taskbar_edu_header_1" msgid="5323217563328273689">"借助任务栏,您可以同时使用 2 个应用,并可以在应用之间切换"</string>
+    <string name="taskbar_edu_next" msgid="4007618274426775841">"继续"</string>
+    <string name="taskbar_edu_close" msgid="887022990168191073">"关闭"</string>
 </resources>
diff --git a/quickstep/res/values-zh-rHK/strings.xml b/quickstep/res/values-zh-rHK/strings.xml
index d1e8392..d3cc14c 100644
--- a/quickstep/res/values-zh-rHK/strings.xml
+++ b/quickstep/res/values-zh-rHK/strings.xml
@@ -84,4 +84,7 @@
     <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"您之後可以在「<xliff:g id="NAME">%1$s</xliff:g>」應用程式找到這些說明"</string>
     <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"取消"</string>
     <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"略過"</string>
+    <string name="taskbar_edu_header_1" msgid="5323217563328273689">"同時使用 2 個應用程式,以及使用工作列切換應用程式"</string>
+    <string name="taskbar_edu_next" msgid="4007618274426775841">"繼續"</string>
+    <string name="taskbar_edu_close" msgid="887022990168191073">"關閉"</string>
 </resources>
diff --git a/quickstep/res/values-zh-rTW/strings.xml b/quickstep/res/values-zh-rTW/strings.xml
index db10354..382f725 100644
--- a/quickstep/res/values-zh-rTW/strings.xml
+++ b/quickstep/res/values-zh-rTW/strings.xml
@@ -84,4 +84,7 @@
     <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"你之後可以在「<xliff:g id="NAME">%1$s</xliff:g>」應用程式找到這些說明"</string>
     <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"取消"</string>
     <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"略過"</string>
+    <string name="taskbar_edu_header_1" msgid="5323217563328273689">"你可以同時使用 2 個應用程式,只要透過工作列即可切換"</string>
+    <string name="taskbar_edu_next" msgid="4007618274426775841">"繼續"</string>
+    <string name="taskbar_edu_close" msgid="887022990168191073">"關閉"</string>
 </resources>
diff --git a/quickstep/res/values-zu/strings.xml b/quickstep/res/values-zu/strings.xml
index bbfb840..1232a82 100644
--- a/quickstep/res/values-zu/strings.xml
+++ b/quickstep/res/values-zu/strings.xml
@@ -84,4 +84,7 @@
     <string name="skip_tutorial_dialog_subtitle" msgid="544063326241955662">"Lokhu ungakuthola kamuva ku-app ye-<xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="gesture_tutorial_action_button_label_cancel" msgid="3809842569351264108">"Khansela"</string>
     <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Yeqa"</string>
+    <string name="taskbar_edu_header_1" msgid="5323217563328273689">"Sebenzisa ama-app ama-2 ngesikhathi esisodwa bese ushintsha ama-app ngebha yomsebenzi"</string>
+    <string name="taskbar_edu_next" msgid="4007618274426775841">"Okulandelayo"</string>
+    <string name="taskbar_edu_close" msgid="887022990168191073">"Vala"</string>
 </resources>
diff --git a/quickstep/res/values/colors.xml b/quickstep/res/values/colors.xml
index 2f24441..4755292 100644
--- a/quickstep/res/values/colors.xml
+++ b/quickstep/res/values/colors.xml
@@ -14,8 +14,6 @@
      limitations under the License.
 -->
 <resources>
-    <color name="back_arrow_color_light">#FFFFFFFF</color>
-    <color name="back_arrow_color_dark">#99000000</color>
 
     <color name="chip_hint_foreground_color">#fff</color>
     <color name="chip_scrim_start_color">#39000000</color>
@@ -28,4 +26,43 @@
     <!-- Taskbar -->
     <color name="taskbar_background">@color/overview_scrim_dark</color>
     <color name="taskbar_icon_selection_ripple">#E0E0E0</color>
+
+    <color name="taskbar_stashed_handle_light_color">#EBffffff</color>
+    <color name="taskbar_stashed_handle_dark_color">#99000000</color>
+
+    <!-- Gesture navigation tutorial -->
+    <color name="gesture_tutorial_back_arrow_color">#FFFFFFFF</color>
+
+    <color name="gesture_tutorial_fake_wallpaper_color">#f9f9f9</color> <!-- White -->
+    <color name="gesture_tutorial_ripple_color">#A0C2F9</color> <!-- Light Blue -->
+    <color name="gesture_tutorial_fake_task_view_color">#6DA1FF</color> <!-- Light Blue -->
+    <!-- Must contrast gesture_tutorial_fake_wallpaper_color -->
+    <color name="gesture_tutorial_fake_previous_task_view_color">#3C4043</color> <!-- Gray -->
+    <color name="gesture_tutorial_action_button_label_color">#FF000000</color>
+    <color name="gesture_tutorial_primary_color">#B7F29F</color> <!-- Light Green -->
+
+    <!-- Mock conversation -->
+    <color name="mock_conversation_background">#f1f3f4</color>
+    <color name="mock_conversation_top_bar">#e8eaed</color>
+    <color name="mock_conversation_top_bar_item">#dadce0</color>
+    <color name="mock_conversation_sent_message">#bdc1c6</color>
+    <color name="mock_conversation_received_message">#e8eaed</color>
+    <color name="mock_conversation_message_input">#dadce0</color>
+    <color name="mock_conversation_profile_icon">#dadce0</color>
+
+    <!-- Mock conversations list -->
+    <color name="mock_list_background">#dadce0</color>
+    <color name="mock_list_top_bar">#e8eaed</color>
+    <color name="mock_list_top_bar_item">#f8f9fa</color>
+    <color name="mock_list_profile_icon">#9aa0a6</color>
+    <color name="mock_list_preview_message">#bdc1c6</color>
+    <color name="mock_list_button">#bdc1c6</color>
+
+    <!-- Mock web page -->
+    <color name="mock_webpage_background">#f1f3f4</color>
+    <color name="mock_webpage_url_bar">#6e7175</color>
+    <color name="mock_webpage_url_bar_item">#9a9a9a</color>
+    <color name="mock_webpage_top_bar">#e8eaed</color>
+    <color name="mock_webpage_top_bar_item">#80868b</color>
+    <color name="mock_webpage_page_text">#bdc1c6</color>
 </resources>
\ No newline at end of file
diff --git a/quickstep/res/values/dimens.xml b/quickstep/res/values/dimens.xml
index 659ff9a..f1f23c4 100644
--- a/quickstep/res/values/dimens.xml
+++ b/quickstep/res/values/dimens.xml
@@ -32,7 +32,8 @@
 
     <dimen name="overview_minimum_next_prev_size">50dp</dimen>
     <dimen name="overview_task_margin">16dp</dimen>
-    <dimen name="overview_task_margin_grid">12dp</dimen>
+    <dimen name="overview_task_margin_focused">12dp</dimen>
+    <dimen name="overview_task_margin_grid">4dp</dimen>
 
     <!-- Overrideable in overlay that provides the Overview Actions. -->
     <dimen name="overview_actions_height">48dp</dimen>
@@ -45,8 +46,8 @@
     <dimen name="overview_actions_horizontal_margin">16dp</dimen>
 
     <dimen name="overview_grid_side_margin">50dp</dimen>
-    <dimen name="overview_grid_row_spacing_portrait">37.13dp</dimen>
-    <dimen name="overview_grid_row_spacing_landscape">33.38dp</dimen>
+    <dimen name="overview_grid_row_spacing_portrait">17.13dp</dimen>
+    <dimen name="overview_grid_row_spacing_landscape">13.38dp</dimen>
     <dimen name="overview_grid_focus_vertical_margin">0dp</dimen>
 
     <!-- These speeds are in dp/s -->
@@ -165,4 +166,5 @@
     <dimen name="taskbar_stashed_size">24dp</dimen>
     <dimen name="taskbar_stashed_handle_width">220dp</dimen>
     <dimen name="taskbar_stashed_handle_height">6dp</dimen>
+    <dimen name="taskbar_edu_bg_corner_radius">28dp</dimen>
 </resources>
diff --git a/quickstep/res/values/strings.xml b/quickstep/res/values/strings.xml
index 4aee2a9..2916121 100644
--- a/quickstep/res/values/strings.xml
+++ b/quickstep/res/values/strings.xml
@@ -203,4 +203,27 @@
     <string name="gesture_tutorial_action_button_label_cancel">Cancel</string>
     <!-- Button text shown on a button on the tutorial skip dialog to exit the tutorial. [CHAR LIMIT=14] -->
     <string name="gesture_tutorial_action_button_label_skip">Skip</string>
+
+    <!-- ******* Taskbar Edu ******* -->
+    <!-- Accessibility text spoken when the taskbar education panel appears [CHAR_LIMIT=NONE] -->
+    <string name="taskbar_edu_opened">Taskbar education appeared</string>
+    <!-- Accessibility text spoken when the taskbar education panel disappears [CHAR_LIMIT=NONE] -->
+    <string name="taskbar_edu_closed">Taskbar education closed</string>
+    <!-- Text in dialog that lets a user know how they can use the taskbar to use multiple apps on their device.
+         [CHAR_LIMIT=60] -->
+    <string name="taskbar_edu_splitscreen" translatable="false">Use 2 apps at once and switch apps with the taskbar</string>
+    <!-- Text in dialog that lets a user know how they can customize the taskbar on their device.
+         [CHAR_LIMIT=60] -->
+    <string name="taskbar_edu_customize" translatable="false">Add your favorite apps and get automatic suggestions</string>
+    <!-- Text in dialog that lets a user know how they can hide the taskbar on their device.
+         [CHAR_LIMIT=60] -->
+    <string name="taskbar_edu_dock">Touch &amp; hold to hide the taskbar anytime</string>
+    <!-- Text on button to go to the next screen of a tutorial [CHAR_LIMIT=16] -->
+    <string name="taskbar_edu_next">Next</string>
+    <!-- Text on button to go to the previous screen of a tutorial [CHAR_LIMIT=16] -->
+    <string name="taskbar_edu_previous">Back</string>
+    <!-- Text on button to exit a tutorial [CHAR_LIMIT=16] -->
+    <string name="taskbar_edu_close">Close</string>
+    <!-- Text on button to finish a tutorial [CHAR_LIMIT=16] -->
+    <string name="taskbar_edu_done">Done</string>
 </resources>
diff --git a/quickstep/res/values/styles.xml b/quickstep/res/values/styles.xml
index 07c448d..ac70279 100644
--- a/quickstep/res/values/styles.xml
+++ b/quickstep/res/values/styles.xml
@@ -139,4 +139,18 @@
     <style name="BaseIcon.Workspace.Taskbar" >
         <item name="iconDisplay">taskbar</item>
     </style>
+
+    <style name="TaskbarEdu.Button.Close" parent="@android:style/Widget.Material.Button">
+        <item name="android:background">@drawable/button_taskbar_edu_bordered</item>
+        <item name="android:stateListAnimator">@null</item>
+        <item name="android:textSize">16sp</item>
+        <item name="android:padding">4dp</item>
+    </style>
+
+    <style name="TaskbarEdu.Button.Next" parent="@android:style/Widget.Material.Button">
+        <item name="android:background">@drawable/button_taskbar_edu_colored</item>
+        <item name="android:stateListAnimator">@null</item>
+        <item name="android:textSize">16sp</item>
+        <item name="android:padding">4dp</item>
+    </style>
 </resources>
\ No newline at end of file
diff --git a/quickstep/robolectric_tests/src/com/android/quickstep/RecentsActivityTest.java b/quickstep/robolectric_tests/src/com/android/quickstep/RecentsActivityTest.java
deleted file mode 100644
index 9df9ab1..0000000
--- a/quickstep/robolectric_tests/src/com/android/quickstep/RecentsActivityTest.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * 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.
- * 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.quickstep;
-
-import static com.android.launcher3.util.LauncherUIHelper.doLayout;
-
-import android.app.ActivityManager.RunningTaskInfo;
-import android.graphics.Bitmap;
-import android.graphics.Bitmap.Config;
-
-import com.android.quickstep.fallback.FallbackRecentsView;
-import com.android.systemui.shared.recents.model.ThumbnailData;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.Robolectric;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.android.controller.ActivityController;
-import org.robolectric.annotation.LooperMode;
-import org.robolectric.annotation.LooperMode.Mode;
-import org.robolectric.shadows.ShadowLooper;
-import org.robolectric.util.ReflectionHelpers;
-
-
-@RunWith(RobolectricTestRunner.class)
-@LooperMode(Mode.PAUSED)
-@org.junit.Ignore
-public class RecentsActivityTest {
-
-    @Test
-    public void testRecentsActivityCreates() {
-        ActivityController<RecentsActivity> controller =
-                Robolectric.buildActivity(RecentsActivity.class);
-
-        RecentsActivity launcher = controller.setup().get();
-        doLayout(launcher);
-
-        // TODO: Ensure that LauncherAppState is not created
-    }
-
-    @Test
-    public void testRecents_showCurrentTask() {
-        ActivityController<RecentsActivity> controller =
-                Robolectric.buildActivity(RecentsActivity.class);
-
-        RecentsActivity activity = controller.setup().get();
-        doLayout(activity);
-
-        FallbackRecentsView frv = activity.getOverviewPanel();
-
-        RunningTaskInfo placeholderTask = new RunningTaskInfo();
-        placeholderTask.taskId = 22;
-        frv.showCurrentTask(placeholderTask);
-        doLayout(activity);
-
-        ThumbnailData thumbnailData = new ThumbnailData();
-        ReflectionHelpers.setField(thumbnailData, "thumbnail",
-                Bitmap.createBitmap(300, 500, Config.ARGB_8888));
-        frv.switchToScreenshot(thumbnailData, () -> { });
-        ShadowLooper.idleMainLooper();
-    }
-}
diff --git a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
index 2da8a45..f06447b 100644
--- a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
+++ b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
@@ -32,7 +32,6 @@
 import static com.android.launcher3.anim.Interpolators.AGGRESSIVE_EASE;
 import static com.android.launcher3.anim.Interpolators.DEACCEL_1_5;
 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;
@@ -71,6 +70,7 @@
 import android.view.View;
 import android.view.ViewRootImpl;
 import android.view.ViewTreeObserver;
+import android.view.animation.AnimationUtils;
 import android.view.animation.Interpolator;
 import android.view.animation.PathInterpolator;
 
@@ -85,6 +85,7 @@
 import com.android.launcher3.icons.FastBitmapDrawable;
 import com.android.launcher3.shortcuts.DeepShortcutView;
 import com.android.launcher3.statehandlers.DepthController;
+import com.android.launcher3.taskbar.LauncherTaskbarUIController;
 import com.android.launcher3.util.ActivityOptionsWrapper;
 import com.android.launcher3.util.MultiValueAlpha.AlphaProperty;
 import com.android.launcher3.util.RunnableList;
@@ -141,21 +142,11 @@
     private static final String CONTROL_REMOTE_APP_TRANSITION_PERMISSION =
             "android.permission.CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS";
 
-    private static final long APP_LAUNCH_DURATION = 450;
-    // Use a shorter duration for x or y translation to create a curve effect
-    private static final long APP_LAUNCH_CURVED_DURATION = 250;
+    private static final long APP_LAUNCH_DURATION = 500;
+
     private static final long APP_LAUNCH_ALPHA_DURATION = 50;
     private static final long APP_LAUNCH_ALPHA_START_DELAY = 25;
 
-    // We scale the durations for the downward app launch animations (minus the scale animation).
-    private static final float APP_LAUNCH_DOWN_DUR_SCALE_FACTOR = 0.8f;
-    private static final long APP_LAUNCH_DOWN_DURATION =
-            (long) (APP_LAUNCH_DURATION * APP_LAUNCH_DOWN_DUR_SCALE_FACTOR);
-    private static final long APP_LAUNCH_DOWN_CURVED_DURATION =
-            (long) (APP_LAUNCH_CURVED_DURATION * APP_LAUNCH_DOWN_DUR_SCALE_FACTOR);
-    private static final long APP_LAUNCH_ALPHA_DOWN_DURATION =
-            (long) (APP_LAUNCH_ALPHA_DURATION * APP_LAUNCH_DOWN_DUR_SCALE_FACTOR);
-
     public static final int ANIMATION_NAV_FADE_IN_DURATION = 266;
     public static final int ANIMATION_NAV_FADE_OUT_DURATION = 133;
     public static final long ANIMATION_DELAY_NAV_FADE_IN =
@@ -165,9 +156,6 @@
     public static final Interpolator NAV_FADE_OUT_INTERPOLATOR =
             new PathInterpolator(0.2f, 0f, 1f, 1f);
 
-    private static final long CROP_DURATION = 375;
-    private static final long RADIUS_DURATION = 375;
-
     public static final int RECENTS_LAUNCH_DURATION = 336;
     private static final int LAUNCHER_RESUME_START_DELAY = 100;
     private static final int CLOSING_TRANSITION_DURATION_MS = 250;
@@ -221,6 +209,9 @@
     // Will never be larger than MAX_NUM_TASKS
     private LinkedHashMap<Integer, Pair<Integer, Integer>> mTaskStartParams;
 
+    private final Interpolator mOpeningXInterpolator;
+    private final Interpolator mOpeningInterpolator;
+
     public QuickstepTransitionManager(Context context) {
         mLauncher = Launcher.cast(Launcher.getLauncher(context));
         mDragLayer = mLauncher.getDragLayer();
@@ -247,6 +238,10 @@
             SystemUiProxy.INSTANCE.get(mLauncher).setStartingWindowListener(
                     mStartingWindowListener);
         }
+
+        mOpeningXInterpolator = AnimationUtils.loadInterpolator(context, R.interpolator.app_open_x);
+        mOpeningInterpolator = AnimationUtils.loadInterpolator(context,
+                R.interpolator.three_point_fast_out_extra_slow_in);
     }
 
     @Override
@@ -427,6 +422,10 @@
                         4 - rotationChange);
             }
         }
+        // TODO(b/196637509): don't do this for immersive apps.
+        if (mDeviceProfile.isTaskbarPresentInApps) {
+            bounds.bottom -= mDeviceProfile.taskbarSize;
+        }
         return bounds;
     }
 
@@ -511,7 +510,10 @@
 
             final boolean scrimEnabled = ENABLE_SCRIM_FOR_APP_LAUNCH.get();
             if (scrimEnabled) {
-                int scrimColor = Themes.getAttrColor(mLauncher, R.attr.overviewScrimColor);
+                boolean useTaskbarColor = mDeviceProfile.isTaskbarPresentInApps;
+                int scrimColor = useTaskbarColor
+                        ? mLauncher.getResources().getColor(R.color.taskbar_background)
+                        : Themes.getAttrColor(mLauncher, R.attr.overviewScrimColor);
                 int scrimColorTrans = ColorUtils.setAlphaComponent(scrimColor, 0);
                 int[] colors = isAppOpening
                         ? new int[]{scrimColorTrans, scrimColor}
@@ -524,6 +526,30 @@
                             colors);
                     scrim.setDuration(CONTENT_SCRIM_DURATION);
                     scrim.setInterpolator(DEACCEL_1_5);
+
+                    if (useTaskbarColor) {
+                        // Hide the taskbar background color since it would duplicate the scrim.
+                        scrim.addListener(new AnimatorListenerAdapter() {
+                            @Override
+                            public void onAnimationStart(Animator animation) {
+                                LauncherTaskbarUIController taskbarUIController =
+                                        mLauncher.getTaskbarUIController();
+                                if (taskbarUIController != null) {
+                                    taskbarUIController.forceHideBackground(true);
+                                }
+                            }
+
+                            @Override
+                            public void onAnimationEnd(Animator animation) {
+                                LauncherTaskbarUIController taskbarUIController =
+                                        mLauncher.getTaskbarUIController();
+                                if (taskbarUIController != null) {
+                                    taskbarUIController.forceHideBackground(false);
+                                }
+                            }
+                        });
+                    }
+
                     launcherAnimator.play(scrim);
                 }
             }
@@ -638,6 +664,10 @@
                 if (v instanceof BubbleTextView) {
                     ((BubbleTextView) v).setStayPressed(false);
                 }
+                LauncherTaskbarUIController taskbarController = mLauncher.getTaskbarUIController();
+                if (taskbarController != null) {
+                    taskbarController.showEdu();
+                }
                 openingTargets.release();
             }
         });
@@ -650,27 +680,29 @@
         final float finalShadowRadius = appTargetsAreTranslucent ? 0 : mMaxShadowRadius;
 
         MultiValueUpdateListener listener = new MultiValueUpdateListener() {
-            FloatProp mDx = new FloatProp(0, prop.dX, 0, prop.xDuration, AGGRESSIVE_EASE);
-            FloatProp mDy = new FloatProp(0, prop.dY, 0, prop.yDuration, AGGRESSIVE_EASE);
+            FloatProp mDx = new FloatProp(0, prop.dX, 0, APP_LAUNCH_DURATION,
+                    mOpeningXInterpolator);
+            FloatProp mDy = new FloatProp(0, prop.dY, 0, APP_LAUNCH_DURATION,
+                    mOpeningInterpolator);
 
             FloatProp mIconScaleToFitScreen = new FloatProp(prop.initialAppIconScale,
-                    prop.finalAppIconScale, 0, APP_LAUNCH_DURATION, EXAGGERATED_EASE);
+                    prop.finalAppIconScale, 0, APP_LAUNCH_DURATION, mOpeningInterpolator);
             FloatProp mIconAlpha = new FloatProp(prop.iconAlphaStart, 0f,
-                    APP_LAUNCH_ALPHA_START_DELAY, prop.alphaDuration, LINEAR);
+                    APP_LAUNCH_ALPHA_START_DELAY, APP_LAUNCH_ALPHA_DURATION, LINEAR);
 
             FloatProp mWindowRadius = new FloatProp(initialWindowRadius, finalWindowRadius, 0,
-                    RADIUS_DURATION, EXAGGERATED_EASE);
+                    APP_LAUNCH_DURATION, mOpeningInterpolator);
             FloatProp mShadowRadius = new FloatProp(0, finalShadowRadius, 0,
-                    APP_LAUNCH_DURATION, EXAGGERATED_EASE);
+                    APP_LAUNCH_DURATION, mOpeningInterpolator);
 
             FloatProp mCropRectCenterX = new FloatProp(prop.cropCenterXStart, prop.cropCenterXEnd,
-                    0, CROP_DURATION, EXAGGERATED_EASE);
+                    0, APP_LAUNCH_DURATION, mOpeningInterpolator);
             FloatProp mCropRectCenterY = new FloatProp(prop.cropCenterYStart, prop.cropCenterYEnd,
-                    0, CROP_DURATION, EXAGGERATED_EASE);
+                    0, APP_LAUNCH_DURATION, mOpeningInterpolator);
             FloatProp mCropRectWidth = new FloatProp(prop.cropWidthStart, prop.cropWidthEnd, 0,
-                    CROP_DURATION, EXAGGERATED_EASE);
+                    APP_LAUNCH_DURATION, mOpeningInterpolator);
             FloatProp mCropRectHeight = new FloatProp(prop.cropHeightStart, prop.cropHeightEnd, 0,
-                    CROP_DURATION, EXAGGERATED_EASE);
+                    APP_LAUNCH_DURATION, mOpeningInterpolator);
 
             FloatProp mNavFadeOut = new FloatProp(1f, 0f, 0, ANIMATION_NAV_FADE_OUT_DURATION,
                     NAV_FADE_OUT_INTERPOLATOR);
@@ -872,22 +904,23 @@
                     WIDGET_CROSSFADE_DURATION_MILLIS / 2 /* delay */,
                     WIDGET_CROSSFADE_DURATION_MILLIS / 2 /* duration */, LINEAR);
             final FloatProp mWindowRadius = new FloatProp(initialWindowRadius, finalWindowRadius,
-                    0 /* start */, RADIUS_DURATION, LINEAR);
-            final FloatProp mCornerRadiusProgress = new FloatProp(0, 1, 0, RADIUS_DURATION, LINEAR);
+                    0 /* start */, APP_LAUNCH_DURATION, mOpeningInterpolator);
+            final FloatProp mCornerRadiusProgress = new FloatProp(0, 1, 0, APP_LAUNCH_DURATION,
+                    mOpeningInterpolator);
 
             // Window & widget background positioning bounds
             final FloatProp mDx = new FloatProp(widgetBackgroundBounds.centerX(),
-                    windowTargetBounds.centerX(), 0 /* delay */, APP_LAUNCH_CURVED_DURATION,
-                    EXAGGERATED_EASE);
+                    windowTargetBounds.centerX(), 0 /* delay */, APP_LAUNCH_DURATION,
+                    mOpeningXInterpolator);
             final FloatProp mDy = new FloatProp(widgetBackgroundBounds.centerY(),
                     windowTargetBounds.centerY(), 0 /* delay */, APP_LAUNCH_DURATION,
-                    EXAGGERATED_EASE);
+                    mOpeningInterpolator);
             final FloatProp mWidth = new FloatProp(widgetBackgroundBounds.width(),
                     windowTargetBounds.width(), 0 /* delay */, APP_LAUNCH_DURATION,
-                    EXAGGERATED_EASE);
+                    mOpeningInterpolator);
             final FloatProp mHeight = new FloatProp(widgetBackgroundBounds.height(),
                     windowTargetBounds.height(), 0 /* delay */, APP_LAUNCH_DURATION,
-                    EXAGGERATED_EASE);
+                    mOpeningInterpolator);
 
             final FloatProp mNavFadeOut = new FloatProp(1f, 0f, 0, ANIMATION_NAV_FADE_OUT_DURATION,
                     NAV_FADE_OUT_INTERPOLATOR);
@@ -1431,10 +1464,6 @@
         public final float dX;
         public final float dY;
 
-        public final long xDuration;
-        public final long yDuration;
-        public final long alphaDuration;
-
         public final float initialAppIconScale;
         public final float finalAppIconScale;
 
@@ -1466,14 +1495,6 @@
             dX = centerX - launcherIconBounds.centerX();
             dY = centerY - launcherIconBounds.centerY();
 
-            boolean useUpwardAnimation = launcherIconBounds.top > centerY
-                    || Math.abs(dY) < dp.cellHeightPx;
-            xDuration = useUpwardAnimation ? APP_LAUNCH_CURVED_DURATION
-                    : APP_LAUNCH_DOWN_DURATION;
-            yDuration = useUpwardAnimation ? APP_LAUNCH_DURATION
-                    : APP_LAUNCH_DOWN_CURVED_DURATION;
-            alphaDuration = useUpwardAnimation ? APP_LAUNCH_ALPHA_DURATION
-                    : APP_LAUNCH_ALPHA_DOWN_DURATION;
             iconAlphaStart = hasSplashScreen && !hasDifferentAppIcon ? 0 : 1f;
 
             final int windowIconSize = ResourceUtils.getDimenByName("starting_surface_icon_size",
diff --git a/quickstep/src/com/android/launcher3/statehandlers/DepthController.java b/quickstep/src/com/android/launcher3/statehandlers/DepthController.java
index aba16c2..68159fa 100644
--- a/quickstep/src/com/android/launcher3/statehandlers/DepthController.java
+++ b/quickstep/src/com/android/launcher3/statehandlers/DepthController.java
@@ -26,6 +26,7 @@
 import android.os.IBinder;
 import android.os.SystemProperties;
 import android.util.FloatProperty;
+import android.view.AttachedSurfaceControl;
 import android.view.CrossWindowBlurListeners;
 import android.view.SurfaceControl;
 import android.view.View;
@@ -108,6 +109,13 @@
         }
     };
 
+    private final Runnable mOpaquenessListener = new Runnable() {
+        @Override
+        public void run() {
+            dispatchTransactionSurface(mDepth);
+        }
+    };
+
     private final Launcher mLauncher;
     /**
      * Blur radius when completely zoomed out, in pixels.
@@ -158,23 +166,28 @@
                     if (windowToken != null) {
                         mWallpaperManager.setWallpaperZoomOut(windowToken, mDepth);
                     }
-                    CrossWindowBlurListeners.getInstance().addListener(mLauncher.getMainExecutor(),
-                            mCrossWindowBlurListener);
+                    onAttached();
                 }
 
                 @Override
                 public void onViewDetachedFromWindow(View view) {
                     CrossWindowBlurListeners.getInstance().removeListener(mCrossWindowBlurListener);
+                    mLauncher.getScrimView().removeOpaquenessListener(mOpaquenessListener);
                 }
             };
             mLauncher.getRootView().addOnAttachStateChangeListener(mOnAttachListener);
             if (mLauncher.getRootView().isAttachedToWindow()) {
-                CrossWindowBlurListeners.getInstance().addListener(mLauncher.getMainExecutor(),
-                        mCrossWindowBlurListener);
+                onAttached();
             }
         }
     }
 
+    private void onAttached() {
+        CrossWindowBlurListeners.getInstance().addListener(mLauncher.getMainExecutor(),
+                mCrossWindowBlurListener);
+        mLauncher.getScrimView().addOpaquenessListener(mOpaquenessListener);
+    }
+
     /**
      * Sets if the underlying activity is started or not
      */
@@ -262,7 +275,7 @@
     public void onOverlayScrollChanged(float progress) {
         // Round out the progress to dedupe frequent, non-perceptable updates
         int progressI = (int) (progress * 256);
-        float progressF = progressI / 256f;
+        float progressF = Utilities.boundToRange(progressI / 256f, 0f, 1f);
         if (Float.compare(mOverlayScrollProgress, progressF) == 0) {
             return;
         }
@@ -304,7 +317,12 @@
                 transaction.setEarlyWakeupEnd();
                 mInEarlyWakeUp = false;
             }
-            transaction.apply();
+
+            AttachedSurfaceControl rootSurfaceControl =
+                    mLauncher.getRootView().getRootSurfaceControl();
+            if (rootSurfaceControl != null) {
+                rootSurfaceControl.applyTransactionOnDraw(transaction);
+            }
         }
         return true;
     }
diff --git a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
index b5c834d..da10bfb 100644
--- a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
@@ -23,24 +23,28 @@
 import android.animation.ObjectAnimator;
 import android.graphics.Rect;
 import android.view.MotionEvent;
+import android.view.View;
 
 import androidx.annotation.NonNull;
 
 import com.android.launcher3.BaseQuickstepLauncher;
+import com.android.launcher3.DeviceProfile;
 import com.android.launcher3.LauncherState;
 import com.android.launcher3.QuickstepTransitionManager;
 import com.android.launcher3.R;
 import com.android.launcher3.anim.AnimatorListeners;
+import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.util.MultiValueAlpha;
 import com.android.launcher3.util.MultiValueAlpha.AlphaProperty;
+import com.android.launcher3.util.OnboardingPrefs;
 import com.android.quickstep.AnimatedFloat;
 import com.android.quickstep.RecentsAnimationCallbacks;
 import com.android.quickstep.RecentsAnimationCallbacks.RecentsAnimationListener;
 import com.android.quickstep.RecentsAnimationController;
 import com.android.quickstep.SystemUiProxy;
+import com.android.quickstep.views.RecentsView;
 import com.android.systemui.shared.recents.model.ThumbnailData;
 
-
 /**
  * A data source which integrates with a Launcher instance
  */
@@ -58,9 +62,13 @@
     private final AnimatedFloat mIconAlignmentForGestureState =
             new AnimatedFloat(this::onIconAlignmentRatioChanged);
 
+    private final DeviceProfile.OnDeviceProfileChangeListener mOnDeviceProfileChangeListener =
+            this::onStashedInAppChanged;
+
     // Initialized in init.
     private TaskbarControllers mControllers;
     private AnimatedFloat mTaskbarBackgroundAlpha;
+    private AnimatedFloat mTaskbarOverrideBackgroundAlpha;
     private AlphaProperty mIconAlphaForHome;
     private boolean mIsAnimatingToLauncherViaResume;
     private boolean mIsAnimatingToLauncherViaGesture;
@@ -84,6 +92,8 @@
 
         mTaskbarBackgroundAlpha = mControllers.taskbarDragLayerController
                 .getTaskbarBackgroundAlpha();
+        mTaskbarOverrideBackgroundAlpha = mControllers.taskbarDragLayerController
+                .getOverrideBackgroundAlpha();
 
         MultiValueAlpha taskbarIconAlpha = mControllers.taskbarViewController.getTaskbarIconAlpha();
         mIconAlphaForHome = taskbarIconAlpha.getProperty(ALPHA_INDEX_HOME);
@@ -94,6 +104,9 @@
         onLauncherResumedOrPaused(mLauncher.hasBeenResumed());
         mIconAlignmentForResumedState.finishAnimation();
         onIconAlignmentRatioChanged();
+
+        onStashedInAppChanged(mLauncher.getDeviceProfile());
+        mLauncher.addOnDeviceProfileChangeListener(mOnDeviceProfileChangeListener);
     }
 
     @Override
@@ -102,6 +115,7 @@
         mIconAlignmentForResumedState.finishAnimation();
         mIconAlignmentForGestureState.finishAnimation();
 
+        mLauncher.removeOnDeviceProfileChangeListener(mOnDeviceProfileChangeListener);
         mLauncher.getHotseat().setIconsAlpha(1f);
         mLauncher.setTaskbarUIController(null);
     }
@@ -159,8 +173,7 @@
      *                 automatically reset once the recents animation finishes
      */
     public Animator createAnimToLauncher(@NonNull LauncherState toState,
-            @NonNull RecentsAnimationCallbacks callbacks,
-            long duration) {
+            @NonNull RecentsAnimationCallbacks callbacks, long duration) {
         TaskbarStashController stashController = mControllers.taskbarStashController;
         ObjectAnimator animator = mIconAlignmentForGestureState
                 .animateToValue(1)
@@ -180,36 +193,20 @@
                 stashController.animateToIsStashed(false, duration);
             }
         });
-        callbacks.addListener(new RecentsAnimationListener() {
-            @Override
-            public void onRecentsAnimationCanceled(ThumbnailData thumbnailData) {
-                endGestureStateOverride(true);
-            }
 
-            @Override
-            public void onRecentsAnimationFinished(RecentsAnimationController controller) {
-                endGestureStateOverride(!controller.getFinishTargetIsLauncher());
-            }
-
-            private void endGestureStateOverride(boolean finishedToApp) {
-                callbacks.removeListener(this);
-                mIsAnimatingToLauncherViaGesture = false;
-
-                mIconAlignmentForGestureState
-                        .animateToValue(0)
-                        .start();
-
-                if (finishedToApp) {
-                    // We only need this for the exiting live tile case.
-                    stashController.animateToIsStashed(stashController.isStashedInApp());
-                }
-            }
+        TaskBarRecentsAnimationListener listener = new TaskBarRecentsAnimationListener(callbacks);
+        callbacks.addListener(listener);
+        RecentsView recentsView = mLauncher.getOverviewPanel();
+        recentsView.setTaskLaunchListener(() -> {
+            listener.endGestureStateOverride(true);
+            callbacks.removeListener(listener);
         });
+
         return animator;
     }
 
     private float getCurrentIconAlignmentRatio() {
-        return  Math.max(mIconAlignmentForResumedState.value, mIconAlignmentForGestureState.value);
+        return Math.max(mIconAlignmentForResumedState.value, mIconAlignmentForGestureState.value);
     }
 
     private void onIconAlignmentRatioChanged() {
@@ -245,8 +242,85 @@
         return mContext.getDragController().isDragging();
     }
 
-    void setTaskbarViewVisible(boolean isVisible) {
+    public View getRootView() {
+        return mTaskbarDragLayer;
+    }
+
+    private void setTaskbarViewVisible(boolean isVisible) {
         mIconAlphaForHome.setValue(isVisible ? 1 : 0);
         mLauncher.getHotseat().setIconsAlpha(isVisible ? 0f : 1f);
     }
+
+    @Override
+    protected void onStashedInAppChanged() {
+        onStashedInAppChanged(mLauncher.getDeviceProfile());
+    }
+
+    private void onStashedInAppChanged(DeviceProfile deviceProfile) {
+        boolean taskbarStashedInApps = mControllers.taskbarStashController.isStashedInApp();
+        deviceProfile.isTaskbarPresentInApps = !taskbarStashedInApps;
+    }
+
+    /**
+     * Sets whether the background behind the taskbar/nav bar should be hidden.
+     */
+    public void forceHideBackground(boolean forceHide) {
+        mTaskbarOverrideBackgroundAlpha.updateValue(forceHide ? 0 : 1);
+    }
+
+    /**
+     * Starts the taskbar education flow, if the user hasn't seen it yet.
+     */
+    public void showEdu() {
+        if (!FeatureFlags.ENABLE_TASKBAR_EDU.get()
+                || mLauncher.getOnboardingPrefs().getBoolean(OnboardingPrefs.TASKBAR_EDU_SEEN)) {
+            return;
+        }
+        mLauncher.getOnboardingPrefs().markChecked(OnboardingPrefs.TASKBAR_EDU_SEEN);
+
+        mControllers.taskbarEduController.showEdu();
+    }
+
+    /**
+     * Manually ends the taskbar education flow.
+     */
+    public void hideEdu() {
+        if (!FeatureFlags.ENABLE_TASKBAR_EDU.get()) {
+            return;
+        }
+
+        mControllers.taskbarEduController.hideEdu();
+    }
+
+    private final class TaskBarRecentsAnimationListener implements RecentsAnimationListener {
+        private final RecentsAnimationCallbacks mCallbacks;
+
+        TaskBarRecentsAnimationListener(RecentsAnimationCallbacks callbacks) {
+            mCallbacks = callbacks;
+        }
+
+        @Override
+        public void onRecentsAnimationCanceled(ThumbnailData thumbnailData) {
+            endGestureStateOverride(true);
+        }
+
+        @Override
+        public void onRecentsAnimationFinished(RecentsAnimationController controller) {
+            endGestureStateOverride(!controller.getFinishTargetIsLauncher());
+        }
+
+        private void endGestureStateOverride(boolean finishedToApp) {
+            mCallbacks.removeListener(this);
+            mIsAnimatingToLauncherViaGesture = false;
+
+            mIconAlignmentForGestureState
+                    .animateToValue(0)
+                    .start();
+
+            TaskbarStashController controller = mControllers.taskbarStashController;
+            if (finishedToApp) {
+                controller.animateToIsStashed(controller.isStashedInApp());
+            }
+        }
+    }
 }
diff --git a/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java b/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java
index 08300e2..e871c25 100644
--- a/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java
@@ -25,8 +25,11 @@
 import static com.android.launcher3.taskbar.TaskbarViewController.ALPHA_INDEX_KEYGUARD;
 import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_A11Y_BUTTON_CLICKABLE;
 import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BACK_DISABLED;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_HOME_DISABLED;
 import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_IME_SHOWING;
 import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_IME_SWITCHER_SHOWING;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_OVERVIEW_DISABLED;
 
 import android.animation.ObjectAnimator;
 import android.annotation.DrawableRes;
@@ -69,6 +72,9 @@
     private static final int FLAG_A11Y_VISIBLE = 1 << 3;
     private static final int FLAG_ONLY_BACK_FOR_BOUNCER_VISIBLE = 1 << 4;
     private static final int FLAG_KEYGUARD_VISIBLE = 1 << 5;
+    private static final int FLAG_DISABLE_HOME = 1 << 6;
+    private static final int FLAG_DISABLE_RECENTS = 1 << 7;
+    private static final int FLAG_DISABLE_BACK = 1 << 8;
 
     private static final int MASK_IME_SWITCHER_VISIBLE = FLAG_SWITCHER_SUPPORTED | FLAG_IME_VISIBLE;
 
@@ -169,7 +175,8 @@
         mBackButton = addButton(R.drawable.ic_sysbar_back, BUTTON_BACK,
                 mNavButtonContainer, mControllers.navButtonController, R.id.back);
         mPropertyHolders.add(new StatePropertyHolder(mBackButton,
-                flags -> (flags & FLAG_IME_VISIBLE) == 0));
+                flags -> (flags & FLAG_IME_VISIBLE) == 0 &&
+                        (flags & FLAG_DISABLE_BACK) == 0));
         // Hide when keyguard is showing, show when bouncer is showing
         mPropertyHolders.add(new StatePropertyHolder(mBackButton,
                 flags -> (flags & FLAG_KEYGUARD_VISIBLE) == 0 ||
@@ -180,12 +187,14 @@
                 navButtonController, R.id.home);
         mPropertyHolders.add(new StatePropertyHolder(homeButton,
                 flags -> (flags & FLAG_IME_VISIBLE) == 0 &&
-                        (flags & FLAG_KEYGUARD_VISIBLE) == 0));
+                        (flags & FLAG_KEYGUARD_VISIBLE) == 0 &&
+                        (flags & FLAG_DISABLE_HOME) == 0));
         View recentsButton = addButton(R.drawable.ic_sysbar_recent, BUTTON_RECENTS,
                 navContainer, navButtonController, R.id.recent_apps);
         mPropertyHolders.add(new StatePropertyHolder(recentsButton,
                 flags -> (flags & FLAG_IME_VISIBLE) == 0 &&
-                        (flags & FLAG_KEYGUARD_VISIBLE) == 0));
+                        (flags & FLAG_KEYGUARD_VISIBLE) == 0 &&
+                        (flags & FLAG_DISABLE_RECENTS) == 0));
 
         // A11y button
         mA11yButton = addButton(R.drawable.ic_sysbar_accessibility_button, BUTTON_A11Y,
@@ -202,6 +211,12 @@
         boolean a11yVisible = (systemUiStateFlags & SYSUI_STATE_A11Y_BUTTON_CLICKABLE) != 0;
         boolean a11yLongClickable =
                 (systemUiStateFlags & SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE) != 0;
+        boolean isHomeDisabled =
+                (systemUiStateFlags & SYSUI_STATE_HOME_DISABLED) != 0;
+        boolean isRecentsDisabled =
+                (systemUiStateFlags & SYSUI_STATE_OVERVIEW_DISABLED) != 0;
+        boolean isBackDisabled =
+                (systemUiStateFlags & SYSUI_STATE_BACK_DISABLED) != 0;
 
         if (!forceUpdate && systemUiStateFlags == mSysuiStateFlags) {
             return;
@@ -211,6 +226,10 @@
         updateStateForFlag(FLAG_IME_VISIBLE, isImeVisible);
         updateStateForFlag(FLAG_SWITCHER_SUPPORTED, isImeSwitcherShowing);
         updateStateForFlag(FLAG_A11Y_VISIBLE, a11yVisible);
+        updateStateForFlag(FLAG_DISABLE_HOME, isHomeDisabled);
+        updateStateForFlag(FLAG_DISABLE_RECENTS, isRecentsDisabled);
+        updateStateForFlag(FLAG_DISABLE_BACK, isBackDisabled);
+
         if (mA11yButton != null) {
             // Only used in 3 button
             mA11yButton.setLongClickable(a11yLongClickable);
diff --git a/quickstep/src/com/android/launcher3/taskbar/StashedHandleView.java b/quickstep/src/com/android/launcher3/taskbar/StashedHandleView.java
new file mode 100644
index 0000000..0224bc4
--- /dev/null
+++ b/quickstep/src/com/android/launcher3/taskbar/StashedHandleView.java
@@ -0,0 +1,70 @@
+/*
+ * 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.Rect;
+import android.util.AttributeSet;
+import android.view.View;
+
+import androidx.annotation.ColorInt;
+import androidx.core.content.ContextCompat;
+
+import com.android.launcher3.R;
+
+public class StashedHandleView extends View {
+
+    private final @ColorInt int mStashedHandleLightColor;
+    private final @ColorInt int mStashedHandleDarkColor;
+    private final Rect mSampledRegion = new Rect();
+    private final int[] mTmpArr = new int[2];
+
+    public StashedHandleView(Context context) {
+        this(context, null);
+    }
+
+    public StashedHandleView(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public StashedHandleView(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public StashedHandleView(Context context, AttributeSet attrs, int defStyleAttr,
+            int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+
+        mStashedHandleLightColor = ContextCompat.getColor(context,
+                R.color.taskbar_stashed_handle_light_color);
+        mStashedHandleDarkColor = ContextCompat.getColor(context,
+                R.color.taskbar_stashed_handle_dark_color);
+    }
+
+    public void updateSampledRegion() {
+        getLocationOnScreen(mTmpArr);
+        mSampledRegion.set(mTmpArr[0], mTmpArr[1], mTmpArr[0] + getWidth(),
+                mTmpArr[1] + getHeight());
+    }
+
+    public Rect getSampledRegion() {
+        return mSampledRegion;
+    }
+
+    public void updateHandleColor(boolean isRegionDark) {
+        setBackgroundColor(isRegionDark ? mStashedHandleLightColor : mStashedHandleDarkColor);
+    }
+}
diff --git a/quickstep/src/com/android/launcher3/taskbar/StashedHandleViewController.java b/quickstep/src/com/android/launcher3/taskbar/StashedHandleViewController.java
index df37261..2858d7c 100644
--- a/quickstep/src/com/android/launcher3/taskbar/StashedHandleViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/StashedHandleViewController.java
@@ -16,6 +16,7 @@
 package com.android.launcher3.taskbar;
 
 import android.animation.Animator;
+import android.content.SharedPreferences;
 import android.content.res.Resources;
 import android.graphics.Outline;
 import android.graphics.Rect;
@@ -25,19 +26,30 @@
 import androidx.annotation.Nullable;
 
 import com.android.launcher3.R;
+import com.android.launcher3.Utilities;
 import com.android.launcher3.anim.RevealOutlineAnimation;
 import com.android.launcher3.anim.RoundedRectRevealOutlineProvider;
+import com.android.launcher3.util.Executors;
 import com.android.quickstep.AnimatedFloat;
+import com.android.systemui.shared.navigationbar.RegionSamplingHelper;
 
 /**
  * Handles properties/data collection, then passes the results to our stashed handle View to render.
  */
 public class StashedHandleViewController {
 
+    /**
+     * The SharedPreferences key for whether the stashed handle region is dark.
+     */
+    private static final String SHARED_PREFS_STASHED_HANDLE_REGION_DARK_KEY =
+            "stashed_handle_region_is_dark";
+
     private final TaskbarActivityContext mActivity;
-    private final View mStashedHandleView;
+    private final SharedPreferences mPrefs;
+    private final StashedHandleView mStashedHandleView;
     private final int mStashedHandleWidth;
     private final int mStashedHandleHeight;
+    private final RegionSamplingHelper mRegionSamplingHelper;
     private final AnimatedFloat mTaskbarStashedHandleAlpha = new AnimatedFloat(
             this::updateStashedHandleAlpha);
     private final AnimatedFloat mTaskbarStashedHandleHintScale = new AnimatedFloat(
@@ -52,13 +64,31 @@
 
     private boolean mIsAtStashedRevealBounds = true;
 
-    public StashedHandleViewController(TaskbarActivityContext activity, View stashedHandleView) {
+    public StashedHandleViewController(TaskbarActivityContext activity,
+            StashedHandleView stashedHandleView) {
         mActivity = activity;
+        mPrefs = Utilities.getPrefs(mActivity);
         mStashedHandleView = stashedHandleView;
+        mStashedHandleView.updateHandleColor(
+                mPrefs.getBoolean(SHARED_PREFS_STASHED_HANDLE_REGION_DARK_KEY, false));
         final Resources resources = mActivity.getResources();
         mStashedHandleWidth = resources.getDimensionPixelSize(R.dimen.taskbar_stashed_handle_width);
         mStashedHandleHeight = resources.getDimensionPixelSize(
                 R.dimen.taskbar_stashed_handle_height);
+        mRegionSamplingHelper = new RegionSamplingHelper(mStashedHandleView,
+                new RegionSamplingHelper.SamplingCallback() {
+                    @Override
+                    public void onRegionDarknessChanged(boolean isRegionDark) {
+                        mStashedHandleView.updateHandleColor(isRegionDark);
+                        mPrefs.edit().putBoolean(SHARED_PREFS_STASHED_HANDLE_REGION_DARK_KEY,
+                                isRegionDark).apply();
+                    }
+
+                    @Override
+                    public Rect getSampledRegion(View sampledView) {
+                        return mStashedHandleView.getSampledRegion();
+                    }
+                }, Executors.UI_HELPER_EXECUTOR);
     }
 
     public void init(TaskbarControllers controllers) {
@@ -93,6 +123,10 @@
         });
     }
 
+    public void onDestroy() {
+        mRegionSamplingHelper.stopAndDestroy();
+    }
+
     public AnimatedFloat getStashedHandleAlpha() {
         return mTaskbarStashedHandleAlpha;
     }
@@ -117,6 +151,16 @@
         return handleRevealProvider.createRevealAnimator(mStashedHandleView, !isStashed);
     }
 
+    public void onIsStashed(boolean isStashed) {
+        mRegionSamplingHelper.setWindowVisible(isStashed);
+        if (isStashed) {
+            mStashedHandleView.updateSampledRegion();
+            mRegionSamplingHelper.start(mStashedHandleView.getSampledRegion());
+        } else {
+            mRegionSamplingHelper.stop();
+        }
+    }
+
     protected void updateStashedHandleAlpha() {
         mStashedHandleView.setAlpha(mTaskbarStashedHandleAlpha.value);
     }
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
index dbe528f..8d7a6dc 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
@@ -36,12 +36,14 @@
 import android.view.Display;
 import android.view.Gravity;
 import android.view.LayoutInflater;
+import android.view.RoundedCorner;
 import android.view.View;
 import android.view.WindowManager;
 import android.widget.FrameLayout;
 import android.widget.Toast;
 
 import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
 
 import com.android.launcher3.AbstractFloatingView;
 import com.android.launcher3.DeviceProfile;
@@ -83,6 +85,7 @@
     private final TaskbarControllers mControllers;
 
     private final WindowManager mWindowManager;
+    private final @Nullable RoundedCorner mLeftCorner, mRightCorner;
     private WindowManager.LayoutParams mWindowLayoutParams;
     private boolean mIsFullscreen;
     // The size we should return to when we call setTaskbarWindowFullscreen(false)
@@ -115,7 +118,7 @@
                 R.layout.taskbar, null, false);
         TaskbarView taskbarView = mDragLayer.findViewById(R.id.taskbar_view);
         FrameLayout navButtonsView = mDragLayer.findViewById(R.id.navbuttons_view);
-        View stashedHandleView = mDragLayer.findViewById(R.id.stashed_handle);
+        StashedHandleView stashedHandleView = mDragLayer.findViewById(R.id.stashed_handle);
 
         // Construct controllers.
         mControllers = new TaskbarControllers(this,
@@ -128,17 +131,20 @@
                 new TaskbarViewController(this, taskbarView),
                 new TaskbarKeyguardController(this),
                 new StashedHandleViewController(this, stashedHandleView),
-                new TaskbarStashController(this));
+                new TaskbarStashController(this),
+                new TaskbarEduController(this));
 
         Display display = windowContext.getDisplay();
         Context c = display.getDisplayId() == Display.DEFAULT_DISPLAY
                 ? windowContext.getApplicationContext()
                 : windowContext.getApplicationContext().createDisplayContext(display);
         mWindowManager = c.getSystemService(WindowManager.class);
+        mLeftCorner = display.getRoundedCorner(RoundedCorner.POSITION_BOTTOM_LEFT);
+        mRightCorner = display.getRoundedCorner(RoundedCorner.POSITION_BOTTOM_RIGHT);
     }
 
     public void init() {
-        mLastRequestedNonFullscreenHeight = mDeviceProfile.taskbarSize;
+        mLastRequestedNonFullscreenHeight = getDefaultTaskbarWindowHeight();
         mWindowLayoutParams = new WindowManager.LayoutParams(
                 MATCH_PARENT,
                 mLastRequestedNonFullscreenHeight,
@@ -168,6 +174,14 @@
         return mNavMode == Mode.THREE_BUTTONS;
     }
 
+    public int getLeftCornerRadius() {
+        return mLeftCorner == null ? 0 : mLeftCorner.getRadius();
+    }
+
+    public int getRightCornerRadius() {
+        return mRightCorner == null ? 0 : mRightCorner.getRadius();
+    }
+
     @Override
     public LayoutInflater getLayoutInflater() {
         return mLayoutInflater;
@@ -234,7 +248,6 @@
             return;
         }
         mControllers.rotationButtonController.onDisable2FlagChanged(state2);
-        mControllers.taskbarKeyguardController.disableNavbarElements(state1, state2);
     }
 
     public void onSystemBarAttributesChanged(int displayId, int behavior) {
@@ -249,8 +262,12 @@
         setTaskbarWindowHeight(fullscreen ? MATCH_PARENT : mLastRequestedNonFullscreenHeight);
     }
 
+    public boolean isTaskbarWindowFullscreen() {
+        return mIsFullscreen;
+    }
+
     /**
-     * Updates the TaskbarContainer height (pass deviceProfile.taskbarSize to reset).
+     * Updates the TaskbarContainer height (pass {@link #getDefaultTaskbarWindowHeight()} to reset).
      */
     public void setTaskbarWindowHeight(int height) {
         if (mWindowLayoutParams.height == height || mIsDestroyed) {
@@ -270,6 +287,13 @@
         mWindowManager.updateViewLayout(mDragLayer, mWindowLayoutParams);
     }
 
+    /**
+     * Returns the default height of the window, including the static corner radii above taskbar.
+     */
+    public int getDefaultTaskbarWindowHeight() {
+        return mDeviceProfile.taskbarSize + Math.max(getLeftCornerRadius(), getRightCornerRadius());
+    }
+
     protected void onTaskbarIconClicked(View view) {
         Object tag = view.getTag();
         if (tag instanceof Task) {
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java
index be26913..b32a41e 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java
@@ -34,6 +34,7 @@
     public final TaskbarKeyguardController taskbarKeyguardController;
     public final StashedHandleViewController stashedHandleViewController;
     public final TaskbarStashController taskbarStashController;
+    public final TaskbarEduController taskbarEduController;
 
     /** Do not store this controller, as it may change at runtime. */
     @NonNull public TaskbarUIController uiController = TaskbarUIController.DEFAULT;
@@ -47,7 +48,8 @@
             TaskbarViewController taskbarViewController,
             TaskbarKeyguardController taskbarKeyguardController,
             StashedHandleViewController stashedHandleViewController,
-            TaskbarStashController taskbarStashController) {
+            TaskbarStashController taskbarStashController,
+            TaskbarEduController taskbarEduController) {
         this.taskbarActivityContext = taskbarActivityContext;
         this.taskbarDragController = taskbarDragController;
         this.navButtonController = navButtonController;
@@ -58,6 +60,7 @@
         this.taskbarKeyguardController = taskbarKeyguardController;
         this.stashedHandleViewController = stashedHandleViewController;
         this.taskbarStashController = taskbarStashController;
+        this.taskbarEduController = taskbarEduController;
     }
 
     /**
@@ -86,5 +89,6 @@
         taskbarDragLayerController.onDestroy();
         taskbarKeyguardController.onDestroy();
         taskbarViewController.onDestroy();
+        stashedHandleViewController.onDestroy();
     }
 }
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayer.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayer.java
index cd1baf7..b42a60c 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayer.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayer.java
@@ -18,6 +18,7 @@
 import android.content.Context;
 import android.graphics.Canvas;
 import android.graphics.Paint;
+import android.graphics.Path;
 import android.util.AttributeSet;
 import android.view.MotionEvent;
 import android.view.View;
@@ -40,9 +41,12 @@
 public class TaskbarDragLayer extends BaseDragLayer<TaskbarActivityContext> {
 
     private final Paint mTaskbarBackgroundPaint;
+    private final Path mInvertedLeftCornerPath, mInvertedRightCornerPath;
     private final OnComputeInsetsListener mTaskbarInsetsComputer = this::onComputeTaskbarInsets;
 
+    // Initialized in init.
     private TaskbarDragLayerController.TaskbarDragLayerCallbacks mControllerCallbacks;
+    private float mLeftCornerRadius, mRightCornerRadius;
 
     private float mTaskbarBackgroundOffset;
 
@@ -65,10 +69,32 @@
         mTaskbarBackgroundPaint = new Paint();
         mTaskbarBackgroundPaint.setColor(getResources().getColor(R.color.taskbar_background));
         mTaskbarBackgroundPaint.setAlpha(0);
+        mTaskbarBackgroundPaint.setFlags(Paint.ANTI_ALIAS_FLAG);
+        mTaskbarBackgroundPaint.setStyle(Paint.Style.FILL);
+
+        // Will be set in init(), but this ensures they are always non-null.
+        mInvertedLeftCornerPath = new Path();
+        mInvertedRightCornerPath = new Path();
     }
 
     public void init(TaskbarDragLayerController.TaskbarDragLayerCallbacks callbacks) {
         mControllerCallbacks = callbacks;
+
+        // Create the paths for the inverted rounded corners above the taskbar. Start with a filled
+        // square, and then subtracting out a circle from the appropriate corner.
+        mLeftCornerRadius = mActivity.getLeftCornerRadius();
+        mRightCornerRadius = mActivity.getRightCornerRadius();
+        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);
+
         recreateControllers();
     }
 
@@ -121,8 +147,20 @@
     protected void dispatchDraw(Canvas canvas) {
         float backgroundHeight = mControllerCallbacks.getTaskbarBackgroundHeight()
                 * (1f - mTaskbarBackgroundOffset);
-        canvas.drawRect(0, canvas.getHeight() - backgroundHeight, canvas.getWidth(),
-                canvas.getHeight(), mTaskbarBackgroundPaint);
+        canvas.save();
+        canvas.translate(0, canvas.getHeight() - backgroundHeight);
+
+        // Draw the background behind taskbar content.
+        canvas.drawRect(0, 0, canvas.getWidth(), backgroundHeight, mTaskbarBackgroundPaint);
+
+        // Draw the inverted rounded corners above the taskbar.
+        canvas.translate(0, -mLeftCornerRadius);
+        canvas.drawPath(mInvertedLeftCornerPath, mTaskbarBackgroundPaint);
+        canvas.translate(0, mLeftCornerRadius);
+        canvas.translate(canvas.getWidth() - mRightCornerRadius, -mRightCornerRadius);
+        canvas.drawPath(mInvertedRightCornerPath, mTaskbarBackgroundPaint);
+
+        canvas.restore();
         super.dispatchDraw(canvas);
     }
 
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java
index df89285..0afa480 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java
@@ -16,6 +16,7 @@
 package com.android.launcher3.taskbar;
 
 import static com.android.launcher3.AbstractFloatingView.TYPE_ALL;
+import static com.android.systemui.shared.system.ViewTreeObserverWrapper.InsetsInfo.TOUCHABLE_INSETS_CONTENT;
 import static com.android.systemui.shared.system.ViewTreeObserverWrapper.InsetsInfo.TOUCHABLE_INSETS_FRAME;
 import static com.android.systemui.shared.system.ViewTreeObserverWrapper.InsetsInfo.TOUCHABLE_INSETS_REGION;
 
@@ -36,10 +37,14 @@
     private final TaskbarActivityContext mActivity;
     private final TaskbarDragLayer mTaskbarDragLayer;
     private final int mFolderMargin;
+
     // Alpha properties for taskbar background.
     private final AnimatedFloat mBgTaskbar = new AnimatedFloat(this::updateBackgroundAlpha);
     private final AnimatedFloat mBgNavbar = new AnimatedFloat(this::updateBackgroundAlpha);
     private final AnimatedFloat mKeyguardBgTaskbar = new AnimatedFloat(this::updateBackgroundAlpha);
+    // Used to hide our background color when someone else (e.g. ScrimView) is handling it.
+    private final AnimatedFloat mBgOverride = new AnimatedFloat(this::updateBackgroundAlpha);
+
     // Translation property for taskbar background.
     private final AnimatedFloat mBgOffset = new AnimatedFloat(this::updateBackgroundOffset);
 
@@ -58,6 +63,7 @@
         mControllers = controllers;
         mTaskbarDragLayer.init(new TaskbarDragLayerCallbacks());
         mKeyguardBgTaskbar.value = 1;
+        mBgOverride.value = 1;
     }
 
     public void onDestroy() {
@@ -86,13 +92,19 @@
         return mKeyguardBgTaskbar;
     }
 
+    public AnimatedFloat getOverrideBackgroundAlpha() {
+        return mBgOverride;
+    }
+
     public AnimatedFloat getTaskbarBackgroundOffset() {
         return mBgOffset;
     }
 
     private void updateBackgroundAlpha() {
+        final float bgNavbar = mBgNavbar.value;
+        final float bgTaskbar = mBgTaskbar.value * mKeyguardBgTaskbar.value;
         mTaskbarDragLayer.setTaskbarBackgroundAlpha(
-                Math.max(mBgNavbar.value, mBgTaskbar.value * mKeyguardBgTaskbar.value)
+                mBgOverride.value * Math.max(bgNavbar, bgTaskbar)
         );
     }
 
@@ -121,13 +133,14 @@
                 // Let touches pass through us.
                 insetsInfo.setTouchableInsets(TOUCHABLE_INSETS_REGION);
             } else if (mControllers.navbarButtonsViewController.isImeVisible()) {
-                insetsInfo.setTouchableInsets(TOUCHABLE_INSETS_FRAME);
+                insetsInfo.setTouchableInsets(TOUCHABLE_INSETS_CONTENT);
             } else if (!mControllers.uiController.isTaskbarTouchable()) {
                 // Let touches pass through us.
                 insetsInfo.setTouchableInsets(TOUCHABLE_INSETS_REGION);
             } else if (mControllers.taskbarViewController.areIconsVisible()) {
                 // Buttons are visible, take over the full taskbar area
-                insetsInfo.setTouchableInsets(TOUCHABLE_INSETS_FRAME);
+                insetsInfo.setTouchableInsets(mActivity.isTaskbarWindowFullscreen()
+                        ? TOUCHABLE_INSETS_FRAME : TOUCHABLE_INSETS_CONTENT);
             } else {
                 insetsInfo.setTouchableInsets(TOUCHABLE_INSETS_REGION);
             }
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarEduController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarEduController.java
new file mode 100644
index 0000000..ae9592d
--- /dev/null
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarEduController.java
@@ -0,0 +1,69 @@
+/*
+ * 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 com.android.launcher3.R;
+
+/** Handles the Taskbar Education flow. */
+public class TaskbarEduController {
+
+    private final TaskbarActivityContext mActivity;
+    private TaskbarEduView mTaskbarEduView;
+
+    public TaskbarEduController(TaskbarActivityContext activity) {
+        mActivity = activity;
+    }
+
+    void showEdu() {
+        mActivity.setTaskbarWindowFullscreen(true);
+        mActivity.getDragLayer().post(() -> {
+            mTaskbarEduView = (TaskbarEduView) mActivity.getLayoutInflater().inflate(
+                    R.layout.taskbar_edu, mActivity.getDragLayer(), false);
+            mTaskbarEduView.init(new TaskbarEduCallbacks());
+            mTaskbarEduView.addOnCloseListener(() -> mTaskbarEduView = null);
+            mTaskbarEduView.show();
+        });
+    }
+
+    void hideEdu() {
+        if (mTaskbarEduView != null) {
+            mTaskbarEduView.close(true /* animate */);
+        }
+    }
+
+
+    /**
+     * Callbacks for {@link TaskbarEduView} to interact with its controller.
+     */
+    class TaskbarEduCallbacks {
+        void onPageChanged(int currentPage, int pageCount) {
+            if (currentPage == 0) {
+                mTaskbarEduView.updateStartButton(R.string.taskbar_edu_close,
+                        v -> mTaskbarEduView.close(true /* animate */));
+            } else {
+                mTaskbarEduView.updateStartButton(R.string.taskbar_edu_previous,
+                        v -> mTaskbarEduView.snapToPage(currentPage - 1));
+            }
+            if (currentPage == pageCount - 1) {
+                mTaskbarEduView.updateEndButton(R.string.taskbar_edu_done,
+                        v -> mTaskbarEduView.close(true /* animate */));
+            } else {
+                mTaskbarEduView.updateEndButton(R.string.taskbar_edu_next,
+                        v -> mTaskbarEduView.snapToPage(currentPage + 1));
+            }
+        }
+    }
+}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarEduPagedView.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarEduPagedView.java
new file mode 100644
index 0000000..5efcc4d
--- /dev/null
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarEduPagedView.java
@@ -0,0 +1,79 @@
+/*
+ * 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.launcher3.AbstractFloatingView.TYPE_ALL;
+import static com.android.launcher3.AbstractFloatingView.TYPE_TASKBAR_EDUCATION_DIALOG;
+
+import android.content.Context;
+import android.util.AttributeSet;
+
+import com.android.launcher3.AbstractFloatingView;
+import com.android.launcher3.PagedView;
+import com.android.launcher3.R;
+import com.android.launcher3.pageindicators.PageIndicatorDots;
+import com.android.launcher3.taskbar.TaskbarEduController.TaskbarEduCallbacks;
+import com.android.launcher3.views.ActivityContext;
+
+/** Horizontal carousel of tutorial screens for Taskbar Edu. */
+public class TaskbarEduPagedView extends PagedView<PageIndicatorDots> {
+
+    private TaskbarEduView mTaskbarEduView;
+    private TaskbarEduCallbacks mControllerCallbacks;
+
+    public TaskbarEduPagedView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_YES);
+    }
+
+    void setTaskbarEduView(TaskbarEduView taskbarEduView) {
+        mTaskbarEduView = taskbarEduView;
+        mPageIndicator = taskbarEduView.findViewById(R.id.content_page_indicator);
+        initParentViews(taskbarEduView);
+    }
+
+    void setControllerCallbacks(TaskbarEduCallbacks controllerCallbacks) {
+        mControllerCallbacks = controllerCallbacks;
+        mControllerCallbacks.onPageChanged(getCurrentPage(), getPageCount());
+    }
+
+    @Override
+    protected int getChildGap() {
+        return mTaskbarEduView.getPaddingLeft() + mTaskbarEduView.getPaddingRight();
+    }
+
+    @Override
+    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
+        super.onScrollChanged(l, t, oldl, oldt);
+        if (mMaxScroll > 0) {
+            mPageIndicator.setScroll(l, mMaxScroll);
+        }
+    }
+
+    @Override
+    protected void notifyPageSwitchListener(int prevPage) {
+        super.notifyPageSwitchListener(prevPage);
+        mControllerCallbacks.onPageChanged(getCurrentPage(), getPageCount());
+    }
+
+    @Override
+    protected boolean canScroll(float absVScroll, float absHScroll) {
+        return AbstractFloatingView.getTopOpenViewWithType(
+                ActivityContext.lookupContext(getContext()),
+                TYPE_ALL & ~TYPE_TASKBAR_EDUCATION_DIALOG) == null;
+    }
+}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarEduView.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarEduView.java
new file mode 100644
index 0000000..9c4e844
--- /dev/null
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarEduView.java
@@ -0,0 +1,149 @@
+/*
+ * 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.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN;
+
+import android.animation.PropertyValuesHolder;
+import android.content.Context;
+import android.graphics.Rect;
+import android.util.AttributeSet;
+import android.util.Pair;
+import android.view.View;
+import android.widget.Button;
+
+import com.android.launcher3.Insettable;
+import com.android.launcher3.R;
+import com.android.launcher3.views.AbstractSlideInView;
+
+/** Education view about the Taskbar. */
+public class TaskbarEduView extends AbstractSlideInView<TaskbarActivityContext>
+        implements Insettable {
+
+    private static final int DEFAULT_CLOSE_DURATION = 200;
+
+    private final Rect mInsets = new Rect();
+
+    private Button mStartButton;
+    private Button mEndButton;
+    private TaskbarEduPagedView mPagedView;
+
+    public TaskbarEduView(Context context, AttributeSet attr) {
+        this(context, attr, 0);
+    }
+
+    public TaskbarEduView(Context context, AttributeSet attrs,
+            int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+    }
+
+    protected void init(TaskbarEduController.TaskbarEduCallbacks callbacks) {
+        if (mPagedView != null) {
+            mPagedView.setControllerCallbacks(callbacks);
+        }
+    }
+
+    @Override
+    protected void handleClose(boolean animate) {
+        handleClose(animate, DEFAULT_CLOSE_DURATION);
+    }
+
+    @Override
+    protected boolean isOfType(int type) {
+        return (type & TYPE_TASKBAR_EDUCATION_DIALOG) != 0;
+    }
+
+    @Override
+    protected void onFinishInflate() {
+        super.onFinishInflate();
+        mContent = findViewById(R.id.edu_view);
+        mStartButton = findViewById(R.id.edu_start_button);
+        mEndButton = findViewById(R.id.edu_end_button);
+        mPagedView = findViewById(R.id.content);
+        mPagedView.setTaskbarEduView(this);
+    }
+
+    @Override
+    public void setInsets(Rect insets) {
+        mInsets.set(insets);
+        mContent.setPadding(mContent.getPaddingStart(),
+                mContent.getPaddingTop(), mContent.getPaddingEnd(), insets.bottom);
+    }
+
+    @Override
+    protected void attachToContainer() {
+        if (mColorScrim != null) {
+            getPopupContainer().addView(mColorScrim, 0);
+        }
+        getPopupContainer().addView(this, 1);
+    }
+
+    /** Show the Education flow. */
+    public void show() {
+        attachToContainer();
+        animateOpen();
+    }
+
+    @Override
+    protected Pair<View, String> getAccessibilityTarget() {
+        return Pair.create(mContent, mIsOpen ? getContext().getString(R.string.taskbar_edu_opened)
+                : getContext().getString(R.string.taskbar_edu_closed));
+    }
+
+    @Override
+    protected int getScrimColor(Context context) {
+        return context.getResources().getColor(R.color.widgets_picker_scrim);
+    }
+
+    @Override
+    protected void onLayout(boolean changed, int l, int t, int r, int b) {
+        int width = r - l;
+        int height = b - t;
+
+        // Lay out the content as center bottom aligned.
+        int contentWidth = mContent.getMeasuredWidth();
+        int contentLeft = (width - contentWidth - mInsets.left - mInsets.right) / 2 + mInsets.left;
+        mContent.layout(contentLeft, height - mContent.getMeasuredHeight(),
+                contentLeft + contentWidth, height);
+
+        setTranslationShift(mTranslationShift);
+    }
+
+    private void animateOpen() {
+        if (mIsOpen || mOpenCloseAnimator.isRunning()) {
+            return;
+        }
+        mIsOpen = true;
+        mOpenCloseAnimator.setValues(
+                PropertyValuesHolder.ofFloat(TRANSLATION_SHIFT, TRANSLATION_SHIFT_OPENED));
+        mOpenCloseAnimator.setInterpolator(FAST_OUT_SLOW_IN);
+        mOpenCloseAnimator.start();
+    }
+
+    void snapToPage(int page) {
+        mPagedView.snapToPage(page);
+    }
+
+    void updateStartButton(int textResId, OnClickListener onClickListener) {
+        mStartButton.setText(textResId);
+        mStartButton.setOnClickListener(onClickListener);
+    }
+
+    void updateEndButton(int textResId, OnClickListener onClickListener) {
+        mEndButton.setText(textResId);
+        mEndButton.setOnClickListener(onClickListener);
+    }
+}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarKeyguardController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarKeyguardController.java
index a2039b6..834cd9c 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarKeyguardController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarKeyguardController.java
@@ -1,7 +1,10 @@
 package com.android.launcher3.taskbar;
 
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BACK_DISABLED;
 import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BOUNCER_SHOWING;
 import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_DEVICE_DOZING;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_HOME_DISABLED;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_OVERVIEW_DISABLED;
 import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING;
 
 import android.app.KeyguardManager;
@@ -9,7 +12,6 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
-import android.view.View;
 
 /**
  * Controller for managing keyguard state for taskbar
@@ -17,10 +19,11 @@
 public class TaskbarKeyguardController {
 
     private static final int KEYGUARD_SYSUI_FLAGS = SYSUI_STATE_BOUNCER_SHOWING |
-            SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING | SYSUI_STATE_DEVICE_DOZING;
+            SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING | SYSUI_STATE_DEVICE_DOZING |
+            SYSUI_STATE_OVERVIEW_DISABLED | SYSUI_STATE_HOME_DISABLED |
+            SYSUI_STATE_BACK_DISABLED;
 
     private final TaskbarActivityContext mContext;
-    private int mDisabledNavIcons;
     private int mKeyguardSysuiFlags;
     private boolean mBouncerShowing;
     private NavbarButtonsViewController mNavbarButtonsViewController;
@@ -70,22 +73,13 @@
         mIsScreenOff = false;
     }
 
-    public void disableNavbarElements(int state1, int state2) {
-        if (mDisabledNavIcons == state1) {
-            // no change
-            return;
-        }
-        mDisabledNavIcons = state1;
-        updateIconsForBouncer();
-    }
-
     /**
      * Hides/shows taskbar when keyguard is up
      */
     private void updateIconsForBouncer() {
-        boolean disableBack = (mDisabledNavIcons & View.STATUS_BAR_DISABLE_BACK) != 0;
-        boolean disableRecent = (mDisabledNavIcons & View.STATUS_BAR_DISABLE_RECENT) != 0;
-        boolean disableHome = (mDisabledNavIcons & View.STATUS_BAR_DISABLE_HOME) != 0;
+        boolean disableBack = (mKeyguardSysuiFlags & SYSUI_STATE_BACK_DISABLED) != 0;
+        boolean disableRecent = (mKeyguardSysuiFlags & SYSUI_STATE_OVERVIEW_DISABLED) != 0;
+        boolean disableHome = (mKeyguardSysuiFlags & SYSUI_STATE_HOME_DISABLED) != 0;
         boolean onlyBackEnabled = !disableBack && disableRecent && disableHome;
 
         boolean showBackForBouncer = onlyBackEnabled &&
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
index 0efec53..1f5ff02 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
@@ -197,6 +197,7 @@
             if (wasStashed != isStashed) {
                 SystemUiProxy.INSTANCE.get(mActivity)
                         .notifyTaskbarStatus(/* visible */ true, /* stashed */ isStashed);
+                mControllers.uiController.onStashedInAppChanged();
                 createAnimToIsStashed(isStashed, TASKBAR_STASH_DURATION).start();
                 return true;
             }
@@ -284,6 +285,7 @@
             @Override
             public void onAnimationStart(Animator animation) {
                 mIsStashed = isStashed;
+                onIsStashed(mIsStashed);
             }
 
             @Override
@@ -325,4 +327,8 @@
                 animateForward ? UNSTASHED_TASKBAR_HANDLE_HINT_SCALE : 1)
                 .setDuration(TASKBAR_HINT_STASH_DURATION).start();
     }
+
+    private void onIsStashed(boolean isStashed) {
+        mControllers.stashedHandleViewController.onIsStashed(isStashed);
+    }
 }
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java
index 260cedc..df88e02 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java
@@ -33,4 +33,6 @@
     }
 
     protected void updateContentInsets(Rect outContentInsets) { }
+
+    protected void onStashedInAppChanged() { }
 }
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java
index 6b95f08..1882762 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java
@@ -165,8 +165,9 @@
         int offsetY = launcherDp.getTaskbarOffsetY();
         setter.setFloat(mTaskbarIconTranslationYForHome, VALUE, -offsetY, LINEAR);
 
-        int collapsedHeight = mActivity.getDeviceProfile().taskbarSize;
-        int expandedHeight = collapsedHeight + offsetY;
+        int collapsedHeight = mActivity.getDefaultTaskbarWindowHeight();
+        int expandedHeight = Math.max(collapsedHeight,
+                mActivity.getDeviceProfile().taskbarSize + offsetY);
         setter.addOnFrameListener(anim -> mActivity.setTaskbarWindowHeight(
                 anim.getAnimatedFraction() > 0 ? expandedHeight : collapsedHeight));
 
diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
index 2009cd7..14bc380 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
@@ -36,9 +36,13 @@
 import android.content.Intent;
 import android.content.SharedPreferences;
 import android.content.res.Configuration;
+import android.hardware.SensorManager;
+import android.hardware.devicestate.DeviceStateManager;
 import android.view.HapticFeedbackConstants;
 import android.view.View;
 
+import androidx.annotation.Nullable;
+
 import com.android.launcher3.BaseQuickstepLauncher;
 import com.android.launcher3.DeviceProfile;
 import com.android.launcher3.Launcher;
@@ -75,9 +79,14 @@
 import com.android.quickstep.SysUINavigationMode.Mode;
 import com.android.quickstep.SystemUiProxy;
 import com.android.quickstep.TaskUtils;
+import com.android.quickstep.util.LauncherUnfoldAnimationController;
+import com.android.quickstep.util.ProxyScreenStatusProvider;
 import com.android.quickstep.util.QuickstepOnboardingPrefs;
 import com.android.quickstep.views.RecentsView;
 import com.android.quickstep.views.TaskView;
+import com.android.systemui.unfold.UnfoldTransitionFactory;
+import com.android.systemui.unfold.UnfoldTransitionProgressProvider;
+import com.android.systemui.unfold.config.UnfoldTransitionConfig;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
@@ -97,10 +106,51 @@
     private FixedContainerItems mAllAppsPredictions;
     private HotseatPredictionController mHotseatPredictionController;
 
+    @Nullable
+    private LauncherUnfoldAnimationController mLauncherUnfoldAnimationController;
+
     @Override
     protected void setupViews() {
         super.setupViews();
         mHotseatPredictionController = new HotseatPredictionController(this);
+
+        final UnfoldTransitionConfig config = UnfoldTransitionFactory.createConfig(this);
+        if (config.isEnabled()) {
+            final UnfoldTransitionProgressProvider unfoldTransitionProgressProvider =
+                    UnfoldTransitionFactory.createUnfoldTransitionProgressProvider(
+                            this,
+                            config,
+                            ProxyScreenStatusProvider.INSTANCE,
+                            getSystemService(DeviceStateManager.class),
+                            getSystemService(SensorManager.class),
+                            getMainThreadHandler(),
+                            getMainExecutor()
+                    );
+
+            mLauncherUnfoldAnimationController = new LauncherUnfoldAnimationController(
+                    this,
+                    getWindowManager(),
+                    unfoldTransitionProgressProvider
+            );
+        }
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+
+        if (mLauncherUnfoldAnimationController != null) {
+            mLauncherUnfoldAnimationController.onResume();
+        }
+    }
+
+    @Override
+    protected void onPause() {
+        if (mLauncherUnfoldAnimationController != null) {
+            mLauncherUnfoldAnimationController.onPause();
+        }
+
+        super.onPause();
     }
 
     @Override
@@ -231,6 +281,10 @@
     public void onDestroy() {
         super.onDestroy();
         mHotseatPredictionController.destroy();
+
+        if (mLauncherUnfoldAnimationController != null) {
+            mLauncherUnfoldAnimationController.onDestroy();
+        }
     }
 
     @Override
diff --git a/quickstep/src/com/android/launcher3/uioverrides/plugins/PluginInitializerImpl.java b/quickstep/src/com/android/launcher3/uioverrides/plugins/PluginInitializerImpl.java
index d14e8ef..0e12e30 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/plugins/PluginInitializerImpl.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/plugins/PluginInitializerImpl.java
@@ -14,35 +14,18 @@
 
 package com.android.launcher3.uioverrides.plugins;
 
-import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
-
 import android.content.Context;
-import android.os.Looper;
 
 import com.android.launcher3.Utilities;
 import com.android.systemui.shared.plugins.PluginInitializer;
 
 public class PluginInitializerImpl implements PluginInitializer {
     @Override
-    public Looper getBgLooper() {
-        return MODEL_EXECUTOR.getLooper();
-    }
-
-    @Override
-    public void onPluginManagerInit() {
-    }
-
-    @Override
-    public String[] getWhitelistedPlugins(Context context) {
+    public String[] getPrivilegedPlugins(Context context) {
         return new String[0];
     }
 
     @Override
-    public PluginEnablerImpl getPluginEnabler(Context context) {
-        return new PluginEnablerImpl(context);
-    }
-
-    @Override
     public void handleWtfs() {
     }
 
diff --git a/quickstep/src/com/android/launcher3/uioverrides/plugins/PluginManagerWrapper.java b/quickstep/src/com/android/launcher3/uioverrides/plugins/PluginManagerWrapper.java
index 2e422b7..e12f42e 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/plugins/PluginManagerWrapper.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/plugins/PluginManagerWrapper.java
@@ -16,6 +16,9 @@
 
 import static android.content.pm.PackageManager.MATCH_DISABLED_COMPONENTS;
 
+import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
+
+import android.app.NotificationManager;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
@@ -24,13 +27,16 @@
 import com.android.launcher3.util.MainThreadInitializedObject;
 import com.android.systemui.plugins.Plugin;
 import com.android.systemui.plugins.PluginListener;
+import com.android.systemui.shared.plugins.PluginInstanceManager;
 import com.android.systemui.shared.plugins.PluginManager;
 import com.android.systemui.shared.plugins.PluginManagerImpl;
 import com.android.systemui.shared.plugins.PluginPrefs;
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
+import java.util.Optional;
 import java.util.Set;
 
 public class PluginManagerWrapper {
@@ -47,8 +53,16 @@
     private PluginManagerWrapper(Context c) {
         mContext = c;
         PluginInitializerImpl pluginInitializer  = new PluginInitializerImpl();
-        mPluginManager = new PluginManagerImpl(c, pluginInitializer);
-        mPluginEnabler = pluginInitializer.getPluginEnabler(c);
+        mPluginEnabler = new PluginEnablerImpl(c);
+        PluginInstanceManager.Factory instanceManagerFactory = new PluginInstanceManager.Factory(
+                c, c.getPackageManager(), c.getMainExecutor(), MODEL_EXECUTOR, pluginInitializer,
+                c.getSystemService(NotificationManager.class), mPluginEnabler,
+                Arrays.asList(pluginInitializer.getPrivilegedPlugins(c)));
+
+        mPluginManager = new PluginManagerImpl(c, instanceManagerFactory,
+                pluginInitializer.isDebuggable(),
+                Optional.ofNullable(Thread.getDefaultUncaughtExceptionHandler()), mPluginEnabler,
+                new PluginPrefs(c), Arrays.asList(pluginInitializer.getPrivilegedPlugins(c)));
     }
 
     public PluginEnablerImpl getPluginEnabler() {
diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java b/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java
index d822c8c..f8c9fd1 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java
@@ -70,7 +70,9 @@
 
     @Override
     protected float getDepthUnchecked(Context context) {
-        return 1f;
+        // The scrim fades in at approximately 50% of the swipe gesture.
+        // This means that the depth should be greater than 1, in order to fully zoom out.
+        return 2f;
     }
 
     @Override
diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java b/quickstep/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java
index fe5a347..4984b95 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java
@@ -23,6 +23,7 @@
 import com.android.launcher3.BaseDraggingActivity;
 import com.android.launcher3.DeviceProfile;
 import com.android.launcher3.Launcher;
+import com.android.launcher3.R;
 import com.android.launcher3.allapps.AllAppsTransitionController;
 import com.android.quickstep.util.LayoutUtils;
 import com.android.quickstep.views.RecentsView;
@@ -89,6 +90,10 @@
 
     @Override
     public int getWorkspaceScrimColor(Launcher launcher) {
+        DeviceProfile dp = launcher.getDeviceProfile();
+        if (dp.isTaskbarPresentInApps) {
+            return launcher.getColor(R.color.taskbar_background);
+        }
         return Color.TRANSPARENT;
     }
 
diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
index 42c89fd..46d5857 100644
--- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
+++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
@@ -65,6 +65,7 @@
 import android.os.Build;
 import android.os.IBinder;
 import android.os.SystemClock;
+import android.util.Log;
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.View.OnApplyWindowInsetsListener;
@@ -87,6 +88,7 @@
 import com.android.launcher3.logging.StatsLogManager.StatsLogger;
 import com.android.launcher3.statemanager.BaseState;
 import com.android.launcher3.statemanager.StatefulActivity;
+import com.android.launcher3.testing.TestProtocol;
 import com.android.launcher3.tracing.InputConsumerProto;
 import com.android.launcher3.tracing.SwipeHandlerProto;
 import com.android.launcher3.util.TraceHelper;
@@ -99,6 +101,7 @@
 import com.android.quickstep.util.AnimatorControllerWithResistance;
 import com.android.quickstep.util.InputConsumerProxy;
 import com.android.quickstep.util.InputProxyHandlerFactory;
+import com.android.quickstep.util.LauncherSplitScreenListener;
 import com.android.quickstep.util.MotionPauseDetector;
 import com.android.quickstep.util.ProtoTracer;
 import com.android.quickstep.util.RecentsOrientedState;
@@ -106,6 +109,7 @@
 import com.android.quickstep.util.StaggeredWorkspaceAnim;
 import com.android.quickstep.util.SurfaceTransactionApplier;
 import com.android.quickstep.util.SwipePipToHomeAnimator;
+import com.android.quickstep.util.TaskViewSimulator;
 import com.android.quickstep.util.TransformParams;
 import com.android.quickstep.views.RecentsView;
 import com.android.quickstep.views.TaskView;
@@ -222,7 +226,7 @@
     protected final TaskAnimationManager mTaskAnimationManager;
 
     // Either RectFSpringAnim (if animating home) or ObjectAnimator (from mCurrentShift) otherwise
-    private RunningWindowAnim mRunningWindowAnim;
+    private RunningWindowAnim[] mRunningWindowAnim;
     // Possible second animation running at the same time as mRunningWindowAnim
     private Animator mParallelRunningAnim;
     private boolean mIsMotionPaused;
@@ -253,6 +257,10 @@
 
     private SwipePipToHomeAnimator mSwipePipToHomeAnimator;
     protected boolean mIsSwipingPipToHome;
+    // TODO(b/195473090) no split PIP for now, remove once we have more clarity
+    //  can try to have RectFSpringAnim evaluate multiple rects at once
+    private final SwipePipToHomeAnimator[] mSwipePipToHomeAnimators =
+            new SwipePipToHomeAnimator[2];
 
     // Interpolate RecentsView scale from start of quick switch scroll until this scroll threshold
     private final float mQuickSwitchScaleScrollThreshold;
@@ -426,7 +434,8 @@
         // RecentsView never updates the display rotation until swipe-up, force update
         // RecentsOrientedState before passing to TaskViewSimulator.
         mRecentsView.updateRecentsRotation();
-        mTaskViewSimulator.setOrientationState(mRecentsView.getPagedViewOrientedState());
+        runActionOnRemoteHandles(remoteTargetHandle -> remoteTargetHandle.mTaskViewSimulator
+                .setOrientationState(mRecentsView.getPagedViewOrientedState()));
 
         // If we've already ended the gesture and are going home, don't prepare recents UI,
         // as that will set the state as BACKGROUND_APP, overriding the animation to NORMAL.
@@ -519,7 +528,21 @@
     }
 
     protected void notifyGestureAnimationStartToRecents() {
-        mRecentsView.onGestureAnimationStart(mGestureState.getRunningTask());
+        ActivityManager.RunningTaskInfo[] runningTasks;
+        if (mIsSwipeForStagedSplit) {
+            int[] splitTaskIds =
+                    LauncherSplitScreenListener.INSTANCE.getNoCreate().getSplitTaskIds();
+            runningTasks = new ActivityManager.RunningTaskInfo[splitTaskIds.length];
+            for (int i = 0; i < splitTaskIds.length; i++) {
+                int taskId = splitTaskIds[i];
+                ActivityManager.RunningTaskInfo rti = new ActivityManager.RunningTaskInfo();
+                rti.taskId = taskId;
+                runningTasks[i] = rti;
+            }
+        } else {
+            runningTasks = new ActivityManager.RunningTaskInfo[]{mGestureState.getRunningTask()};
+        }
+        mRecentsView.onGestureAnimationStart(runningTasks);
     }
 
     private void launcherFrameDrawn() {
@@ -606,15 +629,15 @@
         if (animate) {
             ValueAnimator reapplyWindowTransformAnim = ValueAnimator.ofFloat(0, 1);
             reapplyWindowTransformAnim.addUpdateListener(anim -> {
-                if (mRunningWindowAnim == null) {
-                    applyWindowTransform();
+                if (mRunningWindowAnim == null || mRunningWindowAnim.length == 0) {
+                    applyScrollAndTransform();
                 }
             });
             reapplyWindowTransformAnim.setDuration(RECENTS_ATTACH_DURATION).start();
             mStateCallback.runOnceAtState(STATE_HANDLER_INVALIDATED,
                     reapplyWindowTransformAnim::cancel);
         } else {
-            applyWindowTransform();
+            applyScrollAndTransform();
         }
     }
 
@@ -655,8 +678,13 @@
 
     private void onAnimatorPlaybackControllerCreated(AnimatorControllerWithResistance anim) {
         mLauncherTransitionController = anim;
-        mLauncherTransitionController.getNormalController().dispatchOnStart();
-        updateLauncherTransitionProgress();
+        mStateCallback.runOnceAtState(STATE_GESTURE_STARTED, () -> {
+            // Wait until the gesture is started (touch slop was passed) to start in sync with
+            // mWindowTransitionController. This ensures we don't hide the taskbar background when
+            // long pressing to stash it, for instance.
+            mLauncherTransitionController.getNormalController().dispatchOnStart();
+            updateLauncherTransitionProgress();
+        });
     }
 
     public Intent getLaunchIntent() {
@@ -678,7 +706,7 @@
         }
 
         updateSysUiFlags(mCurrentShift.value);
-        applyWindowTransform();
+        applyScrollAndTransform();
 
         updateLauncherTransitionProgress();
     }
@@ -724,24 +752,23 @@
     @Override
     public void onRecentsAnimationStart(RecentsAnimationController controller,
             RecentsAnimationTargets targets) {
-        ActiveGestureLog.INSTANCE.addLog("startRecentsAnimationCallback", targets.apps.length);
+        super.onRecentsAnimationStart(controller, targets);
         mRecentsAnimationController = controller;
         mRecentsAnimationTargets = targets;
-        mTransformParams.setTargetSet(mRecentsAnimationTargets);
-        RemoteAnimationTargetCompat runningTaskTarget = targets.findTask(
-                mGestureState.getRunningTaskId());
-
-        if (runningTaskTarget != null) {
-            mTaskViewSimulator.setPreview(runningTaskTarget);
-        }
 
         // Only initialize the device profile, if it has not been initialized before, as in some
         // configurations targets.homeContentInsets may not be correct.
         if (mActivity == null) {
-            DeviceProfile dp = mTaskViewSimulator.getOrientationState().getLauncherDeviceProfile();
-            if (targets.minimizedHomeBounds != null && runningTaskTarget != null) {
+            RemoteAnimationTargetCompat primaryTaskTarget = targets.apps[0];
+            // orientation state is independent of which remote target handle we use since both
+            // should be pointing to the same one. Just choose index 0 for now since that works for
+            // both split and non-split
+            RecentsOrientedState orientationState = mRemoteTargetHandles[0].mTaskViewSimulator
+                    .getOrientationState();
+            DeviceProfile dp = orientationState.getLauncherDeviceProfile();
+            if (targets.minimizedHomeBounds != null && primaryTaskTarget != null) {
                 Rect overviewStackBounds = mActivityInterface
-                        .getOverviewWindowBounds(targets.minimizedHomeBounds, runningTaskTarget);
+                        .getOverviewWindowBounds(targets.minimizedHomeBounds, primaryTaskTarget);
                 dp = dp.getMultiWindowProfile(mContext,
                         new WindowBounds(overviewStackBounds, targets.homeContentInsets));
             } else {
@@ -751,7 +778,7 @@
             dp.updateInsets(targets.homeContentInsets);
             dp.updateIsSeascape(mContext);
             initTransitionEndpoints(dp);
-            mTaskViewSimulator.getOrientationState().setMultiWindowMode(dp.isMultiWindowMode);
+            orientationState.setMultiWindowMode(dp.isMultiWindowMode);
         }
 
         // Notify when the animation starts
@@ -851,6 +878,9 @@
      */
     @UiThread
     public void onGestureEnded(float endVelocity, PointF velocity, PointF downPos) {
+        if (Utilities.IS_RUNNING_IN_TEST_HARNESS) {
+            Log.d(TestProtocol.L3_SWIPE_TO_HOME, "3");
+        }
         float flingThreshold = mContext.getResources()
                 .getDimension(R.dimen.quickstep_fling_threshold_speed);
         boolean isFling = mGestureStarted && !mIsMotionPaused
@@ -869,9 +899,17 @@
     private void endRunningWindowAnim(boolean cancel) {
         if (mRunningWindowAnim != null) {
             if (cancel) {
-                mRunningWindowAnim.cancel();
+                for (RunningWindowAnim r : mRunningWindowAnim) {
+                    if (r != null) {
+                        r.cancel();
+                    }
+                }
             } else {
-                mRunningWindowAnim.end();
+                for (RunningWindowAnim r : mRunningWindowAnim) {
+                    if (r != null) {
+                        r.end();
+                    }
+                }
             }
         }
         if (mParallelRunningAnim != null) {
@@ -885,6 +923,9 @@
         // Fast-finish the attaching animation if it's still running.
         maybeUpdateRecentsAttachedState(false);
         final GestureEndTarget endTarget = mGestureState.getEndTarget();
+        // Wait until the given View (if supplied) draws before resuming the last task.
+        View postResumeLastTask = mActivityInterface.onSettledOnEndTarget(endTarget);
+
         if (endTarget != NEW_TASK) {
             InteractionJankMonitorWrapper.cancel(
                     InteractionJankMonitorWrapper.CUJ_QUICK_SWITCH);
@@ -893,6 +934,7 @@
             InteractionJankMonitorWrapper.cancel(
                     InteractionJankMonitorWrapper.CUJ_APP_CLOSE_TO_HOME);
         }
+
         switch (endTarget) {
             case HOME:
                 mStateCallback.setState(STATE_SCALED_CONTROLLER_HOME | STATE_CAPTURE_SCREENSHOT);
@@ -907,7 +949,12 @@
                 mStateCallback.setState(STATE_START_NEW_TASK | STATE_CAPTURE_SCREENSHOT);
                 break;
             case LAST_TASK:
-                mStateCallback.setState(STATE_RESUME_LAST_TASK);
+                if (postResumeLastTask != null) {
+                    ViewUtils.postFrameDrawn(postResumeLastTask,
+                            () -> mStateCallback.setState(STATE_RESUME_LAST_TASK));
+                } else {
+                    mStateCallback.setState(STATE_RESUME_LAST_TASK);
+                }
                 TaskViewUtils.setDividerBarShown(mRecentsAnimationTargets.nonApps, true);
                 break;
         }
@@ -995,6 +1042,9 @@
     @UiThread
     private void handleNormalGestureEnd(float endVelocity, boolean isFling, PointF velocity,
             boolean isCancel) {
+        if (Utilities.IS_RUNNING_IN_TEST_HARNESS) {
+            Log.d(TestProtocol.L3_SWIPE_TO_HOME, "4");
+        }
         long duration = MAX_SWIPE_DURATION;
         float currentShift = mCurrentShift.value;
         final GestureEndTarget endTarget = calculateEndTarget(velocity, endVelocity,
@@ -1113,6 +1163,9 @@
     @UiThread
     private void animateToProgress(float start, float end, long duration, Interpolator interpolator,
             GestureEndTarget target, PointF velocityPxPerMs) {
+        if (Utilities.IS_RUNNING_IN_TEST_HARNESS) {
+            Log.d(TestProtocol.L3_SWIPE_TO_HOME, "5");
+        }
         runOnRecentsAnimationStart(() -> animateToProgressInternal(start, end, duration,
                 interpolator, target, velocityPxPerMs));
     }
@@ -1141,6 +1194,9 @@
     @UiThread
     private void animateToProgressInternal(float start, float end, long duration,
             Interpolator interpolator, GestureEndTarget target, PointF velocityPxPerMs) {
+        if (Utilities.IS_RUNNING_IN_TEST_HARNESS) {
+            Log.d(TestProtocol.L3_SWIPE_TO_HOME, "7");
+        }
         maybeUpdateRecentsAttachedState();
 
         // If we are transitioning to launcher, then listen for the activity to be restarted while
@@ -1181,15 +1237,17 @@
                     createHomeAnimationFactory(cookies, duration, isTranslucent, appCanEnterPip,
                             runningTaskTarget);
             mIsSwipingPipToHome = homeAnimFactory.supportSwipePipToHome() && appCanEnterPip;
-            final RectFSpringAnim windowAnim;
+            final RectFSpringAnim[] windowAnim;
             if (mIsSwipingPipToHome) {
                 mSwipePipToHomeAnimator = createWindowAnimationToPip(
                         homeAnimFactory, runningTaskTarget, start);
-                windowAnim = mSwipePipToHomeAnimator;
+                mSwipePipToHomeAnimators[0] = mSwipePipToHomeAnimator;
+                windowAnim = mSwipePipToHomeAnimators;
             } else {
                 mSwipePipToHomeAnimator = null;
                 windowAnim = createWindowAnimationToHome(start, homeAnimFactory);
-                windowAnim.addAnimatorListener(new AnimationSuccessListener() {
+
+                windowAnim[0].addAnimatorListener(new AnimationSuccessListener() {
                     @Override
                     public void onAnimationSuccess(Animator animator) {
                         if (mRecentsAnimationController == null) {
@@ -1203,15 +1261,22 @@
                     }
                 });
             }
-            windowAnim.start(mContext, velocityPxPerMs);
-            mRunningWindowAnim = RunningWindowAnim.wrap(windowAnim);
+            mRunningWindowAnim = new RunningWindowAnim[windowAnim.length];
+            for (int i = 0, windowAnimLength = windowAnim.length; i < windowAnimLength; i++) {
+                RectFSpringAnim windowAnimation = windowAnim[i];
+                if (windowAnimation == null) {
+                    continue;
+                }
+                windowAnimation.start(mContext, velocityPxPerMs);
+                mRunningWindowAnim[i] = RunningWindowAnim.wrap(windowAnimation);
+            }
             homeAnimFactory.setSwipeVelocity(velocityPxPerMs.y);
             homeAnimFactory.playAtomicAnimation(velocityPxPerMs.y);
             mLauncherTransitionController = null;
 
             if (mRecentsView != null) {
                 mRecentsView.onPrepareGestureEndAnimation(null, mGestureState.getEndTarget(),
-                        mTaskViewSimulator);
+                        getRemoteTaskViewSimulators());
             }
         } else {
             AnimatorSet animatorSet = new AnimatorSet();
@@ -1253,11 +1318,12 @@
             animatorSet.play(windowAnim);
             if (mRecentsView != null) {
                 mRecentsView.onPrepareGestureEndAnimation(
-                        animatorSet, mGestureState.getEndTarget(), mTaskViewSimulator);
+                        animatorSet, mGestureState.getEndTarget(),
+                        getRemoteTaskViewSimulators());
             }
             animatorSet.setDuration(duration).setInterpolator(interpolator);
             animatorSet.start();
-            mRunningWindowAnim = RunningWindowAnim.wrap(animatorSet);
+            mRunningWindowAnim = new RunningWindowAnim[]{RunningWindowAnim.wrap(animatorSet)};
         }
     }
 
@@ -1272,16 +1338,21 @@
         }
     }
 
+    /**
+     * TODO(b/195473090) handle multiple task simulators (if needed) for PIP
+     */
     private SwipePipToHomeAnimator createWindowAnimationToPip(HomeAnimationFactory homeAnimFactory,
             RemoteAnimationTargetCompat runningTaskTarget, float startProgress) {
         // Directly animate the app to PiP (picture-in-picture) mode
         final ActivityManager.RunningTaskInfo taskInfo = mGestureState.getRunningTask();
-        final RecentsOrientedState orientationState = mTaskViewSimulator.getOrientationState();
+        final RecentsOrientedState orientationState = mRemoteTargetHandles[0].mTaskViewSimulator
+                .getOrientationState();
         final int windowRotation = calculateWindowRotation(runningTaskTarget, orientationState);
         final int homeRotation = orientationState.getRecentsActivityRotation();
 
         final Matrix homeToWindowPositionMap = new Matrix();
-        final RectF startRect = updateProgressForStartRect(homeToWindowPositionMap, startProgress);
+        final RectF startRect = updateProgressForStartRect(homeToWindowPositionMap,
+                startProgress)[0];
         // Move the startRect to Launcher space as floatingIconView runs in Launcher
         final Matrix windowToHomePositionMap = new Matrix();
         homeToWindowPositionMap.invert(windowToHomePositionMap);
@@ -1310,7 +1381,7 @@
         // is not ROTATION_0 (which implies the rotation is turned on in launcher settings).
         if (homeRotation == ROTATION_0
                 && (windowRotation == ROTATION_90 || windowRotation == ROTATION_270)) {
-            builder.setFromRotation(mTaskViewSimulator, windowRotation,
+            builder.setFromRotation(mRemoteTargetHandles[0].mTaskViewSimulator, windowRotation,
                     taskInfo.displayCutoutInsets);
         }
         final SwipePipToHomeAnimator swipePipToHomeAnimator = builder.build();
@@ -1340,7 +1411,7 @@
                 mGestureState.setState(STATE_END_TARGET_ANIMATION_FINISHED);
             }
         });
-        setupWindowAnimation(swipePipToHomeAnimator);
+        setupWindowAnimation(new RectFSpringAnim[]{swipePipToHomeAnimator});
         return swipePipToHomeAnimator;
     }
 
@@ -1367,19 +1438,19 @@
      * @param homeAnimationFactory The home animation factory.
      */
     @Override
-    protected RectFSpringAnim createWindowAnimationToHome(float startProgress,
+    protected RectFSpringAnim[] createWindowAnimationToHome(float startProgress,
             HomeAnimationFactory homeAnimationFactory) {
-        RectFSpringAnim anim =
+        RectFSpringAnim[] anim =
                 super.createWindowAnimationToHome(startProgress, homeAnimationFactory);
         setupWindowAnimation(anim);
         return anim;
     }
 
-    private void setupWindowAnimation(RectFSpringAnim anim) {
-        anim.addOnUpdateListener((v, r, p) -> {
+    private void setupWindowAnimation(RectFSpringAnim[] anims) {
+        anims[0].addOnUpdateListener((v, r, p) -> {
             updateSysUiFlags(Math.max(p, mCurrentShift.value));
         });
-        anim.addAnimatorListener(new AnimationSuccessListener() {
+        anims[0].addAnimatorListener(new AnimationSuccessListener() {
             @Override
             public void onAnimationSuccess(Animator animator) {
                 if (mRecentsView != null) {
@@ -1391,7 +1462,7 @@
             }
         });
         if (mRecentsAnimationTargets != null) {
-            mRecentsAnimationTargets.addReleaseCheck(anim);
+            mRecentsAnimationTargets.addReleaseCheck(anims[0]);
         }
     }
 
@@ -1639,7 +1710,7 @@
      * if applicable. This should happen before {@link #finishRecentsControllerToHome(Runnable)}.
      */
     private void maybeFinishSwipePipToHome() {
-        if (mIsSwipingPipToHome && mSwipePipToHomeAnimator != null) {
+        if (mIsSwipingPipToHome && mSwipePipToHomeAnimators[0] != null) {
             SystemUiProxy.INSTANCE.get(mContext).stopSwipePipToHome(
                     mSwipePipToHomeAnimator.getComponentName(),
                     mSwipePipToHomeAnimator.getDestinationBounds(),
@@ -1680,8 +1751,8 @@
      * depend on proper class initialization.
      */
     protected void initAfterSubclassConstructor() {
-        initTransitionEndpoints(
-                mTaskViewSimulator.getOrientationState().getLauncherDeviceProfile());
+        initTransitionEndpoints(mRemoteTargetHandles[0].mTaskViewSimulator
+                        .getOrientationState().getLauncherDeviceProfile());
     }
 
     protected void performHapticFeedback() {
@@ -1698,7 +1769,8 @@
 
     protected void linkRecentsViewScroll() {
         SurfaceTransactionApplier.create(mRecentsView, applier -> {
-            mTransformParams.setSyncTransactionApplier(applier);
+            runActionOnRemoteHandles(remoteTargetHandle -> remoteTargetHandle.mTransformParams
+                            .setSyncTransactionApplier(applier));
             runOnRecentsAnimationStart(() ->
                     mRecentsAnimationTargets.addReleaseCheck(applier));
         });
@@ -1754,6 +1826,9 @@
      * be run when it is next started.
      */
     protected void runOnRecentsAnimationStart(Runnable action) {
+        if (Utilities.IS_RUNNING_IN_TEST_HARNESS) {
+            Log.d(TestProtocol.L3_SWIPE_TO_HOME, "6");
+        }
         if (mRecentsAnimationTargets == null) {
             mRecentsAnimationStartCallbacks.add(action);
         } else {
@@ -1824,19 +1899,25 @@
     /**
      * Applies the transform on the recents animation
      */
-    protected void applyWindowTransform() {
-        if (mWindowTransitionController != null) {
-            mWindowTransitionController.setProgress(
-                    Math.max(mCurrentShift.value, getScaleProgressDueToScroll()),
-                    mDragLengthFactor);
-        }
+    protected void applyScrollAndTransform() {
         // No need to apply any transform if there is ongoing swipe-pip-to-home animator since
         // that animator handles the leash solely.
-        if (mRecentsAnimationTargets != null && !mIsSwipingPipToHome) {
-            if (mRecentsViewScrollLinked && mRecentsView != null) {
-                mTaskViewSimulator.setScroll(mRecentsView.getScrollOffset());
+        boolean notSwipingPipToHome = mRecentsAnimationTargets != null && !mIsSwipingPipToHome;
+        boolean setRecentsScroll = mRecentsViewScrollLinked && mRecentsView != null;
+        for (RemoteTargetHandle remoteHandle : mRemoteTargetHandles) {
+            AnimatorControllerWithResistance playbackController = remoteHandle.mPlaybackController;
+            if (playbackController != null) {
+                playbackController.setProgress(Math.max(mCurrentShift.value,
+                        getScaleProgressDueToScroll()), mDragLengthFactor);
             }
-            mTaskViewSimulator.apply(mTransformParams);
+
+            if (notSwipingPipToHome) {
+                TaskViewSimulator taskViewSimulator = remoteHandle.mTaskViewSimulator;
+                if (setRecentsScroll) {
+                    taskViewSimulator.setScroll(mRecentsView.getScrollOffset());
+                }
+                taskViewSimulator.apply(remoteHandle.mTransformParams);
+            }
         }
         ProtoTracer.INSTANCE.get(mContext).scheduleFrameUpdate();
     }
@@ -1891,7 +1972,6 @@
     }
 
     public interface Factory {
-
         AbsSwipeUpHandler newHandler(GestureState gestureState, long touchTimeMs);
     }
 }
diff --git a/quickstep/src/com/android/quickstep/BaseActivityInterface.java b/quickstep/src/com/android/quickstep/BaseActivityInterface.java
index 624ade2..6298bb8 100644
--- a/quickstep/src/com/android/quickstep/BaseActivityInterface.java
+++ b/quickstep/src/com/android/quickstep/BaseActivityInterface.java
@@ -40,6 +40,7 @@
 import android.os.Build;
 import android.view.Gravity;
 import android.view.MotionEvent;
+import android.view.View;
 
 import androidx.annotation.Nullable;
 import androidx.annotation.UiThread;
@@ -203,8 +204,7 @@
     /**
      * Calculates the taskView size for the provided device configuration.
      */
-    public final void calculateTaskSize(Context context, DeviceProfile dp, Rect outRect,
-            PagedOrientationHandler orientedState) {
+    public final void calculateTaskSize(Context context, DeviceProfile dp, Rect outRect) {
         Resources res = context.getResources();
         if (dp.overviewShowAsGrid) {
             Rect gridRect = new Rect();
@@ -262,19 +262,35 @@
     public static void getTaskDimension(Context context, DeviceProfile dp, PointF out) {
         if (dp.isMultiWindowMode) {
             WindowBounds bounds = SplitScreenBounds.INSTANCE.getSecondaryWindowBounds(context);
-            if (TaskView.CLIP_STATUS_AND_NAV_BARS) {
-                out.x = bounds.availableSize.x;
-                out.y = bounds.availableSize.y;
-            } else {
-                out.x = bounds.availableSize.x + bounds.insets.left + bounds.insets.right;
-                out.y = bounds.availableSize.y + bounds.insets.top + bounds.insets.bottom;
+            out.x = bounds.availableSize.x;
+            out.y = bounds.availableSize.y;
+            if (!TaskView.clipLeft(dp)) {
+                out.x += bounds.insets.left;
             }
-        } else if (TaskView.CLIP_STATUS_AND_NAV_BARS) {
-            out.x = dp.availableWidthPx;
-            out.y = dp.availableHeightPx;
+            if (!TaskView.clipRight(dp)) {
+                out.x += bounds.insets.right;
+            }
+            if (!TaskView.clipTop(dp)) {
+                out.y += bounds.insets.top;
+            }
+            if (!TaskView.clipBottom(dp)) {
+                out.y += bounds.insets.bottom;
+            }
         } else {
             out.x = dp.widthPx;
             out.y = dp.heightPx;
+            if (TaskView.clipLeft(dp)) {
+                out.x -= dp.getInsets().left;
+            }
+            if (TaskView.clipRight(dp)) {
+                out.x -= dp.getInsets().right;
+            }
+            if (TaskView.clipTop(dp)) {
+                out.y -= dp.getInsets().top;
+            }
+            if (TaskView.clipBottom(dp)) {
+                out.y -= Math.max(dp.getInsets().bottom, dp.taskbarSize);
+            }
         }
     }
 
@@ -385,6 +401,15 @@
      */
     public abstract STATE_TYPE stateFromGestureEndTarget(GestureState.GestureEndTarget endTarget);
 
+    /**
+     * Called when the animation to the target has finished, but right before updating the state.
+     * @return A View that needs to draw before ending the recents animation to LAST_TASK.
+     * (This is a hack to ensure Taskbar draws its background first to avoid flickering.)
+     */
+    public @Nullable View onSettledOnEndTarget(GestureState.GestureEndTarget endTarget) {
+        return null;
+    }
+
     public interface AnimationFactory {
 
         void createActivityInterface(long transitionLength);
diff --git a/quickstep/src/com/android/quickstep/FallbackActivityInterface.java b/quickstep/src/com/android/quickstep/FallbackActivityInterface.java
index 7fb8e16..4df1aad 100644
--- a/quickstep/src/com/android/quickstep/FallbackActivityInterface.java
+++ b/quickstep/src/com/android/quickstep/FallbackActivityInterface.java
@@ -57,7 +57,7 @@
     @Override
     public int getSwipeUpDestinationAndLength(DeviceProfile dp, Context context, Rect outRect,
             PagedOrientationHandler orientationHandler) {
-        calculateTaskSize(context, dp, outRect, orientationHandler);
+        calculateTaskSize(context, dp, outRect);
         if (dp.isVerticalBarLayout()
                 && SysUINavigationMode.INSTANCE.get(context).getMode() != NO_BUTTON) {
             return dp.isSeascape() ? outRect.left : (dp.widthPx - outRect.right);
diff --git a/quickstep/src/com/android/quickstep/FallbackSwipeHandler.java b/quickstep/src/com/android/quickstep/FallbackSwipeHandler.java
index e2f198c..773817f 100644
--- a/quickstep/src/com/android/quickstep/FallbackSwipeHandler.java
+++ b/quickstep/src/com/android/quickstep/FallbackSwipeHandler.java
@@ -28,6 +28,7 @@
 
 import android.animation.ObjectAnimator;
 import android.annotation.TargetApi;
+import android.app.ActivityManager;
 import android.app.ActivityOptions;
 import android.content.ActivityNotFoundException;
 import android.content.Context;
@@ -44,6 +45,7 @@
 import android.os.Messenger;
 import android.os.ParcelUuid;
 import android.os.UserHandle;
+import android.util.Log;
 import android.view.Surface;
 import android.view.SurfaceControl;
 import android.view.SurfaceControl.Transaction;
@@ -56,6 +58,7 @@
 import com.android.launcher3.anim.AnimatorPlaybackController;
 import com.android.launcher3.anim.PendingAnimation;
 import com.android.launcher3.anim.SpringAnimationBuilder;
+import com.android.launcher3.testing.TestProtocol;
 import com.android.quickstep.fallback.FallbackRecentsView;
 import com.android.quickstep.fallback.RecentsState;
 import com.android.quickstep.util.AppCloseConfig;
@@ -101,7 +104,9 @@
 
         mRunningOverHome = ActivityManagerWrapper.isHomeTask(mGestureState.getRunningTask());
         if (mRunningOverHome) {
-            mTransformParams.setHomeBuilderProxy(this::updateHomeActivityTransformDuringSwipeUp);
+            runActionOnRemoteHandles(remoteTargetHandle ->
+                    remoteTargetHandle.mTransformParams.setHomeBuilderProxy(
+                    FallbackSwipeHandler.this::updateHomeActivityTransformDuringSwipeUp));
         }
     }
 
@@ -109,7 +114,8 @@
     protected void initTransitionEndpoints(DeviceProfile dp) {
         super.initTransitionEndpoints(dp);
         if (mRunningOverHome) {
-            mMaxLauncherScale = 1 / mTaskViewSimulator.getFullScreenScale();
+            // Full screen scale should be independent of remote target handle
+            mMaxLauncherScale = 1 / mRemoteTargetHandles[0].mTaskViewSimulator.getFullScreenScale();
         }
     }
 
@@ -134,6 +140,10 @@
         mActiveAnimationFactory = new FallbackHomeAnimationFactory(duration);
         ActivityOptions options = ActivityOptions.makeCustomAnimation(mContext, 0, 0);
         Intent intent = new Intent(mGestureState.getHomeIntent());
+        if (Utilities.IS_RUNNING_IN_TEST_HARNESS) {
+            Log.d(TestProtocol.L3_SWIPE_TO_HOME,
+                    "createHomeAnimationFactory: " + intent.toShortString(true, true, true, false));
+        }
         mActiveAnimationFactory.addGestureContract(intent);
         try {
             mContext.startActivity(intent, options.toBundle());
@@ -174,7 +184,8 @@
     protected void notifyGestureAnimationStartToRecents() {
         if (mRunningOverHome) {
             if (SysUINavigationMode.getMode(mContext).hasGestures) {
-                mRecentsView.onGestureAnimationStartOnHome(mGestureState.getRunningTask());
+                mRecentsView.onGestureAnimationStartOnHome(
+                        new ActivityManager.RunningTaskInfo[]{mGestureState.getRunningTask()});
             }
         } else {
             super.notifyGestureAnimationStartToRecents();
@@ -202,19 +213,24 @@
                 mHomeAlpha = new AnimatedFloat();
                 mHomeAlpha.value = Utilities.boundToRange(1 - mCurrentShift.value, 0, 1);
                 mVerticalShiftForScale.value = mCurrentShift.value;
-                mTransformParams.setHomeBuilderProxy(
-                        this::updateHomeActivityTransformDuringHomeAnim);
+                runActionOnRemoteHandles(remoteTargetHandle ->
+                        remoteTargetHandle.mTransformParams.setHomeBuilderProxy(
+                                FallbackHomeAnimationFactory.this
+                                        ::updateHomeActivityTransformDuringHomeAnim));
             } else {
                 mHomeAlpha = new AnimatedFloat(this::updateHomeAlpha);
                 mHomeAlpha.value = 0;
-
-                mHomeAlphaParams.setHomeBuilderProxy(
-                        this::updateHomeActivityTransformDuringHomeAnim);
+                runActionOnRemoteHandles(remoteTargetHandle ->
+                        remoteTargetHandle.mTransformParams.setHomeBuilderProxy(
+                                FallbackHomeAnimationFactory.this
+                                        ::updateHomeActivityTransformDuringHomeAnim));
             }
 
             mRecentsAlpha.value = 1;
-            mTransformParams.setBaseBuilderProxy(
-                    this::updateRecentsActivityTransformDuringHomeAnim);
+            runActionOnRemoteHandles(remoteTargetHandle ->
+                    remoteTargetHandle.mTransformParams.setHomeBuilderProxy(
+                            FallbackHomeAnimationFactory.this
+                                    ::updateRecentsActivityTransformDuringHomeAnim));
         }
 
         @NonNull
diff --git a/quickstep/src/com/android/quickstep/LauncherActivityInterface.java b/quickstep/src/com/android/quickstep/LauncherActivityInterface.java
index d91d5b0..ae6ea79 100644
--- a/quickstep/src/com/android/quickstep/LauncherActivityInterface.java
+++ b/quickstep/src/com/android/quickstep/LauncherActivityInterface.java
@@ -25,10 +25,12 @@
 import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
 
 import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
 import android.animation.AnimatorSet;
 import android.content.Context;
 import android.graphics.Rect;
 import android.view.MotionEvent;
+import android.view.View;
 
 import androidx.annotation.Nullable;
 import androidx.annotation.UiThread;
@@ -71,7 +73,7 @@
     @Override
     public int getSwipeUpDestinationAndLength(DeviceProfile dp, Context context, Rect outRect,
             PagedOrientationHandler orientationHandler) {
-        calculateTaskSize(context, dp, outRect, orientationHandler);
+        calculateTaskSize(context, dp, outRect);
         if (dp.isVerticalBarLayout() && SysUINavigationMode.getMode(context) != Mode.NO_BUTTON) {
             return dp.isSeascape() ? outRect.left : (dp.widthPx - outRect.right);
         } else {
@@ -131,6 +133,18 @@
                         new ClampedDepthProperty(fromDepthRatio, toDepthRatio),
                         fromDepthRatio, toDepthRatio, LINEAR);
 
+                pa.addListener(new AnimatorListenerAdapter() {
+                    @Override
+                    public void onAnimationStart(Animator animation) {
+                        LauncherTaskbarUIController taskbarUIController =
+                                activity.getTaskbarUIController();
+                        if (taskbarUIController != null) {
+                            // Launcher's ScrimView will draw the background throughout the gesture.
+                            taskbarUIController.forceHideBackground(true);
+                        }
+                    }
+                });
+
             }
         };
 
@@ -288,6 +302,10 @@
         } else {
             om.hideOverlay(150);
         }
+        LauncherTaskbarUIController taskbarController = getTaskbarController();
+        if (taskbarController != null) {
+            taskbarController.hideEdu();
+        }
     }
 
     @Override
@@ -354,4 +372,16 @@
                 return NORMAL;
         }
     }
+
+    @Override
+    public View onSettledOnEndTarget(@Nullable GestureEndTarget endTarget) {
+        View superRet = super.onSettledOnEndTarget(endTarget);
+        LauncherTaskbarUIController taskbarUIController = getTaskbarController();
+        if (taskbarUIController != null) {
+            // Start drawing taskbar's background again since launcher might stop drawing.
+            taskbarUIController.forceHideBackground(false);
+            return taskbarUIController.getRootView();
+        }
+        return superRet;
+    }
 }
diff --git a/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java b/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java
index 19cad53..ce3406c 100644
--- a/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java
+++ b/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java
@@ -106,9 +106,11 @@
         boolean canUseWorkspaceView = workspaceView != null && workspaceView.isAttachedToWindow();
 
         mActivity.getRootView().setForceHideBackArrow(true);
-        mActivity.setHintUserWillBeActive();
+        if (!TaskAnimationManager.ENABLE_SHELL_TRANSITIONS) {
+            mActivity.setHintUserWillBeActive();
+        }
 
-        if (!canUseWorkspaceView || appCanEnterPip) {
+        if (!canUseWorkspaceView || appCanEnterPip || mIsSwipeForStagedSplit) {
             return new LauncherHomeAnimationFactory();
         }
         if (workspaceView instanceof LauncherAppWidgetHostView) {
@@ -179,14 +181,16 @@
         final float floatingWidgetAlpha = isTargetTranslucent ? 0 : 1;
         RectF backgroundLocation = new RectF();
         Rect crop = new Rect();
-        mTaskViewSimulator.getCurrentCropRect().roundOut(crop);
+        // We can assume there is only one remote target here because staged split never animates
+        // into the app icon, only into the homescreen
+        mRemoteTargetHandles[0].mTaskViewSimulator.getCurrentCropRect().roundOut(crop);
         Size windowSize = new Size(crop.width(), crop.height());
         int fallbackBackgroundColor =
                 FloatingWidgetView.getDefaultBackgroundColor(mContext, runningTaskTarget);
         FloatingWidgetView floatingWidgetView = FloatingWidgetView.getFloatingWidgetView(mActivity,
                 hostView, backgroundLocation, windowSize,
-                mTaskViewSimulator.getCurrentCornerRadius(), isTargetTranslucent,
-                fallbackBackgroundColor);
+                mRemoteTargetHandles[0].mTaskViewSimulator.getCurrentCornerRadius(),
+                isTargetTranslucent, fallbackBackgroundColor);
 
         return new FloatingViewHomeAnimationFactory(floatingWidgetView) {
 
diff --git a/quickstep/src/com/android/quickstep/OrientationTouchTransformer.java b/quickstep/src/com/android/quickstep/OrientationTouchTransformer.java
index 35a851a..81e6917 100644
--- a/quickstep/src/com/android/quickstep/OrientationTouchTransformer.java
+++ b/quickstep/src/com/android/quickstep/OrientationTouchTransformer.java
@@ -462,7 +462,7 @@
                             + "mRotation: " + mRotation
                             + " this: " + this);
                 }
-                event.transform(mTmpMatrix);
+                event.applyTransform(mTmpMatrix);
                 return true;
             }
             mTmpPoint[0] = event.getX();
@@ -478,7 +478,7 @@
             }
 
             if (contains(mTmpPoint[0], mTmpPoint[1])) {
-                event.transform(mTmpMatrix);
+                event.applyTransform(mTmpMatrix);
                 return true;
             }
             return false;
diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationCallbacks.java b/quickstep/src/com/android/quickstep/RecentsAnimationCallbacks.java
index 239233b..3c05a3e 100644
--- a/quickstep/src/com/android/quickstep/RecentsAnimationCallbacks.java
+++ b/quickstep/src/com/android/quickstep/RecentsAnimationCallbacks.java
@@ -16,20 +16,24 @@
 package com.android.quickstep;
 
 import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
+import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.ACTIVITY_TYPE_HOME;
 
 import android.graphics.Rect;
 import android.util.ArraySet;
+import android.util.Log;
 import android.view.RemoteAnimationTarget;
 
 import androidx.annotation.BinderThread;
 import androidx.annotation.UiThread;
 
 import com.android.launcher3.Utilities;
+import com.android.launcher3.testing.TestProtocol;
 import com.android.launcher3.util.Preconditions;
 import com.android.systemui.shared.recents.model.ThumbnailData;
 import com.android.systemui.shared.system.RecentsAnimationControllerCompat;
 import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
 
+import java.util.Arrays;
 import java.util.Set;
 
 /**
@@ -93,8 +97,19 @@
             RemoteAnimationTargetCompat[] appTargets,
             RemoteAnimationTargetCompat[] wallpaperTargets,
             Rect homeContentInsets, Rect minimizedHomeBounds) {
+        if (Utilities.IS_RUNNING_IN_TEST_HARNESS) {
+            Log.d(TestProtocol.L3_SWIPE_TO_HOME, "RecentsAnimationCallbacks.onAnimationStart");
+        }
+        // Convert appTargets to type RemoteAnimationTarget for all apps except Home app
+        RemoteAnimationTarget[] nonHomeApps = Arrays.stream(appTargets)
+                .filter(remoteAnimationTarget ->
+                        remoteAnimationTarget.activityType != ACTIVITY_TYPE_HOME)
+                .map(RemoteAnimationTargetCompat::unwrap)
+                .toArray(RemoteAnimationTarget[]::new);
+
         RemoteAnimationTarget[] nonAppTargets =
-                mSystemUiProxy.onGoingToRecentsLegacy(mCancelled);
+                mSystemUiProxy.onGoingToRecentsLegacy(mCancelled, nonHomeApps);
+
         RecentsAnimationTargets targets = new RecentsAnimationTargets(appTargets,
                 wallpaperTargets, RemoteAnimationTargetCompat.wrap(nonAppTargets),
                 homeContentInsets, minimizedHomeBounds);
@@ -106,6 +121,10 @@
                     mController::finishAnimationToApp);
         } else {
             Utilities.postAsyncCallback(MAIN_EXECUTOR.getHandler(), () -> {
+                if (Utilities.IS_RUNNING_IN_TEST_HARNESS) {
+                    Log.d(TestProtocol.L3_SWIPE_TO_HOME,
+                            "RecentsAnimationCallbacks.onAnimationStart callback");
+                }
                 for (RecentsAnimationListener listener : getListeners()) {
                     listener.onRecentsAnimationStart(mController, targets);
                 }
diff --git a/quickstep/src/com/android/quickstep/RemoteAnimationTargets.java b/quickstep/src/com/android/quickstep/RemoteAnimationTargets.java
index c032889..b20d488 100644
--- a/quickstep/src/com/android/quickstep/RemoteAnimationTargets.java
+++ b/quickstep/src/com/android/quickstep/RemoteAnimationTargets.java
@@ -77,8 +77,12 @@
      * Gets the navigation bar remote animation target if exists.
      */
     public RemoteAnimationTargetCompat getNavBarRemoteAnimationTarget() {
+        return getNonAppTargetOfType(TYPE_NAVIGATION_BAR);
+    }
+
+    public RemoteAnimationTargetCompat getNonAppTargetOfType(int type) {
         for (RemoteAnimationTargetCompat target : nonApps) {
-            if (target.windowType == TYPE_NAVIGATION_BAR) {
+            if (target.windowType == type) {
                 return target;
             }
         }
diff --git a/quickstep/src/com/android/quickstep/SwipeUpAnimationLogic.java b/quickstep/src/com/android/quickstep/SwipeUpAnimationLogic.java
index 4495455..1f57e99 100644
--- a/quickstep/src/com/android/quickstep/SwipeUpAnimationLogic.java
+++ b/quickstep/src/com/android/quickstep/SwipeUpAnimationLogic.java
@@ -15,9 +15,13 @@
  */
 package com.android.quickstep;
 
+import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
+
 import static com.android.launcher3.anim.Interpolators.ACCEL_1_5;
 import static com.android.launcher3.anim.Interpolators.LINEAR;
+import static com.android.launcher3.config.FeatureFlags.ENABLE_SPLIT_SELECT;
 import static com.android.launcher3.config.FeatureFlags.PROTOTYPE_APP_CLOSE;
+import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_CLOSING;
 
 import android.animation.Animator;
 import android.content.Context;
@@ -36,8 +40,11 @@
 import com.android.launcher3.anim.AnimatorPlaybackController;
 import com.android.launcher3.anim.PendingAnimation;
 import com.android.launcher3.touch.PagedOrientationHandler;
+import com.android.launcher3.util.SplitConfigurationOptions;
+import com.android.quickstep.util.ActiveGestureLog;
 import com.android.quickstep.util.AnimatorControllerWithResistance;
 import com.android.quickstep.util.AppCloseConfig;
+import com.android.quickstep.util.LauncherSplitScreenListener;
 import com.android.quickstep.util.RectFSpringAnim;
 import com.android.quickstep.util.RectFSpringAnim2;
 import com.android.quickstep.util.TaskViewSimulator;
@@ -46,7 +53,11 @@
 import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
 import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat.SurfaceParams.Builder;
 
-public abstract class SwipeUpAnimationLogic {
+import java.util.Arrays;
+import java.util.function.Consumer;
+
+public abstract class SwipeUpAnimationLogic implements
+        RecentsAnimationCallbacks.RecentsAnimationListener{
 
     protected static final Rect TEMP_RECT = new Rect();
 
@@ -55,9 +66,9 @@
     protected final Context mContext;
     protected final RecentsAnimationDeviceState mDeviceState;
     protected final GestureState mGestureState;
-    protected final TaskViewSimulator mTaskViewSimulator;
 
-    protected final TransformParams mTransformParams;
+    protected final RemoteTargetHandle[] mRemoteTargetHandles;
+    protected SplitConfigurationOptions.StagedSplitBounds mStagedSplitBounds;
 
     // Shift in the range of [0, 1].
     // 0 => preview snapShot is completely visible, and hotseat is completely translated down
@@ -70,37 +81,56 @@
     // How much further we can drag past recents, as a factor of mTransitionDragLength.
     protected float mDragLengthFactor = 1;
 
-    protected AnimatorControllerWithResistance mWindowTransitionController;
+    protected boolean mIsSwipeForStagedSplit;
 
     public SwipeUpAnimationLogic(Context context, RecentsAnimationDeviceState deviceState,
             GestureState gestureState, TransformParams transformParams) {
         mContext = context;
         mDeviceState = deviceState;
         mGestureState = gestureState;
-        mTaskViewSimulator = new TaskViewSimulator(context, gestureState.getActivityInterface());
-        mTransformParams = transformParams;
 
-        mTaskViewSimulator.getOrientationState().update(
+        mIsSwipeForStagedSplit = ENABLE_SPLIT_SELECT.get() &&
+                LauncherSplitScreenListener.INSTANCE.getNoCreate().getSplitTaskIds().length > 1;
+
+        TaskViewSimulator primaryTVS = new TaskViewSimulator(context,
+                gestureState.getActivityInterface());
+        primaryTVS.getOrientationState().update(
                 mDeviceState.getRotationTouchHelper().getCurrentActiveRotation(),
                 mDeviceState.getRotationTouchHelper().getDisplayRotation());
+        mRemoteTargetHandles = new RemoteTargetHandle[mIsSwipeForStagedSplit ? 2 : 1];
+        mRemoteTargetHandles[0] = new RemoteTargetHandle(primaryTVS, transformParams);
+
+        if (mIsSwipeForStagedSplit) {
+            TaskViewSimulator secondaryTVS = new TaskViewSimulator(context,
+                    gestureState.getActivityInterface());
+            secondaryTVS.getOrientationState().update(
+                    mDeviceState.getRotationTouchHelper().getCurrentActiveRotation(),
+                    mDeviceState.getRotationTouchHelper().getDisplayRotation());
+            mRemoteTargetHandles[1] = new RemoteTargetHandle(secondaryTVS, new TransformParams());
+        }
     }
 
     protected void initTransitionEndpoints(DeviceProfile dp) {
         mDp = dp;
-
-        mTaskViewSimulator.setDp(dp);
         mTransitionDragLength = mGestureState.getActivityInterface().getSwipeUpDestinationAndLength(
-                dp, mContext, TEMP_RECT,
-                mTaskViewSimulator.getOrientationState().getOrientationHandler());
+                dp, mContext, TEMP_RECT, mRemoteTargetHandles[0].mTaskViewSimulator
+                        .getOrientationState().getOrientationHandler());
         mDragLengthFactor = (float) dp.heightPx / mTransitionDragLength;
 
-        PendingAnimation pa = new PendingAnimation(mTransitionDragLength * 2);
-        mTaskViewSimulator.addAppToOverviewAnim(pa, LINEAR);
-        AnimatorPlaybackController normalController = pa.createPlaybackController();
-        mWindowTransitionController = AnimatorControllerWithResistance.createForRecents(
-                normalController, mContext, mTaskViewSimulator.getOrientationState(),
-                mDp, mTaskViewSimulator.recentsViewScale, AnimatedFloat.VALUE,
-                mTaskViewSimulator.recentsViewSecondaryTranslation, AnimatedFloat.VALUE);
+        for (RemoteTargetHandle remoteHandle : mRemoteTargetHandles) {
+            PendingAnimation pendingAnimation = new PendingAnimation(mTransitionDragLength * 2);
+            TaskViewSimulator taskViewSimulator = remoteHandle.mTaskViewSimulator;
+            taskViewSimulator.setDp(dp);
+            taskViewSimulator.addAppToOverviewAnim(pendingAnimation, LINEAR);
+            AnimatorPlaybackController playbackController =
+                    pendingAnimation.createPlaybackController();
+
+            remoteHandle.mPlaybackController = AnimatorControllerWithResistance.createForRecents(
+                    playbackController, mContext, taskViewSimulator.getOrientationState(),
+                    mDp, taskViewSimulator.recentsViewScale, AnimatedFloat.VALUE,
+                    taskViewSimulator.recentsViewSecondaryTranslation, AnimatedFloat.VALUE
+            );
+        }
     }
 
     @UiThread
@@ -125,7 +155,9 @@
     public abstract void updateFinalShift();
 
     protected PagedOrientationHandler getOrientationHandler() {
-        return mTaskViewSimulator.getOrientationState().getOrientationHandler();
+        // OrientationHandler should be independent of remote target, can directly take one
+        return mRemoteTargetHandles[0].mTaskViewSimulator
+                .getOrientationState().getOrientationHandler();
     }
 
     protected abstract class HomeAnimationFactory {
@@ -207,31 +239,104 @@
      * @param startProgress The progress of {@link #mCurrentShift} to start thw window from.
      * @return {@link RectF} represents the bounds as starting point in window space.
      */
-    protected RectF updateProgressForStartRect(Matrix outMatrix, float startProgress) {
+    protected RectF[] updateProgressForStartRect(Matrix outMatrix, float startProgress) {
         mCurrentShift.updateValue(startProgress);
-        mTaskViewSimulator.apply(mTransformParams.setProgress(startProgress));
-        RectF cropRectF = new RectF(mTaskViewSimulator.getCurrentCropRect());
+        RectF[] startRects = new RectF[mRemoteTargetHandles.length];
+        for (int i = 0, mRemoteTargetHandlesLength = mRemoteTargetHandles.length;
+                i < mRemoteTargetHandlesLength; i++) {
+            RemoteTargetHandle remoteHandle = mRemoteTargetHandles[i];
+            TaskViewSimulator tvs = remoteHandle.mTaskViewSimulator;
+            tvs.apply(remoteHandle.mTransformParams.setProgress(startProgress));
 
-        mTaskViewSimulator.applyWindowToHomeRotation(outMatrix);
-
-        final RectF startRect = new RectF(cropRectF);
-        mTaskViewSimulator.getCurrentMatrix().mapRect(startRect);
-        return startRect;
+            startRects[i] = new RectF(tvs.getCurrentCropRect());
+            tvs.applyWindowToHomeRotation(outMatrix);
+            tvs.getCurrentMatrix().mapRect(startRects[i]);
+        }
+        return startRects;
     }
 
+    /** Helper to avoid writing some for-loops to iterate over {@link #mRemoteTargetHandles} */
+    protected void runActionOnRemoteHandles(Consumer<RemoteTargetHandle> consumer) {
+        for (RemoteTargetHandle handle : mRemoteTargetHandles) {
+            consumer.accept(handle);
+        }
+    }
+
+    /** @return only the TaskViewSimulators from {@link #mRemoteTargetHandles} */
+    protected TaskViewSimulator[] getRemoteTaskViewSimulators() {
+        return Arrays.stream(mRemoteTargetHandles)
+                .map(remoteTargetHandle -> remoteTargetHandle.mTaskViewSimulator)
+                .toArray(TaskViewSimulator[]::new);
+    }
+
+    @Override
+    public void onRecentsAnimationStart(RecentsAnimationController controller,
+            RecentsAnimationTargets targets) {
+        ActiveGestureLog.INSTANCE.addLog("startRecentsAnimationCallback", targets.apps.length);
+        RemoteAnimationTargetCompat dividerTarget = targets.getNonAppTargetOfType(
+                TYPE_DOCK_DIVIDER);
+        RemoteAnimationTargetCompat primaryTaskTarget;
+        RemoteAnimationTargetCompat secondaryTaskTarget;
+
+        // TODO(b/197568823) Determine if we need to exclude assistant as one of the targets we
+        //  animate
+        if (!mIsSwipeForStagedSplit) {
+            primaryTaskTarget = targets.findTask(mGestureState.getRunningTaskId());
+            mRemoteTargetHandles[0].mTransformParams.setTargetSet(targets);
+
+            if (primaryTaskTarget != null) {
+                mRemoteTargetHandles[0].mTaskViewSimulator.setPreview(primaryTaskTarget);
+            }
+        } else {
+            // We're in staged split
+            primaryTaskTarget = targets.apps[0];
+            secondaryTaskTarget = targets.apps[1];
+            mStagedSplitBounds = new SplitConfigurationOptions.StagedSplitBounds(
+                    primaryTaskTarget.screenSpaceBounds,
+                    secondaryTaskTarget.screenSpaceBounds, dividerTarget.screenSpaceBounds);
+            mRemoteTargetHandles[0].mTaskViewSimulator.setPreview(primaryTaskTarget,
+                    mStagedSplitBounds);
+            mRemoteTargetHandles[1].mTaskViewSimulator.setPreview(secondaryTaskTarget,
+                    mStagedSplitBounds);
+            mRemoteTargetHandles[0].mTransformParams.setTargetSet(
+                    createRemoteAnimationTargetsForTarget(primaryTaskTarget));
+            mRemoteTargetHandles[1].mTransformParams.setTargetSet(
+                    createRemoteAnimationTargetsForTarget(secondaryTaskTarget));
+        }
+    }
+
+    private RemoteAnimationTargets createRemoteAnimationTargetsForTarget(
+            RemoteAnimationTargetCompat target) {
+        return new RemoteAnimationTargets(new RemoteAnimationTargetCompat[]{target},
+                null, null, MODE_CLOSING);
+    }
     /**
      * Creates an animation that transforms the current app window into the home app.
      * @param startProgress The progress of {@link #mCurrentShift} to start the window from.
      * @param homeAnimationFactory The home animation factory.
      */
-    protected RectFSpringAnim createWindowAnimationToHome(float startProgress,
+    protected RectFSpringAnim[] createWindowAnimationToHome(float startProgress,
             HomeAnimationFactory homeAnimationFactory) {
+        // TODO(b/195473584) compute separate end targets for different staged split
         final RectF targetRect = homeAnimationFactory.getWindowTargetRect();
-
+        RectFSpringAnim[] out = new RectFSpringAnim[mRemoteTargetHandles.length];
         Matrix homeToWindowPositionMap = new Matrix();
-        final RectF startRect = updateProgressForStartRect(homeToWindowPositionMap, startProgress);
-        RectF cropRectF = new RectF(mTaskViewSimulator.getCurrentCropRect());
+        RectF[] startRects = updateProgressForStartRect(homeToWindowPositionMap, startProgress);
+        for (int i = 0, mRemoteTargetHandlesLength = mRemoteTargetHandles.length;
+                i < mRemoteTargetHandlesLength; i++) {
+            RemoteTargetHandle remoteHandle = mRemoteTargetHandles[i];
+            out[i] = getWindowAnimationToHomeInternal(homeAnimationFactory,
+                    targetRect, remoteHandle.mTransformParams, remoteHandle.mTaskViewSimulator,
+                    startRects[i], homeToWindowPositionMap);
+        }
+        return out;
+    }
 
+    private RectFSpringAnim getWindowAnimationToHomeInternal(
+            HomeAnimationFactory homeAnimationFactory, RectF targetRect,
+            TransformParams transformParams, TaskViewSimulator taskViewSimulator,
+            RectF startRect, Matrix homeToWindowPositionMap) {
+        RectF cropRectF = new RectF(taskViewSimulator.getCurrentCropRect());
         // Move the startRect to Launcher space as floatingIconView runs in Launcher
         Matrix windowToHomePositionMap = new Matrix();
         homeToWindowPositionMap.invert(windowToHomePositionMap);
@@ -240,7 +345,7 @@
         RectFSpringAnim anim;
         if (PROTOTYPE_APP_CLOSE.get()) {
             anim = new RectFSpringAnim2(startRect, targetRect, mContext,
-                    mTaskViewSimulator.getCurrentCornerRadius(),
+                    taskViewSimulator.getCurrentCornerRadius(),
                     homeAnimationFactory.getEndRadius(cropRectF));
         } else {
             anim = new RectFSpringAnim(startRect, targetRect, mContext);
@@ -248,9 +353,10 @@
         homeAnimationFactory.setAnimation(anim);
 
         SpringAnimationRunner runner = new SpringAnimationRunner(
-                homeAnimationFactory, cropRectF, homeToWindowPositionMap);
-        anim.addOnUpdateListener(runner);
+                homeAnimationFactory, cropRectF, homeToWindowPositionMap,
+                transformParams, taskViewSimulator);
         anim.addAnimatorListener(runner);
+        anim.addOnUpdateListener(runner);
         return anim;
     }
 
@@ -262,6 +368,7 @@
 
         final RectF mWindowCurrentRect = new RectF();
         final Matrix mHomeToWindowPositionMap;
+        private final TransformParams mLocalTransformParams;
         final HomeAnimationFactory mAnimationFactory;
 
         final AnimatorPlaybackController mHomeAnim;
@@ -271,17 +378,19 @@
         final float mEndRadius;
 
         SpringAnimationRunner(HomeAnimationFactory factory, RectF cropRectF,
-                Matrix homeToWindowPositionMap) {
+                Matrix homeToWindowPositionMap, TransformParams transformParams,
+                TaskViewSimulator taskViewSimulator) {
             mAnimationFactory = factory;
             mHomeAnim = factory.createActivityAnimationToHome();
             mCropRectF = cropRectF;
             mHomeToWindowPositionMap = homeToWindowPositionMap;
+            mLocalTransformParams = transformParams;
 
             cropRectF.roundOut(mCropRect);
 
             // End on a "round-enough" radius so that the shape reveal doesn't have to do too much
             // rounding at the end of the animation.
-            mStartRadius = mTaskViewSimulator.getCurrentCornerRadius();
+            mStartRadius = taskViewSimulator.getCurrentCornerRadius();
             mEndRadius = factory.getEndRadius(cropRectF);
         }
 
@@ -300,10 +409,11 @@
             if (mAnimationFactory.keepWindowOpaque()) {
                 alpha = 1f;
             }
-            mTransformParams
+            mLocalTransformParams
                     .setTargetAlpha(alpha)
                     .setCornerRadius(cornerRadius);
-            mTransformParams.applySurfaceParams(mTransformParams.createSurfaceParams(this));
+            mLocalTransformParams.applySurfaceParams(mLocalTransformParams
+                    .createSurfaceParams(this));
             mAnimationFactory.update(config, currentRect, progress,
                     mMatrix.mapRadius(cornerRadius));
         }
@@ -332,6 +442,21 @@
         }
     }
 
+    /**
+     * Container to keep together all the associated objects whose properties need to be updated to
+     * animate a single remote app target
+     */
+    public static class RemoteTargetHandle {
+        public TaskViewSimulator mTaskViewSimulator;
+        public TransformParams mTransformParams;
+        public AnimatorControllerWithResistance mPlaybackController;
+        public RemoteTargetHandle(TaskViewSimulator taskViewSimulator,
+                TransformParams transformParams) {
+            mTransformParams = transformParams;
+            mTaskViewSimulator = taskViewSimulator;
+        }
+    }
+
     public interface RunningWindowAnim {
         void end();
 
diff --git a/quickstep/src/com/android/quickstep/SystemUiProxy.java b/quickstep/src/com/android/quickstep/SystemUiProxy.java
index 11ca4b1..7d2d413 100644
--- a/quickstep/src/com/android/quickstep/SystemUiProxy.java
+++ b/quickstep/src/com/android/quickstep/SystemUiProxy.java
@@ -17,6 +17,7 @@
 
 import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
 
+import android.app.ActivityManager;
 import android.app.PendingIntent;
 import android.app.PictureInPictureParams;
 import android.content.ComponentName;
@@ -632,10 +633,11 @@
      * @param cancel true if recents starting is being cancelled.
      * @return RemoteAnimationTargets of windows that need to animate but only exist in shell.
      */
-    public RemoteAnimationTarget[] onGoingToRecentsLegacy(boolean cancel) {
+    public RemoteAnimationTarget[] onGoingToRecentsLegacy(boolean cancel,
+            RemoteAnimationTarget[] apps) {
         if (mSplitScreen != null) {
             try {
-                return mSplitScreen.onGoingToRecentsLegacy(cancel);
+                return mSplitScreen.onGoingToRecentsLegacy(cancel, apps);
             } catch (RemoteException e) {
                 Log.w(TAG, "Failed call onGoingToRecentsLegacy");
             }
diff --git a/quickstep/src/com/android/quickstep/TaskViewUtils.java b/quickstep/src/com/android/quickstep/TaskViewUtils.java
index b5da097..5b9e214 100644
--- a/quickstep/src/com/android/quickstep/TaskViewUtils.java
+++ b/quickstep/src/com/android/quickstep/TaskViewUtils.java
@@ -154,9 +154,10 @@
         boolean isRunningTask = v.isRunningTask();
         TransformParams params = null;
         TaskViewSimulator tsv = null;
+        // TODO(b/195675206) handle two TSVs here
         if (ENABLE_QUICKSTEP_LIVE_TILE.get() && isRunningTask) {
-            params = v.getRecentsView().getLiveTileParams();
-            tsv = v.getRecentsView().getLiveTileTaskViewSimulator();
+            params = v.getRecentsView().getRemoteTargetHandles()[0].mTransformParams;
+            tsv = v.getRecentsView().getRemoteTargetHandles()[0].mTaskViewSimulator;
         }
         createRecentsWindowAnimator(v, skipViewChanges, appTargets, wallpaperTargets, nonAppTargets,
                 depthController, out, params, tsv);
diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java
index 61622ee..2e42392 100644
--- a/quickstep/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java
@@ -99,7 +99,9 @@
 import com.android.quickstep.inputconsumers.TaskbarStashInputConsumer;
 import com.android.quickstep.util.ActiveGestureLog;
 import com.android.quickstep.util.AssistantUtilities;
+import com.android.quickstep.util.LauncherSplitScreenListener;
 import com.android.quickstep.util.ProtoTracer;
+import com.android.quickstep.util.ProxyScreenStatusProvider;
 import com.android.quickstep.util.SplitScreenBounds;
 import com.android.systemui.plugins.OverscrollPlugin;
 import com.android.systemui.plugins.PluginListener;
@@ -144,7 +146,7 @@
     private static final int SYSTEM_ACTION_ID_ALL_APPS = 14;
 
     public static final boolean ENABLE_PER_WINDOW_INPUT_ROTATION =
-            SystemProperties.getBoolean("persist.debug.per_window_input_rotation", false);
+            SystemProperties.getBoolean("persist.debug.per_window_input_rotation", true);
 
     private int mBackGestureNotificationCounter = -1;
     @Nullable
@@ -268,6 +270,12 @@
             MAIN_EXECUTOR.execute(() -> SplitScreenBounds.INSTANCE.setSecondaryWindowBounds(wb));
         }
 
+        @BinderThread
+        @Override
+        public void onScreenTurnedOn() {
+            MAIN_EXECUTOR.execute(ProxyScreenStatusProvider.INSTANCE::onScreenTurnedOn);
+        }
+
         @Override
         public void onRotationProposal(int rotation, boolean isValid) {
             executeForTaskbarManager(() -> mTaskbarManager.onRotationProposal(rotation, isValid));
@@ -357,6 +365,7 @@
         mDeviceState.runOnUserUnlocked(this::onUserUnlocked);
         mDeviceState.runOnUserUnlocked(mTaskbarManager::onUserUnlocked);
         ProtoTracer.INSTANCE.get(this).add(this);
+        LauncherSplitScreenListener.INSTANCE.get(this).init();
         sConnected = true;
     }
 
@@ -513,6 +522,7 @@
         getSystemService(AccessibilityManager.class)
                 .unregisterSystemAction(SYSTEM_ACTION_ID_ALL_APPS);
 
+        LauncherSplitScreenListener.INSTANCE.get(this).destroy();
         mTaskbarManager.destroy();
         sConnected = false;
         super.onDestroy();
diff --git a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
index 64a428f..765480c 100644
--- a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
+++ b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
@@ -79,8 +79,10 @@
      * to the home task. This allows us to handle quick-switch similarly to a quick-switching
      * from a foreground task.
      */
-    public void onGestureAnimationStartOnHome(RunningTaskInfo homeTaskInfo) {
-        mHomeTaskInfo = homeTaskInfo;
+    public void onGestureAnimationStartOnHome(RunningTaskInfo[] homeTaskInfo) {
+        // TODO(b/195607777) General fallback love, but this might be correct
+        //  Home task should be defined as the front-most task info I think?
+        mHomeTaskInfo = homeTaskInfo[0];
         onGestureAnimationStart(homeTaskInfo);
     }
 
@@ -92,8 +94,8 @@
     @Override
     public void onPrepareGestureEndAnimation(
             @Nullable AnimatorSet animatorSet, GestureState.GestureEndTarget endTarget,
-            TaskViewSimulator taskViewSimulator) {
-        super.onPrepareGestureEndAnimation(animatorSet, endTarget, taskViewSimulator);
+            TaskViewSimulator[] taskViewSimulators) {
+        super.onPrepareGestureEndAnimation(animatorSet, endTarget, taskViewSimulators);
         if (mHomeTaskInfo != null && endTarget == RECENTS && animatorSet != null) {
             TaskView tv = getTaskViewByTaskId(mHomeTaskInfo.taskId);
             if (tv != null) {
@@ -133,7 +135,13 @@
     }
 
     @Override
-    protected boolean shouldAddStubTaskView(RunningTaskInfo runningTaskInfo) {
+    protected boolean shouldAddStubTaskView(RunningTaskInfo[] runningTaskInfos) {
+        if (runningTaskInfos.length > 1) {
+            // can't be in split screen w/ home task
+            return super.shouldAddStubTaskView(runningTaskInfos);
+        }
+
+        RunningTaskInfo runningTaskInfo = runningTaskInfos[0];
         if (mHomeTaskInfo != null && runningTaskInfo != null &&
                 mHomeTaskInfo.taskId == runningTaskInfo.taskId
                 && getTaskViewCount() == 0) {
@@ -141,7 +149,7 @@
             // show the empty recents message instead of showing a stub task and later removing it.
             return false;
         }
-        return super.shouldAddStubTaskView(runningTaskInfo);
+        return super.shouldAddStubTaskView(runningTaskInfos);
     }
 
     @Override
@@ -149,6 +157,7 @@
         // When quick-switching on 3p-launcher, we add a "stub" tile corresponding to Launcher
         // as well. This tile is never shown as we have setCurrentTaskHidden, but allows use to
         // track the index of the next task appropriately, as if we are switching on any other app.
+        // TODO(b/195607777) Confirm home task info is front-most task and not mixed in with others
         int runningTaskId = getTaskIdsForRunningTaskView()[0];
         if (mHomeTaskInfo != null && mHomeTaskInfo.taskId == runningTaskId && !tasks.isEmpty()) {
             // Check if the task list has running task
diff --git a/quickstep/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java
index 725c7c4..e6285f2 100644
--- a/quickstep/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java
+++ b/quickstep/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java
@@ -50,6 +50,7 @@
 import androidx.annotation.UiThread;
 
 import com.android.launcher3.R;
+import com.android.launcher3.Utilities;
 import com.android.launcher3.testing.TestLogging;
 import com.android.launcher3.testing.TestProtocol;
 import com.android.launcher3.tracing.InputConsumerProto;
@@ -356,6 +357,9 @@
             }
             case ACTION_CANCEL:
             case ACTION_UP: {
+                if (Utilities.IS_RUNNING_IN_TEST_HARNESS) {
+                    Log.d(TestProtocol.L3_SWIPE_TO_HOME, "1");
+                }
                 if (DEBUG_FAILED_QUICKSWITCH && !mPassedWindowMoveSlop) {
                     float displacementX = mLastPos.x - mDownPos.x;
                     float displacementY = mLastPos.y - mDownPos.y;
@@ -409,6 +413,9 @@
      * the animation can still be running.
      */
     private void finishTouchTracking(MotionEvent ev) {
+        if (Utilities.IS_RUNNING_IN_TEST_HARNESS) {
+            Log.d(TestProtocol.L3_SWIPE_TO_HOME, "2");
+        }
         Object traceToken = TraceHelper.INSTANCE.beginSection(UP_EVT,
                 FLAG_CHECK_FOR_RACE_CONDITIONS);
 
diff --git a/quickstep/src/com/android/quickstep/interaction/AssistantGestureTutorialController.java b/quickstep/src/com/android/quickstep/interaction/AssistantGestureTutorialController.java
index 957f776..2f3a912 100644
--- a/quickstep/src/com/android/quickstep/interaction/AssistantGestureTutorialController.java
+++ b/quickstep/src/com/android/quickstep/interaction/AssistantGestureTutorialController.java
@@ -68,7 +68,6 @@
                         showFeedback(R.string.assistant_gesture_feedback_swipe_too_far_from_corner);
                         break;
                     case ASSISTANT_COMPLETED:
-                        hideFeedback(true);
                         showRippleEffect(null);
                         showFeedback(R.string.assistant_gesture_tutorial_playground_subtitle);
                         break;
diff --git a/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialController.java b/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialController.java
index 3cb22f4..f2402e3 100644
--- a/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialController.java
+++ b/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialController.java
@@ -18,10 +18,9 @@
 import static com.android.quickstep.interaction.TutorialController.TutorialType.BACK_NAVIGATION;
 import static com.android.quickstep.interaction.TutorialController.TutorialType.BACK_NAVIGATION_COMPLETE;
 
+import android.annotation.LayoutRes;
 import android.graphics.PointF;
 
-import androidx.appcompat.content.res.AppCompatResources;
-
 import com.android.launcher3.R;
 import com.android.quickstep.interaction.EdgeBackGestureHandler.BackGestureResult;
 import com.android.quickstep.interaction.NavBarGestureHandler.NavBarGestureResult;
@@ -44,8 +43,18 @@
     }
 
     @Override
-    protected int getMockAppTaskThumbnailResId(boolean forDarkMode) {
-        return R.drawable.mock_conversation;
+    protected int getMockAppTaskLayoutResId() {
+        return getMockAppTaskCurrentPageLayoutResId();
+    }
+
+    @LayoutRes
+    int getMockAppTaskCurrentPageLayoutResId() {
+        return R.layout.gesture_tutorial_mock_conversation;
+    }
+
+    @LayoutRes
+    int getMockAppTaskPreviousPageLayoutResId() {
+        return R.layout.gesture_tutorial_mock_conversation_list;
     }
 
     @Override
@@ -70,10 +79,8 @@
         switch (result) {
             case BACK_COMPLETED_FROM_LEFT:
             case BACK_COMPLETED_FROM_RIGHT:
-                mTutorialFragment.releaseGestureVideoView();
-                hideFeedback(true);
-                mFakeTaskView.setBackground(AppCompatResources.getDrawable(mContext,
-                        R.drawable.mock_conversations_list));
+                mTutorialFragment.releaseFeedbackAnimation();
+                updateFakeAppTaskViewLayout(getMockAppTaskPreviousPageLayoutResId());
                 int subtitleResId = mTutorialFragment.isAtFinalStep()
                         ? R.string.back_gesture_feedback_complete_without_follow_up
                         : R.string.back_gesture_feedback_complete_with_overview_follow_up;
diff --git a/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialFragment.java b/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialFragment.java
index 1740f68..f54734d 100644
--- a/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialFragment.java
+++ b/quickstep/src/com/android/quickstep/interaction/BackGestureTutorialFragment.java
@@ -15,6 +15,10 @@
  */
 package com.android.quickstep.interaction;
 
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
 import android.view.MotionEvent;
 import android.view.View;
 
@@ -23,18 +27,76 @@
 import com.android.launcher3.R;
 import com.android.quickstep.interaction.TutorialController.TutorialType;
 
+import java.util.ArrayList;
+
 /** Shows the Back gesture interactive tutorial. */
 public class BackGestureTutorialFragment extends TutorialFragment {
+
     @Nullable
     @Override
-    Integer getFeedbackVideoResId(boolean forDarkMode) {
-        return R.drawable.gesture_tutorial_motion_back;
+    Integer getEdgeAnimationResId() {
+        return R.drawable.gesture_tutorial_loop_back;
     }
 
     @Nullable
     @Override
-    Integer getGestureVideoResId() {
-        return R.drawable.gesture_tutorial_loop_back;
+    protected Animator createGestureAnimation() {
+        if (!(mTutorialController instanceof BackGestureTutorialController)) {
+            return null;
+        }
+        BackGestureTutorialController controller =
+                (BackGestureTutorialController) mTutorialController;
+        float fingerDotStartTranslationX = (float) -(mRootView.getWidth() / 2);
+
+        AnimatorSet fingerDotAppearanceAnimator = controller.createFingerDotAppearanceAnimatorSet();
+        fingerDotAppearanceAnimator.addListener(new AnimatorListenerAdapter() {
+            @Override
+            public void onAnimationStart(Animator animation) {
+                super.onAnimationStart(animation);
+                mFingerDotView.setTranslationX(fingerDotStartTranslationX);
+            }
+        });
+
+        ObjectAnimator translationAnimator = ObjectAnimator.ofFloat(
+                mFingerDotView, View.TRANSLATION_X, fingerDotStartTranslationX, 0);
+        translationAnimator.addListener(new AnimatorListenerAdapter() {
+            @Override
+            public void onAnimationEnd(Animator animation) {
+                super.onAnimationEnd(animation);
+                controller.updateFakeAppTaskViewLayout(
+                        controller.getMockAppTaskPreviousPageLayoutResId());
+            }
+        });
+        translationAnimator.setDuration(1000);
+
+        Animator animationPause = controller.createAnimationPause();
+        animationPause.addListener(new AnimatorListenerAdapter() {
+            @Override
+            public void onAnimationEnd(Animator animation) {
+                super.onAnimationEnd(animation);
+                controller.updateFakeAppTaskViewLayout(
+                        controller.getMockAppTaskCurrentPageLayoutResId());
+            }
+        });
+        ArrayList<Animator> animators = new ArrayList<>();
+
+        animators.add(fingerDotAppearanceAnimator);
+        animators.add(translationAnimator);
+        animators.add(controller.createFingerDotDisappearanceAnimatorSet());
+        animators.add(animationPause);
+
+        AnimatorSet finalAnimation = new AnimatorSet();
+        finalAnimation.addListener(new AnimatorListenerAdapter() {
+            @Override
+            public void onAnimationCancel(Animator animation) {
+                super.onAnimationCancel(animation);
+                controller.updateFakeAppTaskViewLayout(
+                        controller.getMockAppTaskCurrentPageLayoutResId());
+            }
+        });
+        finalAnimation.playSequentially(animators);
+
+        return finalAnimation;
     }
 
     @Override
@@ -49,6 +111,7 @@
 
     @Override
     public boolean onTouch(View view, MotionEvent motionEvent) {
+        releaseFeedbackAnimation();
         if (motionEvent.getAction() == MotionEvent.ACTION_DOWN && mTutorialController != null) {
             mTutorialController.setRippleHotspot(motionEvent.getX(), motionEvent.getY());
         }
diff --git a/quickstep/src/com/android/quickstep/interaction/EdgeBackGesturePanel.java b/quickstep/src/com/android/quickstep/interaction/EdgeBackGesturePanel.java
index 0521db4..7465db3 100644
--- a/quickstep/src/com/android/quickstep/interaction/EdgeBackGesturePanel.java
+++ b/quickstep/src/com/android/quickstep/interaction/EdgeBackGesturePanel.java
@@ -282,9 +282,7 @@
                         .setDampingRatio(SpringForce.DAMPING_RATIO_LOW_BOUNCY));
         int currentNightMode =
                 context.getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK;
-        mPaint.setColor(context.getColor(currentNightMode == Configuration.UI_MODE_NIGHT_YES
-                ? R.color.back_arrow_color_light
-                : R.color.back_arrow_color_dark));
+        mPaint.setColor(context.getColor(R.color.gesture_tutorial_back_arrow_color));
         loadDimens();
         updateArrowDirection();
 
diff --git a/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialController.java b/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialController.java
index 819c91c..307a8fd 100644
--- a/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialController.java
+++ b/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialController.java
@@ -42,8 +42,8 @@
     }
 
     @Override
-    protected int getMockAppTaskThumbnailResId(boolean forDarkMode) {
-        return forDarkMode ? R.drawable.mock_webpage_dark_mode : R.drawable.mock_webpage_light_mode;
+    protected int getMockAppTaskLayoutResId() {
+        return R.layout.gesture_tutorial_mock_webpage;
     }
 
     @Override
@@ -80,7 +80,7 @@
             case HOME_NAVIGATION:
                 switch (result) {
                     case HOME_GESTURE_COMPLETED: {
-                        mTutorialFragment.releaseGestureVideoView();
+                        mTutorialFragment.releaseFeedbackAnimation();
                         animateFakeTaskViewHome(finalVelocity, null);
                         int subtitleResId = mTutorialFragment.isAtFinalStep()
                                 ? R.string.home_gesture_feedback_complete_without_follow_up
diff --git a/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialFragment.java b/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialFragment.java
index 9572637..dcae07d 100644
--- a/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialFragment.java
+++ b/quickstep/src/com/android/quickstep/interaction/HomeGestureTutorialFragment.java
@@ -15,25 +15,73 @@
  */
 package com.android.quickstep.interaction;
 
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.AnimatorSet;
+import android.view.MotionEvent;
+import android.view.View;
+
 import androidx.annotation.Nullable;
 
 import com.android.launcher3.R;
 import com.android.quickstep.interaction.TutorialController.TutorialType;
 
+import java.util.ArrayList;
+
 /** Shows the Home gesture interactive tutorial. */
 public class HomeGestureTutorialFragment extends TutorialFragment {
+
     @Nullable
     @Override
-    Integer getFeedbackVideoResId(boolean forDarkMode) {
-        return forDarkMode
-                ? R.drawable.gesture_tutorial_motion_home_dark_mode
-                : R.drawable.gesture_tutorial_motion_home_light_mode;
+    Integer getEdgeAnimationResId() {
+        return R.drawable.gesture_tutorial_loop_home;
     }
 
     @Nullable
     @Override
-    Integer getGestureVideoResId() {
-        return R.drawable.gesture_tutorial_loop_home;
+    protected Animator createGestureAnimation() {
+        if (!(mTutorialController instanceof HomeGestureTutorialController)) {
+            return null;
+        }
+        float fingerDotStartTranslationY = (float) mRootView.getFullscreenHeight() / 2;
+        HomeGestureTutorialController controller =
+                (HomeGestureTutorialController) mTutorialController;
+
+        AnimatorSet fingerDotAppearanceAnimator = controller.createFingerDotAppearanceAnimatorSet();
+        fingerDotAppearanceAnimator.addListener(new AnimatorListenerAdapter() {
+            @Override
+            public void onAnimationStart(Animator animation) {
+                super.onAnimationStart(animation);
+                mFingerDotView.setTranslationY(fingerDotStartTranslationY);
+            }
+        });
+
+        Animator animationPause = controller.createAnimationPause();
+        animationPause.addListener(new AnimatorListenerAdapter() {
+            @Override
+            public void onAnimationEnd(Animator animation) {
+                super.onAnimationEnd(animation);
+                controller.resetFakeTaskView();
+            }
+        });
+        ArrayList<Animator> animators = new ArrayList<>();
+
+        animators.add(fingerDotAppearanceAnimator);
+        animators.add(controller.createFingerDotHomeSwipeAnimator(fingerDotStartTranslationY));
+        animators.add(controller.createFingerDotDisappearanceAnimatorSet());
+        animators.add(animationPause);
+
+        AnimatorSet finalAnimation = new AnimatorSet();
+        finalAnimation.addListener(new AnimatorListenerAdapter() {
+            @Override
+            public void onAnimationCancel(Animator animation) {
+                super.onAnimationCancel(animation);
+                controller.resetFakeTaskView();
+            }
+        });
+        finalAnimation.playSequentially(animators);
+
+        return finalAnimation;
     }
 
     @Override
@@ -45,4 +93,10 @@
     Class<? extends TutorialController> getControllerClass() {
         return HomeGestureTutorialController.class;
     }
+
+    @Override
+    public boolean onTouch(View view, MotionEvent motionEvent) {
+        releaseFeedbackAnimation();
+        return super.onTouch(view, motionEvent);
+    }
 }
diff --git a/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialController.java b/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialController.java
index 77ddb2b..b38a641 100644
--- a/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialController.java
+++ b/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialController.java
@@ -49,8 +49,8 @@
     }
 
     @Override
-    protected int getMockAppTaskThumbnailResId(boolean forDarkMode) {
-        return R.drawable.mock_conversations_list;
+    protected int getMockAppTaskLayoutResId() {
+        return R.layout.gesture_tutorial_mock_conversation_list;
     }
 
     @Override
@@ -98,13 +98,8 @@
                         showFeedback(R.string.overview_gesture_feedback_swipe_too_far_from_edge);
                         break;
                     case OVERVIEW_GESTURE_COMPLETED:
-                        mTutorialFragment.releaseGestureVideoView();
-                        PendingAnimation anim = new PendingAnimation(300);
-                        anim.setFloat(mTaskViewSwipeUpAnimation
-                                .getCurrentShift(), AnimatedFloat.VALUE, 1, ACCEL);
-                        AnimatorSet animset = anim.buildAnim();
-                        animset.start();
-                        mRunningWindowAnim = SwipeUpAnimationLogic.RunningWindowAnim.wrap(animset);
+                        mTutorialFragment.releaseFeedbackAnimation();
+                        animateTaskViewToOverview();
                         onMotionPaused(true /*arbitrary value*/);
                         int subtitleResId = mTutorialFragment.getNumSteps() > 1
                                 && mTutorialFragment.isAtFinalStep()
@@ -126,4 +121,13 @@
                 break;
         }
     }
+
+    public void animateTaskViewToOverview() {
+        PendingAnimation anim = new PendingAnimation(300);
+        anim.setFloat(mTaskViewSwipeUpAnimation
+                .getCurrentShift(), AnimatedFloat.VALUE, 1, ACCEL);
+        AnimatorSet animset = anim.buildAnim();
+        animset.start();
+        mRunningWindowAnim = SwipeUpAnimationLogic.RunningWindowAnim.wrap(animset);
+    }
 }
diff --git a/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialFragment.java b/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialFragment.java
index d2ec327..968412b 100644
--- a/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialFragment.java
+++ b/quickstep/src/com/android/quickstep/interaction/OverviewGestureTutorialFragment.java
@@ -15,25 +15,96 @@
  */
 package com.android.quickstep.interaction;
 
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.AnimatorSet;
+import android.view.MotionEvent;
+import android.view.View;
+
 import androidx.annotation.Nullable;
 
 import com.android.launcher3.R;
 import com.android.quickstep.interaction.TutorialController.TutorialType;
 
+import java.util.ArrayList;
+
 /** Shows the Overview gesture interactive tutorial. */
 public class OverviewGestureTutorialFragment extends TutorialFragment {
+
     @Nullable
     @Override
-    Integer getFeedbackVideoResId(boolean forDarkMode) {
-        return forDarkMode
-                ? R.drawable.gesture_tutorial_motion_overview_dark_mode
-                : R.drawable.gesture_tutorial_motion_overview_light_mode;
+    Integer getEdgeAnimationResId() {
+        return R.drawable.gesture_tutorial_loop_overview;
     }
 
     @Nullable
     @Override
-    Integer getGestureVideoResId() {
-        return R.drawable.gesture_tutorial_loop_overview;
+    protected Animator createGestureAnimation() {
+        if (!(mTutorialController instanceof OverviewGestureTutorialController)) {
+            return null;
+        }
+        float fingerDotStartTranslationY = (float) mRootView.getFullscreenHeight() / 2;
+        OverviewGestureTutorialController controller =
+                (OverviewGestureTutorialController) mTutorialController;
+
+        AnimatorSet fingerDotAppearanceAnimator = controller.createFingerDotAppearanceAnimatorSet();
+        fingerDotAppearanceAnimator.addListener(new AnimatorListenerAdapter() {
+            @Override
+            public void onAnimationStart(Animator animation) {
+                super.onAnimationStart(animation);
+
+                mFingerDotView.setTranslationY(fingerDotStartTranslationY);
+            }
+        });
+
+        Animator swipeAnimator =
+                controller.createFingerDotOverviewSwipeAnimator(fingerDotStartTranslationY);
+        swipeAnimator.addListener(new AnimatorListenerAdapter() {
+            @Override
+            public void onAnimationEnd(Animator animation) {
+                super.onAnimationEnd(animation);
+                mFakePreviousTaskView.setVisibility(View.VISIBLE);
+                controller.onMotionPaused(true /*arbitrary value*/);
+            }
+        });
+
+        AnimatorSet fingerDotDisappearanceAnimator =
+                controller.createFingerDotDisappearanceAnimatorSet();
+        fingerDotDisappearanceAnimator.addListener(new AnimatorListenerAdapter() {
+            @Override
+            public void onAnimationStart(Animator animation) {
+                super.onAnimationStart(animation);
+                controller.animateTaskViewToOverview();
+            }
+        });
+
+        Animator animationPause = controller.createAnimationPause();
+        animationPause.addListener(new AnimatorListenerAdapter() {
+            @Override
+            public void onAnimationEnd(Animator animation) {
+                super.onAnimationEnd(animation);
+                controller.resetFakeTaskView();
+            }
+        });
+        ArrayList<Animator> animators = new ArrayList<>();
+
+        animators.add(fingerDotAppearanceAnimator);
+        animators.add(swipeAnimator);
+        animators.add(controller.createAnimationPause());
+        animators.add(fingerDotDisappearanceAnimator);
+        animators.add(animationPause);
+
+        AnimatorSet finalAnimation = new AnimatorSet();
+        finalAnimation.addListener(new AnimatorListenerAdapter() {
+            @Override
+            public void onAnimationCancel(Animator animation) {
+                super.onAnimationCancel(animation);
+                controller.resetFakeTaskView();
+            }
+        });
+        finalAnimation.playSequentially(animators);
+
+        return finalAnimation;
     }
 
     @Override
@@ -45,4 +116,10 @@
     Class<? extends TutorialController> getControllerClass() {
         return OverviewGestureTutorialController.class;
     }
+
+    @Override
+    public boolean onTouch(View view, MotionEvent motionEvent) {
+        releaseFeedbackAnimation();
+        return super.onTouch(view, motionEvent);
+    }
 }
diff --git a/quickstep/src/com/android/quickstep/interaction/RootSandboxLayout.java b/quickstep/src/com/android/quickstep/interaction/RootSandboxLayout.java
index db1afc2..ac0c17d 100644
--- a/quickstep/src/com/android/quickstep/interaction/RootSandboxLayout.java
+++ b/quickstep/src/com/android/quickstep/interaction/RootSandboxLayout.java
@@ -16,8 +16,10 @@
 package com.android.quickstep.interaction;
 
 import android.content.Context;
+import android.graphics.Insets;
 import android.util.AttributeSet;
 import android.view.MotionEvent;
+import android.view.WindowInsets;
 import android.widget.RelativeLayout;
 
 import androidx.fragment.app.FragmentManager;
@@ -41,4 +43,13 @@
         return ((TutorialFragment) FragmentManager.findFragment(this))
                 .onInterceptTouch(motionEvent);
     }
+
+    /**
+     * Returns this view's fullscreen height. This method is agnostic of this view's actual height.
+     */
+    public int getFullscreenHeight() {
+        Insets insets = getRootWindowInsets().getInsets(WindowInsets.Type.systemBars());
+
+        return getHeight() + insets.top + insets.bottom;
+    }
 }
diff --git a/quickstep/src/com/android/quickstep/interaction/SwipeUpGestureTutorialController.java b/quickstep/src/com/android/quickstep/interaction/SwipeUpGestureTutorialController.java
index b2183d6..c2c8f61 100644
--- a/quickstep/src/com/android/quickstep/interaction/SwipeUpGestureTutorialController.java
+++ b/quickstep/src/com/android/quickstep/interaction/SwipeUpGestureTutorialController.java
@@ -25,6 +25,7 @@
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.animation.AnimatorSet;
+import android.animation.ValueAnimator;
 import android.annotation.TargetApi;
 import android.content.Context;
 import android.graphics.Outline;
@@ -32,7 +33,6 @@
 import android.graphics.Rect;
 import android.graphics.RectF;
 import android.os.Build;
-import android.util.DisplayMetrics;
 import android.view.SurfaceControl;
 import android.view.View;
 import android.view.ViewOutlineProvider;
@@ -46,6 +46,7 @@
 import com.android.launcher3.anim.AnimatorListeners;
 import com.android.launcher3.anim.AnimatorPlaybackController;
 import com.android.launcher3.anim.PendingAnimation;
+import com.android.launcher3.statemanager.StatefulActivity;
 import com.android.quickstep.AnimatedFloat;
 import com.android.quickstep.GestureState;
 import com.android.quickstep.OverviewComponentObserver;
@@ -62,23 +63,24 @@
 
     private static final int FAKE_PREVIOUS_TASK_MARGIN = Utilities.dpToPx(12);
 
+    private static final long HOME_SWIPE_ANIMATION_DURATION_MILLIS = 625;
+    private static final long OVERVIEW_SWIPE_ANIMATION_DURATION_MILLIS = 1000;
+
     final ViewSwipeUpAnimation mTaskViewSwipeUpAnimation;
     private float mFakeTaskViewRadius;
-    private Rect mFakeTaskViewRect = new Rect();
+    private final Rect mFakeTaskViewRect = new Rect();
     RunningWindowAnim mRunningWindowAnim;
     private boolean mShowTasks = false;
     private boolean mShowPreviousTasks = false;
 
-    private AnimatorListenerAdapter mResetTaskView = new AnimatorListenerAdapter() {
+    private final AnimatorListenerAdapter mResetTaskView = new AnimatorListenerAdapter() {
         @Override
         public void onAnimationEnd(Animator animation) {
             mFakeHotseatView.setVisibility(View.INVISIBLE);
             mFakeIconView.setVisibility(View.INVISIBLE);
             if (mTutorialFragment.getActivity() != null) {
-                DisplayMetrics displayMetrics =
-                        mTutorialFragment.getResources().getDisplayMetrics();
-                int height = displayMetrics.heightPixels;
-                int width = displayMetrics.widthPixels;
+                int height = mTutorialFragment.getRootView().getFullscreenHeight();
+                int width = mTutorialFragment.getRootView().getWidth();
                 mFakeTaskViewRect.set(0, 0, width, height);
             }
             mFakeTaskViewRadius = 0;
@@ -107,9 +109,8 @@
                 .copy(mContext);
         mTaskViewSwipeUpAnimation.initDp(dp);
 
-        DisplayMetrics displayMetrics = mContext.getResources().getDisplayMetrics();
-        int height = displayMetrics.heightPixels;
-        int width = displayMetrics.widthPixels;
+        int height = mTutorialFragment.getRootView().getFullscreenHeight();
+        int width = mTutorialFragment.getRootView().getWidth();
         mFakeTaskViewRect.set(0, 0, width, height);
         mFakeTaskViewRadius = 0;
 
@@ -137,7 +138,6 @@
     /** Fades the task view, optionally after animating to a fake Overview. */
     void fadeOutFakeTaskView(boolean toOverviewFirst, boolean reset,
                              @Nullable Runnable onEndRunnable) {
-        hideFeedback(true);
         cancelRunningAnimation();
         PendingAnimation anim = new PendingAnimation(300);
         if (toOverviewFirst) {
@@ -183,6 +183,7 @@
     }
 
     void resetFakeTaskView() {
+        mFakeTaskView.setVisibility(View.VISIBLE);
         PendingAnimation anim = new PendingAnimation(300);
         anim.setFloat(mTaskViewSwipeUpAnimation
                 .getCurrentShift(), AnimatedFloat.VALUE, 0, ACCEL);
@@ -194,7 +195,6 @@
     }
 
     void animateFakeTaskViewHome(PointF finalVelocity, @Nullable Runnable onEndRunnable) {
-        hideFeedback(true);
         cancelRunningAnimation();
         mFakePreviousTaskView.setVisibility(View.INVISIBLE);
         mFakeHotseatView.setVisibility(View.VISIBLE);
@@ -217,9 +217,6 @@
         if (mGestureCompleted) {
             return;
         }
-        if (displacement != null) {
-            hideFeedback(true);
-        }
         if (mTutorialType == HOME_NAVIGATION_COMPLETE
                 || mTutorialType == OVERVIEW_NAVIGATION_COMPLETE) {
             mFakeTaskView.setVisibility(View.INVISIBLE);
@@ -263,14 +260,16 @@
 
         void initDp(DeviceProfile dp) {
             initTransitionEndpoints(dp);
-            mTaskViewSimulator.setPreviewBounds(
+            mRemoteTargetHandles[0].mTaskViewSimulator.setPreviewBounds(
                     new Rect(0, 0, dp.widthPx, dp.heightPx), dp.getInsets());
         }
 
         @Override
         public void updateFinalShift() {
-            mWindowTransitionController.setProgress(mCurrentShift.value, mDragLengthFactor);
-            mTaskViewSimulator.apply(mTransformParams);
+            mRemoteTargetHandles[0].mPlaybackController
+                    .setProgress(mCurrentShift.value, mDragLengthFactor);
+            mRemoteTargetHandles[0].mTaskViewSimulator.apply(
+                    mRemoteTargetHandles[0].mTransformParams);
         }
 
         AnimatedFloat getCurrentShift() {
@@ -326,12 +325,51 @@
                     mFakeIconView.setVisibility(View.INVISIBLE);
                 }
             };
-            RectFSpringAnim windowAnim = createWindowAnimationToHome(startShift, homeAnimFactory);
+            RectFSpringAnim windowAnim = createWindowAnimationToHome(startShift,
+                    homeAnimFactory)[0];
             windowAnim.start(mContext, velocityPxPerMs);
             return windowAnim;
         }
     }
 
+    protected Animator createFingerDotHomeSwipeAnimator(float fingerDotStartTranslationY) {
+        Animator homeSwipeAnimator = createFingerDotSwipeUpAnimator(fingerDotStartTranslationY)
+                .setDuration(HOME_SWIPE_ANIMATION_DURATION_MILLIS);
+
+        homeSwipeAnimator.addListener(new AnimatorListenerAdapter() {
+            @Override
+            public void onAnimationEnd(Animator animation) {
+                super.onAnimationEnd(animation);
+                animateFakeTaskViewHome(
+                        new PointF(
+                                0f,
+                                fingerDotStartTranslationY / HOME_SWIPE_ANIMATION_DURATION_MILLIS),
+                        null);
+            }
+        });
+
+        return homeSwipeAnimator;
+    }
+
+    protected Animator createFingerDotOverviewSwipeAnimator(float fingerDotStartTranslationY) {
+        return createFingerDotSwipeUpAnimator(fingerDotStartTranslationY)
+                .setDuration(OVERVIEW_SWIPE_ANIMATION_DURATION_MILLIS);
+    }
+
+
+    private Animator createFingerDotSwipeUpAnimator(float fingerDotStartTranslationY) {
+        ValueAnimator swipeAnimator = ValueAnimator.ofFloat(0f, 1f);
+
+        swipeAnimator.addUpdateListener(valueAnimator -> {
+            float gestureProgress =
+                    -fingerDotStartTranslationY * valueAnimator.getAnimatedFraction();
+            setNavBarGestureProgress(gestureProgress);
+            mFingerDotView.setTranslationY(fingerDotStartTranslationY + gestureProgress);
+        });
+
+        return swipeAnimator;
+    }
+
     private class FakeTransformParams extends TransformParams {
 
         @Override
diff --git a/quickstep/src/com/android/quickstep/interaction/TutorialController.java b/quickstep/src/com/android/quickstep/interaction/TutorialController.java
index 4b4e7e6..77bfc31 100644
--- a/quickstep/src/com/android/quickstep/interaction/TutorialController.java
+++ b/quickstep/src/com/android/quickstep/interaction/TutorialController.java
@@ -16,25 +16,32 @@
 package com.android.quickstep.interaction;
 
 import static android.view.View.GONE;
+import static android.view.View.NO_ID;
+import static android.view.View.inflate;
 
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
+import android.animation.ValueAnimator;
 import android.content.Context;
 import android.content.pm.PackageManager;
-import android.graphics.drawable.Animatable2;
 import android.graphics.drawable.AnimatedVectorDrawable;
 import android.graphics.drawable.ColorDrawable;
-import android.graphics.drawable.Drawable;
 import android.graphics.drawable.RippleDrawable;
 import android.util.Log;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.accessibility.AccessibilityEvent;
 import android.widget.Button;
+import android.widget.FrameLayout;
 import android.widget.ImageView;
 import android.widget.RelativeLayout;
 import android.widget.TextView;
 
 import androidx.annotation.CallSuper;
 import androidx.annotation.DrawableRes;
+import androidx.annotation.LayoutRes;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.annotation.StringRes;
@@ -48,18 +55,25 @@
 import com.android.quickstep.interaction.EdgeBackGestureHandler.BackGestureAttemptCallback;
 import com.android.quickstep.interaction.NavBarGestureHandler.NavBarGestureAttemptCallback;
 
+import java.util.ArrayList;
+
 abstract class TutorialController implements BackGestureAttemptCallback,
         NavBarGestureAttemptCallback {
 
     private static final String TAG = "TutorialController";
 
+    private static final float FINGER_DOT_VISIBLE_ALPHA = 0.6f;
+    private static final float FINGER_DOT_SMALL_SCALE = 0.7f;
+    private static final int FINGER_DOT_ANIMATION_DURATION_MILLIS = 500;
+
     private static final String PIXEL_TIPS_APP_PACKAGE_NAME = "com.google.android.apps.tips";
     private static final CharSequence DEFAULT_PIXEL_TIPS_APP_NAME = "Pixel Tips";
 
-    private static final int FEEDBACK_ANIMATION_MS = 250;
+    private static final int FEEDBACK_ANIMATION_MS = 133;
     private static final int RIPPLE_VISIBLE_MS = 300;
     private static final int GESTURE_ANIMATION_DELAY_MS = 1500;
     private static final int ADVANCE_TUTORIAL_TIMEOUT_MS = 4000;
+    private static final long GESTURE_ANIMATION_PAUSE_DURATION_MILLIS = 1000;
 
     final TutorialFragment mTutorialFragment;
     TutorialType mTutorialType;
@@ -68,17 +82,17 @@
     final TextView mCloseButton;
     final ViewGroup mFeedbackView;
     final TextView mFeedbackTitleView;
-    final ImageView mFeedbackVideoView;
-    final ImageView mGestureVideoView;
+    final ImageView mEdgeGestureVideoView;
     final RelativeLayout mFakeLauncherView;
     final ImageView mFakeHotseatView;
     final ClipIconView mFakeIconView;
-    final View mFakeTaskView;
+    final FrameLayout mFakeTaskView;
     final View mFakePreviousTaskView;
     final View mRippleView;
     final RippleDrawable mRippleDrawable;
     final Button mActionButton;
     final TutorialStepIndicator mTutorialStepView;
+    final ImageView mFingerDotView;
     private final AlertDialog mSkipTutorialDialog;
 
     protected boolean mGestureCompleted = false;
@@ -87,7 +101,8 @@
     // views before posting new callbacks.
     private final Runnable mTitleViewCallback;
     @Nullable private Runnable mFeedbackViewCallback;
-    @Nullable private Runnable mFeedbackVideoViewCallback;
+    @Nullable private Runnable mFakeTaskViewCallback;
+    private final Runnable mShowFeedbackRunnable;
 
     TutorialController(TutorialFragment tutorialFragment, TutorialType tutorialType) {
         mTutorialFragment = tutorialFragment;
@@ -100,8 +115,7 @@
         mFeedbackView = rootView.findViewById(R.id.gesture_tutorial_fragment_feedback_view);
         mFeedbackTitleView = mFeedbackView.findViewById(
                 R.id.gesture_tutorial_fragment_feedback_title);
-        mFeedbackVideoView = rootView.findViewById(R.id.gesture_tutorial_feedback_video);
-        mGestureVideoView = rootView.findViewById(R.id.gesture_tutorial_gesture_video);
+        mEdgeGestureVideoView = rootView.findViewById(R.id.gesture_tutorial_edge_gesture_video);
         mFakeLauncherView = rootView.findViewById(R.id.gesture_tutorial_fake_launcher_view);
         mFakeHotseatView = rootView.findViewById(R.id.gesture_tutorial_fake_hotseat_view);
         mFakeIconView = rootView.findViewById(R.id.gesture_tutorial_fake_icon_view);
@@ -113,10 +127,34 @@
         mActionButton = rootView.findViewById(R.id.gesture_tutorial_fragment_action_button);
         mTutorialStepView =
                 rootView.findViewById(R.id.gesture_tutorial_fragment_feedback_tutorial_step);
+        mFingerDotView = rootView.findViewById(R.id.gesture_tutorial_finger_dot);
         mSkipTutorialDialog = createSkipTutorialDialog();
 
         mTitleViewCallback = () -> mFeedbackTitleView.sendAccessibilityEvent(
                 AccessibilityEvent.TYPE_VIEW_FOCUSED);
+        mShowFeedbackRunnable = () -> {
+            mFeedbackView.setAlpha(0f);
+            mFeedbackView.setScaleX(0.95f);
+            mFeedbackView.setScaleY(0.95f);
+            mFeedbackView.setVisibility(View.VISIBLE);
+            mFeedbackView.animate()
+                    .setDuration(FEEDBACK_ANIMATION_MS)
+                    .alpha(1f)
+                    .scaleX(1f)
+                    .scaleY(1f)
+                    .withEndAction(() -> {
+                        if (mGestureCompleted && !mTutorialFragment.isAtFinalStep()) {
+                            if (mFeedbackViewCallback != null) {
+                                mFeedbackView.removeCallbacks(mFeedbackViewCallback);
+                            }
+                            mFeedbackViewCallback = mTutorialFragment::continueTutorial;
+                            mFeedbackView.postDelayed(mFeedbackViewCallback,
+                                    ADVANCE_TUTORIAL_TIMEOUT_MS);
+                        }
+                    })
+                    .start();
+            mFeedbackTitleView.postDelayed(mTitleViewCallback, FEEDBACK_ANIMATION_MS);
+        };
     }
 
     private void showSkipTutorialDialog() {
@@ -134,9 +172,9 @@
         return R.drawable.default_sandbox_mock_launcher;
     }
 
-    @DrawableRes
-    protected int getMockAppTaskThumbnailResId(boolean forDarkMode) {
-        return R.drawable.default_sandbox_app_task_thumbnail;
+    @LayoutRes
+    protected int getMockAppTaskLayoutResId() {
+        return View.NO_ID;
     }
 
     @DrawableRes
@@ -173,17 +211,10 @@
             mFeedbackView.setTranslationY(0);
             return;
         }
-        AnimatedVectorDrawable tutorialAnimation = mTutorialFragment.getTutorialAnimation();
-        AnimatedVectorDrawable gestureAnimation = mTutorialFragment.getGestureAnimation();
-
-        if (tutorialAnimation != null && gestureAnimation != null) {
-            TextView title = mFeedbackView.findViewById(
-                    R.id.gesture_tutorial_fragment_feedback_title);
-
-            playFeedbackVideo(tutorialAnimation, gestureAnimation, () -> {
-                mFeedbackView.setTranslationY(0);
-                title.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED);
-            }, true);
+        Animator gestureAnimation = mTutorialFragment.getGestureAnimation();
+        AnimatedVectorDrawable edgeAnimation = mTutorialFragment.getEdgeAnimation();
+        if (gestureAnimation != null && edgeAnimation != null) {
+            playFeedbackAnimation(gestureAnimation, edgeAnimation, mShowFeedbackRunnable, true);
         }
     }
 
@@ -215,8 +246,13 @@
             int subtitleResId,
             boolean isGestureSuccessful,
             boolean useGestureAnimationDelay) {
-        mFeedbackTitleView.setText(titleResId);
         mFeedbackTitleView.removeCallbacks(mTitleViewCallback);
+        if (mFeedbackViewCallback != null) {
+            mFeedbackView.removeCallbacks(mFeedbackViewCallback);
+            mFeedbackViewCallback = null;
+        }
+
+        mFeedbackTitleView.setText(titleResId);
         TextView subtitle =
                 mFeedbackView.findViewById(R.id.gesture_tutorial_fragment_feedback_subtitle);
         subtitle.setText(subtitleResId);
@@ -226,77 +262,68 @@
                 showActionButton();
             }
 
-            if (mFeedbackVideoViewCallback != null) {
-                mFeedbackVideoView.removeCallbacks(mFeedbackVideoViewCallback);
-                mFeedbackVideoViewCallback = null;
+            if (mFakeTaskViewCallback != null) {
+                mFakeTaskView.removeCallbacks(mFakeTaskViewCallback);
+                mFakeTaskViewCallback = null;
             }
         }
         mGestureCompleted = isGestureSuccessful;
 
-        AnimatedVectorDrawable tutorialAnimation = mTutorialFragment.getTutorialAnimation();
-        AnimatedVectorDrawable gestureAnimation = mTutorialFragment.getGestureAnimation();
-        if (tutorialAnimation != null && gestureAnimation != null) {
-            if (!isGestureSuccessful) {
-                playFeedbackVideo(tutorialAnimation, gestureAnimation, () -> {
-                    mFeedbackView.setTranslationY(
-                            -mFeedbackView.getHeight() - mFeedbackView.getTop());
-                    mFeedbackView.setVisibility(View.VISIBLE);
-                    mFeedbackView.animate()
-                            .setDuration(FEEDBACK_ANIMATION_MS)
-                            .translationY(0)
-                            .start();
-                    mFeedbackTitleView.postDelayed(mTitleViewCallback, FEEDBACK_ANIMATION_MS);
-                }, useGestureAnimationDelay);
-                return;
-            } else {
-                mTutorialFragment.releaseFeedbackVideoView();
-            }
+        Animator gestureAnimation = mTutorialFragment.getGestureAnimation();
+        AnimatedVectorDrawable edgeAnimation = mTutorialFragment.getEdgeAnimation();
+        if (!isGestureSuccessful && gestureAnimation != null && edgeAnimation != null) {
+            playFeedbackAnimation(
+                    gestureAnimation,
+                    edgeAnimation,
+                    mShowFeedbackRunnable,
+                    useGestureAnimationDelay);
+            return;
+        } else {
+            mTutorialFragment.releaseFeedbackAnimation();
         }
-        mFeedbackView.setTranslationY(-mFeedbackView.getHeight() - mFeedbackView.getTop());
-        mFeedbackView.setVisibility(View.VISIBLE);
-        mFeedbackView.animate()
-                .setDuration(FEEDBACK_ANIMATION_MS)
-                .translationY(0)
-                .withEndAction(() -> {
-                    if (isGestureSuccessful && !mTutorialFragment.isAtFinalStep()) {
-                        if (mFeedbackViewCallback != null) {
-                            mFeedbackView.removeCallbacks(mFeedbackViewCallback);
-                        }
-                        mFeedbackViewCallback = mTutorialFragment::continueTutorial;
-                        mFeedbackView.postDelayed(mFeedbackViewCallback,
-                                ADVANCE_TUTORIAL_TIMEOUT_MS);
-                    }
-                })
-                .start();
-        mFeedbackTitleView.postDelayed(mTitleViewCallback, FEEDBACK_ANIMATION_MS);
+        mFeedbackViewCallback = mShowFeedbackRunnable;
+
+        mFeedbackView.post(mFeedbackViewCallback);
     }
 
-    void hideFeedback(boolean releaseFeedbackVideo) {
+    void hideFeedback() {
+        cancelQueuedGestureAnimation();
         mFeedbackView.clearAnimation();
         mFeedbackView.setVisibility(View.INVISIBLE);
-        if (releaseFeedbackVideo) {
-            mTutorialFragment.releaseFeedbackVideoView();
-        }
     }
 
-    private void playFeedbackVideo(
-            @NonNull AnimatedVectorDrawable tutorialAnimation,
-            @NonNull AnimatedVectorDrawable gestureAnimation,
+    void cancelQueuedGestureAnimation() {
+        if (mFeedbackViewCallback != null) {
+            mFeedbackView.removeCallbacks(mFeedbackViewCallback);
+            mFeedbackViewCallback = null;
+        }
+        if (mFakeTaskViewCallback != null) {
+            mFakeTaskView.removeCallbacks(mFakeTaskViewCallback);
+            mFakeTaskViewCallback = null;
+        }
+        mFeedbackTitleView.removeCallbacks(mTitleViewCallback);
+    }
+
+    private void playFeedbackAnimation(
+            @NonNull Animator gestureAnimation,
+            @NonNull AnimatedVectorDrawable edgeAnimation,
             @NonNull Runnable onStartRunnable,
             boolean useGestureAnimationDelay) {
 
-        if (tutorialAnimation.isRunning()) {
-            tutorialAnimation.reset();
+        if (gestureAnimation.isRunning()) {
+            gestureAnimation.cancel();
         }
-        tutorialAnimation.registerAnimationCallback(new Animatable2.AnimationCallback() {
-
+        if (edgeAnimation.isRunning()) {
+            edgeAnimation.reset();
+        }
+        gestureAnimation.addListener(new AnimatorListenerAdapter() {
             @Override
-            public void onAnimationStart(Drawable drawable) {
-                super.onAnimationStart(drawable);
+            public void onAnimationStart(Animator animation) {
+                super.onAnimationStart(animation);
 
-                mGestureVideoView.setVisibility(GONE);
-                if (gestureAnimation.isRunning()) {
-                    gestureAnimation.stop();
+                mEdgeGestureVideoView.setVisibility(GONE);
+                if (edgeAnimation.isRunning()) {
+                    edgeAnimation.stop();
                 }
 
                 if (!useGestureAnimationDelay) {
@@ -305,37 +332,25 @@
             }
 
             @Override
-            public void onAnimationEnd(Drawable drawable) {
-                super.onAnimationEnd(drawable);
+            public void onAnimationEnd(Animator animation) {
+                super.onAnimationEnd(animation);
 
-                mGestureVideoView.setVisibility(View.VISIBLE);
-                gestureAnimation.start();
+                mEdgeGestureVideoView.setVisibility(View.VISIBLE);
+                edgeAnimation.start();
 
-                tutorialAnimation.unregisterAnimationCallback(this);
+                gestureAnimation.removeListener(this);
             }
         });
 
-        if (mFeedbackViewCallback != null) {
-            mFeedbackVideoView.removeCallbacks(mFeedbackViewCallback);
-            mFeedbackViewCallback = null;
-        }
-        if (mFeedbackVideoViewCallback != null) {
-            mFeedbackVideoView.removeCallbacks(mFeedbackVideoViewCallback);
-            mFeedbackVideoViewCallback = null;
-        }
+        cancelQueuedGestureAnimation();
         if (useGestureAnimationDelay) {
             mFeedbackViewCallback = onStartRunnable;
-            mFeedbackVideoViewCallback = () -> {
-                mFeedbackVideoView.setVisibility(View.VISIBLE);
-                tutorialAnimation.start();
-            };
+            mFakeTaskViewCallback = gestureAnimation::start;
 
-            mFeedbackVideoView.setVisibility(View.GONE);
             mFeedbackView.post(mFeedbackViewCallback);
-            mFeedbackVideoView.postDelayed(mFeedbackVideoViewCallback, GESTURE_ANIMATION_DELAY_MS);
+            mFakeTaskView.postDelayed(mFakeTaskViewCallback, GESTURE_ANIMATION_DELAY_MS);
         } else {
-            mFeedbackVideoView.setVisibility(View.VISIBLE);
-            tutorialAnimation.start();
+            gestureAnimation.start();
         }
     }
 
@@ -360,7 +375,7 @@
 
     @CallSuper
     void transitToController() {
-        hideFeedback(false);
+        hideFeedback();
         hideActionButton();
         updateSubtext();
         updateDrawables();
@@ -395,6 +410,17 @@
         mActionButton.setOnClickListener(this::onActionButtonClicked);
     }
 
+    void updateFakeAppTaskViewLayout(@LayoutRes int mockAppTaskLayoutResId) {
+        mFakeTaskView.removeAllViews();
+        if (mockAppTaskLayoutResId != NO_ID) {
+            mFakeTaskView.addView(
+                    inflate(mContext, mockAppTaskLayoutResId, null),
+                    new FrameLayout.LayoutParams(
+                            ViewGroup.LayoutParams.MATCH_PARENT,
+                            ViewGroup.LayoutParams.MATCH_PARENT));
+        }
+    }
+
     private void updateSubtext() {
         mTutorialStepView.setTutorialProgress(
                 mTutorialFragment.getCurrentStep(), mTutorialFragment.getNumSteps());
@@ -404,15 +430,12 @@
         if (mContext != null) {
             mTutorialFragment.getRootView().setBackground(AppCompatResources.getDrawable(
                     mContext, getMockWallpaperResId()));
-            mTutorialFragment.updateFeedbackVideo();
+            mTutorialFragment.updateFeedbackAnimation();
             mFakeLauncherView.setBackgroundColor(
-                    mContext.getColor(Utilities.isDarkTheme(mContext)
-                            ? R.color.fake_wallpaper_color_dark_mode
-                            : R.color.fake_wallpaper_color_light_mode));
+                    mContext.getColor(R.color.gesture_tutorial_fake_wallpaper_color));
             mFakeHotseatView.setImageDrawable(AppCompatResources.getDrawable(
                     mContext, getMockHotseatResId()));
-            mFakeTaskView.setBackground(AppCompatResources.getDrawable(
-                    mContext, getMockAppTaskThumbnailResId(Utilities.isDarkTheme(mContext))));
+            updateFakeAppTaskViewLayout(getMockAppTaskLayoutResId());
             mFakeTaskView.animate().alpha(1).setListener(
                     AnimatorListeners.forSuccessCallback(() -> mFakeTaskView.animate().cancel()));
             mFakePreviousTaskView.setBackground(AppCompatResources.getDrawable(
@@ -485,6 +508,52 @@
         return null;
     }
 
+    protected AnimatorSet createFingerDotAppearanceAnimatorSet() {
+        ObjectAnimator alphaAnimator = ObjectAnimator.ofFloat(
+                mFingerDotView, View.ALPHA, 0f, FINGER_DOT_VISIBLE_ALPHA);
+        ObjectAnimator yScaleAnimator = ObjectAnimator.ofFloat(
+                mFingerDotView, View.SCALE_Y, FINGER_DOT_SMALL_SCALE, 1f);
+        ObjectAnimator xScaleAnimator = ObjectAnimator.ofFloat(
+                mFingerDotView, View.SCALE_X, FINGER_DOT_SMALL_SCALE, 1f);
+        ArrayList<Animator> animators = new ArrayList<>();
+
+        animators.add(alphaAnimator);
+        animators.add(xScaleAnimator);
+        animators.add(yScaleAnimator);
+
+        AnimatorSet appearanceAnimatorSet = new AnimatorSet();
+
+        appearanceAnimatorSet.playTogether(animators);
+        appearanceAnimatorSet.setDuration(FINGER_DOT_ANIMATION_DURATION_MILLIS);
+
+        return appearanceAnimatorSet;
+    }
+
+    protected AnimatorSet createFingerDotDisappearanceAnimatorSet() {
+        ObjectAnimator alphaAnimator = ObjectAnimator.ofFloat(
+                mFingerDotView, View.ALPHA, FINGER_DOT_VISIBLE_ALPHA, 0f);
+        ObjectAnimator yScaleAnimator = ObjectAnimator.ofFloat(
+                mFingerDotView, View.SCALE_Y, 1f, FINGER_DOT_SMALL_SCALE);
+        ObjectAnimator xScaleAnimator = ObjectAnimator.ofFloat(
+                mFingerDotView, View.SCALE_X, 1f, FINGER_DOT_SMALL_SCALE);
+        ArrayList<Animator> animators = new ArrayList<>();
+
+        animators.add(alphaAnimator);
+        animators.add(xScaleAnimator);
+        animators.add(yScaleAnimator);
+
+        AnimatorSet appearanceAnimatorSet = new AnimatorSet();
+
+        appearanceAnimatorSet.playTogether(animators);
+        appearanceAnimatorSet.setDuration(FINGER_DOT_ANIMATION_DURATION_MILLIS);
+
+        return appearanceAnimatorSet;
+    }
+
+    protected Animator createAnimationPause() {
+        return ValueAnimator.ofFloat(0f, 1f).setDuration(GESTURE_ANIMATION_PAUSE_DURATION_MILLIS);
+    }
+
     /** Denotes the type of the tutorial. */
     enum TutorialType {
         BACK_NAVIGATION,
diff --git a/quickstep/src/com/android/quickstep/interaction/TutorialFragment.java b/quickstep/src/com/android/quickstep/interaction/TutorialFragment.java
index 7637450..52ec9b3 100644
--- a/quickstep/src/com/android/quickstep/interaction/TutorialFragment.java
+++ b/quickstep/src/com/android/quickstep/interaction/TutorialFragment.java
@@ -15,6 +15,8 @@
  */
 package com.android.quickstep.interaction;
 
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
 import android.app.Activity;
 import android.content.Context;
 import android.content.Intent;
@@ -29,6 +31,7 @@
 import android.view.View;
 import android.view.View.OnTouchListener;
 import android.view.ViewGroup;
+import android.view.ViewTreeObserver;
 import android.view.WindowInsets;
 import android.widget.ImageView;
 
@@ -38,7 +41,6 @@
 import androidx.fragment.app.FragmentActivity;
 
 import com.android.launcher3.R;
-import com.android.launcher3.Utilities;
 import com.android.quickstep.interaction.TutorialController.TutorialType;
 
 abstract class TutorialFragment extends Fragment implements OnTouchListener {
@@ -49,13 +51,14 @@
     TutorialType mTutorialType;
     @Nullable TutorialController mTutorialController = null;
     RootSandboxLayout mRootView;
+    View mFingerDotView;
+    View mFakePreviousTaskView;
     EdgeBackGestureHandler mEdgeBackGestureHandler;
     NavBarGestureHandler mNavBarGestureHandler;
-    private ImageView mFeedbackVideoView;
-    private ImageView mGestureVideoView;
+    private ImageView mEdgeGestureVideoView;
 
-    @Nullable private AnimatedVectorDrawable mTutorialAnimation = null;
-    @Nullable private AnimatedVectorDrawable mGestureAnimation = null;
+    @Nullable private Animator mGestureAnimation = null;
+    @Nullable private AnimatedVectorDrawable mEdgeAnimation = null;
     private boolean mIntroductionShown = false;
 
     private boolean mFragmentStopped = false;
@@ -96,24 +99,26 @@
         return null;
     }
 
-    @Nullable Integer getFeedbackVideoResId(boolean forDarkMode) {
-        return null;
-    }
-
-    @Nullable Integer getGestureVideoResId() {
+    @Nullable Integer getEdgeAnimationResId() {
         return null;
     }
 
     @Nullable
-    AnimatedVectorDrawable getTutorialAnimation() {
-        return mTutorialAnimation;
-    }
-
-    @Nullable
-    AnimatedVectorDrawable getGestureAnimation() {
+    Animator getGestureAnimation() {
         return mGestureAnimation;
     }
 
+    @Nullable
+    AnimatedVectorDrawable getEdgeAnimation() {
+        return mEdgeAnimation;
+    }
+
+
+    @Nullable
+    protected Animator createGestureAnimation() {
+        return null;
+    }
+
     abstract TutorialController createController(TutorialType type);
 
     abstract Class<? extends TutorialController> getControllerClass();
@@ -147,21 +152,22 @@
             return insets;
         });
         mRootView.setOnTouchListener(this);
-        mFeedbackVideoView = mRootView.findViewById(R.id.gesture_tutorial_feedback_video);
-        mGestureVideoView = mRootView.findViewById(R.id.gesture_tutorial_gesture_video);
+        mEdgeGestureVideoView = mRootView.findViewById(R.id.gesture_tutorial_edge_gesture_video);
+        mFingerDotView = mRootView.findViewById(R.id.gesture_tutorial_finger_dot);
+        mFakePreviousTaskView = mRootView.findViewById(
+                R.id.gesture_tutorial_fake_previous_task_view);
         return mRootView;
     }
 
     @Override
     public void onStop() {
         super.onStop();
-        releaseFeedbackVideoView();
-        releaseGestureVideoView();
+        releaseFeedbackAnimation();
         mFragmentStopped = true;
     }
 
     void initializeFeedbackVideoView() {
-        if (!updateFeedbackVideo()) {
+        if (!updateFeedbackAnimation()) {
             return;
         }
 
@@ -176,87 +182,90 @@
         }
     }
 
-    boolean updateFeedbackVideo() {
-        if (getContext() == null) {
+    boolean updateFeedbackAnimation() {
+        if (!updateEdgeAnimation()) {
             return false;
         }
-        Integer feedbackVideoResId = getFeedbackVideoResId(Utilities.isDarkTheme(getContext()));
-
-        if (feedbackVideoResId == null || !updateGestureVideo()) {
-            return false;
-        }
-        mTutorialAnimation = (AnimatedVectorDrawable) getContext().getDrawable(feedbackVideoResId);
-
-        if (mTutorialAnimation != null) {
-            mTutorialAnimation.registerAnimationCallback(new Animatable2.AnimationCallback() {
-
-                @Override
-                public void onAnimationStart(Drawable drawable) {
-                    super.onAnimationStart(drawable);
-
-                    mFeedbackVideoView.setVisibility(View.VISIBLE);
-                }
-
-                @Override
-                public void onAnimationEnd(Drawable drawable) {
-                    super.onAnimationEnd(drawable);
-
-                    releaseFeedbackVideoView();
-                }
-            });
-        }
-        mFeedbackVideoView.setImageDrawable(mTutorialAnimation);
-
-        return true;
-    }
-
-    boolean updateGestureVideo() {
-        Integer gestureVideoResId = getGestureVideoResId();
-        if (gestureVideoResId == null || getContext() == null) {
-            return false;
-        }
-        mGestureAnimation = (AnimatedVectorDrawable) getContext().getDrawable(gestureVideoResId);
+        mGestureAnimation = createGestureAnimation();
 
         if (mGestureAnimation != null) {
-            mGestureAnimation.registerAnimationCallback(new Animatable2.AnimationCallback() {
+            mGestureAnimation.addListener(new AnimatorListenerAdapter() {
+                @Override
+                public void onAnimationStart(Animator animation) {
+                    super.onAnimationStart(animation);
+                    mFingerDotView.setVisibility(View.VISIBLE);
+                }
+
+                @Override
+                public void onAnimationCancel(Animator animation) {
+                    super.onAnimationCancel(animation);
+                    mFingerDotView.setVisibility(View.GONE);
+                }
+
+                @Override
+                public void onAnimationEnd(Animator animation) {
+                    super.onAnimationEnd(animation);
+                    mFingerDotView.setVisibility(View.GONE);
+                }
+            });
+        }
+
+        return mGestureAnimation != null;
+    }
+
+    boolean updateEdgeAnimation() {
+        Integer edgeAnimationResId = getEdgeAnimationResId();
+        if (edgeAnimationResId == null || getContext() == null) {
+            return false;
+        }
+        mEdgeAnimation = (AnimatedVectorDrawable) getContext().getDrawable(edgeAnimationResId);
+
+        if (mEdgeAnimation != null) {
+            mEdgeAnimation.registerAnimationCallback(new Animatable2.AnimationCallback() {
 
                 @Override
                 public void onAnimationEnd(Drawable drawable) {
                     super.onAnimationEnd(drawable);
 
-                    mGestureAnimation.start();
+                    mEdgeAnimation.start();
                 }
             });
         }
-        mGestureVideoView.setImageDrawable(mGestureAnimation);
+        mEdgeGestureVideoView.setImageDrawable(mEdgeAnimation);
 
-        return true;
+        return mEdgeAnimation != null;
     }
 
-    void releaseFeedbackVideoView() {
-        if (mTutorialAnimation != null && mTutorialAnimation.isRunning()) {
-            mTutorialAnimation.stop();
+    void releaseFeedbackAnimation() {
+        if (mTutorialController != null) {
+            mTutorialController.cancelQueuedGestureAnimation();
         }
-
-        mFeedbackVideoView.setVisibility(View.GONE);
-    }
-
-    void releaseGestureVideoView() {
         if (mGestureAnimation != null && mGestureAnimation.isRunning()) {
-            mGestureAnimation.stop();
+            mGestureAnimation.cancel();
+        }
+        if (mEdgeAnimation != null && mEdgeAnimation.isRunning()) {
+            mEdgeAnimation.stop();
         }
 
-        mGestureVideoView.setVisibility(View.GONE);
+        mEdgeGestureVideoView.setVisibility(View.GONE);
     }
 
     @Override
     public void onResume() {
         super.onResume();
+        releaseFeedbackAnimation();
         if (mFragmentStopped && mTutorialController != null) {
             mTutorialController.showFeedback();
             mFragmentStopped = false;
         } else {
-            changeController(mTutorialType);
+            mRootView.getViewTreeObserver().addOnGlobalLayoutListener(
+                    new ViewTreeObserver.OnGlobalLayoutListener() {
+                        @Override
+                        public void onGlobalLayout() {
+                            changeController(mTutorialType);
+                            mRootView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
+                        }
+                    });
         }
     }
 
@@ -292,6 +301,7 @@
         mEdgeBackGestureHandler.registerBackGestureAttemptCallback(mTutorialController);
         mNavBarGestureHandler.registerNavBarGestureAttemptCallback(mTutorialController);
         mTutorialType = tutorialType;
+
         initializeFeedbackVideoView();
     }
 
diff --git a/quickstep/src/com/android/quickstep/util/AnimatorControllerWithResistance.java b/quickstep/src/com/android/quickstep/util/AnimatorControllerWithResistance.java
index f1b4e3d..7c83833 100644
--- a/quickstep/src/com/android/quickstep/util/AnimatorControllerWithResistance.java
+++ b/quickstep/src/com/android/quickstep/util/AnimatorControllerWithResistance.java
@@ -48,15 +48,16 @@
 public class AnimatorControllerWithResistance {
 
     private enum RecentsResistanceParams {
-        FROM_APP(0.75f, 0.5f, 1f),
-        FROM_APP_TABLET(0.9f, 0.75f, 1f),
-        FROM_OVERVIEW(1f, 0.75f, 0.5f);
+        FROM_APP(0.75f, 0.5f, 1f, false),
+        FROM_APP_TABLET(1f, 0.7f, 1f, true),
+        FROM_OVERVIEW(1f, 0.75f, 0.5f, false);
 
         RecentsResistanceParams(float scaleStartResist, float scaleMaxResist,
-                float translationFactor) {
+                float translationFactor, boolean stopScalingAtTop) {
             this.scaleStartResist = scaleStartResist;
             this.scaleMaxResist = scaleMaxResist;
             this.translationFactor = translationFactor;
+            this.stopScalingAtTop = stopScalingAtTop;
         }
 
         /**
@@ -74,6 +75,12 @@
          * where 0 will keep it centered and 1 will have it barely touch the top of the screen.
          */
         public final float translationFactor;
+
+        /**
+         * Whether to end scaling effect when the scaled down version of TaskView's top reaches the
+         * non-scaled version of TaskView's top.
+         */
+        public final boolean stopScalingAtTop;
     }
 
     private static final TimeInterpolator RECENTS_SCALE_RESIST_INTERPOLATOR = DEACCEL;
@@ -151,8 +158,7 @@
         Rect startRect = new Rect();
         PagedOrientationHandler orientationHandler = params.recentsOrientedState
                 .getOrientationHandler();
-        LauncherActivityInterface.INSTANCE.calculateTaskSize(params.context, params.dp, startRect,
-                orientationHandler);
+        LauncherActivityInterface.INSTANCE.calculateTaskSize(params.context, params.dp, startRect);
         long distanceToCover = startRect.bottom;
         PendingAnimation resistAnim = params.resistAnim != null
                 ? params.resistAnim
@@ -161,26 +167,6 @@
         PointF pivot = new PointF();
         float fullscreenScale = params.recentsOrientedState.getFullScreenScaleAndPivot(
                 startRect, params.dp, pivot);
-        float prevScaleRate = (fullscreenScale - params.startScale)
-                / (params.dp.heightPx - startRect.bottom);
-        // This is what the scale would be at the end of the drag if we didn't apply resistance.
-        float endScale = params.startScale - prevScaleRate * distanceToCover;
-        // Create an interpolator that resists the scale so the scale doesn't get smaller than
-        // RECENTS_SCALE_MAX_RESIST.
-        float startResist = Utilities.getProgress(params.resistanceParams.scaleStartResist,
-                params.startScale, endScale);
-        float maxResist = Utilities.getProgress(params.resistanceParams.scaleMaxResist,
-                params.startScale, endScale);
-        final TimeInterpolator scaleInterpolator = t -> {
-            if (t < startResist) {
-                return t;
-            }
-            float resistProgress = Utilities.getProgress(t, startResist, 1);
-            resistProgress = RECENTS_SCALE_RESIST_INTERPOLATOR.getInterpolation(resistProgress);
-            return startResist + resistProgress * (maxResist - startResist);
-        };
-        resistAnim.addFloat(params.scaleTarget, params.scaleProperty, params.startScale, endScale,
-                scaleInterpolator);
 
         // Compute where the task view would be based on the end scale.
         RectF endRectF = new RectF(startRect);
@@ -195,6 +181,32 @@
         resistAnim.addFloat(params.translationTarget, params.translationProperty,
                 params.startTranslation, endTranslation, RECENTS_TRANSLATE_RESIST_INTERPOLATOR);
 
+        float prevScaleRate = (fullscreenScale - params.startScale)
+                / (params.dp.heightPx - startRect.bottom);
+        // This is what the scale would be at the end of the drag if we didn't apply resistance.
+        float endScale = params.startScale - prevScaleRate * distanceToCover;
+        // Create an interpolator that resists the scale so the scale doesn't get smaller than
+        // RECENTS_SCALE_MAX_RESIST.
+        float startResist = Utilities.getProgress(params.resistanceParams.scaleStartResist,
+                params.startScale, endScale);
+        float maxResist = Utilities.getProgress(params.resistanceParams.scaleMaxResist,
+                params.startScale, endScale);
+        float stopResist =
+                params.resistanceParams.stopScalingAtTop ? 1f - startRect.top / endRectF.top : 1f;
+        final TimeInterpolator scaleInterpolator = t -> {
+            if (t < startResist) {
+                return t;
+            }
+            if (t > stopResist) {
+                return maxResist;
+            }
+            float resistProgress = Utilities.getProgress(t, startResist, stopResist);
+            resistProgress = RECENTS_SCALE_RESIST_INTERPOLATOR.getInterpolation(resistProgress);
+            return startResist + resistProgress * (maxResist - startResist);
+        };
+        resistAnim.addFloat(params.scaleTarget, params.scaleProperty, params.startScale, endScale,
+                scaleInterpolator);
+
         return resistAnim;
     }
 
diff --git a/quickstep/src/com/android/quickstep/util/LauncherSplitScreenListener.java b/quickstep/src/com/android/quickstep/util/LauncherSplitScreenListener.java
new file mode 100644
index 0000000..da665d4
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/util/LauncherSplitScreenListener.java
@@ -0,0 +1,104 @@
+package com.android.quickstep.util;
+
+import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT;
+
+import android.content.Context;
+import android.os.IBinder;
+
+import com.android.launcher3.util.MainThreadInitializedObject;
+import com.android.launcher3.util.SplitConfigurationOptions;
+import com.android.launcher3.util.SplitConfigurationOptions.StagePosition;
+import com.android.launcher3.util.SplitConfigurationOptions.StageType;
+import com.android.launcher3.util.SplitConfigurationOptions.StagedSplitTaskPosition;
+import com.android.quickstep.SystemUiProxy;
+import com.android.wm.shell.splitscreen.ISplitScreenListener;
+
+/**
+ * Listeners for system wide split screen position and stage changes.
+ * Use {@link #getSplitTaskIds()} to determine which tasks, if any, are in staged split.
+ */
+public class LauncherSplitScreenListener extends ISplitScreenListener.Stub {
+
+    public static final MainThreadInitializedObject<LauncherSplitScreenListener> INSTANCE =
+            new MainThreadInitializedObject<>(LauncherSplitScreenListener::new);
+
+    private final StagedSplitTaskPosition mMainStagePosition = new StagedSplitTaskPosition();
+    private final StagedSplitTaskPosition mSideStagePosition = new StagedSplitTaskPosition();
+
+    public LauncherSplitScreenListener(Context context) {
+        mMainStagePosition.stageType = SplitConfigurationOptions.STAGE_TYPE_MAIN;
+        mSideStagePosition.stageType = SplitConfigurationOptions.STAGE_TYPE_SIDE;
+    }
+
+    /** Also call {@link #destroy()} when done. */
+    public void init() {
+        SystemUiProxy.INSTANCE.getNoCreate().registerSplitScreenListener(this);
+    }
+
+    public void destroy() {
+        SystemUiProxy.INSTANCE.getNoCreate().unregisterSplitScreenListener(this);
+    }
+
+    /**
+     * @return index 0 will be task in left/top position, index 1 in right/bottom position.
+     *         Will return empty array if device is not in staged split
+     */
+    public int[] getSplitTaskIds() {
+        if (mMainStagePosition.taskId == -1 || mSideStagePosition.taskId == -1) {
+            return new int[]{};
+        }
+        int[] out = new int[2];
+        if (mMainStagePosition.stagePosition == STAGE_POSITION_TOP_OR_LEFT) {
+            out[0] = mMainStagePosition.taskId;
+            out[1] = mSideStagePosition.taskId;
+        } else {
+            out[1] = mMainStagePosition.taskId;
+            out[0] = mSideStagePosition.taskId;
+        }
+        return out;
+    }
+
+    @Override
+    public void onStagePositionChanged(@StageType int stage, @StagePosition int position) {
+        if (stage == SplitConfigurationOptions.STAGE_TYPE_MAIN) {
+            mMainStagePosition.stagePosition = position;
+        } else {
+            mSideStagePosition.stagePosition = position;
+        }
+    }
+
+    @Override
+    public void onTaskStageChanged(int taskId, @StageType int stage, boolean visible) {
+        // If task is not visible but we are tracking it, stop tracking it
+        if (!visible) {
+            if (mMainStagePosition.taskId == taskId) {
+                resetTaskId(mMainStagePosition);
+            } else if (mSideStagePosition.taskId == taskId) {
+                resetTaskId(mSideStagePosition);
+            } // else it's an un-tracked child
+            return;
+        }
+
+        // If stage has moved to undefined, stop tracking the task
+        if (stage == SplitConfigurationOptions.STAGE_TYPE_UNDEFINED) {
+            resetTaskId(taskId == mMainStagePosition.taskId ?
+                    mMainStagePosition : mSideStagePosition);
+            return;
+        }
+
+        if (stage == SplitConfigurationOptions.STAGE_TYPE_MAIN) {
+            mMainStagePosition.taskId = taskId;
+        } else {
+            mSideStagePosition.taskId = taskId;
+        }
+    }
+
+    private void resetTaskId(StagedSplitTaskPosition taskPosition) {
+        taskPosition.taskId = -1;
+    }
+
+    @Override
+    public IBinder asBinder() {
+        return this;
+    }
+}
diff --git a/quickstep/src/com/android/quickstep/util/LauncherUnfoldAnimationController.java b/quickstep/src/com/android/quickstep/util/LauncherUnfoldAnimationController.java
new file mode 100644
index 0000000..c5ab84d
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/util/LauncherUnfoldAnimationController.java
@@ -0,0 +1,149 @@
+/*
+ * 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.quickstep.util;
+
+import static com.android.launcher3.Utilities.comp;
+
+import android.annotation.Nullable;
+import android.view.ViewTreeObserver;
+import android.view.WindowManager;
+
+import com.android.launcher3.Hotseat;
+import com.android.launcher3.Launcher;
+import com.android.launcher3.util.HorizontalInsettableView;
+import com.android.systemui.unfold.UnfoldTransitionProgressProvider;
+import com.android.systemui.unfold.UnfoldTransitionProgressProvider.TransitionProgressListener;
+
+/**
+ * Controls animations that are happening during unfolding foldable devices
+ */
+public class LauncherUnfoldAnimationController {
+
+    // Percentage of the width of the quick search bar that will be reduced
+    // from the both sides of the bar when progress is 0
+    private static final float MAX_WIDTH_INSET_FRACTION = 0.15f;
+
+    private final Launcher mLauncher;
+    private final UnfoldTransitionProgressProvider mUnfoldTransitionProgressProvider;
+    private final UnfoldMoveFromCenterWorkspaceAnimator mMoveFromCenterWorkspaceAnimation;
+
+    @Nullable
+    private HorizontalInsettableView mQsbInsettable;
+
+    private final AnimationListener mAnimationListener = new AnimationListener();
+
+    private boolean mIsTransitionRunning = false;
+    private boolean mIsReadyToPlayAnimation = false;
+
+    public LauncherUnfoldAnimationController(
+            Launcher launcher,
+            WindowManager windowManager,
+            UnfoldTransitionProgressProvider unfoldTransitionProgressProvider) {
+        mLauncher = launcher;
+        mUnfoldTransitionProgressProvider = unfoldTransitionProgressProvider;
+        mMoveFromCenterWorkspaceAnimation = new UnfoldMoveFromCenterWorkspaceAnimator(launcher,
+                windowManager);
+        mUnfoldTransitionProgressProvider.addCallback(mAnimationListener);
+    }
+
+    /**
+     * Called when launcher is resumed
+     */
+    public void onResume() {
+        Hotseat hotseat = mLauncher.getHotseat();
+        if (hotseat != null && hotseat.getQsb() instanceof HorizontalInsettableView) {
+            mQsbInsettable = (HorizontalInsettableView) hotseat.getQsb();
+        }
+
+        final ViewTreeObserver obs = mLauncher.getWorkspace().getViewTreeObserver();
+        obs.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
+            @Override
+            public boolean onPreDraw() {
+                if (obs.isAlive()) {
+                    onPreDrawAfterResume();
+                    obs.removeOnPreDrawListener(this);
+                }
+                return true;
+            }
+        });
+    }
+
+    /**
+     * Called when launcher activity is paused
+     */
+    public void onPause() {
+        if (mIsTransitionRunning) {
+            mIsTransitionRunning = false;
+            mAnimationListener.onTransitionFinished();
+        }
+
+        mIsReadyToPlayAnimation = false;
+        mQsbInsettable = null;
+    }
+
+    /**
+     * Called when launcher activity is destroyed
+     */
+    public void onDestroy() {
+        mUnfoldTransitionProgressProvider.removeCallback(mAnimationListener);
+    }
+
+    /**
+     * Called after performing layouting of the views after configuration change
+     */
+    private void onPreDrawAfterResume() {
+        mIsReadyToPlayAnimation = true;
+
+        if (mIsTransitionRunning) {
+            mMoveFromCenterWorkspaceAnimation.onTransitionStarted();
+        }
+    }
+
+    private class AnimationListener implements TransitionProgressListener {
+
+        @Override
+        public void onTransitionStarted() {
+            mIsTransitionRunning = true;
+
+            if (mIsReadyToPlayAnimation) {
+                mMoveFromCenterWorkspaceAnimation.onTransitionStarted();
+            }
+        }
+
+        @Override
+        public void onTransitionFinished() {
+            if (mIsReadyToPlayAnimation) {
+                mMoveFromCenterWorkspaceAnimation.onTransitionFinished();
+
+                if (mQsbInsettable != null) {
+                    mQsbInsettable.setHorizontalInsets(0);
+                }
+            }
+
+            mIsTransitionRunning = false;
+        }
+
+        @Override
+        public void onTransitionProgress(float progress) {
+            mMoveFromCenterWorkspaceAnimation.onTransitionProgress(progress);
+
+            if (mQsbInsettable != null) {
+                float insetPercentage = comp(progress) * MAX_WIDTH_INSET_FRACTION;
+                mQsbInsettable.setHorizontalInsets(insetPercentage);
+            }
+        }
+    }
+}
diff --git a/quickstep/src/com/android/quickstep/util/LayoutUtils.java b/quickstep/src/com/android/quickstep/util/LayoutUtils.java
index 8834dc2..302526d 100644
--- a/quickstep/src/com/android/quickstep/util/LayoutUtils.java
+++ b/quickstep/src/com/android/quickstep/util/LayoutUtils.java
@@ -42,8 +42,7 @@
             PagedOrientationHandler orientationHandler) {
         // Track the bottom of the window.
         Rect taskSize = new Rect();
-        LauncherActivityInterface.INSTANCE.calculateTaskSize(
-                context, dp, taskSize, orientationHandler);
+        LauncherActivityInterface.INSTANCE.calculateTaskSize(context, dp, taskSize);
         return orientationHandler.getDistanceToBottomOfRect(dp, taskSize);
     }
 
diff --git a/quickstep/src/com/android/quickstep/util/MotionPauseDetector.java b/quickstep/src/com/android/quickstep/util/MotionPauseDetector.java
index ac2534e..b83e26e 100644
--- a/quickstep/src/com/android/quickstep/util/MotionPauseDetector.java
+++ b/quickstep/src/com/android/quickstep/util/MotionPauseDetector.java
@@ -119,9 +119,10 @@
      * @param pointerIndex Index for the pointer being tracked in the motion event
      */
     public void addPosition(MotionEvent ev, int pointerIndex) {
-        mForcePauseTimeout.setAlarm(TestProtocol.sForcePauseTimeout != null
+        long timeoutMs = TestProtocol.sForcePauseTimeout != null
                 ? TestProtocol.sForcePauseTimeout
-                : mMakePauseHarderToTrigger ? HARDER_TRIGGER_TIMEOUT : FORCE_PAUSE_TIMEOUT);
+                : mMakePauseHarderToTrigger ? HARDER_TRIGGER_TIMEOUT : FORCE_PAUSE_TIMEOUT;
+        mForcePauseTimeout.setAlarm(timeoutMs);
         float newVelocity = mVelocityProvider.addMotionEvent(ev, ev.getPointerId(pointerIndex));
         if (mPreviousVelocity != null) {
             checkMotionPaused(newVelocity, mPreviousVelocity, ev.getEventTime());
diff --git a/quickstep/src/com/android/quickstep/util/ProxyScreenStatusProvider.java b/quickstep/src/com/android/quickstep/util/ProxyScreenStatusProvider.java
new file mode 100644
index 0000000..3777c65
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/util/ProxyScreenStatusProvider.java
@@ -0,0 +1,51 @@
+/*
+ * 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.quickstep.util;
+
+import androidx.annotation.NonNull;
+
+import com.android.systemui.unfold.updates.screen.ScreenStatusProvider;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Screen status provider implementation that exposes methods to provide screen
+ * status updates to listeners. It is used to receive screen turned on event from
+ * SystemUI to Launcher.
+ */
+public class ProxyScreenStatusProvider implements ScreenStatusProvider {
+
+    public static final ProxyScreenStatusProvider INSTANCE = new ProxyScreenStatusProvider();
+    private final List<ScreenListener> mListeners = new ArrayList<>();
+
+    /**
+     * Called when the screen is on and ready (windows are drawn and screen blocker is removed)
+     */
+    public void onScreenTurnedOn() {
+        mListeners.forEach(ScreenListener::onScreenTurnedOn);
+    }
+
+    @Override
+    public void addCallback(@NonNull ScreenListener listener) {
+        mListeners.add(listener);
+    }
+
+    @Override
+    public void removeCallback(@NonNull ScreenListener listener) {
+        mListeners.remove(listener);
+    }
+}
diff --git a/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java b/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java
index 7cfd151..841e578 100644
--- a/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java
+++ b/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java
@@ -396,9 +396,17 @@
         Rect insets = dp.getInsets();
         float fullWidth = dp.widthPx;
         float fullHeight = dp.heightPx;
-        if (TaskView.CLIP_STATUS_AND_NAV_BARS) {
-            fullWidth -= insets.left + insets.right;
-            fullHeight -= insets.top + insets.bottom;
+        if (TaskView.clipLeft(dp)) {
+            fullWidth -= insets.left;
+        }
+        if (TaskView.clipRight(dp)) {
+            fullWidth -= insets.right;
+        }
+        if (TaskView.clipTop(dp)) {
+            fullHeight -= insets.top;
+        }
+        if (TaskView.clipBottom(dp)) {
+            fullHeight -= insets.bottom;
         }
 
         getTaskDimension(mContext, dp, outPivot);
diff --git a/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java b/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java
index 7eee415..760f665 100644
--- a/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java
+++ b/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java
@@ -17,6 +17,7 @@
 
 import static com.android.launcher3.states.RotationHelper.deltaRotation;
 import static com.android.launcher3.touch.PagedOrientationHandler.MATRIX_POST_TRANSLATE;
+import static com.android.launcher3.util.SplitConfigurationOptions.*;
 import static com.android.quickstep.util.RecentsOrientedState.postDisplayRotation;
 import static com.android.quickstep.util.RecentsOrientedState.preDisplayRotation;
 import static com.android.systemui.shared.system.WindowManagerWrapper.WINDOWING_MODE_FULLSCREEN;
@@ -29,6 +30,7 @@
 import android.graphics.PointF;
 import android.graphics.Rect;
 import android.graphics.RectF;
+import android.util.Log;
 
 import androidx.annotation.NonNull;
 
@@ -49,8 +51,13 @@
  */
 public class TaskViewSimulator implements TransformParams.BuilderProxy {
 
+    private final String TAG = "TaskViewSimulator";
+    private final boolean DEBUG = false;
+
     private final Rect mTmpCropRect = new Rect();
     private final RectF mTempRectF = new RectF();
+    // Additional offset for split tasks
+    private final Point mSplitOffset = new Point();
     private final float[] mTempPoint = new float[2];
 
     private final Context mContext;
@@ -63,6 +70,8 @@
     private final Rect mTaskRect = new Rect();
     private final PointF mPivot = new PointF();
     private DeviceProfile mDp;
+    @StagePosition
+    private int mStagePosition = STAGE_POSITION_UNDEFINED;
 
     private final Matrix mMatrix = new Matrix();
     private final Matrix mMatrixTmp = new Matrix();
@@ -89,6 +98,7 @@
     // Cached calculations
     private boolean mLayoutValid = false;
     private int mOrientationStateId;
+    private StagedSplitBounds mStagedSplitBounds;
 
     public TaskViewSimulator(Context context, BaseActivityInterface sizeStrategy) {
         mContext = context;
@@ -128,9 +138,20 @@
         if (mDp == null) {
             return 1;
         }
-        mSizeStrategy.calculateTaskSize(mContext, mDp, mTaskRect,
-                mOrientationState.getOrientationHandler());
-        return mOrientationState.getFullScreenScaleAndPivot(mTaskRect, mDp, mPivot);
+        Rect fullTaskSize = new Rect();
+        mSizeStrategy.calculateTaskSize(mContext, mDp, fullTaskSize);
+
+        if (mStagedSplitBounds != null) {
+            // The task rect changes according to the staged split task sizes, but recents
+            // fullscreen scale and pivot remains the same since the task fits into the existing
+            // sized task space bounds
+            mSizeStrategy.calculateTaskSize(mContext, mDp, mTaskRect);
+            mOrientationState.getOrientationHandler()
+                    .setSplitTaskSwipeRect(mDp, mTaskRect, mStagedSplitBounds, mStagePosition);
+        } else {
+            mTaskRect.set(fullTaskSize);
+        }
+        return mOrientationState.getFullScreenScaleAndPivot(fullTaskSize, mDp, mPivot);
     }
 
     /**
@@ -143,6 +164,24 @@
     }
 
     /**
+     * Sets the targets which the simulator will control specifically for targets to animate when
+     * in split screen
+     *
+     * @param splitInfo set to {@code null} when not in staged split mode
+     */
+    public void setPreview(RemoteAnimationTargetCompat runningTarget, StagedSplitBounds splitInfo) {
+        setPreview(runningTarget);
+        mStagedSplitBounds = splitInfo;
+        if (mStagedSplitBounds == null) {
+            mStagePosition = STAGE_POSITION_UNDEFINED;
+            return;
+        }
+        mStagePosition = mThumbnailPosition.equals(splitInfo.mLeftTopBounds) ?
+                STAGE_POSITION_TOP_OR_LEFT :
+                STAGE_POSITION_BOTTOM_OR_RIGHT;
+    }
+
+    /**
      * Sets the targets which the simulator will control
      */
     public void setPreviewBounds(Rect bounds, Rect insets) {
@@ -239,6 +278,11 @@
             getFullScreenScale();
             mThumbnailData.rotation = mOrientationState.getDisplayRotation();
 
+            if (mStagedSplitBounds != null) {
+                mOrientationState.getOrientationHandler().setLeashSplitOffset(mSplitOffset, mDp,
+                        mStagedSplitBounds, mStagePosition);
+            }
+
             // mIsRecentsRtl is the inverse of TaskView RTL.
             boolean isRtlEnabled = !mIsRecentsRtl;
             mPositionHelper.updateThumbnailMatrix(
@@ -246,6 +290,9 @@
                     mTaskRect.width(), mTaskRect.height(),
                     mDp, mOrientationState.getRecentsActivityRotation(), isRtlEnabled);
             mPositionHelper.getMatrix().invert(mInversePositionMatrix);
+            if (DEBUG) {
+                Log.d(TAG, " taskRect: " + mTaskRect + " splitOffset: " + mSplitOffset);
+            }
         }
 
         float fullScreenProgress = Utilities.boundToRange(this.fullScreenProgress.value, 0, 1);
@@ -280,6 +327,9 @@
                 recentsViewPrimaryTranslation.value);
         applyWindowToHomeRotation(mMatrix);
 
+        // Move lower/right split window into correct position
+        mMatrix.postTranslate(mSplitOffset.x, mSplitOffset.y);
+
         // Crop rect is the inverse of thumbnail matrix
         mTempRectF.set(-insets.left, -insets.top,
                 taskWidth + insets.right, taskHeight + insets.bottom);
@@ -287,6 +337,25 @@
         mTempRectF.roundOut(mTmpCropRect);
 
         params.applySurfaceParams(params.createSurfaceParams(this));
+
+        if (!DEBUG) {
+            return;
+        }
+        Log.d(TAG, "progress: " + fullScreenProgress
+                + " scale: " + scale
+                + " recentsViewScale: " + recentsViewScale.value
+                + " crop: " + mTmpCropRect
+                + " radius: " + getCurrentCornerRadius()
+                + " translate: " + mSplitOffset
+                + " taskW: " + taskWidth + " H: " + taskHeight
+                + " taskRect: " + mTaskRect
+                + " taskPrimaryT: " + taskPrimaryTranslation.value
+                + " recentsPrimaryT: " + recentsViewPrimaryTranslation.value
+                + " recentsSecondaryT: " + recentsViewSecondaryTranslation.value
+                + " taskSecondaryT: " + taskSecondaryTranslation.value
+                + " recentsScroll: " + recentsViewScroll.value
+                + " pivot: " + mPivot
+        );
     }
 
     @Override
diff --git a/quickstep/src/com/android/quickstep/util/UnfoldMoveFromCenterWorkspaceAnimator.java b/quickstep/src/com/android/quickstep/util/UnfoldMoveFromCenterWorkspaceAnimator.java
new file mode 100644
index 0000000..482092d
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/util/UnfoldMoveFromCenterWorkspaceAnimator.java
@@ -0,0 +1,140 @@
+/*
+ * 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.quickstep.util;
+
+import android.annotation.NonNull;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.WindowManager;
+
+import com.android.launcher3.BubbleTextView;
+import com.android.launcher3.CellLayout;
+import com.android.launcher3.Hotseat;
+import com.android.launcher3.Launcher;
+import com.android.launcher3.ShortcutAndWidgetContainer;
+import com.android.launcher3.Workspace;
+import com.android.launcher3.widget.NavigableAppWidgetHostView;
+import com.android.systemui.shared.animation.UnfoldMoveFromCenterAnimator;
+import com.android.systemui.shared.animation.UnfoldMoveFromCenterAnimator.TranslationApplier;
+import com.android.systemui.unfold.UnfoldTransitionProgressProvider;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Animation that moves launcher icons and widgets from center to the sides (final position)
+ */
+public class UnfoldMoveFromCenterWorkspaceAnimator
+        implements UnfoldTransitionProgressProvider.TransitionProgressListener {
+
+    private final Launcher mLauncher;
+    private final UnfoldMoveFromCenterAnimator mMoveFromCenterAnimation;
+
+    private final Map<ViewGroup, Boolean> mOriginalClipToPadding = new HashMap<>();
+    private final Map<ViewGroup, Boolean> mOriginalClipChildren = new HashMap<>();
+
+    public UnfoldMoveFromCenterWorkspaceAnimator(Launcher launcher, WindowManager windowManager) {
+        mLauncher = launcher;
+        mMoveFromCenterAnimation = new UnfoldMoveFromCenterAnimator(windowManager,
+                new WorkspaceViewsTranslationApplier());
+    }
+
+    @Override
+    public void onTransitionStarted() {
+        mMoveFromCenterAnimation.updateDisplayProperties();
+
+        Workspace workspace = mLauncher.getWorkspace();
+        Hotseat hotseat = mLauncher.getHotseat();
+
+        // App icons and widgets
+        workspace
+                .forEachVisiblePage(page -> {
+                    final CellLayout cellLayout = (CellLayout) page;
+                    ShortcutAndWidgetContainer itemsContainer = cellLayout
+                            .getShortcutsAndWidgets();
+                    disableClipping(cellLayout);
+
+                    for (int i = 0; i < itemsContainer.getChildCount(); i++) {
+                        View child = itemsContainer.getChildAt(i);
+                        mMoveFromCenterAnimation.registerViewForAnimation(child);
+                    }
+                });
+
+        disableClipping(workspace);
+
+        // Hotseat icons
+        ViewGroup hotseatIcons = hotseat.getShortcutsAndWidgets();
+        disableClipping(hotseat);
+
+        for (int i = 0; i < hotseatIcons.getChildCount(); i++) {
+            View child = hotseatIcons.getChildAt(i);
+            mMoveFromCenterAnimation.registerViewForAnimation(child);
+        }
+
+        onTransitionProgress(0f);
+    }
+
+    @Override
+    public void onTransitionProgress(float progress) {
+        mMoveFromCenterAnimation.onTransitionProgress(progress);
+    }
+
+    @Override
+    public void onTransitionFinished() {
+        mMoveFromCenterAnimation.onTransitionFinished();
+        mMoveFromCenterAnimation.clearRegisteredViews();
+
+        restoreClipping(mLauncher.getWorkspace());
+        mLauncher.getWorkspace().forEachVisiblePage(page -> restoreClipping((CellLayout) page));
+        restoreClipping(mLauncher.getHotseat());
+
+        mOriginalClipChildren.clear();
+        mOriginalClipToPadding.clear();
+    }
+
+    private void disableClipping(ViewGroup view) {
+        mOriginalClipToPadding.put(view, view.getClipToPadding());
+        mOriginalClipChildren.put(view, view.getClipChildren());
+        view.setClipToPadding(false);
+        view.setClipChildren(false);
+    }
+
+    private void restoreClipping(ViewGroup view) {
+        final Boolean originalClipToPadding = mOriginalClipToPadding.get(view);
+        if (originalClipToPadding != null) {
+            view.setClipToPadding(originalClipToPadding);
+        }
+        final Boolean originalClipChildren = mOriginalClipChildren.get(view);
+        if (originalClipChildren != null) {
+            view.setClipChildren(originalClipChildren);
+        }
+    }
+
+    private static class WorkspaceViewsTranslationApplier implements TranslationApplier {
+
+        @Override
+        public void apply(@NonNull View view, float x, float y) {
+            if (view instanceof NavigableAppWidgetHostView) {
+                ((NavigableAppWidgetHostView) view).setTranslationForMoveFromCenterAnimation(x, y);
+            } else if (view instanceof BubbleTextView) {
+                ((BubbleTextView) view).setTranslationForMoveFromCenterAnimation(x, y);
+            } else {
+                view.setTranslationX(x);
+                view.setTranslationY(y);
+            }
+        }
+    }
+}
diff --git a/quickstep/src/com/android/quickstep/views/GroupedTaskView.java b/quickstep/src/com/android/quickstep/views/GroupedTaskView.java
new file mode 100644
index 0000000..1bc7c75
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/views/GroupedTaskView.java
@@ -0,0 +1,120 @@
+package com.android.quickstep.views;
+
+import android.content.Context;
+import android.util.AttributeSet;
+
+import com.android.launcher3.R;
+import com.android.launcher3.util.SplitConfigurationOptions;
+import com.android.quickstep.RecentsModel;
+import com.android.quickstep.TaskThumbnailCache;
+import com.android.quickstep.util.CancellableTask;
+import com.android.quickstep.util.RecentsOrientedState;
+import com.android.systemui.shared.recents.model.Task;
+
+/**
+ * TaskView that contains and shows thumbnails for not one, BUT TWO(!!) tasks
+ *
+ * That's right. If you call within the next 5 minutes we'll go ahead and double your order and
+ * send you !! TWO !! Tasks along with their TaskThumbnailViews complimentary. On. The. House.
+ * And not only that, we'll even clean up your thumbnail request if you don't like it.
+ * All the benefits of one TaskView, except DOUBLED!
+ *
+ * (Icon loading sold separately, fees may apply. Shipping & Handling for Overlays not included).
+ */
+public class GroupedTaskView extends TaskView {
+
+    private Task mSecondaryTask;
+    private TaskThumbnailView mSnapshotView2;
+    private CancellableTask mThumbnailLoadRequest2;
+
+    public GroupedTaskView(Context context) {
+        super(context);
+    }
+
+    public GroupedTaskView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    public GroupedTaskView(Context context, AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+    }
+
+    @Override
+    protected void onFinishInflate() {
+        super.onFinishInflate();
+        mSnapshotView2 = findViewById(R.id.bottomright_snapshot);
+    }
+
+    public void bind(Task primary, Task secondary, RecentsOrientedState orientedState,
+            SplitConfigurationOptions.StagedSplitBounds splitBoundsConfig) {
+        super.bind(primary, orientedState);
+        mSecondaryTask = secondary;
+        mTaskIdContainer[1] = secondary.key.id;
+        mTaskIdAttributeContainer[1] = new TaskIdAttributeContainer(secondary, mSnapshotView2);
+        mSnapshotView2.bind(secondary);
+        adjustThumbnailBoundsForSplit(splitBoundsConfig, orientedState);
+    }
+
+    @Override
+    public void onTaskListVisibilityChanged(boolean visible, int changes) {
+        super.onTaskListVisibilityChanged(visible, changes);
+        if (visible) {
+            RecentsModel model = RecentsModel.INSTANCE.get(getContext());
+            TaskThumbnailCache thumbnailCache = model.getThumbnailCache();
+
+            if (needsUpdate(changes, FLAG_UPDATE_THUMBNAIL)) {
+                mThumbnailLoadRequest2 = thumbnailCache.updateThumbnailInBackground(mSecondaryTask,
+                        thumbnailData -> mSnapshotView2.setThumbnail(
+                                mSecondaryTask, thumbnailData
+                        ));
+            }
+
+            if (needsUpdate(changes, FLAG_UPDATE_ICON)) {
+                // TODO What's the Icon for this going to look like? :o
+            }
+        } else {
+            if (needsUpdate(changes, FLAG_UPDATE_THUMBNAIL)) {
+                mSnapshotView2.setThumbnail(null, null);
+                // Reset the task thumbnail reference as well (it will be fetched from the cache or
+                // reloaded next time we need it)
+                mSecondaryTask.thumbnail = null;
+            }
+            if (needsUpdate(changes, FLAG_UPDATE_ICON)) {
+                // TODO
+            }
+        }
+    }
+
+    @Override
+    protected void cancelPendingLoadTasks() {
+        super.cancelPendingLoadTasks();
+        if (mThumbnailLoadRequest2 != null) {
+            mThumbnailLoadRequest2.cancel();
+            mThumbnailLoadRequest2 = null;
+        }
+    }
+
+    @Override
+    public void onRecycle() {
+        super.onRecycle();
+        mSnapshotView2.setThumbnail(mSecondaryTask, null);
+    }
+
+    @Override
+    public void setOverlayEnabled(boolean overlayEnabled) {
+        super.setOverlayEnabled(overlayEnabled);
+        mSnapshotView2.setOverlayEnabled(overlayEnabled);
+    }
+
+    private void adjustThumbnailBoundsForSplit(
+            SplitConfigurationOptions.StagedSplitBounds splitBoundsConfig,
+            RecentsOrientedState orientedState) {
+        if (splitBoundsConfig == null) {
+            return;
+        }
+
+        orientedState.getOrientationHandler().setGroupedTaskViewThumbnailBounds(
+                mSnapshotView, mSnapshotView2, this, splitBoundsConfig,
+                mActivity.getDeviceProfile());
+    }
+}
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index b077ca6..ad41321 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -19,6 +19,7 @@
 import static android.view.Surface.ROTATION_0;
 import static android.view.View.MeasureSpec.EXACTLY;
 import static android.view.View.MeasureSpec.makeMeasureSpec;
+import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
 
 import static com.android.launcher3.AbstractFloatingView.TYPE_TASK_MENU;
 import static com.android.launcher3.AbstractFloatingView.getTopOpenViewWithType;
@@ -42,6 +43,7 @@
 import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASK_DISMISS_SWIPE_UP;
 import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASK_LAUNCH_SWIPE_DOWN;
 import static com.android.launcher3.statehandlers.DepthController.DEPTH;
+import static com.android.launcher3.testing.TestProtocol.TASK_VIEW_ID_CRASH;
 import static com.android.launcher3.touch.PagedOrientationHandler.CANVAS_TRANSLATE;
 import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
 import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
@@ -50,6 +52,7 @@
 import static com.android.quickstep.views.OverviewActionsView.HIDDEN_NON_ZERO_ROTATION;
 import static com.android.quickstep.views.OverviewActionsView.HIDDEN_NO_RECENTS;
 import static com.android.quickstep.views.OverviewActionsView.HIDDEN_NO_TASKS;
+import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_CLOSING;
 
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
@@ -82,6 +85,7 @@
 import android.text.TextPaint;
 import android.util.AttributeSet;
 import android.util.FloatProperty;
+import android.util.Log;
 import android.util.SparseBooleanArray;
 import android.view.HapticFeedbackConstants;
 import android.view.KeyEvent;
@@ -123,6 +127,7 @@
 import com.android.launcher3.touch.OverScroll;
 import com.android.launcher3.touch.PagedOrientationHandler;
 import com.android.launcher3.util.DynamicResource;
+import com.android.launcher3.util.IntArray;
 import com.android.launcher3.util.IntSet;
 import com.android.launcher3.util.MultiValueAlpha;
 import com.android.launcher3.util.ResourceBasedOverride.Overrides;
@@ -140,11 +145,13 @@
 import com.android.quickstep.RecentsModel;
 import com.android.quickstep.RecentsModel.TaskVisualsChangeListener;
 import com.android.quickstep.RemoteAnimationTargets;
+import com.android.quickstep.SwipeUpAnimationLogic.RemoteTargetHandle;
 import com.android.quickstep.SystemUiProxy;
 import com.android.quickstep.TaskOverlayFactory;
 import com.android.quickstep.TaskThumbnailCache;
 import com.android.quickstep.TaskViewUtils;
 import com.android.quickstep.ViewUtils;
+import com.android.quickstep.util.LauncherSplitScreenListener;
 import com.android.quickstep.util.LayoutUtils;
 import com.android.quickstep.util.RecentsOrientedState;
 import com.android.quickstep.util.SplitScreenBounds;
@@ -314,7 +321,13 @@
                     view.setScaleY(scale);
                     view.mLastComputedTaskStartPushOutDistance = null;
                     view.mLastComputedTaskEndPushOutDistance = null;
-                    view.mLiveTileTaskViewSimulator.recentsViewScale.value = scale;
+                    view.runActionOnRemoteHandles(new Consumer<RemoteTargetHandle>() {
+                        @Override
+                        public void accept(RemoteTargetHandle remoteTargetHandle) {
+                            remoteTargetHandle.mTaskViewSimulator.recentsViewScale.value =
+                                    scale;
+                        }
+                    });
                     view.setTaskViewsResistanceTranslation(view.mTaskViewsSecondaryTranslation);
                     view.updatePageOffsets();
                 }
@@ -362,8 +375,7 @@
     // mTaskGridVerticalDiff and mTopBottomRowHeightDiff summed together provides the top
     // position for bottom row of grid tasks.
 
-    protected final TransformParams mLiveTileParams = new TransformParams();
-    protected final TaskViewSimulator mLiveTileTaskViewSimulator;
+    protected RemoteTargetHandle[] mRemoteTargetHandles;
     protected final Rect mLastComputedTaskSize = new Rect();
     protected final Rect mLastComputedGridSize = new Rect();
     protected final Rect mLastComputedGridTaskSize = new Rect();
@@ -399,9 +411,10 @@
     private final InvariantDeviceProfile mIdp;
 
     /**
-     * Getting views should be done via {@link #getTaskViewFromPool()}
+     * Getting views should be done via {@link #getTaskViewFromPool(boolean)}
      */
     private final ViewPool<TaskView> mTaskViewPool;
+    private final ViewPool<GroupedTaskView> mGroupedTaskViewPool;
 
     private final TaskOverlayFactory mTaskOverlayFactory;
 
@@ -501,13 +514,13 @@
     // Only valid until the launcher state changes to NORMAL
     /**
      * ID for the current running TaskView view, unique amongst TaskView instances. ID's are set
-     * through {@link #getTaskViewFromPool()} and incremented by {@link #mTaskViewIdCount}
+     * through {@link #getTaskViewFromPool(boolean)} and incremented by {@link #mTaskViewIdCount}
      */
     protected int mRunningTaskViewId = -1;
     private int mTaskViewIdCount;
     private final int[] INVALID_TASK_IDS = new int[]{-1, -1};
     protected boolean mRunningTaskTileHidden;
-    private Task mTmpRunningTask;
+    private Task[] mTmpRunningTasks;
     protected int mFocusedTaskViewId = -1;
 
     private boolean mTaskIconScaledDown = false;
@@ -562,6 +575,7 @@
      */
     private TaskView mSplitHiddenTaskView;
     private TaskView mSecondSplitHiddenTaskView;
+    private SplitConfigurationOptions.StagedSplitBounds mSplitBoundsConfig;
 
     /**
      * Keeps track of the index of the TaskView that split screen was initialized with so we know
@@ -600,6 +614,7 @@
             };
 
     private RunnableList mSideTaskLaunchCallback;
+    private TaskLaunchListener mTaskLaunchListener;
 
     public RecentsView(Context context, AttributeSet attrs, int defStyleAttr,
             BaseActivityInterface sizeStrategy) {
@@ -622,6 +637,9 @@
         mClearAllButton.setOnClickListener(this::dismissAllTasks);
         mTaskViewPool = new ViewPool<>(context, this, R.layout.task, 20 /* max size */,
                 10 /* initial size */);
+        // There's only one pair of grouped tasks we can envision at the moment
+        mGroupedTaskViewPool = new ViewPool<>(context, this,
+                R.layout.task_grouped, 2 /* max size */, 1 /* initial size */);
 
         mIsRtl = mOrientationHandler.getRecentsRtlSetting(getResources());
         setLayoutDirection(mIsRtl ? View.LAYOUT_DIRECTION_RTL : View.LAYOUT_DIRECTION_LTR);
@@ -652,10 +670,6 @@
         // Initialize quickstep specific cache params here, as this is constructed only once
         mActivity.getViewCache().setCacheSize(R.layout.digital_wellbeing_toast, 5);
 
-        mLiveTileTaskViewSimulator = new TaskViewSimulator(getContext(), getSizeStrategy());
-        mLiveTileTaskViewSimulator.recentsViewScale.value = 1;
-        mLiveTileTaskViewSimulator.setOrientationState(mOrientationState);
-
         mTintingColor = getForegroundScrimDimColor(context);
     }
 
@@ -703,7 +717,7 @@
             super.dispatchDraw(canvas);
         }
         if (ENABLE_QUICKSTEP_LIVE_TILE.get() && mEnableDrawingLiveTile
-                && mLiveTileParams.getTargetSet() != null) {
+                && mRemoteTargetHandles != null) {
             redrawLiveTile();
         }
     }
@@ -745,9 +759,13 @@
         if (mHandleTaskStackChanges) {
             TaskView taskView = getTaskViewByTaskId(taskId);
             if (taskView != null) {
-                Task task = taskView.getTask();
-                taskView.getThumbnail().setThumbnail(task, thumbnailData);
-                return task;
+                for (TaskView.TaskIdAttributeContainer container :
+                        taskView.getTaskIdAttributeContainers()) {
+                    if (container == null || taskId != container.getTask().key.id) {
+                        continue;
+                    }
+                    container.getThumbnailView().setThumbnail(container.getTask(), thumbnailData);
+                }
             }
         }
         return null;
@@ -808,7 +826,8 @@
         mActivity.addMultiWindowModeChangedListener(mMultiWindowModeChangedListener);
         TaskStackChangeListeners.getInstance().registerTaskStackListener(mTaskStackListener);
         mSyncTransactionApplier = new SurfaceTransactionApplier(this);
-        mLiveTileParams.setSyncTransactionApplier(mSyncTransactionApplier);
+        runActionOnRemoteHandles(remoteTargetHandle -> remoteTargetHandle.mTransformParams
+                .setSyncTransactionApplier(mSyncTransactionApplier));
         RecentsModel.INSTANCE.get(getContext()).addThumbnailChangeListener(this);
         mIPipAnimationListener.setActivityAndRecentsView(mActivity, this);
         SystemUiProxy.INSTANCE.get(getContext()).setPinnedStackAnimationListener(
@@ -826,7 +845,8 @@
         mActivity.removeMultiWindowModeChangedListener(mMultiWindowModeChangedListener);
         TaskStackChangeListeners.getInstance().unregisterTaskStackListener(mTaskStackListener);
         mSyncTransactionApplier = null;
-        mLiveTileParams.setSyncTransactionApplier(null);
+        runActionOnRemoteHandles(remoteTargetHandle -> remoteTargetHandle.mTransformParams
+                .setSyncTransactionApplier(null));
         executeSideTaskLaunchCallback();
         RecentsModel.INSTANCE.get(getContext()).removeThumbnailChangeListener(this);
         SystemUiProxy.INSTANCE.get(getContext()).setPinnedStackAnimationListener(null);
@@ -847,9 +867,15 @@
         if (child instanceof TaskView && child != mSplitHiddenTaskView
                 && child != mMovingTaskView) {
             TaskView taskView = (TaskView) child;
-            mHasVisibleTaskData.delete(taskView.getTaskIds()[0]);
+            for (int i : taskView.getTaskIds()) {
+                mHasVisibleTaskData.delete(i);
+            }
+            if (child instanceof GroupedTaskView) {
+                mGroupedTaskViewPool.recycle((GroupedTaskView)taskView);
+            } else {
+                mTaskViewPool.recycle(taskView);
+            }
             taskView.setTaskViewId(-1);
-            mTaskViewPool.recycle(taskView);
             mActionsView.updateHiddenFlags(HIDDEN_NO_TASKS, getTaskViewCount() == 0);
         }
         updateTaskStartIndex(child);
@@ -880,6 +906,21 @@
         mSideTaskLaunchCallback.add(callback::executeAllAndDestroy);
     }
 
+    /**
+     * This is a one-time callback when touching in live tile mode. It's reset to null right
+     * after it's called.
+     */
+    public void setTaskLaunchListener(TaskLaunchListener taskLaunchListener) {
+        mTaskLaunchListener = taskLaunchListener;
+    }
+
+    public void onTaskLaunchedInLiveTileMode() {
+        if (mTaskLaunchListener != null) {
+            mTaskLaunchListener.onTaskLaunched();
+            mTaskLaunchListener = null;
+        }
+    }
+
     private void executeSideTaskLaunchCallback() {
         if (mSideTaskLaunchCallback != null) {
             mSideTaskLaunchCallback.executeAllAndDestroy();
@@ -887,10 +928,15 @@
         }
     }
 
+    /**
+     * TODO(b/195675206) Check both taskIDs from runningTaskViewId
+     *  and launch if either of them is {@param taskId}
+     */
     public void launchSideTaskInLiveTileModeForRestartedApp(int taskId) {
         int runningTaskViewId = getTaskViewIdFromTaskId(taskId);
         if (mRunningTaskViewId != -1 && mRunningTaskViewId == runningTaskViewId) {
-            RemoteAnimationTargets targets = getLiveTileParams().getTargetSet();
+            TransformParams params = mRemoteTargetHandles[0].mTransformParams;
+            RemoteAnimationTargets targets = params.getTargetSet();
             if (targets != null && targets.findTask(taskId) != null) {
                 launchSideTaskInLiveTileMode(taskId, targets.apps, targets.wallpapers,
                         targets.nonApps);
@@ -996,10 +1042,21 @@
         if (!enabled) {
             // Reset the running task when leaving overview since it can still have a reference to
             // its thumbnail
-            mTmpRunningTask = null;
+            mTmpRunningTasks = null;
             if (mSplitSelectStateController.isSplitSelectActive()) {
                 cancelSplitSelect(false);
             }
+            // Remove grouped tasks and recycle once we exit overview
+            int taskCount = getTaskViewCount();
+            for (int i = 0; i < taskCount; i++) {
+                View v = getTaskViewAt(i);
+                if (!(v instanceof GroupedTaskView)) {
+                    return;
+                }
+                GroupedTaskView gtv = (GroupedTaskView) v;
+                gtv.onTaskListVisibilityChanged(false);
+                removeView(gtv);
+            }
         }
         updateLocusId();
     }
@@ -1170,7 +1227,7 @@
         mMovingTaskView = focusedTaskView;
         removeView(focusedTaskView);
         mMovingTaskView = null;
-        focusedTaskView.onRecycle();
+        focusedTaskView.resetPersistentViewTransforms();
         addView(focusedTaskView, mTaskViewStartIndex);
         setCurrentPage(mTaskViewStartIndex);
 
@@ -1201,18 +1258,32 @@
         TaskView ignoreResetTaskView =
                 mIgnoreResetTaskId == -1 ? null : getTaskViewByTaskId(mIgnoreResetTaskId);
 
-        final int requiredTaskCount = tasks.size();
-        if (getTaskViewCount() != requiredTaskCount) {
+        int[] splitTaskIds =
+                LauncherSplitScreenListener.INSTANCE.getNoCreate().getSplitTaskIds();
+        int requiredGroupTaskViews = splitTaskIds.length / 2;
+
+        // Subtract half the number of split tasks and not total number because we've already
+        // added a GroupedTaskView when swipe up gesture happens.
+        // This will need to change if we start showing GroupedTaskViews during swipe up from home
+        int requiredTaskViewCount = tasks.size() - requiredGroupTaskViews;
+
+        if (getTaskViewCount() != requiredTaskViewCount) {
             if (indexOfChild(mClearAllButton) != -1) {
                 removeView(mClearAllButton);
             }
-            for (int i = getTaskViewCount(); i < requiredTaskCount; i++) {
-                addView(getTaskViewFromPool());
+
+            for (int i = getTaskViewCount(); i < requiredTaskViewCount; i++) {
+                addView(getTaskViewFromPool(false));
             }
-            while (getTaskViewCount() > requiredTaskCount) {
+            while (getTaskViewCount() > requiredTaskViewCount) {
                 removeView(getChildAt(getChildCount() - 1));
             }
-            if (requiredTaskCount > 0) {
+            while (requiredGroupTaskViews > 0) {
+                // Add to front of list
+                addView(getTaskViewFromPool(true), 0);
+                requiredGroupTaskViews--;
+            }
+            if (requiredTaskViewCount > 0) {
                 addView(mClearAllButton);
             }
         }
@@ -1222,13 +1293,33 @@
         // TODO set these type to array and check all taskIDs? Maybe we can get away w/ only one
         int runningTaskId = getTaskIdsForTaskViewId(mRunningTaskViewId)[0];
         int focusedTaskId = getTaskIdsForTaskViewId(mFocusedTaskViewId)[0];
+        Log.d(TASK_VIEW_ID_CRASH, "runningTaskId beforeBind: " + runningTaskId
+                + " runningTaskViewId: " + mRunningTaskViewId
+                + " forTaskView: " + getTaskViewFromTaskViewId(mRunningTaskViewId));
 
-        // Rebind and reset all task views
-        for (int i = requiredTaskCount - 1; i >= 0; i--) {
-            final int pageIndex = requiredTaskCount - i - 1 + mTaskViewStartIndex;
-            final Task task = tasks.get(i);
+        for (int taskViewIndex = requiredTaskViewCount - 1, taskDataIndex = tasks.size() - 1;
+                taskViewIndex >= 0;
+                taskViewIndex--, taskDataIndex--) {
+            final int pageIndex = requiredTaskViewCount - taskViewIndex - 1 + mTaskViewStartIndex;
+            final Task task = tasks.get(taskDataIndex);
             final TaskView taskView = (TaskView) getChildAt(pageIndex);
-            taskView.bind(task, mOrientationState);
+            if (taskView instanceof GroupedTaskView) {
+                Task leftTop;
+                Task rightBottom;
+                if (task.key.id == splitTaskIds[0]) {
+                    leftTop = task;
+                    taskDataIndex--;
+                    rightBottom = tasks.get(taskDataIndex);
+                } else {
+                    rightBottom = task;
+                    taskDataIndex--;
+                    leftTop = tasks.get(taskDataIndex);
+                }
+                ((GroupedTaskView) taskView).bind(leftTop, rightBottom, mOrientationState,
+                        mSplitBoundsConfig);
+            } else {
+                taskView.bind(task, mOrientationState);
+            }
         }
 
         // Keep same previous focused task
@@ -1240,12 +1331,26 @@
         mFocusedTaskViewId = newFocusedTaskView != null ?
                 newFocusedTaskView.getTaskViewId() : -1;
         updateTaskSize();
+        updateChildTaskOrientations();
 
         TaskView newRunningTaskView = null;
         if (runningTaskId != -1) {
             // Update mRunningTaskViewId to be the new TaskView that was assigned by binding
             // the full list of tasks to taskViews
             newRunningTaskView = getTaskViewByTaskId(runningTaskId);
+            if (newRunningTaskView == null) {
+                StringBuilder sb = new StringBuilder();
+                for (int i = requiredTaskViewCount - 1; i >= 0; i--) {
+                    final int pageIndex = requiredTaskViewCount - i - 1 + mTaskViewStartIndex;
+                    final TaskView taskView = (TaskView) getChildAt(pageIndex);
+                    int taskViewId = taskView.getTaskViewId();
+                    sb.append(" taskViewId: " + taskViewId
+                            + " taskId: " + getTaskIdsForTaskViewId(taskViewId)[0]
+                            + " for taskView: " + taskView + "\n");
+                }
+                Log.d(TASK_VIEW_ID_CRASH, "taskViewCount: " + getTaskViewCount()
+                        + " " + sb.toString());
+            }
             mRunningTaskViewId = newRunningTaskView.getTaskViewId();
         }
 
@@ -1320,12 +1425,12 @@
             // Since we reuse the same mLiveTileTaskViewSimulator in the RecentsView, we need
             // to reset the params after it settles in Overview from swipe up so that we don't
             // render with obsolete param values.
-            mLiveTileTaskViewSimulator.taskPrimaryTranslation.value = 0;
-            mLiveTileTaskViewSimulator.taskSecondaryTranslation.value = 0;
-            mLiveTileTaskViewSimulator.fullScreenProgress.value = 0;
-            mLiveTileTaskViewSimulator.recentsViewScale.value = 1;
-
-            mLiveTileParams.setTargetAlpha(1);
+            runActionOnRemoteHandles(remoteTargetHandle -> {
+                remoteTargetHandle.mTaskViewSimulator.taskPrimaryTranslation.value = 0;
+                remoteTargetHandle.mTaskViewSimulator.taskSecondaryTranslation.value = 0;
+                remoteTargetHandle.mTaskViewSimulator.fullScreenProgress.value = 0;
+                remoteTargetHandle.mTaskViewSimulator.recentsViewScale.value = 1;
+            });
 
             // Similar to setRunningTaskHidden below, reapply the state before runningTaskView is
             // null.
@@ -1379,7 +1484,8 @@
         setPageSpacing(dp.overviewPageSpacing);
 
         // Propagate DeviceProfile change event.
-        mLiveTileTaskViewSimulator.setDp(dp);
+        runActionOnRemoteHandles(
+                remoteTargetHandle -> remoteTargetHandle.mTaskViewSimulator.setDp(dp));
         mActionsView.setDp(dp);
         mOrientationState.setDeviceProfile(dp);
 
@@ -1490,8 +1596,7 @@
     }
 
     public void getTaskSize(Rect outRect) {
-        mSizeStrategy.calculateTaskSize(mActivity, mActivity.getDeviceProfile(), outRect,
-                mOrientationHandler);
+        mSizeStrategy.calculateTaskSize(mActivity, mActivity.getDeviceProfile(), outRect);
         mLastComputedTaskSize.set(outRect);
     }
 
@@ -1499,8 +1604,7 @@
      * Returns the size of task selected to enter modal state.
      */
     public Point getSelectedTaskSize() {
-        mSizeStrategy.calculateTaskSize(mActivity, mActivity.getDeviceProfile(), mTempRect,
-                mOrientationHandler);
+        mSizeStrategy.calculateTaskSize(mActivity, mActivity.getDeviceProfile(), mTempRect);
         return new Point(mTempRect.width(), mTempRect.height());
     }
 
@@ -1633,8 +1737,17 @@
                 visible = lower <= index && index <= upper;
             }
             if (visible) {
-                if (task == mTmpRunningTask) {
-                    // Skip loading if this is the task that we are animating into
+                boolean skipLoadingTask = false;
+                if (mTmpRunningTasks != null) {
+                    for (Task t : mTmpRunningTasks) {
+                        if (task == t) {
+                            // Skip loading if this is the task that we are animating into
+                            skipLoadingTask = true;
+                            break;
+                        }
+                    }
+                }
+                if (skipLoadingTask) {
                     continue;
                 }
                 if (!mHasVisibleTaskData.get(task.key.id)) {
@@ -1709,7 +1822,8 @@
             }
         }
         setEnableDrawingLiveTile(false);
-        mLiveTileParams.setTargetSet(null);
+        runActionOnRemoteHandles(remoteTargetHandle -> remoteTargetHandle.mTransformParams
+                .setTargetSet(null));
 
         // These are relatively expensive and don't need to be done this frame (RecentsView isn't
         // visible anyway), so defer by a frame to get off the critical path, e.g. app to home.
@@ -1776,8 +1890,10 @@
      * Handle the edge case where Recents could increment task count very high over long
      * period of device usage. Probably will never happen, but meh.
      */
-    private TaskView getTaskViewFromPool() {
-        TaskView taskView = mTaskViewPool.getView();
+    private <T extends TaskView> T getTaskViewFromPool(boolean isGrouped) {
+        T taskView = isGrouped ?
+                (T) mGroupedTaskViewPool.getView() :
+                (T) mTaskViewPool.getView();
         taskView.setTaskViewId(mTaskViewIdCount);
         if (mTaskViewIdCount == Integer.MAX_VALUE) {
             mTaskViewIdCount = 0;
@@ -1813,7 +1929,7 @@
     /**
      * Called when a gesture from an app is starting.
      */
-    public void onGestureAnimationStart(RunningTaskInfo runningTaskInfo) {
+    public void onGestureAnimationStart(RunningTaskInfo[] runningTaskInfo) {
         mGestureActive = true;
         // This needs to be called before the other states are set since it can create the task view
         if (mOrientationState.setGestureActive(true)) {
@@ -1864,7 +1980,6 @@
         return as;
     }
 
-
     private void updateChildTaskOrientations() {
         for (int i = 0; i < getTaskViewCount(); i++) {
             getTaskViewAt(i).setOrientationState(mOrientationState);
@@ -1880,10 +1995,9 @@
      */
     public void onPrepareGestureEndAnimation(
             @Nullable AnimatorSet animatorSet, GestureState.GestureEndTarget endTarget,
-            TaskViewSimulator taskViewSimulator) {
+            TaskViewSimulator[] taskViewSimulators) {
         mCurrentGestureEndTarget = endTarget;
         if (endTarget == GestureState.GestureEndTarget.RECENTS) {
-            setEnableFreeScroll(true);
             updateGridProperties();
         }
 
@@ -1897,13 +2011,16 @@
                         runningTaskView.getGridTranslationX(),
                         runningTaskView.getGridTranslationY());
             }
-            if (animatorSet == null) {
-                setGridProgress(1);
-                taskViewSimulator.taskPrimaryTranslation.value = runningTaskPrimaryGridTranslation;
-            } else {
-                animatorSet.play(ObjectAnimator.ofFloat(this, RECENTS_GRID_PROGRESS, 1));
-                animatorSet.play(taskViewSimulator.taskPrimaryTranslation.animateToValue(
-                        runningTaskPrimaryGridTranslation));
+            for (TaskViewSimulator tvs : taskViewSimulators) {
+                if (animatorSet == null) {
+                    setGridProgress(1);
+                    tvs.taskPrimaryTranslation.value =
+                            runningTaskPrimaryGridTranslation;
+                } else {
+                    animatorSet.play(ObjectAnimator.ofFloat(this, RECENTS_GRID_PROGRESS, 1));
+                    animatorSet.play(tvs.taskPrimaryTranslation.animateToValue(
+                            runningTaskPrimaryGridTranslation));
+                }
             }
         }
     }
@@ -1932,7 +2049,21 @@
     /**
      * Returns true if we should add a stub taskView for the running task id
      */
-    protected boolean shouldAddStubTaskView(RunningTaskInfo runningTaskInfo) {
+    protected boolean shouldAddStubTaskView(RunningTaskInfo[] runningTaskInfos) {
+        if (runningTaskInfos.length > 1) {
+            // * Always create new view for GroupedTaskView
+            // * Remove existing associated taskViews for tasks currently in split
+            for (RunningTaskInfo rti : runningTaskInfos) {
+                TaskView taskView = getTaskViewByTaskId(rti.taskId);
+                if (taskView == null) {
+                    continue;
+                }
+                taskView.onTaskListVisibilityChanged(false);
+                removeView(taskView);
+            }
+            return true;
+        }
+        RunningTaskInfo runningTaskInfo = runningTaskInfos[0];
         return runningTaskInfo != null && getTaskViewByTaskId(runningTaskInfo.taskId) == null;
     }
 
@@ -1942,29 +2073,47 @@
      * All subsequent calls to reload will keep the task as the first item until {@link #reset()}
      * is called.  Also scrolls the view to this task.
      */
-    public void showCurrentTask(RunningTaskInfo runningTaskInfo) {
+    public void showCurrentTask(RunningTaskInfo[] runningTaskInfo) {
         int runningTaskViewId = -1;
+        boolean needGroupTaskView = runningTaskInfo.length > 1;
+        RunningTaskInfo taskInfo = runningTaskInfo[0];
         if (shouldAddStubTaskView(runningTaskInfo)) {
             boolean wasEmpty = getChildCount() == 0;
             // Add an empty view for now until the task plan is loaded and applied
-            final TaskView taskView = getTaskViewFromPool();
+            final TaskView taskView;
+            if (needGroupTaskView) {
+                taskView = getTaskViewFromPool(true);
+                RunningTaskInfo secondaryTaskInfo = runningTaskInfo[1];
+                mTmpRunningTasks = new Task[]{
+                        Task.from(new TaskKey(taskInfo), taskInfo, false),
+                        Task.from(new TaskKey(secondaryTaskInfo), secondaryTaskInfo, false)
+                };
+                addView(taskView, mTaskViewStartIndex);
+                // When we create a placeholder task view mSplitBoundsConfig will be null, but with
+                // the actual app running we won't need to show the thumbnail until all the tasks
+                // load later anyways
+                ((GroupedTaskView)taskView).bind(mTmpRunningTasks[0], mTmpRunningTasks[1],
+                        mOrientationState, mSplitBoundsConfig);
+            } else {
+                taskView = getTaskViewFromPool(false);
+                addView(taskView, mTaskViewStartIndex);
+                // The temporary running task is only used for the duration between the start of the
+                // gesture and the task list is loaded and applied
+                mTmpRunningTasks = new Task[]{Task.from(new TaskKey(taskInfo), taskInfo, false)};
+                taskView.bind(mTmpRunningTasks[0], mOrientationState);
+            }
             runningTaskViewId = taskView.getTaskViewId();
-            addView(taskView, mTaskViewStartIndex);
             if (wasEmpty) {
                 addView(mClearAllButton);
             }
-            // The temporary running task is only used for the duration between the start of the
-            // gesture and the task list is loaded and applied
-            mTmpRunningTask = Task.from(new TaskKey(runningTaskInfo), runningTaskInfo, false);
-            taskView.bind(mTmpRunningTask, mOrientationState);
 
             // Measure and layout immediately so that the scroll values is updated instantly
             // as the user might be quick-switching
             measure(makeMeasureSpec(getMeasuredWidth(), EXACTLY),
                     makeMeasureSpec(getMeasuredHeight(), EXACTLY));
             layout(getLeft(), getTop(), getRight(), getBottom());
-        } else if (getTaskViewByTaskId(runningTaskInfo.taskId) != null) {
-            runningTaskViewId = getTaskViewByTaskId(runningTaskInfo.taskId).getTaskViewId();
+        } else if (!needGroupTaskView && getTaskViewByTaskId(taskInfo.taskId) != null) {
+            runningTaskViewId = getTaskViewByTaskId(taskInfo.taskId).getTaskViewId();
         }
 
         boolean runningTaskTileHidden = mRunningTaskTileHidden;
@@ -1975,6 +2124,7 @@
         setRunningTaskHidden(runningTaskTileHidden);
         // Update task size after setting current task.
         updateTaskSize();
+        updateChildTaskOrientations();
 
         // Reload the task list
         mTaskListChangeId = mModel.getTasks(this::applyLoadPlan);
@@ -1984,6 +2134,8 @@
      * Sets the running task id, cleaning up the old running task if necessary.
      */
     public void setCurrentTask(int runningTaskViewId) {
+        Log.d(TASK_VIEW_ID_CRASH, "currentRunningTaskViewId: " + mRunningTaskViewId
+                + " requestedTaskViewId: " + runningTaskViewId);
         if (mRunningTaskViewId == runningTaskViewId) {
             return;
         }
@@ -2054,23 +2206,39 @@
         }
     }
 
-    /** Updates TaskView and ClearAllButtion scaling and translation required to turn into grid
+    /**
+     * Updates TaskView and ClearAllButtion scaling and translation required to turn into grid
      * layout.
      * This method is used when no task dismissal has occurred.
      */
     private void updateGridProperties() {
-        updateGridProperties(false);
+        updateGridProperties(false, Integer.MAX_VALUE);
+    }
+
+    /**
+     * Updates TaskView and ClearAllButtion scaling and translation required to turn into grid
+     * layout.
+     *
+     * This method is used when task dismissal has occurred, but rebalance is not needed.
+     *
+     * @param isTaskDismissal indicates if update was called due to task dismissal
+     */
+    private void updateGridProperties(boolean isTaskDismissal) {
+        updateGridProperties(isTaskDismissal, Integer.MAX_VALUE);
     }
 
     /**
      * Updates TaskView and ClearAllButton scaling and translation required to turn into grid
      * layout.
+     *
      * This method only calculates the potential position and depends on {@link #setGridProgress} to
      * apply the actual scaling and translation.
      *
-     * @param isTaskDismissal indicates if update was called due to task dismissal
+     * @param isTaskDismissal    indicates if update was called due to task dismissal
+     * @param startRebalanceAfter which view index to start rebalancing from. Use Integer.MAX_VALUE
+     *                           to skip rebalance
      */
-    private void updateGridProperties(boolean isTaskDismissal) {
+    private void updateGridProperties(boolean isTaskDismissal, int startRebalanceAfter) {
         int taskCount = getTaskViewCount();
         if (taskCount == 0) {
             return;
@@ -2137,8 +2305,20 @@
                     focusedTaskShift += mIsRtl ? taskWidthAndSpacing : -taskWidthAndSpacing;
                 }
                 int taskViewId = taskView.getTaskViewId();
-                boolean isTopRow = isTaskDismissal ? mTopRowIdSet.contains(taskViewId)
-                        : topRowWidth <= bottomRowWidth;
+
+                // Rebalance the grid starting after a certain index
+                boolean isTopRow;
+                if (isTaskDismissal) {
+                    if (i > startRebalanceAfter) {
+                        mTopRowIdSet.remove(taskViewId);
+                        isTopRow = topRowWidth <= bottomRowWidth;
+                    } else {
+                        isTopRow = mTopRowIdSet.contains(taskViewId);
+                    }
+                } else {
+                    isTopRow = topRowWidth <= bottomRowWidth;
+                }
+
                 if (isTopRow) {
                     if (homeTaskView != null && nextFocusedTaskView == null) {
                         // TaskView will be focused when swipe up, don't count towards row width.
@@ -2351,8 +2531,11 @@
         // Use setFloat instead of setViewAlpha as we want to keep the view visible even when it's
         // alpha is set to 0 so that it can be recycled in the view pool properly
         if (ENABLE_QUICKSTEP_LIVE_TILE.get() && taskView.isRunningTask()) {
-            anim.setFloat(mLiveTileParams, TransformParams.TARGET_ALPHA, 0,
-                    clampToProgress(ACCEL, 0, 0.5f));
+            runActionOnRemoteHandles(remoteTargetHandle -> {
+                TransformParams params = remoteTargetHandle.mTransformParams;
+                anim.setFloat(params, TransformParams.TARGET_ALPHA, 0,
+                        clampToProgress(ACCEL, 0, 0.5f));
+            });
         }
         anim.setFloat(taskView, VIEW_ALPHA, 0, clampToProgress(ACCEL, 0, 0.5f));
         FloatProperty<TaskView> secondaryViewTranslate =
@@ -2371,10 +2554,12 @@
         if (ENABLE_QUICKSTEP_LIVE_TILE.get() && mEnableDrawingLiveTile
                 && taskView.isRunningTask()) {
             anim.addOnFrameCallback(() -> {
-                mLiveTileTaskViewSimulator.taskSecondaryTranslation.value =
-                        mOrientationHandler.getSecondaryValue(
-                                taskView.getTranslationX(),
-                                taskView.getTranslationY());
+                runActionOnRemoteHandles(
+                        remoteTargetHandle -> remoteTargetHandle.mTaskViewSimulator
+                                .taskSecondaryTranslation.value = mOrientationHandler
+                                .getSecondaryValue(taskView.getTranslationX(),
+                                        taskView.getTranslationY()
+                                ));
                 redrawLiveTile();
             });
         }
@@ -2425,7 +2610,6 @@
         boolean showAsGrid = showAsGrid();
         int taskCount = getTaskViewCount();
         int dismissedIndex = indexOfChild(dismissedTaskView);
-        int dismissedTaskId = dismissedTaskView.getTaskIds()[0];
         int dismissedTaskViewId = dismissedTaskView.getTaskViewId();
 
         // Grid specific properties.
@@ -2523,9 +2707,14 @@
                             && child instanceof TaskView
                             && ((TaskView) child).isRunningTask()) {
                         anim.addOnFrameCallback(() -> {
-                            mLiveTileTaskViewSimulator.taskPrimaryTranslation.value =
-                                    mOrientationHandler.getPrimaryValue(child.getTranslationX(),
-                                            child.getTranslationY());
+                            runActionOnRemoteHandles(
+                                    remoteTargetHandle ->
+                                            remoteTargetHandle.mTaskViewSimulator
+                                                    .taskPrimaryTranslation.value =
+                                                    mOrientationHandler.getPrimaryValue(
+                                                            child.getTranslationX(),
+                                                            child.getTranslationY()
+                                                    ));
                             redrawLiveTile();
                         });
                     }
@@ -2607,9 +2796,9 @@
                             if (ENABLE_QUICKSTEP_LIVE_TILE.get()
                                     && dismissedTaskView.isRunningTask()) {
                                 finishRecentsAnimation(true /* toRecents */, false /* shouldPip */,
-                                        () -> removeTaskInternal(dismissedTaskId));
+                                        () -> removeTaskInternal(dismissedTaskViewId));
                             } else {
-                                removeTaskInternal(dismissedTaskId);
+                                removeTaskInternal(dismissedTaskViewId);
                             }
                             mActivity.getStatsLogManager().logger()
                                     .withItemInfo(dismissedTaskView.getItemInfo())
@@ -2622,14 +2811,49 @@
                     resetTaskVisuals();
 
                     int pageToSnapTo = mCurrentPage;
-                    if ((dismissedIndex < pageToSnapTo && !showAsGrid)
-                            || pageToSnapTo == taskCount - 1) {
-                        pageToSnapTo -= 1;
-                    }
+                    int taskViewIdToSnapTo = -1;
                     if (showAsGrid) {
+                        // Get the id of the task view we will snap to based on the current
+                        // page's relative position as the order of indices change over time due
+                        // to dismissals.
+                        TaskView snappedTaskView = getTaskViewAtByAbsoluteIndex(mCurrentPage);
+                        if (snappedTaskView != null) {
+                            if (snappedTaskView.getTaskViewId() == mFocusedTaskViewId) {
+                                if (finalNextFocusedTaskView != null) {
+                                    taskViewIdToSnapTo = finalNextFocusedTaskView.getTaskViewId();
+                                } else {
+                                    taskViewIdToSnapTo = mFocusedTaskViewId;
+                                }
+                            } else {
+                                int snappedTaskViewId = snappedTaskView.getTaskViewId();
+                                boolean isSnappedTaskInTopRow = mTopRowIdSet.contains(
+                                        snappedTaskViewId);
+                                IntArray taskViewIdArray =
+                                        isSnappedTaskInTopRow ? getTopRowIdArray()
+                                                : getBottomRowIdArray();
+                                int snappedIndex = taskViewIdArray.indexOf(snappedTaskViewId);
+                                taskViewIdArray.removeValue(dismissedTaskViewId);
+                                if (snappedIndex < taskViewIdArray.size()) {
+                                    taskViewIdToSnapTo = taskViewIdArray.get(snappedIndex);
+                                } else if (snappedIndex == taskViewIdArray.size()) {
+                                    // If the snapped task is the last item from the dismissed row,
+                                    // snap to the same column in the other grid row
+                                    IntArray inverseRowTaskViewIdArray =
+                                            isSnappedTaskInTopRow ? getBottomRowIdArray()
+                                                    : getTopRowIdArray();
+                                    if (snappedIndex < inverseRowTaskViewIdArray.size()) {
+                                        taskViewIdToSnapTo = inverseRowTaskViewIdArray.get(
+                                                snappedIndex);
+                                    }
+                                }
+                            }
+                        }
+
                         int primaryScroll = mOrientationHandler.getPrimaryScroll(RecentsView.this);
                         int currentPageScroll = getScrollForPage(pageToSnapTo);
                         mCurrentPageScrollDiff = primaryScroll - currentPageScroll;
+                    } else if (dismissedIndex < pageToSnapTo || pageToSnapTo == taskCount - 1) {
+                        pageToSnapTo -= 1;
                     }
                     removeViewInLayout(dismissedTaskView);
                     mTopRowIdSet.remove(dismissedTaskViewId);
@@ -2644,9 +2868,55 @@
                             mTopRowIdSet.remove(mFocusedTaskViewId);
                             finalNextFocusedTaskView.animateIconScaleAndDimIntoView();
                         }
-                        updateTaskSize(true);
+                        updateTaskSize(/*isTaskDismissal=*/ true);
+                        updateChildTaskOrientations();
                         // Update scroll and snap to page.
                         updateScrollSynchronously();
+
+                        if (showAsGrid) {
+                            // Rebalance tasks in the grid
+                            int highestVisibleTaskIndex = getHighestVisibleTaskIndex();
+                            if (highestVisibleTaskIndex < Integer.MAX_VALUE) {
+                                TaskView taskView = getTaskViewAt(highestVisibleTaskIndex);
+
+                                boolean shouldRebalance = false;
+                                int screenStart = mOrientationHandler.getPrimaryScroll(
+                                        RecentsView.this);
+                                int taskStart = mOrientationHandler.getChildStart(taskView)
+                                        + (int) taskView.getOffsetAdjustment(/*fullscreenEnabled=*/
+                                        false, /*gridEnabled=*/ true);
+
+                                // Rebalance only if there is a maximum gap between the task and the
+                                // screen's edge; this ensures that rebalanced tasks are outside the
+                                // visible screen.
+                                if (mIsRtl) {
+                                    shouldRebalance = taskStart <= screenStart + mPageSpacing;
+                                } else {
+                                    int screenEnd =
+                                            screenStart + mOrientationHandler.getMeasuredSize(
+                                                    RecentsView.this);
+                                    int taskSize = (int) (mOrientationHandler.getMeasuredSize(
+                                            taskView) * taskView
+                                            .getSizeAdjustment(/*fullscreenEnabled=*/false));
+                                    int taskEnd = taskStart + taskSize;
+
+                                    shouldRebalance = taskEnd >= screenEnd - mPageSpacing;
+                                }
+
+                                if (shouldRebalance) {
+                                    updateGridProperties(/*isTaskDismissal=*/ true,
+                                            highestVisibleTaskIndex);
+                                    updateScrollSynchronously();
+                                }
+                            }
+
+                            // If snapping to another page due to indices rearranging, find the new
+                            // index after dismissal & rearrange using the task view id.
+                            if (taskViewIdToSnapTo != -1) {
+                                pageToSnapTo = indexOfChild(
+                                        getTaskViewFromTaskViewId(taskViewIdToSnapTo));
+                            }
+                        }
                         setCurrentPage(pageToSnapTo);
                         dispatchScrollChanged();
                     }
@@ -2658,9 +2928,85 @@
         return anim;
     }
 
-    private void removeTaskInternal(int dismissedTaskId) {
+    /**
+     * Returns all the tasks in the top row, without the focused task
+     */
+    private IntArray getTopRowIdArray() {
+        if (mTopRowIdSet.isEmpty()) {
+            return new IntArray(0);
+        }
+        IntArray topArray = new IntArray(mTopRowIdSet.size());
+        int taskViewCount = getTaskViewCount();
+        for (int i = 0; i < taskViewCount; i++) {
+            int taskViewId = getTaskViewAt(i).getTaskViewId();
+            if (mTopRowIdSet.contains(taskViewId)) {
+                topArray.add(taskViewId);
+            }
+        }
+        return topArray;
+    }
+
+    /**
+     * Returns all the tasks in the bottom row, without the focused task
+     */
+    private IntArray getBottomRowIdArray() {
+        int bottomRowIdArraySize = getTaskViewCount() - mTopRowIdSet.size() - 1;
+        if (bottomRowIdArraySize <= 0) {
+            return new IntArray(0);
+        }
+        IntArray bottomArray = new IntArray(bottomRowIdArraySize);
+        int taskViewCount = getTaskViewCount();
+        for (int i = 0; i < taskViewCount; i++) {
+            int taskViewId = getTaskViewAt(i).getTaskViewId();
+            if (!mTopRowIdSet.contains(taskViewId) && taskViewId != mFocusedTaskViewId) {
+                bottomArray.add(taskViewId);
+            }
+        }
+        return bottomArray;
+    }
+
+    /**
+     * Iterate the grid by columns instead of by TaskView index, starting after the focused task and
+     * up to the last balanced column.
+     *
+     * @return the highest visible TaskView index between both rows
+     */
+    private int getHighestVisibleTaskIndex() {
+        if (mTopRowIdSet.isEmpty()) return Integer.MAX_VALUE; // return earlier
+
+        int lastVisibleIndex = Integer.MAX_VALUE;
+        IntArray topRowIdArray = getTopRowIdArray();
+        IntArray bottomRowIdArray = getBottomRowIdArray();
+        int balancedColumns = Math.min(bottomRowIdArray.size(), topRowIdArray.size());
+
+        for (int i = 0; i < balancedColumns; i++) {
+            TaskView topTask = getTaskViewFromTaskViewId(topRowIdArray.get(i));
+
+            if (isTaskViewVisible(topTask)) {
+                TaskView bottomTask = getTaskViewFromTaskViewId(bottomRowIdArray.get(i));
+                lastVisibleIndex = Math.max(
+                        indexOfChild(topTask) - mTaskViewStartIndex,
+                        indexOfChild(bottomTask) - mTaskViewStartIndex
+                );
+            } else if (lastVisibleIndex < Integer.MAX_VALUE) {
+                break;
+            }
+        }
+
+        return lastVisibleIndex;
+    }
+
+    private void removeTaskInternal(int dismissedTaskViewId) {
+        int[] taskIds = getTaskIdsForTaskViewId(dismissedTaskViewId);
+        int primaryTaskId = taskIds[0];
+        int secondaryTaskId = taskIds[1];
         UI_HELPER_EXECUTOR.getHandler().postDelayed(
-                () -> ActivityManagerWrapper.getInstance().removeTask(dismissedTaskId),
+                () -> {
+                    ActivityManagerWrapper.getInstance().removeTask(primaryTaskId);
+                    if (secondaryTaskId != -1) {
+                        ActivityManagerWrapper.getInstance().removeTask(secondaryTaskId);
+                    }
+                },
                 REMOVE_TASK_WAIT_FOR_APP_STOP_MS);
     }
 
@@ -2973,9 +3319,9 @@
 
     @Override
     protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
-        // If we're going to HOME, avoid unnecessary onLayout that cause TaskViews to re-arrange
-        // during animation to HOME.
-        if (mCurrentGestureEndTarget == GestureState.GestureEndTarget.HOME) {
+        // If we're going to a state without overview panel, avoid unnecessary onLayout that
+        // cause TaskViews to re-arrange during animation to that state.
+        if (!mOverviewStateEnabled && !mFirstLayout) {
             return;
         }
 
@@ -2993,7 +3339,9 @@
         mLastComputedTaskStartPushOutDistance = null;
         mLastComputedTaskEndPushOutDistance = null;
         updatePageOffsets();
-        mLiveTileTaskViewSimulator.setScroll(getScrollOffset());
+        runActionOnRemoteHandles(
+                remoteTargetHandle -> remoteTargetHandle.mTaskViewSimulator
+                        .setScroll(getScrollOffset()));
         setImportantForAccessibility(isModal() ? IMPORTANT_FOR_ACCESSIBILITY_NO
                 : IMPORTANT_FOR_ACCESSIBILITY_AUTO);
     }
@@ -3057,7 +3405,9 @@
             translationProperty.set(child, totalTranslation);
             if (ENABLE_QUICKSTEP_LIVE_TILE.get() && mEnableDrawingLiveTile
                     && i == getRunningTaskIndex()) {
-                mLiveTileTaskViewSimulator.taskPrimaryTranslation.value = totalTranslation;
+                runActionOnRemoteHandles(
+                        remoteTargetHandle -> remoteTargetHandle.mTaskViewSimulator
+                                .taskPrimaryTranslation.value = totalTranslation);
                 redrawLiveTile();
             }
         }
@@ -3106,8 +3456,11 @@
         boolean isStartShift;
         if (midpointIndex > -1) {
             // When there is a midpoint reference task, adjacent tasks have less distance to travel
-            // to reach offscreen. Offset the task position to the task's starting point.
-            int midpointScroll = getScrollForPage(midpointIndex);
+            // to reach offscreen. Offset the task position to the task's starting point, and offset
+            // by current page's scroll diff.
+            int midpointScroll = getScrollForPage(midpointIndex)
+                    + mOrientationHandler.getPrimaryScroll(this) - getScrollForPage(mCurrentPage);
+
             getPersistentChildPosition(midpointIndex, midpointScroll, taskPosition);
             float midpointStart = mOrientationHandler.getStart(taskPosition);
 
@@ -3160,7 +3513,9 @@
             TaskView task = getTaskViewAt(i);
             task.getTaskResistanceTranslationProperty().set(task, translation / getScaleY());
         }
-        mLiveTileTaskViewSimulator.recentsViewSecondaryTranslation.value = translation;
+        runActionOnRemoteHandles(
+                remoteTargetHandle -> remoteTargetHandle.mTaskViewSimulator
+                        .recentsViewSecondaryTranslation.value = translation);
     }
 
     protected void setTaskViewsPrimarySplitTranslation(float translation) {
@@ -3362,8 +3717,6 @@
         resetTaskVisuals();
         mSplitHiddenTaskView.setVisibility(VISIBLE);
         mSplitHiddenTaskView = null;
-        mSecondSplitHiddenTaskView.setVisibility(VISIBLE);
-        mSecondSplitHiddenTaskView = null;
         mSplitHiddenTaskViewIndex = -1;
         if (mFirstFloatingTaskView != null) {
             mActivity.getRootView().removeView(mFirstFloatingTaskView);
@@ -3372,6 +3725,8 @@
         if (mSecondFloatingTaskView != null) {
             mActivity.getRootView().removeView(mSecondFloatingTaskView);
             mSecondFloatingTaskView = null;
+            mSecondSplitHiddenTaskView.setVisibility(VISIBLE);
+            mSecondSplitHiddenTaskView = null;
         }
     }
 
@@ -3467,10 +3822,12 @@
             int runningTaskIndex = recentsView.getRunningTaskIndex();
             if (ENABLE_QUICKSTEP_LIVE_TILE.get() && runningTaskIndex != -1
                     && runningTaskIndex != taskIndex) {
-                anim.play(ObjectAnimator.ofFloat(
-                        recentsView.getLiveTileTaskViewSimulator().taskPrimaryTranslation,
-                        AnimatedFloat.VALUE,
-                        primaryTranslation));
+                for (RemoteTargetHandle remoteHandle : recentsView.getRemoteTargetHandles()) {
+                    anim.play(ObjectAnimator.ofFloat(
+                            remoteHandle.mTaskViewSimulator.taskPrimaryTranslation,
+                            AnimatedFloat.VALUE,
+                            primaryTranslation));
+                }
             }
 
             int otherAdjacentTaskIndex = centerTaskIndex + (centerTaskIndex - taskIndex);
@@ -3550,7 +3907,9 @@
         mPendingAnimation = new PendingAnimation(duration);
         mPendingAnimation.add(anim);
         if (ENABLE_QUICKSTEP_LIVE_TILE.get()) {
-            mLiveTileTaskViewSimulator.addOverviewToAppAnim(mPendingAnimation, interpolator);
+            runActionOnRemoteHandles(
+                    remoteTargetHandle -> remoteTargetHandle.mTaskViewSimulator
+                            .addOverviewToAppAnim(mPendingAnimation, interpolator));
             mPendingAnimation.addOnFrameCallback(this::redrawLiveTile);
         }
         mPendingAnimation.addEndListener(isSuccess -> {
@@ -3641,31 +4000,88 @@
     }
 
     public void redrawLiveTile() {
-        if (mLiveTileParams.getTargetSet() != null) {
-            mLiveTileTaskViewSimulator.apply(mLiveTileParams);
-        }
+        runActionOnRemoteHandles(remoteTargetHandle -> {
+            TransformParams params = remoteTargetHandle.mTransformParams;
+            if (params.getTargetSet() != null) {
+                remoteTargetHandle.mTaskViewSimulator.apply(params);
+            }
+        });
     }
 
-    public TaskViewSimulator getLiveTileTaskViewSimulator() {
-        return mLiveTileTaskViewSimulator;
-    }
-
-    public TransformParams getLiveTileParams() {
-        return mLiveTileParams;
+    public RemoteTargetHandle[] getRemoteTargetHandles() {
+        return mRemoteTargetHandles;
     }
 
     // TODO: To be removed in a follow up CL
     public void setRecentsAnimationTargets(RecentsAnimationController recentsAnimationController,
             RecentsAnimationTargets recentsAnimationTargets) {
         mRecentsAnimationController = recentsAnimationController;
-        if (recentsAnimationTargets != null && recentsAnimationTargets.apps.length > 0) {
-            if (mSyncTransactionApplier != null) {
-                recentsAnimationTargets.addReleaseCheck(mSyncTransactionApplier);
-            }
-            mLiveTileTaskViewSimulator.setPreview(
-                    recentsAnimationTargets.apps[recentsAnimationTargets.apps.length - 1]);
-            mLiveTileParams.setTargetSet(recentsAnimationTargets);
+        if (recentsAnimationTargets == null || recentsAnimationTargets.apps.length == 0) {
+            return;
         }
+
+        if (mSyncTransactionApplier != null) {
+            recentsAnimationTargets.addReleaseCheck(mSyncTransactionApplier);
+        }
+
+        RemoteAnimationTargetCompat dividerTarget =
+                recentsAnimationTargets.getNonAppTargetOfType(TYPE_DOCK_DIVIDER);
+        // TODO Consolidate this shared code with SwipeUpAnimationLogic (or maybe just reuse
+        //  what that class has and pass it into here)
+        mRemoteTargetHandles = new RemoteTargetHandle[dividerTarget == null ? 1 : 2];
+        TaskViewSimulator primaryTvs = createTaskViewSimulator();
+        mRemoteTargetHandles[0] = new RemoteTargetHandle(primaryTvs, new TransformParams());
+        if (dividerTarget == null) {
+            mRemoteTargetHandles[0].mTaskViewSimulator
+                    .setPreview(recentsAnimationTargets.apps[0], null);
+            mRemoteTargetHandles[0].mTransformParams.setTargetSet(recentsAnimationTargets);
+        } else {
+            TaskViewSimulator secondaryTvs = createTaskViewSimulator();
+            secondaryTvs.setOrientationState(mOrientationState);
+            secondaryTvs.recentsViewScale.value = 1;
+
+            mRemoteTargetHandles[1] = new RemoteTargetHandle(secondaryTvs, new TransformParams());
+            RemoteAnimationTargetCompat primaryTaskTarget = recentsAnimationTargets.apps[0];
+            RemoteAnimationTargetCompat secondaryTaskTarget = recentsAnimationTargets.apps[1];
+            mSplitBoundsConfig = new SplitConfigurationOptions.StagedSplitBounds(
+                    primaryTaskTarget.screenSpaceBounds,
+                    secondaryTaskTarget.screenSpaceBounds, dividerTarget.screenSpaceBounds);
+            mRemoteTargetHandles[0].mTaskViewSimulator.setPreview(primaryTaskTarget,
+                    mSplitBoundsConfig);
+            mRemoteTargetHandles[1].mTaskViewSimulator.setPreview(secondaryTaskTarget,
+                    mSplitBoundsConfig);
+            RemoteAnimationTargets rats = new RemoteAnimationTargets(
+                    new RemoteAnimationTargetCompat[]{primaryTaskTarget},
+                    recentsAnimationTargets.wallpapers, recentsAnimationTargets.nonApps,
+                    MODE_CLOSING
+            );
+            RemoteAnimationTargets splitRats = new RemoteAnimationTargets(
+                    new RemoteAnimationTargetCompat[]{secondaryTaskTarget},
+                    recentsAnimationTargets.wallpapers, recentsAnimationTargets.nonApps,
+                    MODE_CLOSING
+            );
+            mRemoteTargetHandles[0].mTransformParams.setTargetSet(rats);
+            mRemoteTargetHandles[1].mTransformParams.setTargetSet(splitRats);
+        }
+    }
+
+    /** Helper to avoid writing some for-loops to iterate over {@link #mRemoteTargetHandles} */
+    private void runActionOnRemoteHandles(Consumer<RemoteTargetHandle> consumer) {
+        if (mRemoteTargetHandles == null) {
+            return;
+        }
+
+        for (RemoteTargetHandle handle : mRemoteTargetHandles) {
+            consumer.accept(handle);
+        }
+    }
+
+    private TaskViewSimulator createTaskViewSimulator() {
+        TaskViewSimulator tvs = new TaskViewSimulator(getContext(), getSizeStrategy());
+        tvs.setOrientationState(mOrientationState);
+        tvs.setDp(mActivity.getDeviceProfile());
+        tvs.recentsViewScale.value = 1;
+        return tvs;
     }
 
     public void finishRecentsAnimation(boolean toRecents, Runnable onFinishComplete) {
@@ -3721,6 +4137,7 @@
         setCurrentTask(-1);
         mRecentsAnimationController = null;
         executeSideTaskLaunchCallback();
+        mRemoteTargetHandles = null;
     }
 
     public void setDisallowScrollToClearAll(boolean disallowScrollToClearAll) {
@@ -3971,14 +4388,42 @@
             }
             return;
         }
-        int runningTaskId = getTaskIdsForRunningTaskView()[0];
-        switchToScreenshot(mRunningTaskViewId == -1 ? null
-                : mRecentsAnimationController.screenshotTask(runningTaskId), onFinishRunnable);
+
+        switchToScreenshotInternal(onFinishRunnable);
+    }
+
+    private void switchToScreenshotInternal(Runnable onFinishRunnable) {
+        TaskView taskView = getRunningTaskView();
+        if (taskView == null) {
+            onFinishRunnable.run();
+            return;
+        }
+
+        taskView.setShowScreenshot(true);
+        for (TaskView.TaskIdAttributeContainer container :
+                taskView.getTaskIdAttributeContainers()) {
+            if (container == null) {
+                continue;
+            }
+
+            ThumbnailData td =
+                    mRecentsAnimationController.screenshotTask(container.getTask().key.id);
+            TaskThumbnailView thumbnailView = container.getThumbnailView();
+            if (td != null) {
+                thumbnailView.setThumbnail(container.getTask(), td);
+            } else {
+                thumbnailView.refresh();
+            }
+        }
+        ViewUtils.postFrameDrawn(taskView, onFinishRunnable);
     }
 
     /**
      * Switch the current running task view to static snapshot mode, using the
      * provided thumbnail data as the snapshot.
+     * TODO(b/195609063) Consolidate this method w/ the one above, except this thumbnail data comes
+     *  from gesture state, which is a larger change of it having to keep track of multiple tasks.
+     *  OR. Maybe it doesn't need to pass in a thumbnail and we can use the exact same flow as above
      */
     public void switchToScreenshot(ThumbnailData thumbnailData, Runnable onFinishRunnable) {
         TaskView taskView = getRunningTaskView();
@@ -4131,7 +4576,8 @@
     }
 
     private void dispatchScrollChanged() {
-        mLiveTileTaskViewSimulator.setScroll(getScrollOffset());
+        runActionOnRemoteHandles(remoteTargetHandle ->
+                remoteTargetHandle.mTaskViewSimulator.setScroll(getScrollOffset()));
         for (int i = mScrollListeners.size() - 1; i >= 0; i--) {
             mScrollListeners.get(i).onScrollChanged();
         }
@@ -4193,4 +4639,8 @@
         // Set locus context is a binder call, don't want it to happen during a transition
         UI_HELPER_EXECUTOR.post(() -> mActivity.setLocusContext(id, Bundle.EMPTY));
     }
+
+    public interface TaskLaunchListener {
+        void onTaskLaunched();
+    }
 }
diff --git a/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java b/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java
index 35e21ad..28044e4 100644
--- a/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java
@@ -211,10 +211,6 @@
             return Insets.NONE;
         }
 
-        if (!TaskView.CLIP_STATUS_AND_NAV_BARS) {
-            return Insets.NONE;
-        }
-
         RectF bitmapRect = new RectF(
                 0, 0,
                 mThumbnailData.thumbnail.getWidth(), mThumbnailData.thumbnail.getHeight());
@@ -228,11 +224,14 @@
         RectF boundsInBitmapSpace = new RectF();
         boundsToBitmapSpace.mapRect(boundsInBitmapSpace, viewRect);
 
-        return Insets.of(
-            Math.round(boundsInBitmapSpace.left),
-            Math.round(boundsInBitmapSpace.top),
-            Math.round(bitmapRect.right - boundsInBitmapSpace.right),
-            Math.round(bitmapRect.bottom - boundsInBitmapSpace.bottom));
+        DeviceProfile dp = mActivity.getDeviceProfile();
+        int leftInset = TaskView.clipLeft(dp) ? Math.round(boundsInBitmapSpace.left) : 0;
+        int topInset = TaskView.clipTop(dp) ? Math.round(boundsInBitmapSpace.top) : 0;
+        int rightInset = TaskView.clipRight(dp) ? Math.round(
+                bitmapRect.right - boundsInBitmapSpace.right) : 0;
+        int bottomInset = TaskView.clipBottom(dp)
+                ? Math.round(bitmapRect.bottom - boundsInBitmapSpace.bottom) : 0;
+        return Insets.of(leftInset, topInset, rightInset, bottomInset);
     }
 
 
@@ -440,8 +439,19 @@
 
             int thumbnailRotation = thumbnailData.rotation;
             int deltaRotate = getRotationDelta(currentRotation, thumbnailRotation);
-            RectF thumbnailClipHint = TaskView.CLIP_STATUS_AND_NAV_BARS
-                    ? new RectF(thumbnailData.insets) : new RectF();
+            RectF thumbnailClipHint = new RectF();
+            if (TaskView.clipLeft(dp)) {
+                thumbnailClipHint.left = thumbnailData.insets.left;
+            }
+            if (TaskView.clipRight(dp)) {
+                thumbnailClipHint.right = thumbnailData.insets.right;
+            }
+            if (TaskView.clipTop(dp)) {
+                thumbnailClipHint.top = thumbnailData.insets.top;
+            }
+            if (TaskView.clipBottom(dp)) {
+                thumbnailClipHint.bottom = thumbnailData.insets.bottom;
+            }
 
             float scale = thumbnailData.scale;
             final float thumbnailScale;
@@ -554,7 +564,7 @@
                         -thumbnailClipHint.left * scale,
                         -thumbnailClipHint.top * scale);
             } else {
-                setThumbnailRotation(deltaRotate, thumbnailClipHint, scale, thumbnailBounds);
+                setThumbnailRotation(deltaRotate, thumbnailClipHint, scale, thumbnailBounds, dp);
             }
 
             final float widthWithInsets;
@@ -599,7 +609,7 @@
         }
 
         private void setThumbnailRotation(int deltaRotate, RectF thumbnailInsets, float scale,
-                Rect thumbnailPosition) {
+                Rect thumbnailPosition, DeviceProfile dp) {
             float newLeftInset = 0;
             float newTopInset = 0;
             float translateX = 0;
@@ -626,7 +636,7 @@
             }
             mClippedInsets.offsetTo(newLeftInset * scale, newTopInset * scale);
             mMatrix.postTranslate(translateX, translateY);
-            if (TaskView.FULL_THUMBNAIL) {
+            if (TaskView.useFullThumbnail(dp)) {
                 mMatrix.postTranslate(-mClippedInsets.left, -mClippedInsets.top);
             }
         }
@@ -634,8 +644,8 @@
         /**
          * Insets to used for clipping the thumbnail (in case it is drawing outside its own space)
          */
-        public RectF getInsetsToDrawInFullscreen() {
-            return TaskView.FULL_THUMBNAIL ? mClippedInsets : EMPTY_RECT_F;
+        public RectF getInsetsToDrawInFullscreen(DeviceProfile dp) {
+            return TaskView.useFullThumbnail(dp) ? mClippedInsets : EMPTY_RECT_F;
         }
     }
 }
diff --git a/quickstep/src/com/android/quickstep/views/TaskView.java b/quickstep/src/com/android/quickstep/views/TaskView.java
index 02c5d84..5986649 100644
--- a/quickstep/src/com/android/quickstep/views/TaskView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskView.java
@@ -91,6 +91,7 @@
 import com.android.launcher3.util.ViewPool.Reusable;
 import com.android.quickstep.RecentsModel;
 import com.android.quickstep.RemoteAnimationTargets;
+import com.android.quickstep.SwipeUpAnimationLogic.RemoteTargetHandle;
 import com.android.quickstep.SystemUiProxy;
 import com.android.quickstep.TaskIconCache;
 import com.android.quickstep.TaskOverlayFactory;
@@ -100,16 +101,20 @@
 import com.android.quickstep.util.CancellableTask;
 import com.android.quickstep.util.RecentsOrientedState;
 import com.android.quickstep.util.TaskCornerRadius;
+import com.android.quickstep.util.TransformParams;
 import com.android.quickstep.views.TaskThumbnailView.PreviewPositionHelper;
 import com.android.systemui.shared.recents.model.Task;
 import com.android.systemui.shared.system.ActivityManagerWrapper;
 import com.android.systemui.shared.system.ActivityOptionsCompat;
 import com.android.systemui.shared.system.QuickStepContract;
+import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
 
 import java.lang.annotation.Retention;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
 import java.util.function.Consumer;
+import java.util.stream.Stream;
 
 /**
  * A task in the Recents view.
@@ -141,15 +146,39 @@
     public static final float MAX_PAGE_SCRIM_ALPHA = 0.4f;
 
     /**
-     * Should the TaskView display clip off the status and navigation bars in recents. When this
-     * is false the overview shows the whole screen scaled down instead.
+     * Should the TaskView display clip off the left inset in RecentsView.
      */
-    public static final boolean CLIP_STATUS_AND_NAV_BARS = false;
+    public static boolean clipLeft(DeviceProfile deviceProfile) {
+        return false;
+    }
+
+    /**
+     * Should the TaskView display clip off the top inset in RecentsView.
+     */
+    public static boolean clipTop(DeviceProfile deviceProfile) {
+        return false;
+    }
+
+    /**
+     * Should the TaskView display clip off the right inset in RecentsView.
+     */
+    public static boolean clipRight(DeviceProfile deviceProfile) {
+        return false;
+    }
+
+    /**
+     * Should the TaskView display clip off the bottom inset in RecentsView.
+     */
+    public static boolean clipBottom(DeviceProfile deviceProfile) {
+        return deviceProfile.isTablet;
+    }
 
     /**
      * Should the TaskView scale down to fit whole thumbnail in fullscreen.
      */
-    public static final boolean FULL_THUMBNAIL = false;
+    public static boolean useFullThumbnail(DeviceProfile deviceProfile) {
+        return deviceProfile.isTablet && !deviceProfile.isTaskbarPresentInApps;
+    }
 
     private static final float EDGE_SCALE_DOWN_FACTOR_CAROUSEL = 0.03f;
     private static final float EDGE_SCALE_DOWN_FACTOR_GRID = 0.00f;
@@ -329,8 +358,8 @@
 
     private final TaskOutlineProvider mOutlineProvider;
 
-    private Task mTask;
-    private TaskThumbnailView mSnapshotView;
+    protected Task mTask;
+    protected TaskThumbnailView mSnapshotView;
     private IconView mIconView;
     private final DigitalWellBeingToast mDigitalWellBeingToast;
     private float mFullscreenProgress;
@@ -338,7 +367,7 @@
     private float mNonGridScale = 1;
     private float mDismissScale = 1;
     private final FullscreenDrawParams mCurrentFullscreenParams;
-    private final StatefulActivity mActivity;
+    protected final StatefulActivity mActivity;
 
     // Various causes of changing primary translation, which we aggregate to setTranslationX/Y().
     private float mDismissTranslationX;
@@ -367,7 +396,12 @@
     private float mStableAlpha = 1;
 
     private int mTaskViewId = -1;
-    private final int[] mTaskIdContainer = new int[]{-1, -1};
+    /**
+     * Index 0 will contain taskID of left/top task, index 1 will contain taskId of bottom/right
+     */
+    protected final int[] mTaskIdContainer = new int[]{-1, -1};
+    protected final TaskIdAttributeContainer[] mTaskIdAttributeContainer =
+            new TaskIdAttributeContainer[2];
 
     private boolean mShowScreenshot;
 
@@ -518,10 +552,15 @@
         cancelPendingLoadTasks();
         mTask = task;
         mTaskIdContainer[0] = mTask.key.id;
+        mTaskIdAttributeContainer[0] = new TaskIdAttributeContainer(task, mSnapshotView);
         mSnapshotView.bind(task);
         setOrientationState(orientedState);
     }
 
+    public TaskIdAttributeContainer[] getTaskIdAttributeContainers() {
+        return mTaskIdAttributeContainer;
+    }
+
     public Task getTask() {
         return mTask;
     }
@@ -563,7 +602,29 @@
 
             mIsClickableAsLiveTile = false;
             RecentsView recentsView = getRecentsView();
-            final RemoteAnimationTargets targets = recentsView.getLiveTileParams().getTargetSet();
+            RemoteAnimationTargets targets;
+            RemoteTargetHandle[] remoteTargetHandles =
+                    recentsView.mRemoteTargetHandles;
+            if (remoteTargetHandles.length == 1) {
+                targets = remoteTargetHandles[0].mTransformParams.getTargetSet();
+            } else {
+                TransformParams topLeftParams = remoteTargetHandles[0].mTransformParams;
+                TransformParams rightBottomParams = remoteTargetHandles[1].mTransformParams;
+                RemoteAnimationTargetCompat[] apps = Stream.concat(
+                        Arrays.stream(topLeftParams.getTargetSet().apps),
+                        Arrays.stream(rightBottomParams.getTargetSet().apps))
+                        .toArray(RemoteAnimationTargetCompat[]::new);
+                RemoteAnimationTargetCompat[] wallpapers = Stream.concat(
+                        Arrays.stream(topLeftParams.getTargetSet().wallpapers),
+                        Arrays.stream(rightBottomParams.getTargetSet().wallpapers))
+                        .toArray(RemoteAnimationTargetCompat[]::new);
+                RemoteAnimationTargetCompat[] nonApps = Stream.concat(
+                        Arrays.stream(topLeftParams.getTargetSet().nonApps),
+                        Arrays.stream(rightBottomParams.getTargetSet().nonApps))
+                        .toArray(RemoteAnimationTargetCompat[]::new);
+                targets = new RemoteAnimationTargets(apps, wallpapers, nonApps,
+                        topLeftParams.getTargetSet().targetMode);
+            }
             if (targets == null) {
                 // If the recents animation is cancelled somehow between the parent if block and
                 // here, try to launch the task as a non live tile task.
@@ -584,6 +645,7 @@
                 }
             });
             anim.start();
+            recentsView.onTaskLaunchedInLiveTileMode();
         } else {
             launchTaskAnimated();
         }
@@ -614,12 +676,14 @@
             ActivityOptionsWrapper opts =  mActivity.getActivityLaunchOptions(this, null);
             if (ActivityManagerWrapper.getInstance()
                     .startActivityFromRecents(mTask.key, opts.options)) {
-                if (ENABLE_QUICKSTEP_LIVE_TILE.get() &&
-                        getRecentsView().getRunningTaskViewId() != -1) {
+                RecentsView recentsView = getRecentsView();
+                if (ENABLE_QUICKSTEP_LIVE_TILE.get() && recentsView.getRunningTaskViewId() != -1) {
+                    recentsView.onTaskLaunchedInLiveTileMode();
+
                     // Return a fresh callback in the live tile case, so that it's not accidentally
                     // triggered by QuickstepTransitionManager.AppLaunchAnimationRunner.
                     RunnableList callbackList = new RunnableList();
-                    getRecentsView().addSideTaskLaunchCallback(callbackList);
+                    recentsView.addSideTaskLaunchCallback(callbackList);
                     return callbackList;
                 }
                 return opts.onEndCallback;
@@ -720,11 +784,11 @@
         }
     }
 
-    private boolean needsUpdate(@TaskDataChanges int dataChange, @TaskDataChanges int flag) {
+    protected boolean needsUpdate(@TaskDataChanges int dataChange, @TaskDataChanges int flag) {
         return (dataChange & flag) == flag;
     }
 
-    private void cancelPendingLoadTasks() {
+    protected void cancelPendingLoadTasks() {
         if (mThumbnailLoadRequest != null) {
             mThumbnailLoadRequest.cancel();
             mThumbnailLoadRequest = null;
@@ -781,8 +845,11 @@
         LayoutParams snapshotParams = (LayoutParams) mSnapshotView.getLayoutParams();
         DeviceProfile deviceProfile = mActivity.getDeviceProfile();
         snapshotParams.topMargin = deviceProfile.overviewTaskThumbnailTopMarginPx;
-        int taskIconMargin = deviceProfile.overviewTaskMarginPx;
+        boolean isGridTask = deviceProfile.overviewShowAsGrid && !isFocusedTask();
         int taskIconHeight = deviceProfile.overviewTaskIconSizePx;
+        int taskMargin = isGridTask ? deviceProfile.overviewTaskMarginGridPx
+                : deviceProfile.overviewTaskMarginPx;
+        int taskIconMargin = snapshotParams.topMargin - taskIconHeight - taskMargin;
         LayoutParams iconParams = (LayoutParams) mIconView.getLayoutParams();
         switch (orientationHandler.getRotation()) {
             case ROTATION_90:
@@ -814,6 +881,9 @@
         iconParams.width = iconParams.height = taskIconHeight;
         mIconView.setLayoutParams(iconParams);
         mIconView.setRotation(orientationHandler.getDegreesRotated());
+        int iconDrawableSize = isGridTask ? deviceProfile.overviewTaskIconDrawableSizeGridPx
+                : deviceProfile.overviewTaskIconDrawableSizePx;
+        mIconView.setDrawableSize(iconDrawableSize, iconDrawableSize);
         snapshotParams.topMargin = deviceProfile.overviewTaskThumbnailTopMarginPx;
         mSnapshotView.setLayoutParams(snapshotParams);
         mSnapshotView.getTaskOverlay().updateOrientationState(orientationState);
@@ -871,6 +941,12 @@
         setIconAndDimTransitionProgress(iconScale, invert);
     }
 
+    protected void resetPersistentViewTransforms() {
+        mNonGridTranslationX = mNonGridTranslationY =
+                mGridTranslationX = mGridTranslationY = mBoxTranslationY = 0f;
+        resetViewTransforms();
+    }
+
     protected void resetViewTransforms() {
         // fullscreenTranslation and accumulatedTranslation should not be reset, as
         // resetViewTransforms is called during Quickswitch scrolling.
@@ -894,9 +970,7 @@
 
     @Override
     public void onRecycle() {
-        mNonGridTranslationX = mNonGridTranslationY =
-                mGridTranslationX = mGridTranslationY = mBoxTranslationY = 0f;
-        resetViewTransforms();
+        resetPersistentViewTransforms();
         // Clear any references to the thumbnail (it will be re-read either from the cache or the
         // system on next bind)
         mSnapshotView.setThumbnail(mTask, null);
@@ -1353,7 +1427,6 @@
         float boxTranslationY;
         int expectedWidth;
         int expectedHeight;
-        int iconDrawableSize;
         DeviceProfile deviceProfile = mActivity.getDeviceProfile();
         if (deviceProfile.overviewShowAsGrid) {
             final int thumbnailPadding = deviceProfile.overviewTaskThumbnailTopMarginPx;
@@ -1369,13 +1442,11 @@
                 // that is associated with the original orientation of the focused task.
                 boxWidth = taskWidth;
                 boxHeight = taskHeight;
-                iconDrawableSize = deviceProfile.overviewTaskIconDrawableSizePx;
             } else {
                 // Otherwise task is in grid, and should use lastComputedGridTaskSize.
                 Rect lastComputedGridTaskSize = getRecentsView().getLastComputedGridTaskSize();
                 boxWidth = lastComputedGridTaskSize.width();
                 boxHeight = lastComputedGridTaskSize.height();
-                iconDrawableSize = deviceProfile.overviewTaskIconDrawableSizeGridPx;
             }
 
             // Bound width/height to the box size.
@@ -1392,7 +1463,6 @@
             boxTranslationY = 0f;
             expectedWidth = ViewGroup.LayoutParams.MATCH_PARENT;
             expectedHeight = ViewGroup.LayoutParams.MATCH_PARENT;
-            iconDrawableSize = deviceProfile.overviewTaskIconDrawableSizePx;
         }
 
         setNonGridScale(nonGridScale);
@@ -1402,7 +1472,6 @@
             params.height = expectedHeight;
             setLayoutParams(params);
         }
-        mIconView.setDrawableSize(iconDrawableSize, iconDrawableSize);
     }
 
     private float getGridTrans(float endTranslation) {
@@ -1482,12 +1551,16 @@
          */
         public void setProgress(float fullscreenProgress, float parentScale, float taskViewScale,
                 int previewWidth, DeviceProfile dp, PreviewPositionHelper pph) {
-            RectF insets = pph.getInsetsToDrawInFullscreen();
+            RectF insets = pph.getInsetsToDrawInFullscreen(dp);
 
             float currentInsetsLeft = insets.left * fullscreenProgress;
             float currentInsetsRight = insets.right * fullscreenProgress;
+            float insetsBottom = insets.bottom;
+            if (dp.isTaskbarPresentInApps) {
+                insetsBottom = Math.max(0, insetsBottom - dp.taskbarSize);
+            }
             mCurrentDrawnInsets.set(currentInsetsLeft, insets.top * fullscreenProgress,
-                    currentInsetsRight, insets.bottom * fullscreenProgress);
+                    currentInsetsRight, insetsBottom * fullscreenProgress);
             float fullscreenCornerRadius = dp.isMultiWindowMode ? 0 : mWindowCornerRadius;
 
             mCurrentDrawnCornerRadius =
@@ -1502,4 +1575,22 @@
         }
 
     }
+
+    public class TaskIdAttributeContainer {
+        private final TaskThumbnailView thumbnailView;
+        private final Task task;
+
+        public TaskIdAttributeContainer(Task task, TaskThumbnailView thumbnailView) {
+            this.task = task;
+            this.thumbnailView = thumbnailView;
+        }
+
+        public TaskThumbnailView getThumbnailView() {
+            return thumbnailView;
+        }
+
+        public Task getTask() {
+            return task;
+        }
+    }
 }
diff --git a/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java b/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java
index e4f5a19..45e7e69 100644
--- a/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java
+++ b/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java
@@ -59,7 +59,6 @@
 import com.android.launcher3.testing.TestProtocol;
 import com.android.launcher3.util.Wait;
 import com.android.launcher3.util.rule.FailureWatcher;
-import com.android.launcher3.util.rule.ScreenRecordRule.ScreenRecord;
 import com.android.quickstep.views.RecentsView;
 
 import org.junit.After;
@@ -215,7 +214,6 @@
     // b/143488140
     //@NavigationModeSwitch
     @Test
-    @ScreenRecord // b/187080582
     public void testOverview() {
         startAppFast(getAppPackageName());
         startAppFast(resolveSystemApp(Intent.CATEGORY_APP_CALCULATOR));
diff --git a/quickstep/tests/src/com/android/quickstep/NavigationModeSwitchRule.java b/quickstep/tests/src/com/android/quickstep/NavigationModeSwitchRule.java
index 67840d1..416c193 100644
--- a/quickstep/tests/src/com/android/quickstep/NavigationModeSwitchRule.java
+++ b/quickstep/tests/src/com/android/quickstep/NavigationModeSwitchRule.java
@@ -30,7 +30,6 @@
 import android.content.pm.PackageManager;
 import android.util.Log;
 
-import androidx.test.uiautomator.By;
 import androidx.test.uiautomator.UiDevice;
 
 import com.android.launcher3.tapl.LauncherInstrumentation;
@@ -49,6 +48,7 @@
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
 import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
 
 /**
  * Test rule that allows executing a test with Quickstep on and then Quickstep off.
@@ -182,17 +182,12 @@
                     };
             targetContext.getMainExecutor().execute(() ->
                     SYS_UI_NAVIGATION_MODE.addModeChangeListener(listener));
-            // b/139137636
-//            latch.await(60, TimeUnit.SECONDS);
+            latch.await(60, TimeUnit.SECONDS);
             targetContext.getMainExecutor().execute(() ->
                     SYS_UI_NAVIGATION_MODE.removeModeChangeListener(listener));
 
-            Wait.atMost(() -> "Navigation mode didn't change to " + expectedMode,
-                    () -> currentSysUiNavigationMode() == expectedMode, WAIT_TIME_MS,
-                    launcher);
-            // b/139137636
-//            assertTrue(launcher, "Navigation mode didn't change to " + expectedMode,
-//                    currentSysUiNavigationMode() == expectedMode, description);
+            assertTrue(launcher, "Navigation mode didn't change to " + expectedMode,
+                    currentSysUiNavigationMode() == expectedMode, description);
 
         }
 
@@ -221,12 +216,7 @@
 
     private static void assertTrue(LauncherInstrumentation launcher, String message,
             boolean condition, Description description) {
-        if (launcher.getDevice().hasObject(By.textStartsWith(""))) {
-            // The condition above is "screen is not empty". We are not treating
-            // "Screen is empty" as an anomaly here. It's an acceptable state when
-            // Launcher just starts under instrumentation.
-            launcher.checkForAnomaly();
-        }
+        launcher.checkForAnomaly(true);
         if (!condition) {
             final AssertionError assertionError = new AssertionError(message);
             if (description != null) {
diff --git a/quickstep/robolectric_tests/src/com/android/quickstep/OrientationTouchTransformerTest.java b/quickstep/tests/src/com/android/quickstep/OrientationTouchTransformerTest.java
similarity index 98%
rename from quickstep/robolectric_tests/src/com/android/quickstep/OrientationTouchTransformerTest.java
rename to quickstep/tests/src/com/android/quickstep/OrientationTouchTransformerTest.java
index 2b1b57c..159a51f 100644
--- a/quickstep/robolectric_tests/src/com/android/quickstep/OrientationTouchTransformerTest.java
+++ b/quickstep/tests/src/com/android/quickstep/OrientationTouchTransformerTest.java
@@ -19,6 +19,8 @@
 
 import static android.view.Display.DEFAULT_DISPLAY;
 
+import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
+
 import static com.android.quickstep.SysUINavigationMode.Mode.NO_BUTTON;
 
 import static org.junit.Assert.assertFalse;
@@ -40,6 +42,9 @@
 import android.view.MotionEvent;
 import android.view.Surface;
 
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
 import com.android.launcher3.ResourceUtils;
 import com.android.launcher3.util.DisplayController;
 
@@ -47,10 +52,9 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
 
-@RunWith(RobolectricTestRunner.class)
+@SmallTest
+@RunWith(AndroidJUnit4.class)
 public class OrientationTouchTransformerTest {
     static class ScreenSize {
         int mHeight;
@@ -293,7 +297,7 @@
     }
 
     private DisplayController.Info createDisplayInfo(ScreenSize screenSize, int rotation) {
-        Context context = RuntimeEnvironment.application;
+        Context context = getApplicationContext();
         Display display = spy(context.getSystemService(DisplayManager.class)
                 .getDisplay(DEFAULT_DISPLAY));
 
diff --git a/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java b/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java
index 164e755..e5e560a 100644
--- a/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java
+++ b/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java
@@ -37,7 +37,6 @@
 import com.android.launcher3.tapl.OverviewActions;
 import com.android.launcher3.tapl.OverviewTask;
 import com.android.launcher3.ui.TaplTestsLauncher3;
-import com.android.launcher3.util.rule.ScreenRecordRule.ScreenRecord;
 import com.android.quickstep.NavigationModeSwitchRule.NavigationModeSwitch;
 import com.android.quickstep.views.RecentsView;
 
@@ -158,7 +157,6 @@
     @Test
     @NavigationModeSwitch
     @PortraitLandscape
-    @ScreenRecord //b/193125090
     public void testOverviewActions() throws Exception {
         // Experimenting for b/165029151:
         final Overview overview = mLauncher.pressHome().switchToOverview();
diff --git a/quickstep/tests/src/com/android/quickstep/ViewInflationDuringSwipeUp.java b/quickstep/tests/src/com/android/quickstep/ViewInflationDuringSwipeUp.java
index f33abb0..0f5a1c8 100644
--- a/quickstep/tests/src/com/android/quickstep/ViewInflationDuringSwipeUp.java
+++ b/quickstep/tests/src/com/android/quickstep/ViewInflationDuringSwipeUp.java
@@ -19,9 +19,9 @@
 import static androidx.test.InstrumentationRegistry.getInstrumentation;
 import static androidx.test.InstrumentationRegistry.getTargetContext;
 
-import static com.android.launcher3.common.WidgetUtils.createWidgetInfo;
 import static com.android.launcher3.testcomponent.TestCommandReceiver.EXTRA_VALUE;
 import static com.android.launcher3.testcomponent.TestCommandReceiver.SET_LIST_VIEW_SERVICE_BINDER;
+import static com.android.launcher3.util.WidgetUtils.createWidgetInfo;
 import static com.android.quickstep.NavigationModeSwitchRule.Mode.ZERO_BUTTON;
 
 import static org.junit.Assert.assertEquals;
diff --git a/res/drawable-v28/widgets_bottom_sheet_background.xml b/res/drawable-v28/widgets_bottom_sheet_background.xml
deleted file mode 100644
index 7fb8681..0000000
--- a/res/drawable-v28/widgets_bottom_sheet_background.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     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.
--->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
-    android:shape="rectangle">
-    <solid android:color="@color/surface" />
-    <corners
-        android:topLeftRadius="?android:attr/dialogCornerRadius"
-        android:topRightRadius="?android:attr/dialogCornerRadius"
-        android:bottomLeftRadius="0dp"
-        android:bottomRightRadius="0dp"
-        />
-</shape>
\ No newline at end of file
diff --git a/res/drawable/widgets_bottom_sheet_background.xml b/res/drawable/bg_widgets_full_sheet.xml
similarity index 65%
rename from res/drawable/widgets_bottom_sheet_background.xml
rename to res/drawable/bg_widgets_full_sheet.xml
index b877546..dfcd354 100644
--- a/res/drawable/widgets_bottom_sheet_background.xml
+++ b/res/drawable/bg_widgets_full_sheet.xml
@@ -1,6 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2021 The Android Open Source Project
+<!-- 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.
@@ -14,13 +13,11 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
+
 <shape xmlns:android="http://schemas.android.com/apk/res/android"
-    android:shape="rectangle">
-    <solid android:color="@color/surface" />
+    android:shape="rectangle" >
+    <solid android:color="?android:attr/colorBackground" />
     <corners
-        android:topLeftRadius="@dimen/default_dialog_corner_radius"
-        android:topRightRadius="@dimen/default_dialog_corner_radius"
-        android:bottomLeftRadius="0dp"
-        android:bottomRightRadius="0dp"
-        />
+        android:topLeftRadius="@dimen/dialogCornerRadius"
+        android:topRightRadius="@dimen/dialogCornerRadius" />
 </shape>
\ No newline at end of file
diff --git a/res/drawable/bg_widgets_picker_handle.xml b/res/drawable/bg_widgets_picker_handle.xml
deleted file mode 100644
index 68681a6..0000000
--- a/res/drawable/bg_widgets_picker_handle.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
-    <item>
-        <shape android:shape="rectangle">
-            <solid android:color="?android:attr/colorBackground" />
-            <padding android:top="16dp"/>
-        </shape>
-    </item>
-    <item android:gravity="center">
-        <shape android:shape="rectangle">
-            <solid android:color="?android:attr/textColorSecondary" />
-            <size android:width="48dp" android:height="2dp" />
-        </shape>
-    </item>
-</layer-list>
\ No newline at end of file
diff --git a/res/drawable/gesture_tutorial_motion_overview_light_mode.xml b/res/drawable/gesture_tutorial_motion_overview_light_mode.xml
deleted file mode 100644
index 75887c9..0000000
--- a/res/drawable/gesture_tutorial_motion_overview_light_mode.xml
+++ /dev/null
@@ -1,1587 +0,0 @@
-<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:aapt="http://schemas.android.com/aapt">
-    <target android:name="_R_G_L_4_G_N_3_T_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="1050"
-                    android:pathData="M 206,446C 206,446 206,395 206,395"
-                    android:propertyName="translateXY"
-                    android:propertyXName="translateX"
-                    android:propertyYName="translateY"
-                    android:startOffset="217">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.5,0 0.5,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_4_G_N_3_T_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="1050"
-                    android:propertyName="scaleX"
-                    android:startOffset="217"
-                    android:valueFrom="1"
-                    android:valueTo="0.6"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.5,0 0.5,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="1050"
-                    android:propertyName="scaleY"
-                    android:startOffset="217"
-                    android:valueFrom="1"
-                    android:valueTo="0.6"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.5,0 0.5,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_4_G_N_3_T_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="3400"
-                    android:valueFrom="1"
-                    android:valueTo="0"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_3_G_L_0_G_L_27_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="2083"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_3_G_L_0_G_L_26_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="2083"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_3_G_L_0_G_L_25_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="2083"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_3_G_L_0_G_L_24_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="2083"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_3_G_L_0_G_L_23_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="2083"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_3_G_L_0_G_L_22_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="2083"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_3_G_L_0_G_L_21_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="2083"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_3_G_L_0_G_L_20_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="2083"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_3_G_L_0_G_L_19_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="2083"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_3_G_L_0_G_L_18_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="2083"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_3_G_L_0_G_L_17_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="2083"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_3_G_L_0_G_L_16_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="2083"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_3_G_L_0_G_L_15_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="2083"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_3_G_L_0_G_L_14_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="2083"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_3_G_L_0_G_L_13_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="2083"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_3_G_L_0_G_L_12_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="2083"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_3_G_L_0_G_L_11_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="2083"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_3_G_L_0_G_L_10_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="2083"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_3_G_L_0_G_L_9_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="2083"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_3_G_L_0_G_L_8_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="2083"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_3_G_L_0_G_L_7_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="2083"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_3_G_L_0_G_L_6_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="2083"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_3_G_L_0_G_L_5_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="2083"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_3_G_L_0_G_L_4_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="2083"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_3_G_L_0_G_L_3_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="2083"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_3_G_L_0_G_L_2_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="2083"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_3_G_L_0_G_L_1_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="2083"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_3_G_L_0_G_L_0_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="2083"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_3_G_L_0_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="2083"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_3_G_N_2_T_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="350"
-                    android:pathData="M 206,395C 206,403.5 206,437.5 206,446"
-                    android:propertyName="translateXY"
-                    android:propertyXName="translateX"
-                    android:propertyYName="translateY"
-                    android:startOffset="2083">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.34,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_3_G_N_2_T_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="350"
-                    android:propertyName="scaleX"
-                    android:startOffset="2083"
-                    android:valueFrom="0.6"
-                    android:valueTo="0.72718"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.34,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="350"
-                    android:propertyName="scaleY"
-                    android:startOffset="2083"
-                    android:valueFrom="0.6"
-                    android:valueTo="0.72718"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.34,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="217"
-                    android:propertyName="scaleX"
-                    android:startOffset="2433"
-                    android:valueFrom="0.72718"
-                    android:valueTo="0.72"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0 0.51,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="217"
-                    android:propertyName="scaleY"
-                    android:startOffset="2433"
-                    android:valueFrom="0.72718"
-                    android:valueTo="0.72"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0 0.51,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_3_G_N_2_T_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="2083"
-                    android:valueFrom="0"
-                    android:valueTo="0.6"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_2_G_D_0_P_0_G_0_T_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="167"
-                    android:propertyName="scaleX"
-                    android:startOffset="2567"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="167"
-                    android:propertyName="scaleY"
-                    android:startOffset="2567"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_2_G_N_2_T_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="350"
-                    android:pathData="M 206,395C 206,403.5 206,437.5 206,446"
-                    android:propertyName="translateXY"
-                    android:propertyXName="translateX"
-                    android:propertyYName="translateY"
-                    android:startOffset="2083">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.34,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_2_G_N_2_T_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="350"
-                    android:propertyName="scaleX"
-                    android:startOffset="2083"
-                    android:valueFrom="0.6"
-                    android:valueTo="0.72718"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.34,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="350"
-                    android:propertyName="scaleY"
-                    android:startOffset="2083"
-                    android:valueFrom="0.6"
-                    android:valueTo="0.72718"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.34,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="217"
-                    android:propertyName="scaleX"
-                    android:startOffset="2433"
-                    android:valueFrom="0.72718"
-                    android:valueTo="0.72"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0 0.51,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="217"
-                    android:propertyName="scaleY"
-                    android:startOffset="2433"
-                    android:valueFrom="0.72718"
-                    android:valueTo="0.72"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0 0.51,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_2_G_N_2_T_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="2567"
-                    android:valueFrom="0"
-                    android:valueTo="0.6"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_1_G">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="250"
-                    android:pathData="M -556.176,-7.307C -556.176,-7.307 -421.176,-7.307 -421.176,-7.307"
-                    android:propertyName="translateXY"
-                    android:propertyXName="translateX"
-                    android:propertyYName="translateY"
-                    android:startOffset="1350">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.272,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="417"
-                    android:pathData="M -421.176,-7.307C -421.176,-7.307 -429.51,-7.307 -429.51,-7.307"
-                    android:propertyName="translateXY"
-                    android:propertyXName="translateX"
-                    android:propertyYName="translateY"
-                    android:startOffset="1600">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_1_G_N_2_T_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="350"
-                    android:pathData="M 206,395C 206,403.5 206,437.5 206,446"
-                    android:propertyName="translateXY"
-                    android:propertyXName="translateX"
-                    android:propertyYName="translateY"
-                    android:startOffset="2083">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.34,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_1_G_N_2_T_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="350"
-                    android:propertyName="scaleX"
-                    android:startOffset="2083"
-                    android:valueFrom="0.6"
-                    android:valueTo="0.72718"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.34,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="350"
-                    android:propertyName="scaleY"
-                    android:startOffset="2083"
-                    android:valueFrom="0.6"
-                    android:valueTo="0.72718"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.34,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="217"
-                    android:propertyName="scaleX"
-                    android:startOffset="2433"
-                    android:valueFrom="0.72718"
-                    android:valueTo="0.72"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0 0.51,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="217"
-                    android:propertyName="scaleY"
-                    android:startOffset="2433"
-                    android:valueFrom="0.72718"
-                    android:valueTo="0.72"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0 0.51,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_1_G_N_2_T_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="0"
-                    android:propertyName="scaleY"
-                    android:startOffset="1350"
-                    android:valueFrom="0"
-                    android:valueTo="0.6"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_0_G_D_0_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="217"
-                    android:propertyName="fillAlpha"
-                    android:startOffset="0"
-                    android:valueFrom="0"
-                    android:valueTo="0.75"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.833,0.833 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="1833"
-                    android:propertyName="fillAlpha"
-                    android:startOffset="217"
-                    android:valueFrom="0.75"
-                    android:valueTo="0.75"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.167,0 0.667,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="167"
-                    android:propertyName="fillAlpha"
-                    android:startOffset="2050"
-                    android:valueFrom="0.75"
-                    android:valueTo="0"
-                    android:valueType="floatType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="_R_G_L_0_G_D_0_P_0">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="217"
-                    android:propertyName="pathData"
-                    android:startOffset="0"
-                    android:valueFrom="M0 406 C21.54,406 39,423.46 39,445 C39,466.54 21.54,484 0,484 C-21.54,484 -39,466.54 -39,445 C-39,423.46 -21.54,406 0,406c "
-                    android:valueTo="M0 395 C27.61,395 50,417.39 50,445 C50,472.61 27.61,495 0,495 C-27.61,495 -50,472.61 -50,445 C-50,417.39 -27.61,395 0,395c "
-                    android:valueType="pathType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="1050"
-                    android:propertyName="pathData"
-                    android:startOffset="217"
-                    android:valueFrom="M0 395 C27.61,395 50,417.39 50,445 C50,472.61 27.61,495 0,495 C-27.61,495 -50,472.61 -50,445 C-50,417.39 -27.61,395 0,395c "
-                    android:valueTo="M0 166 C27.61,166 50,188.39 50,216 C50,243.61 27.61,266 0,266 C-27.61,266 -50,243.61 -50,216 C-50,188.39 -27.61,166 0,166c "
-                    android:valueType="pathType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.5,0 0.5,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="783"
-                    android:propertyName="pathData"
-                    android:startOffset="1267"
-                    android:valueFrom="M0 166 C27.61,166 50,188.39 50,216 C50,243.61 27.61,266 0,266 C-27.61,266 -50,243.61 -50,216 C-50,188.39 -27.61,166 0,166c "
-                    android:valueTo="M0 166 C27.61,166 50,188.39 50,216 C50,243.61 27.61,266 0,266 C-27.61,266 -50,243.61 -50,216 C-50,188.39 -27.61,166 0,166c "
-                    android:valueType="pathType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-                <objectAnimator
-                    android:duration="167"
-                    android:propertyName="pathData"
-                    android:startOffset="2050"
-                    android:valueFrom="M0 166 C27.61,166 50,188.39 50,216 C50,243.61 27.61,266 0,266 C-27.61,266 -50,243.61 -50,216 C-50,188.39 -27.61,166 0,166c "
-                    android:valueTo="M0 180 C19.88,180 36,196.12 36,216 C36,235.88 19.88,252 0,252 C-19.88,252 -36,235.88 -36,216 C-36,196.12 -19.88,180 0,180c "
-                    android:valueType="pathType">
-                    <aapt:attr name="android:interpolator">
-                        <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
-                    </aapt:attr>
-                </objectAnimator>
-            </set>
-        </aapt:attr>
-    </target>
-    <target android:name="time_group">
-        <aapt:attr name="android:animation">
-            <set android:ordering="together">
-                <objectAnimator
-                    android:duration="2750"
-                    android:propertyName="translateX"
-                    android:startOffset="0"
-                    android:valueFrom="0"
-                    android:valueTo="1"
-                    android:valueType="floatType" />
-            </set>
-        </aapt:attr>
-    </target>
-    <aapt:attr name="android:drawable">
-        <vector
-            android:width="412dp"
-            android:height="892dp"
-            android:viewportHeight="892"
-            android:viewportWidth="412">
-            <group android:name="_R_G">
-                <group
-                    android:name="_R_G_L_5_G"
-                    android:translateX="206"
-                    android:translateY="446">
-                    <path
-                        android:name="_R_G_L_5_G_D_0_P_0"
-                        android:fillAlpha="1"
-                        android:fillColor="@color/fake_wallpaper_color_light_mode"
-                        android:fillType="nonZero"
-                        android:pathData=" M206 -446 C206,-446 206,446 206,446 C206,446 -206,446 -206,446 C-206,446 -206,-446 -206,-446 C-206,-446 206,-446 206,-446c " />
-                </group>
-                <group
-                    android:name="_R_G_L_4_G_N_3_T_0"
-                    android:scaleX="1"
-                    android:scaleY="1"
-                    android:translateX="206"
-                    android:translateY="446">
-                    <group
-                        android:name="_R_G_L_4_G"
-                        android:translateX="-206"
-                        android:translateY="-446">
-                        <group android:name="_R_G_L_4_G_L_0_G">
-                            <group
-                                android:name="_R_G_L_4_G_L_0_G_L_27_G"
-                                android:translateX="206"
-                                android:translateY="422.5">
-                                <path
-                                    android:name="_R_G_L_4_G_L_0_G_L_27_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#dadce0"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M206 -395.5 C206,-395.5 206,395.5 206,395.5 C206,395.5 -206,395.5 -206,395.5 C-206,395.5 -206,-395.5 -206,-395.5 C-206,-395.5 206,-395.5 206,-395.5c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_4_G_L_0_G_L_26_G"
-                                android:translateX="206"
-                                android:translateY="496.5">
-                                <path
-                                    android:name="_R_G_L_4_G_L_0_G_L_26_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#dadce0"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M206 -377.5 C206,-377.5 206,377.5 206,377.5 C206,387.43 197.93,395.5 188,395.5 C188,395.5 -188,395.5 -188,395.5 C-197.93,395.5 -206,387.43 -206,377.5 C-206,377.5 -206,-377.5 -206,-377.5 C-206,-387.43 -197.93,-395.5 -188,-395.5 C-188,-395.5 188,-395.5 188,-395.5 C197.93,-395.5 206,-387.43 206,-377.5c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_4_G_L_0_G_L_25_G"
-                                android:translateX="206"
-                                android:translateY="50.5">
-                                <path
-                                    android:name="_R_G_L_4_G_L_0_G_L_25_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#e8eaed"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M206 -23.5 C206,-23.5 206,50.5 206,50.5 C206,50.5 -206,50.5 -206,50.5 C-206,50.5 -206,-23.5 -206,-23.5 C-206,-23.5 206,-23.5 206,-23.5c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_4_G_L_0_G_L_24_G"
-                                android:translateX="206"
-                                android:translateY="50.5">
-                                <path
-                                    android:name="_R_G_L_4_G_L_0_G_L_24_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#e8eaed"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M206 -32.5 C206,-32.5 206,32.5 206,32.5 C206,42.43 197.93,50.5 188,50.5 C188,50.5 -188,50.5 -188,50.5 C-197.93,50.5 -206,42.43 -206,32.5 C-206,32.5 -206,-32.5 -206,-32.5 C-206,-42.43 -197.93,-50.5 -188,-50.5 C-188,-50.5 188,-50.5 188,-50.5 C197.93,-50.5 206,-42.43 206,-32.5c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_4_G_L_0_G_L_23_G"
-                                android:translateX="54"
-                                android:translateY="157">
-                                <path
-                                    android:name="_R_G_L_4_G_L_0_G_L_23_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#9aa0a6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_4_G_L_0_G_L_22_G"
-                                android:translateX="54"
-                                android:translateY="157">
-                                <path
-                                    android:name="_R_G_L_4_G_L_0_G_L_22_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#9aa0a6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_4_G_L_0_G_L_21_G"
-                                android:translateX="148.5"
-                                android:translateY="148">
-                                <path
-                                    android:name="_R_G_L_4_G_L_0_G_L_21_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#bdc1c6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M46.5 -5 C46.5,-5 46.5,5 46.5,5 C46.5,7.21 44.71,9 42.5,9 C42.5,9 -42.5,9 -42.5,9 C-44.71,9 -46.5,7.21 -46.5,5 C-46.5,5 -46.5,-5 -46.5,-5 C-46.5,-7.21 -44.71,-9 -42.5,-9 C-42.5,-9 42.5,-9 42.5,-9 C44.71,-9 46.5,-7.21 46.5,-5c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_4_G_L_0_G_L_20_G"
-                                android:translateX="186"
-                                android:translateY="169">
-                                <path
-                                    android:name="_R_G_L_4_G_L_0_G_L_20_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#bdc1c6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M84 -4 C84,-4 84,4 84,4 C84,6.21 82.21,8 80,8 C80,8 -80,8 -80,8 C-82.21,8 -84,6.21 -84,4 C-84,4 -84,-4 -84,-4 C-84,-6.21 -82.21,-8 -80,-8 C-80,-8 80,-8 80,-8 C82.21,-8 84,-6.21 84,-4c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_4_G_L_0_G_L_19_G"
-                                android:translateX="54"
-                                android:translateY="245">
-                                <path
-                                    android:name="_R_G_L_4_G_L_0_G_L_19_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#9aa0a6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_4_G_L_0_G_L_18_G"
-                                android:translateX="162"
-                                android:translateY="236">
-                                <path
-                                    android:name="_R_G_L_4_G_L_0_G_L_18_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#bdc1c6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M60 -5 C60,-5 60,5 60,5 C60,7.21 58.21,9 56,9 C56,9 -56,9 -56,9 C-58.21,9 -60,7.21 -60,5 C-60,5 -60,-5 -60,-5 C-60,-7.21 -58.21,-9 -56,-9 C-56,-9 56,-9 56,-9 C58.21,-9 60,-7.21 60,-5c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_4_G_L_0_G_L_17_G"
-                                android:translateX="171.5"
-                                android:translateY="257">
-                                <path
-                                    android:name="_R_G_L_4_G_L_0_G_L_17_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#bdc1c6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M69.5 -4 C69.5,-4 69.5,4 69.5,4 C69.5,6.21 67.71,8 65.5,8 C65.5,8 -65.5,8 -65.5,8 C-67.71,8 -69.5,6.21 -69.5,4 C-69.5,4 -69.5,-4 -69.5,-4 C-69.5,-6.21 -67.71,-8 -65.5,-8 C-65.5,-8 65.5,-8 65.5,-8 C67.71,-8 69.5,-6.21 69.5,-4c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_4_G_L_0_G_L_16_G"
-                                android:translateX="54"
-                                android:translateY="333">
-                                <path
-                                    android:name="_R_G_L_4_G_L_0_G_L_16_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#9aa0a6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_4_G_L_0_G_L_15_G"
-                                android:translateX="158"
-                                android:translateY="324">
-                                <path
-                                    android:name="_R_G_L_4_G_L_0_G_L_15_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#bdc1c6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M56 -5 C56,-5 56,5 56,5 C56,7.21 54.21,9 52,9 C52,9 -52,9 -52,9 C-54.21,9 -56,7.21 -56,5 C-56,5 -56,-5 -56,-5 C-56,-7.21 -54.21,-9 -52,-9 C-52,-9 52,-9 52,-9 C54.21,-9 56,-7.21 56,-5c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_4_G_L_0_G_L_14_G"
-                                android:translateX="217.5"
-                                android:translateY="345">
-                                <path
-                                    android:name="_R_G_L_4_G_L_0_G_L_14_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#bdc1c6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M115.5 -4 C115.5,-4 115.5,4 115.5,4 C115.5,6.21 113.71,8 111.5,8 C111.5,8 -111.5,8 -111.5,8 C-113.71,8 -115.5,6.21 -115.5,4 C-115.5,4 -115.5,-4 -115.5,-4 C-115.5,-6.21 -113.71,-8 -111.5,-8 C-111.5,-8 111.5,-8 111.5,-8 C113.71,-8 115.5,-6.21 115.5,-4c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_4_G_L_0_G_L_13_G"
-                                android:translateX="54"
-                                android:translateY="421">
-                                <path
-                                    android:name="_R_G_L_4_G_L_0_G_L_13_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#9aa0a6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_4_G_L_0_G_L_12_G"
-                                android:translateX="170"
-                                android:translateY="412">
-                                <path
-                                    android:name="_R_G_L_4_G_L_0_G_L_12_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#bdc1c6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M68 -5 C68,-5 68,5 68,5 C68,7.21 66.21,9 64,9 C64,9 -64,9 -64,9 C-66.21,9 -68,7.21 -68,5 C-68,5 -68,-5 -68,-5 C-68,-7.21 -66.21,-9 -64,-9 C-64,-9 64,-9 64,-9 C66.21,-9 68,-7.21 68,-5c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_4_G_L_0_G_L_11_G"
-                                android:translateX="198.5"
-                                android:translateY="433">
-                                <path
-                                    android:name="_R_G_L_4_G_L_0_G_L_11_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#bdc1c6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M96.5 -4 C96.5,-4 96.5,4 96.5,4 C96.5,6.21 94.71,8 92.5,8 C92.5,8 -92.5,8 -92.5,8 C-94.71,8 -96.5,6.21 -96.5,4 C-96.5,4 -96.5,-4 -96.5,-4 C-96.5,-6.21 -94.71,-8 -92.5,-8 C-92.5,-8 92.5,-8 92.5,-8 C94.71,-8 96.5,-6.21 96.5,-4c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_4_G_L_0_G_L_10_G"
-                                android:translateX="54"
-                                android:translateY="509">
-                                <path
-                                    android:name="_R_G_L_4_G_L_0_G_L_10_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#9aa0a6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_4_G_L_0_G_L_9_G"
-                                android:translateX="135"
-                                android:translateY="500">
-                                <path
-                                    android:name="_R_G_L_4_G_L_0_G_L_9_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#bdc1c6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M33 -5 C33,-5 33,5 33,5 C33,7.21 31.21,9 29,9 C29,9 -29,9 -29,9 C-31.21,9 -33,7.21 -33,5 C-33,5 -33,-5 -33,-5 C-33,-7.21 -31.21,-9 -29,-9 C-29,-9 29,-9 29,-9 C31.21,-9 33,-7.21 33,-5c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_4_G_L_0_G_L_8_G"
-                                android:translateX="185.5"
-                                android:translateY="521">
-                                <path
-                                    android:name="_R_G_L_4_G_L_0_G_L_8_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#bdc1c6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M83.5 -4 C83.5,-4 83.5,4 83.5,4 C83.5,6.21 81.71,8 79.5,8 C79.5,8 -79.5,8 -79.5,8 C-81.71,8 -83.5,6.21 -83.5,4 C-83.5,4 -83.5,-4 -83.5,-4 C-83.5,-6.21 -81.71,-8 -79.5,-8 C-79.5,-8 79.5,-8 79.5,-8 C81.71,-8 83.5,-6.21 83.5,-4c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_4_G_L_0_G_L_7_G"
-                                android:translateX="54"
-                                android:translateY="597">
-                                <path
-                                    android:name="_R_G_L_4_G_L_0_G_L_7_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#9aa0a6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_4_G_L_0_G_L_6_G"
-                                android:translateX="168.5"
-                                android:translateY="588">
-                                <path
-                                    android:name="_R_G_L_4_G_L_0_G_L_6_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#bdc1c6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M66.5 -5 C66.5,-5 66.5,5 66.5,5 C66.5,7.21 64.71,9 62.5,9 C62.5,9 -62.5,9 -62.5,9 C-64.71,9 -66.5,7.21 -66.5,5 C-66.5,5 -66.5,-5 -66.5,-5 C-66.5,-7.21 -64.71,-9 -62.5,-9 C-62.5,-9 62.5,-9 62.5,-9 C64.71,-9 66.5,-7.21 66.5,-5c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_4_G_L_0_G_L_5_G"
-                                android:translateX="198.5"
-                                android:translateY="609">
-                                <path
-                                    android:name="_R_G_L_4_G_L_0_G_L_5_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#bdc1c6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M96.5 -4 C96.5,-4 96.5,4 96.5,4 C96.5,6.21 94.71,8 92.5,8 C92.5,8 -92.5,8 -92.5,8 C-94.71,8 -96.5,6.21 -96.5,4 C-96.5,4 -96.5,-4 -96.5,-4 C-96.5,-6.21 -94.71,-8 -92.5,-8 C-92.5,-8 92.5,-8 92.5,-8 C94.71,-8 96.5,-6.21 96.5,-4c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_4_G_L_0_G_L_4_G"
-                                android:translateX="54"
-                                android:translateY="685">
-                                <path
-                                    android:name="_R_G_L_4_G_L_0_G_L_4_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#9aa0a6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_4_G_L_0_G_L_3_G"
-                                android:translateX="162.5"
-                                android:translateY="676">
-                                <path
-                                    android:name="_R_G_L_4_G_L_0_G_L_3_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#bdc1c6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M60.5 -5 C60.5,-5 60.5,5 60.5,5 C60.5,7.21 58.71,9 56.5,9 C56.5,9 -56.5,9 -56.5,9 C-58.71,9 -60.5,7.21 -60.5,5 C-60.5,5 -60.5,-5 -60.5,-5 C-60.5,-7.21 -58.71,-9 -56.5,-9 C-56.5,-9 56.5,-9 56.5,-9 C58.71,-9 60.5,-7.21 60.5,-5c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_4_G_L_0_G_L_2_G"
-                                android:translateX="174"
-                                android:translateY="697">
-                                <path
-                                    android:name="_R_G_L_4_G_L_0_G_L_2_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#bdc1c6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M72 -4 C72,-4 72,4 72,4 C72,6.21 70.21,8 68,8 C68,8 -68,8 -68,8 C-70.21,8 -72,6.21 -72,4 C-72,4 -72,-4 -72,-4 C-72,-6.21 -70.21,-8 -68,-8 C-68,-8 68,-8 68,-8 C70.21,-8 72,-6.21 72,-4c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_4_G_L_0_G_L_1_G"
-                                android:translateX="313.5"
-                                android:translateY="798">
-                                <path
-                                    android:name="_R_G_L_4_G_L_0_G_L_1_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#bdc1c6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M74.5 0 C74.5,0 74.5,0 74.5,0 C74.5,15.45 61.95,28 46.5,28 C46.5,28 -46.5,28 -46.5,28 C-61.95,28 -74.5,15.45 -74.5,0 C-74.5,0 -74.5,0 -74.5,0 C-74.5,-15.45 -61.95,-28 -46.5,-28 C-46.5,-28 46.5,-28 46.5,-28 C61.95,-28 74.5,-15.45 74.5,0c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_4_G_L_0_G_L_0_G"
-                                android:translateX="205.5"
-                                android:translateY="61">
-                                <path
-                                    android:name="_R_G_L_4_G_L_0_G_L_0_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#f8f9fa"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M171.5 -14 C171.5,-14 171.5,14 171.5,14 C171.5,16.21 169.71,18 167.5,18 C167.5,18 -167.5,18 -167.5,18 C-169.71,18 -171.5,16.21 -171.5,14 C-171.5,14 -171.5,-14 -171.5,-14 C-171.5,-16.21 -169.71,-18 -167.5,-18 C-167.5,-18 167.5,-18 167.5,-18 C169.71,-18 171.5,-16.21 171.5,-14c " />
-                            </group>
-                        </group>
-                    </group>
-                </group>
-                <group
-                    android:name="_R_G_L_3_G_N_2_T_0"
-                    android:scaleX="0.6"
-                    android:scaleY="0"
-                    android:translateX="206"
-                    android:translateY="395">
-                    <group
-                        android:name="_R_G_L_3_G"
-                        android:translateX="-206"
-                        android:translateY="-446">
-                        <group
-                            android:name="_R_G_L_3_G_L_0_G"
-                            android:scaleY="0">
-                            <group
-                                android:name="_R_G_L_3_G_L_0_G_L_27_G"
-                                android:scaleY="0"
-                                android:translateX="206"
-                                android:translateY="422.5">
-                                <path
-                                    android:name="_R_G_L_3_G_L_0_G_L_27_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#dadce0"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M206 -395.5 C206,-395.5 206,395.5 206,395.5 C206,395.5 -206,395.5 -206,395.5 C-206,395.5 -206,-395.5 -206,-395.5 C-206,-395.5 206,-395.5 206,-395.5c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_3_G_L_0_G_L_26_G"
-                                android:scaleY="0"
-                                android:translateX="206"
-                                android:translateY="496.5">
-                                <path
-                                    android:name="_R_G_L_3_G_L_0_G_L_26_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#dadce0"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M206 -377.5 C206,-377.5 206,377.5 206,377.5 C206,387.43 197.93,395.5 188,395.5 C188,395.5 -188,395.5 -188,395.5 C-197.93,395.5 -206,387.43 -206,377.5 C-206,377.5 -206,-377.5 -206,-377.5 C-206,-387.43 -197.93,-395.5 -188,-395.5 C-188,-395.5 188,-395.5 188,-395.5 C197.93,-395.5 206,-387.43 206,-377.5c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_3_G_L_0_G_L_25_G"
-                                android:scaleY="0"
-                                android:translateX="206"
-                                android:translateY="50.5">
-                                <path
-                                    android:name="_R_G_L_3_G_L_0_G_L_25_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#e8eaed"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M206 -23.5 C206,-23.5 206,50.5 206,50.5 C206,50.5 -206,50.5 -206,50.5 C-206,50.5 -206,-23.5 -206,-23.5 C-206,-23.5 206,-23.5 206,-23.5c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_3_G_L_0_G_L_24_G"
-                                android:scaleY="0"
-                                android:translateX="206"
-                                android:translateY="50.5">
-                                <path
-                                    android:name="_R_G_L_3_G_L_0_G_L_24_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#e8eaed"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M206 -32.5 C206,-32.5 206,32.5 206,32.5 C206,42.43 197.93,50.5 188,50.5 C188,50.5 -188,50.5 -188,50.5 C-197.93,50.5 -206,42.43 -206,32.5 C-206,32.5 -206,-32.5 -206,-32.5 C-206,-42.43 -197.93,-50.5 -188,-50.5 C-188,-50.5 188,-50.5 188,-50.5 C197.93,-50.5 206,-42.43 206,-32.5c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_3_G_L_0_G_L_23_G"
-                                android:scaleY="0"
-                                android:translateX="54"
-                                android:translateY="157">
-                                <path
-                                    android:name="_R_G_L_3_G_L_0_G_L_23_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#9aa0a6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_3_G_L_0_G_L_22_G"
-                                android:scaleY="0"
-                                android:translateX="54"
-                                android:translateY="157">
-                                <path
-                                    android:name="_R_G_L_3_G_L_0_G_L_22_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#9aa0a6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_3_G_L_0_G_L_21_G"
-                                android:scaleY="0"
-                                android:translateX="148.5"
-                                android:translateY="148">
-                                <path
-                                    android:name="_R_G_L_3_G_L_0_G_L_21_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#bdc1c6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M46.5 -5 C46.5,-5 46.5,5 46.5,5 C46.5,7.21 44.71,9 42.5,9 C42.5,9 -42.5,9 -42.5,9 C-44.71,9 -46.5,7.21 -46.5,5 C-46.5,5 -46.5,-5 -46.5,-5 C-46.5,-7.21 -44.71,-9 -42.5,-9 C-42.5,-9 42.5,-9 42.5,-9 C44.71,-9 46.5,-7.21 46.5,-5c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_3_G_L_0_G_L_20_G"
-                                android:scaleY="0"
-                                android:translateX="186"
-                                android:translateY="169">
-                                <path
-                                    android:name="_R_G_L_3_G_L_0_G_L_20_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#bdc1c6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M84 -4 C84,-4 84,4 84,4 C84,6.21 82.21,8 80,8 C80,8 -80,8 -80,8 C-82.21,8 -84,6.21 -84,4 C-84,4 -84,-4 -84,-4 C-84,-6.21 -82.21,-8 -80,-8 C-80,-8 80,-8 80,-8 C82.21,-8 84,-6.21 84,-4c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_3_G_L_0_G_L_19_G"
-                                android:scaleY="0"
-                                android:translateX="54"
-                                android:translateY="245">
-                                <path
-                                    android:name="_R_G_L_3_G_L_0_G_L_19_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#9aa0a6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_3_G_L_0_G_L_18_G"
-                                android:scaleY="0"
-                                android:translateX="162"
-                                android:translateY="236">
-                                <path
-                                    android:name="_R_G_L_3_G_L_0_G_L_18_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#bdc1c6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M60 -5 C60,-5 60,5 60,5 C60,7.21 58.21,9 56,9 C56,9 -56,9 -56,9 C-58.21,9 -60,7.21 -60,5 C-60,5 -60,-5 -60,-5 C-60,-7.21 -58.21,-9 -56,-9 C-56,-9 56,-9 56,-9 C58.21,-9 60,-7.21 60,-5c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_3_G_L_0_G_L_17_G"
-                                android:scaleY="0"
-                                android:translateX="171.5"
-                                android:translateY="257">
-                                <path
-                                    android:name="_R_G_L_3_G_L_0_G_L_17_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#bdc1c6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M69.5 -4 C69.5,-4 69.5,4 69.5,4 C69.5,6.21 67.71,8 65.5,8 C65.5,8 -65.5,8 -65.5,8 C-67.71,8 -69.5,6.21 -69.5,4 C-69.5,4 -69.5,-4 -69.5,-4 C-69.5,-6.21 -67.71,-8 -65.5,-8 C-65.5,-8 65.5,-8 65.5,-8 C67.71,-8 69.5,-6.21 69.5,-4c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_3_G_L_0_G_L_16_G"
-                                android:scaleY="0"
-                                android:translateX="54"
-                                android:translateY="333">
-                                <path
-                                    android:name="_R_G_L_3_G_L_0_G_L_16_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#9aa0a6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_3_G_L_0_G_L_15_G"
-                                android:scaleY="0"
-                                android:translateX="158"
-                                android:translateY="324">
-                                <path
-                                    android:name="_R_G_L_3_G_L_0_G_L_15_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#bdc1c6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M56 -5 C56,-5 56,5 56,5 C56,7.21 54.21,9 52,9 C52,9 -52,9 -52,9 C-54.21,9 -56,7.21 -56,5 C-56,5 -56,-5 -56,-5 C-56,-7.21 -54.21,-9 -52,-9 C-52,-9 52,-9 52,-9 C54.21,-9 56,-7.21 56,-5c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_3_G_L_0_G_L_14_G"
-                                android:scaleY="0"
-                                android:translateX="217.5"
-                                android:translateY="345">
-                                <path
-                                    android:name="_R_G_L_3_G_L_0_G_L_14_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#bdc1c6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M115.5 -4 C115.5,-4 115.5,4 115.5,4 C115.5,6.21 113.71,8 111.5,8 C111.5,8 -111.5,8 -111.5,8 C-113.71,8 -115.5,6.21 -115.5,4 C-115.5,4 -115.5,-4 -115.5,-4 C-115.5,-6.21 -113.71,-8 -111.5,-8 C-111.5,-8 111.5,-8 111.5,-8 C113.71,-8 115.5,-6.21 115.5,-4c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_3_G_L_0_G_L_13_G"
-                                android:scaleY="0"
-                                android:translateX="54"
-                                android:translateY="421">
-                                <path
-                                    android:name="_R_G_L_3_G_L_0_G_L_13_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#9aa0a6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_3_G_L_0_G_L_12_G"
-                                android:scaleY="0"
-                                android:translateX="170"
-                                android:translateY="412">
-                                <path
-                                    android:name="_R_G_L_3_G_L_0_G_L_12_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#bdc1c6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M68 -5 C68,-5 68,5 68,5 C68,7.21 66.21,9 64,9 C64,9 -64,9 -64,9 C-66.21,9 -68,7.21 -68,5 C-68,5 -68,-5 -68,-5 C-68,-7.21 -66.21,-9 -64,-9 C-64,-9 64,-9 64,-9 C66.21,-9 68,-7.21 68,-5c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_3_G_L_0_G_L_11_G"
-                                android:scaleY="0"
-                                android:translateX="198.5"
-                                android:translateY="433">
-                                <path
-                                    android:name="_R_G_L_3_G_L_0_G_L_11_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#bdc1c6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M96.5 -4 C96.5,-4 96.5,4 96.5,4 C96.5,6.21 94.71,8 92.5,8 C92.5,8 -92.5,8 -92.5,8 C-94.71,8 -96.5,6.21 -96.5,4 C-96.5,4 -96.5,-4 -96.5,-4 C-96.5,-6.21 -94.71,-8 -92.5,-8 C-92.5,-8 92.5,-8 92.5,-8 C94.71,-8 96.5,-6.21 96.5,-4c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_3_G_L_0_G_L_10_G"
-                                android:scaleY="0"
-                                android:translateX="54"
-                                android:translateY="509">
-                                <path
-                                    android:name="_R_G_L_3_G_L_0_G_L_10_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#9aa0a6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_3_G_L_0_G_L_9_G"
-                                android:scaleY="0"
-                                android:translateX="135"
-                                android:translateY="500">
-                                <path
-                                    android:name="_R_G_L_3_G_L_0_G_L_9_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#bdc1c6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M33 -5 C33,-5 33,5 33,5 C33,7.21 31.21,9 29,9 C29,9 -29,9 -29,9 C-31.21,9 -33,7.21 -33,5 C-33,5 -33,-5 -33,-5 C-33,-7.21 -31.21,-9 -29,-9 C-29,-9 29,-9 29,-9 C31.21,-9 33,-7.21 33,-5c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_3_G_L_0_G_L_8_G"
-                                android:scaleY="0"
-                                android:translateX="185.5"
-                                android:translateY="521">
-                                <path
-                                    android:name="_R_G_L_3_G_L_0_G_L_8_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#bdc1c6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M83.5 -4 C83.5,-4 83.5,4 83.5,4 C83.5,6.21 81.71,8 79.5,8 C79.5,8 -79.5,8 -79.5,8 C-81.71,8 -83.5,6.21 -83.5,4 C-83.5,4 -83.5,-4 -83.5,-4 C-83.5,-6.21 -81.71,-8 -79.5,-8 C-79.5,-8 79.5,-8 79.5,-8 C81.71,-8 83.5,-6.21 83.5,-4c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_3_G_L_0_G_L_7_G"
-                                android:scaleY="0"
-                                android:translateX="54"
-                                android:translateY="597">
-                                <path
-                                    android:name="_R_G_L_3_G_L_0_G_L_7_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#9aa0a6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_3_G_L_0_G_L_6_G"
-                                android:scaleY="0"
-                                android:translateX="168.5"
-                                android:translateY="588">
-                                <path
-                                    android:name="_R_G_L_3_G_L_0_G_L_6_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#bdc1c6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M66.5 -5 C66.5,-5 66.5,5 66.5,5 C66.5,7.21 64.71,9 62.5,9 C62.5,9 -62.5,9 -62.5,9 C-64.71,9 -66.5,7.21 -66.5,5 C-66.5,5 -66.5,-5 -66.5,-5 C-66.5,-7.21 -64.71,-9 -62.5,-9 C-62.5,-9 62.5,-9 62.5,-9 C64.71,-9 66.5,-7.21 66.5,-5c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_3_G_L_0_G_L_5_G"
-                                android:scaleY="0"
-                                android:translateX="198.5"
-                                android:translateY="609">
-                                <path
-                                    android:name="_R_G_L_3_G_L_0_G_L_5_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#bdc1c6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M96.5 -4 C96.5,-4 96.5,4 96.5,4 C96.5,6.21 94.71,8 92.5,8 C92.5,8 -92.5,8 -92.5,8 C-94.71,8 -96.5,6.21 -96.5,4 C-96.5,4 -96.5,-4 -96.5,-4 C-96.5,-6.21 -94.71,-8 -92.5,-8 C-92.5,-8 92.5,-8 92.5,-8 C94.71,-8 96.5,-6.21 96.5,-4c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_3_G_L_0_G_L_4_G"
-                                android:scaleY="0"
-                                android:translateX="54"
-                                android:translateY="685">
-                                <path
-                                    android:name="_R_G_L_3_G_L_0_G_L_4_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#9aa0a6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M28 0 C28,15.46 15.46,28 0,28 C-15.46,28 -28,15.46 -28,0 C-28,-15.46 -15.46,-28 0,-28 C15.46,-28 28,-15.46 28,0c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_3_G_L_0_G_L_3_G"
-                                android:scaleY="0"
-                                android:translateX="162.5"
-                                android:translateY="676">
-                                <path
-                                    android:name="_R_G_L_3_G_L_0_G_L_3_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#bdc1c6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M60.5 -5 C60.5,-5 60.5,5 60.5,5 C60.5,7.21 58.71,9 56.5,9 C56.5,9 -56.5,9 -56.5,9 C-58.71,9 -60.5,7.21 -60.5,5 C-60.5,5 -60.5,-5 -60.5,-5 C-60.5,-7.21 -58.71,-9 -56.5,-9 C-56.5,-9 56.5,-9 56.5,-9 C58.71,-9 60.5,-7.21 60.5,-5c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_3_G_L_0_G_L_2_G"
-                                android:scaleY="0"
-                                android:translateX="174"
-                                android:translateY="697">
-                                <path
-                                    android:name="_R_G_L_3_G_L_0_G_L_2_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#bdc1c6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M72 -4 C72,-4 72,4 72,4 C72,6.21 70.21,8 68,8 C68,8 -68,8 -68,8 C-70.21,8 -72,6.21 -72,4 C-72,4 -72,-4 -72,-4 C-72,-6.21 -70.21,-8 -68,-8 C-68,-8 68,-8 68,-8 C70.21,-8 72,-6.21 72,-4c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_3_G_L_0_G_L_1_G"
-                                android:scaleY="0"
-                                android:translateX="313.5"
-                                android:translateY="798">
-                                <path
-                                    android:name="_R_G_L_3_G_L_0_G_L_1_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#bdc1c6"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M74.5 0 C74.5,0 74.5,0 74.5,0 C74.5,15.45 61.95,28 46.5,28 C46.5,28 -46.5,28 -46.5,28 C-61.95,28 -74.5,15.45 -74.5,0 C-74.5,0 -74.5,0 -74.5,0 C-74.5,-15.45 -61.95,-28 -46.5,-28 C-46.5,-28 46.5,-28 46.5,-28 C61.95,-28 74.5,-15.45 74.5,0c " />
-                            </group>
-                            <group
-                                android:name="_R_G_L_3_G_L_0_G_L_0_G"
-                                android:scaleY="0"
-                                android:translateX="205.5"
-                                android:translateY="61">
-                                <path
-                                    android:name="_R_G_L_3_G_L_0_G_L_0_G_D_0_P_0"
-                                    android:fillAlpha="1"
-                                    android:fillColor="#f8f9fa"
-                                    android:fillType="nonZero"
-                                    android:pathData=" M171.5 -14 C171.5,-14 171.5,14 171.5,14 C171.5,16.21 169.71,18 167.5,18 C167.5,18 -167.5,18 -167.5,18 C-169.71,18 -171.5,16.21 -171.5,14 C-171.5,14 -171.5,-14 -171.5,-14 C-171.5,-16.21 -169.71,-18 -167.5,-18 C-167.5,-18 167.5,-18 167.5,-18 C169.71,-18 171.5,-16.21 171.5,-14c " />
-                            </group>
-                        </group>
-                    </group>
-                </group>
-                <group
-                    android:name="_R_G_L_2_G_N_2_T_0"
-                    android:scaleX="0.6"
-                    android:scaleY="0"
-                    android:translateX="206"
-                    android:translateY="395">
-                    <group
-                        android:name="_R_G_L_2_G"
-                        android:scaleX="1.3767699999999998"
-                        android:scaleY="1.3767699999999998"
-                        android:translateY="-508.163">
-                        <group
-                            android:name="_R_G_L_2_G_D_0_P_0_G_0_T_0"
-                            android:scaleX="0"
-                            android:scaleY="0">
-                            <path
-                                android:name="_R_G_L_2_G_D_0_P_0"
-                                android:fillAlpha="1"
-                                android:fillColor="#9aa0a6"
-                                android:fillType="nonZero"
-                                android:pathData=" M0 25 C13.81,25 25,13.81 25,0 C25,-13.81 13.81,-25 0,-25 C-13.81,-25 -25,-13.81 -25,0 C-25,13.81 -13.81,25 0,25c " />
-                        </group>
-                    </group>
-                </group>
-                <group
-                    android:name="_R_G_L_1_G_N_2_T_0"
-                    android:scaleX="0.6"
-                    android:scaleY="0"
-                    android:translateX="206"
-                    android:translateY="395">
-                    <group
-                        android:name="_R_G_L_1_G"
-                        android:scaleX="1.39"
-                        android:scaleY="1.39"
-                        android:translateX="-556.176"
-                        android:translateY="-7.307">
-                        <path
-                            android:name="_R_G_L_1_G_D_0_P_0"
-                            android:fillAlpha="1"
-                            android:fillColor="@color/gesture_tutorial_fake_previous_task_view_color"
-                            android:fillType="nonZero"
-                            android:pathData=" M135 -301 C135,-301 135,311 135,311 C135,319.28 128.28,326 120,326 C120,326 -120,326 -120,326 C-128.28,326 -135,319.28 -135,311 C-135,311 -135,-301 -135,-301 C-135,-309.28 -128.28,-316 -120,-316 C-120,-316 120,-316 120,-316 C128.28,-316 135,-309.28 135,-301c " />
-                    </group>
-                </group>
-                <group
-                    android:name="_R_G_L_0_G"
-                    android:translateX="206"
-                    android:translateY="446">
-                    <path
-                        android:name="_R_G_L_0_G_D_0_P_0"
-                        android:fillAlpha="0"
-                        android:fillColor="#84ba69"
-                        android:fillType="nonZero"
-                        android:pathData=" M0 406 C21.54,406 39,423.46 39,445 C39,466.54 21.54,484 0,484 C-21.54,484 -39,466.54 -39,445 C-39,423.46 -21.54,406 0,406c " />
-                </group>
-            </group>
-            <group android:name="time_group" />
-        </vector>
-    </aapt:attr>
-</animated-vector>
\ No newline at end of file
diff --git a/res/layout/launcher_preview_two_panel_layout.xml b/res/layout/launcher_preview_two_panel_layout.xml
index 7b227e0..f76fc5a 100644
--- a/res/layout/launcher_preview_two_panel_layout.xml
+++ b/res/layout/launcher_preview_two_panel_layout.xml
@@ -25,24 +25,24 @@
         android:layout_height="match_parent">
 
         <com.android.launcher3.CellLayout
-            android:id="@+id/workspace_left"
+            android:id="@+id/workspace"
             android:layout_width="0dp"
             android:layout_height="0dp"
             android:theme="@style/HomeScreenElementTheme"
             launcher:containerType="workspace"
             launcher:layout_constraintStart_toStartOf="parent"
             launcher:layout_constraintTop_toTopOf="parent"
-            launcher:layout_constraintEnd_toStartOf="@id/workspace"
+            launcher:layout_constraintEnd_toStartOf="@id/workspace_right"
             launcher:layout_constraintBottom_toBottomOf="parent"
             launcher:pageIndicator="@+id/page_indicator" />
 
         <com.android.launcher3.CellLayout
-            android:id="@+id/workspace"
+            android:id="@+id/workspace_right"
             android:layout_width="0dp"
             android:layout_height="0dp"
             android:theme="@style/HomeScreenElementTheme"
             launcher:containerType="workspace"
-            launcher:layout_constraintStart_toEndOf="@id/workspace_left"
+            launcher:layout_constraintStart_toEndOf="@id/workspace"
             launcher:layout_constraintTop_toTopOf="parent"
             launcher:layout_constraintEnd_toEndOf="parent"
             launcher:layout_constraintBottom_toBottomOf="parent"
diff --git a/res/layout/widgets_bottom_sheet_content.xml b/res/layout/widgets_bottom_sheet_content.xml
index 3d330dc..1a2cfc6 100644
--- a/res/layout/widgets_bottom_sheet_content.xml
+++ b/res/layout/widgets_bottom_sheet_content.xml
@@ -18,7 +18,7 @@
         android:id="@+id/widgets_bottom_sheet"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:background="@drawable/widgets_bottom_sheet_background"
+        android:background="@drawable/bg_rounded_corner_bottom_sheet"
         android:paddingTop="16dp"
         android:orientation="vertical">
         <View
diff --git a/res/layout/widgets_full_sheet.xml b/res/layout/widgets_full_sheet.xml
index 96b73c2..8afd40b 100644
--- a/res/layout/widgets_full_sheet.xml
+++ b/res/layout/widgets_full_sheet.xml
@@ -19,13 +19,21 @@
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:orientation="vertical"
-    android:theme="?attr/widgetsTheme" >
+    android:theme="?attr/widgetsTheme">
 
-    <com.android.launcher3.views.TopRoundedCornerView
+    <com.android.launcher3.views.SpringRelativeLayout
         android:id="@+id/container"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
-        android:background="?android:attr/colorBackground">
+        android:background="@drawable/bg_widgets_full_sheet">
+
+        <View
+            android:id="@+id/collapse_handle"
+            android:layout_width="48dp"
+            android:layout_height="2dp"
+            android:layout_marginTop="16dp"
+            android:layout_centerHorizontal="true"
+            android:background="?android:attr/textColorSecondary"/>
 
         <TextView
             android:id="@+id/no_widgets_text"
@@ -35,6 +43,7 @@
             android:visibility="gone"
             android:fontFamily="sans-serif-medium"
             android:textSize="20sp"
+            android:layout_below="@id/search_and_recommendations_container"
             tools:text="No widgets available" />
 
         <!-- Fast scroller popup -->
@@ -57,9 +66,10 @@
             android:id="@+id/search_widgets_list_view"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
+            android:layout_below="@id/collapse_handle"
             android:layout_marginHorizontal="@dimen/widget_list_horizontal_margin"
             android:visibility="gone"
             android:clipToPadding="false" />
 
-    </com.android.launcher3.views.TopRoundedCornerView>
+    </com.android.launcher3.views.SpringRelativeLayout>
 </com.android.launcher3.widget.picker.WidgetsFullSheet>
\ No newline at end of file
diff --git a/res/layout/widgets_full_sheet_paged_view.xml b/res/layout/widgets_full_sheet_paged_view.xml
index fefad19..85f14cd 100644
--- a/res/layout/widgets_full_sheet_paged_view.xml
+++ b/res/layout/widgets_full_sheet_paged_view.xml
@@ -22,7 +22,7 @@
         android:layout_height="match_parent"
         android:layout_marginHorizontal="@dimen/widget_list_horizontal_margin"
         android:clipToPadding="false"
-        android:paddingTop="@dimen/widget_picker_view_pager_top_padding"
+        android:layout_below="@id/collapse_handle"
         android:descendantFocusability="afterDescendants"
         launcher:pageIndicator="@+id/tabs">
 
@@ -40,5 +40,84 @@
 
     </com.android.launcher3.workprofile.PersonalWorkPagedView>
 
-    <include layout="@layout/widgets_personal_work_tabs"/>
+    <!-- SearchAndRecommendationsView contains the tab layout as well -->
+    <com.android.launcher3.widget.picker.SearchAndRecommendationsView
+        android:id="@+id/search_and_recommendations_container"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginHorizontal="@dimen/widget_list_horizontal_margin"
+        android:layout_below="@id/collapse_handle"
+        android:paddingBottom="0dp"
+        android:orientation="vertical">
+
+        <TextView
+            android:id="@+id/title"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:gravity="center_horizontal"
+            android:textSize="24sp"
+            android:layout_marginTop="24dp"
+            android:textColor="?android:attr/textColorSecondary"
+            android:text="@string/widget_button_text"/>
+
+        <FrameLayout
+            android:id="@+id/search_bar_container"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:elevation="0.1dp"
+            android:background="?android:attr/colorBackground"
+            android:paddingBottom="8dp"
+            android:clipToPadding="false">
+            <include layout="@layout/widgets_search_bar" />
+        </FrameLayout>
+
+        <com.android.launcher3.widget.picker.WidgetsRecommendationTableLayout
+            android:id="@+id/recommended_widget_table"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="8dp"
+            android:background="@drawable/widgets_recommendation_background"
+            android:paddingVertical="@dimen/recommended_widgets_table_vertical_padding"
+            android:visibility="gone" />
+
+        <com.android.launcher3.workprofile.PersonalWorkSlidingTabStrip
+            android:id="@+id/tabs"
+            android:layout_width="match_parent"
+            android:layout_height="64dp"
+            android:gravity="center_horizontal"
+            android:orientation="horizontal"
+            android:paddingVertical="8dp"
+            android:paddingLeft="@dimen/widget_tabs_horizontal_padding"
+            android:paddingRight="@dimen/widget_tabs_horizontal_padding"
+            android:background="?android:attr/colorBackground"
+            style="@style/TextHeadline">
+
+            <Button
+                android:id="@+id/tab_personal"
+                android:layout_width="0dp"
+                android:layout_height="match_parent"
+                android:layout_marginEnd="@dimen/widget_tabs_button_horizontal_padding"
+                android:layout_marginVertical="@dimen/widget_apps_tabs_vertical_padding"
+                android:layout_weight="1"
+                android:background="@drawable/all_apps_tabs_background"
+                android:text="@string/widgets_full_sheet_personal_tab"
+                android:textColor="@color/all_apps_tab_text"
+                android:textSize="14sp"
+                style="?android:attr/borderlessButtonStyle" />
+
+            <Button
+                android:id="@+id/tab_work"
+                android:layout_width="0dp"
+                android:layout_height="match_parent"
+                android:layout_marginEnd="@dimen/widget_tabs_button_horizontal_padding"
+                android:layout_marginVertical="@dimen/widget_apps_tabs_vertical_padding"
+                android:layout_weight="1"
+                android:background="@drawable/all_apps_tabs_background"
+                android:text="@string/widgets_full_sheet_work_tab"
+                android:textColor="@color/all_apps_tab_text"
+                android:textSize="14sp"
+                style="?android:attr/borderlessButtonStyle" />
+        </com.android.launcher3.workprofile.PersonalWorkSlidingTabStrip>
+
+    </com.android.launcher3.widget.picker.SearchAndRecommendationsView>
 </merge>
\ No newline at end of file
diff --git a/res/layout/widgets_full_sheet_recyclerview.xml b/res/layout/widgets_full_sheet_recyclerview.xml
index 0f7e020..dde82ea 100644
--- a/res/layout/widgets_full_sheet_recyclerview.xml
+++ b/res/layout/widgets_full_sheet_recyclerview.xml
@@ -13,10 +13,54 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<com.android.launcher3.widget.picker.WidgetsRecyclerView
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/primary_widgets_list_view"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:layout_marginHorizontal="@dimen/widget_list_horizontal_margin"
-    android:clipToPadding="false" />
\ No newline at end of file
+<merge xmlns:android="http://schemas.android.com/apk/res/android">
+    <com.android.launcher3.widget.picker.WidgetsRecyclerView
+        android:id="@+id/primary_widgets_list_view"
+        android:layout_below="@id/collapse_handle"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:layout_marginHorizontal="@dimen/widget_list_horizontal_margin"
+        android:clipToPadding="false" />
+
+    <!-- SearchAndRecommendationsView without the tab layout as well -->
+    <com.android.launcher3.widget.picker.SearchAndRecommendationsView
+        android:id="@+id/search_and_recommendations_container"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginHorizontal="@dimen/widget_list_horizontal_margin"
+        android:layout_below="@id/collapse_handle"
+        android:paddingBottom="16dp"
+        android:orientation="vertical">
+
+        <TextView
+            android:id="@+id/title"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:gravity="center_horizontal"
+            android:textSize="24sp"
+            android:layout_marginTop="24dp"
+            android:textColor="?android:attr/textColorSecondary"
+            android:text="@string/widget_button_text"/>
+
+        <FrameLayout
+            android:id="@+id/search_bar_container"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:elevation="0.1dp"
+            android:background="?android:attr/colorBackground"
+            android:paddingBottom="8dp"
+            android:clipToPadding="false">
+            <include layout="@layout/widgets_search_bar" />
+        </FrameLayout>
+
+        <com.android.launcher3.widget.picker.WidgetsRecommendationTableLayout
+            android:id="@+id/recommended_widget_table"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="8dp"
+            android:background="@drawable/widgets_recommendation_background"
+            android:paddingVertical="@dimen/recommended_widgets_table_vertical_padding"
+            android:visibility="gone" />
+    </com.android.launcher3.widget.picker.SearchAndRecommendationsView>
+
+</merge>
\ No newline at end of file
diff --git a/res/layout/widgets_full_sheet_search_and_recommendations.xml b/res/layout/widgets_full_sheet_search_and_recommendations.xml
deleted file mode 100644
index 938c8ed..0000000
--- a/res/layout/widgets_full_sheet_search_and_recommendations.xml
+++ /dev/null
@@ -1,61 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-<com.android.launcher3.widget.picker.SearchAndRecommendationsView
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/search_and_recommendations_container"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:layout_marginHorizontal="@dimen/widget_list_horizontal_margin"
-    android:layout_marginBottom="16dp"
-    android:orientation="vertical">
-
-    <View
-        android:id="@+id/collapse_handle"
-        android:layout_width="match_parent"
-        android:layout_height="18dp"
-        android:elevation="0.1dp"
-        android:background="@drawable/bg_widgets_picker_handle"/>
-
-    <TextView
-        android:id="@+id/title"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:gravity="center_horizontal"
-        android:textSize="24sp"
-        android:layout_marginTop="24dp"
-        android:textColor="?android:attr/textColorSecondary"
-        android:text="@string/widget_button_text"/>
-
-    <FrameLayout
-        android:id="@+id/search_bar_container"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:elevation="0.1dp"
-        android:background="?android:attr/colorBackground"
-        android:paddingBottom="8dp"
-        android:clipToPadding="false">
-        <include layout="@layout/widgets_search_bar" />
-    </FrameLayout>
-
-    <com.android.launcher3.widget.picker.WidgetsRecommendationTableLayout
-        android:id="@+id/recommended_widget_table"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:layout_marginTop="8dp"
-        android:background="@drawable/widgets_recommendation_background"
-        android:paddingVertical="@dimen/recommended_widgets_table_vertical_padding"
-        android:visibility="gone" />
-</com.android.launcher3.widget.picker.SearchAndRecommendationsView>
diff --git a/res/layout/widgets_personal_work_tabs.xml b/res/layout/widgets_personal_work_tabs.xml
deleted file mode 100644
index 532c422..0000000
--- a/res/layout/widgets_personal_work_tabs.xml
+++ /dev/null
@@ -1,53 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  ~ 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.
--->
-
-<com.android.launcher3.workprofile.PersonalWorkSlidingTabStrip
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/tabs"
-    android:layout_width="match_parent"
-    android:layout_height="@dimen/all_apps_header_pill_height"
-    android:gravity="center_horizontal"
-    android:orientation="horizontal"
-    android:layout_marginHorizontal="@dimen/widget_tabs_horizontal_margin"
-    style="@style/TextHeadline">
-
-    <Button
-        android:id="@+id/tab_personal"
-        android:layout_width="0dp"
-        android:layout_height="match_parent"
-        android:layout_marginEnd="@dimen/widget_tabs_button_horizontal_padding"
-        android:layout_marginVertical="@dimen/widget_apps_tabs_vertical_padding"
-        android:layout_weight="1"
-        android:background="@drawable/all_apps_tabs_background"
-        android:text="@string/widgets_full_sheet_personal_tab"
-        android:textColor="@color/all_apps_tab_text"
-        android:textSize="14sp"
-        style="?android:attr/borderlessButtonStyle" />
-
-    <Button
-        android:id="@+id/tab_work"
-        android:layout_width="0dp"
-        android:layout_height="match_parent"
-        android:layout_marginEnd="@dimen/widget_tabs_button_horizontal_padding"
-        android:layout_marginVertical="@dimen/widget_apps_tabs_vertical_padding"
-        android:layout_weight="1"
-        android:background="@drawable/all_apps_tabs_background"
-        android:text="@string/widgets_full_sheet_work_tab"
-        android:textColor="@color/all_apps_tab_text"
-        android:textSize="14sp"
-        style="?android:attr/borderlessButtonStyle" />
-</com.android.launcher3.workprofile.PersonalWorkSlidingTabStrip>
\ No newline at end of file
diff --git a/res/values-ta/strings.xml b/res/values-ta/strings.xml
index c4ee9ae..25a1739 100644
--- a/res/values-ta/strings.xml
+++ b/res/values-ta/strings.xml
@@ -101,8 +101,8 @@
     <string name="folder_tap_to_rename" msgid="4017685068016979677">"மாற்றிய பெயரைச் சேமிக்க, தட்டவும்"</string>
     <string name="folder_closed" msgid="4100806530910930934">"கோப்புறை மூடப்பட்டது"</string>
     <string name="folder_renamed" msgid="1794088362165669656">"கோப்புறை <xliff:g id="NAME">%1$s</xliff:g> என மறுபெயரிடப்பட்டது"</string>
-    <string name="folder_name_format_exact" msgid="8626242716117004803">"கோப்புறை: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> கோப்புகள்"</string>
-    <string name="folder_name_format_overflow" msgid="4270108890534995199">"கோப்புறை: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> அல்லது அதற்கு அதிகமான கோப்புகள்"</string>
+    <string name="folder_name_format_exact" msgid="8626242716117004803">"கோப்புறை: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> ஃபைல்கள்"</string>
+    <string name="folder_name_format_overflow" msgid="4270108890534995199">"கோப்புறை: <xliff:g id="NAME">%1$s</xliff:g>, <xliff:g id="SIZE">%2$d</xliff:g> அல்லது அதற்கு அதிகமான ஃபைல்கள்"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"வால்பேப்பர்கள்"</string>
     <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"வால்பேப்பர் &amp; ஸ்டைல்"</string>
     <string name="settings_button_text" msgid="8873672322605444408">"முகப்பு அமைப்புகள்"</string>
diff --git a/res/values-te/strings.xml b/res/values-te/strings.xml
index 80a6f10..22aa785 100644
--- a/res/values-te/strings.xml
+++ b/res/values-te/strings.xml
@@ -58,7 +58,7 @@
     <string name="reconfigurable_widget_education_tip" msgid="6336962690888067057">"విడ్జెట్ సెట్టింగ్‌లను మార్చడానికి ట్యాప్ చేయండి"</string>
     <string name="widget_education_close_button" msgid="8676165703104836580">"అర్థమైంది"</string>
     <string name="widget_reconfigure_button_content_description" msgid="8811472721881205250">"విడ్జెట్ సెట్టింగ్‌లను మార్చండి"</string>
-    <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"అప్లికేషన్‌లను శోధించండి"</string>
+    <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"అప్లికేషన్‌లను వెతకండి"</string>
     <string name="all_apps_loading_message" msgid="5813968043155271636">"అప్లికేషన్‌లను లోడ్ చేస్తోంది…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\"కి సరిపోలే అప్లికేషన్‌లేవీ కనుగొనబడలేదు"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"మరిన్ని యాప్‌ల కోసం వెతుకు"</string>
@@ -68,9 +68,9 @@
     <string name="long_accessible_way_to_add_shortcut" msgid="2199537273817090740">"షార్ట్‌కట్‌ను తరలించడానికి లేదా అనుకూల చర్యలను ఉపయోగించడానికి రెండుసార్లు నొక్కండి &amp; హోల్డ్ చేయండి."</string>
     <string name="out_of_space" msgid="6692471482459245734">"ఈ మొదటి స్క్రీన్‌లో స్థలం లేదు"</string>
     <string name="hotseat_out_of_space" msgid="7448809638125333693">"ఇష్టమైనవి ట్రేలో ఖాళీ లేదు"</string>
-    <string name="all_apps_button_label" msgid="8130441508702294465">"అనువర్తనాల జాబితా"</string>
-    <string name="all_apps_button_personal_label" msgid="1315764287305224468">"వ్యక్తిగత యాప్‌ల జాబితా"</string>
-    <string name="all_apps_button_work_label" msgid="7270707118948892488">"కార్యాలయ యాప్‌ల జాబితా"</string>
+    <string name="all_apps_button_label" msgid="8130441508702294465">"యాప్‌ల లిస్ట్‌"</string>
+    <string name="all_apps_button_personal_label" msgid="1315764287305224468">"వ్యక్తిగత యాప్‌ల లిస్ట్‌"</string>
+    <string name="all_apps_button_work_label" msgid="7270707118948892488">"కార్యాలయ యాప్‌ల లిస్ట్‌"</string>
     <string name="remove_drop_target_label" msgid="7812859488053230776">"తీసివేయి"</string>
     <string name="uninstall_drop_target_label" msgid="4722034217958379417">"అన్ఇన్‌స్టాల్ చేయి"</string>
     <string name="app_info_drop_target_label" msgid="692894985365717661">"యాప్ సమాచారం"</string>
@@ -78,12 +78,12 @@
     <string name="dismiss_prediction_label" msgid="3357562989568808658">"యాప్‌ను సూచించవద్దు"</string>
     <string name="pin_prediction" msgid="4196423321649756498">"సూచనను పిన్ చేయండి"</string>
     <string name="permlab_install_shortcut" msgid="5632423390354674437">"షార్ట్‌కట్‌లను ఇన్‌స్టాల్ చేయడం"</string>
-    <string name="permdesc_install_shortcut" msgid="923466509822011139">"వినియోగదారు ప్రమేయం లేకుండా సత్వరమార్గాలను జోడించడానికి యాప్‌ను అనుమతిస్తుంది."</string>
-    <string name="permlab_read_settings" msgid="1941457408239617576">"హోమ్ సెట్టింగ్‌లు మరియు సత్వరమార్గాలను చదవడం"</string>
-    <string name="permdesc_read_settings" msgid="5833423719057558387">"హోమ్‌లో సెట్టింగ్‌లు మరియు సత్వరమార్గాలను చదవడానికి యాప్‌ను అనుమతిస్తుంది."</string>
-    <string name="permlab_write_settings" msgid="3574213698004620587">"హోమ్ సెట్టింగ్‌లు మరియు సత్వరమార్గాలను వ్రాయడం"</string>
-    <string name="permdesc_write_settings" msgid="5440712911516509985">"హోమ్‌లో సెట్టింగ్‌లు మరియు సత్వరమార్గాలను మార్చడానికి యాప్‌ను అనుమతిస్తుంది."</string>
-    <string name="msg_no_phone_permission" msgid="9208659281529857371">"ఫోన్ కాల్‌లను చేసేందుకు <xliff:g id="APP_NAME">%1$s</xliff:g>కి అనుమతి లేదు"</string>
+    <string name="permdesc_install_shortcut" msgid="923466509822011139">"వినియోగదారు ప్రమేయం లేకుండా షార్ట్‌కట్‌లను జోడించడానికి యాప్‌ను అనుమతిస్తుంది."</string>
+    <string name="permlab_read_settings" msgid="1941457408239617576">"హోమ్ సెట్టింగ్‌లు మరియు షార్ట్‌కట్‌లను చదవడం"</string>
+    <string name="permdesc_read_settings" msgid="5833423719057558387">"హోమ్‌లో సెట్టింగ్‌లు మరియు షార్ట్‌కట్‌లను చదవడానికి యాప్‌ను అనుమతిస్తుంది."</string>
+    <string name="permlab_write_settings" msgid="3574213698004620587">"హోమ్ సెట్టింగ్‌లు మరియు షార్ట్‌కట్‌లను వ్రాయడం"</string>
+    <string name="permdesc_write_settings" msgid="5440712911516509985">"హోమ్‌లో సెట్టింగ్‌లు మరియు షార్ట్‌కట్‌లను మార్చడానికి యాప్‌ను అనుమతిస్తుంది."</string>
+    <string name="msg_no_phone_permission" msgid="9208659281529857371">"ఫోన్ కాల్స్‌ను చేసేందుకు <xliff:g id="APP_NAME">%1$s</xliff:g>కి అనుమతి లేదు"</string>
     <string name="gadget_error_text" msgid="740356548025791839">"విడ్జెట్‌ను లోడ్ చేయడం సాధ్యం కాలేదు"</string>
     <string name="gadget_setup_text" msgid="1745356155479272374">"సెటప్‌ను పూర్తి చేయడానికి ట్యాప్ చేయండి"</string>
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"ఇది సిస్టమ్ యాప్ మరియు దీన్ని అన్‌ఇన్‌స్టాల్ చేయడం సాధ్యపడదు."</string>
@@ -126,8 +126,8 @@
     <string name="app_installing_title" msgid="5864044122733792085">"<xliff:g id="NAME">%1$s</xliff:g>‌ను ఇన్‌స్టాల్ చేయడం, <xliff:g id="PROGRESS">%2$s</xliff:g> పూర్తయింది"</string>
     <string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> డౌన్‌లోడ్ అవుతోంది, <xliff:g id="PROGRESS">%2$s</xliff:g> పూర్తయింది"</string>
     <string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> ఇన్‌స్టాల్ కావడానికి వేచి ఉంది"</string>
-    <string name="widgets_list" msgid="796804551140113767">"విడ్జెట్‌ల జాబితా"</string>
-    <string name="widgets_list_closed" msgid="6141506579418771922">"విడ్జెట్‌ల జాబితా మూసివేయబడింది"</string>
+    <string name="widgets_list" msgid="796804551140113767">"విడ్జెట్‌ల లిస్ట్‌"</string>
+    <string name="widgets_list_closed" msgid="6141506579418771922">"విడ్జెట్‌ల లిస్ట్‌ మూసివేయబడింది"</string>
     <string name="action_add_to_workspace" msgid="8902165848117513641">"హోమ్ స్క్రీన్‌కు జోడించండి"</string>
     <string name="action_move_here" msgid="2170188780612570250">"అంశాన్ని ఇక్కడికి తరలించు"</string>
     <string name="item_added_to_workspace" msgid="4211073925752213539">"అంశం హోమ్‌స్క్రీన్‌కి జోడించబడింది"</string>
@@ -141,7 +141,7 @@
     <string name="add_to_folder" msgid="9040534766770853243">"ఈ ఫోల్డర్‌కి జోడించండి: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="add_to_folder_with_app" msgid="4534929978967147231">"<xliff:g id="NAME">%1$s</xliff:g> గల ఫోల్డర్‌కు జోడించు"</string>
     <string name="added_to_folder" msgid="4793259502305558003">"అంశం ఫోల్డర్‌కు జోడించబడింది"</string>
-    <string name="create_folder_with" msgid="4050141361160214248">"ఈ పేరుతో ఫోల్డర్‌ను సృష్టించండి: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="create_folder_with" msgid="4050141361160214248">"ఈ పేరుతో ఫోల్డర్‌ను క్రియేట్ చేయండి: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="folder_created" msgid="6409794597405184510">"ఫోల్డర్ సృష్టించబడింది"</string>
     <string name="action_move_to_workspace" msgid="1603837886334246317">"హోమ్‌స్క్రీన్‌కు తరలించు"</string>
     <string name="action_resize" msgid="1802976324781771067">"పరిమాణం మార్చు"</string>
@@ -150,7 +150,7 @@
     <string name="action_decrease_width" msgid="1374549771083094654">"వెడల్పును తగ్గించు"</string>
     <string name="action_decrease_height" msgid="282377193880900022">"ఎత్తును తగ్గించు"</string>
     <string name="widget_resized" msgid="9130327887929620">"విడ్జెట్ పరిమాణం వెడల్పు <xliff:g id="NUMBER_0">%1$s</xliff:g>కి, ఎత్తు <xliff:g id="NUMBER_1">%2$s</xliff:g>కి మార్చబడింది"</string>
-    <string name="action_deep_shortcut" msgid="2864038805849372848">"సత్వరమార్గాలు"</string>
+    <string name="action_deep_shortcut" msgid="2864038805849372848">"షార్ట్‌కట్స్"</string>
     <string name="shortcuts_menu_with_notifications_description" msgid="2676582286544232849">"షార్ట్‌కట్‌లు మరియు నోటిఫికేషన్‌లు"</string>
     <string name="action_dismiss_notification" msgid="5909461085055959187">"తీసివేయి"</string>
     <string name="accessibility_close" msgid="2277148124685870734">"మూసివేస్తుంది"</string>
diff --git a/res/values-v31/colors.xml b/res/values-v31/colors.xml
index c2ebeff..55cedf4 100644
--- a/res/values-v31/colors.xml
+++ b/res/values-v31/colors.xml
@@ -41,6 +41,8 @@
     <color name="wallpaper_popup_scrim">@android:color/system_neutral1_900</color>
 
     <color name="folder_dot_color">@android:color/system_accent2_50</color>
+    <color name="folder_pagination_color_light">@android:color/system_accent1_600</color>
+    <color name="folder_pagination_color_dark">@android:color/system_accent2_100</color>
 
     <color name="home_settings_header_accent">@android:color/system_accent1_600</color>
     <color name="home_settings_header_collapsed">@android:color/system_neutral1_100</color>
diff --git a/res/values/attrs.xml b/res/values/attrs.xml
index 00cf31c..65b46cf 100644
--- a/res/values/attrs.xml
+++ b/res/values/attrs.xml
@@ -42,6 +42,7 @@
     <attr name="popupNotificationDotColor" format="color" />
 
     <attr name="folderDotColor" format="color" />
+    <attr name="folderPaginationColor" format="color" />
     <attr name="folderFillColor" format="color" />
     <attr name="folderIconRadius" format="float" />
     <attr name="folderIconBorderColor" format="color" />
@@ -148,9 +149,16 @@
 
         <attr name="dbFile" format="string" />
         <attr name="defaultLayoutId" format="reference" />
+        <attr name="defaultSplitDisplayLayoutId" format="reference" />
         <attr name="demoModeLayoutId" format="reference" />
         <attr name="isScalable" format="boolean" />
         <attr name="devicePaddingId" format="reference" />
+        <attr name="gridEnabled" format="integer" >
+            <!-- Enable on all devices; default value -->
+            <enum name="all_displays" value="0" />
+            <!-- Enable on single display devices only -->
+            <enum name="single_display" value="1" />
+        </attr>
 
     </declare-styleable>
 
@@ -176,11 +184,20 @@
         <attr name="borderSpacingDps" format="float" />
 
         <attr name="iconImageSize" format="float" />
-        <!-- landscapeIconSize defaults to iconSize, if not specified -->
+        <!-- landscapeIconSize defaults to iconImageSize, if not specified -->
         <attr name="landscapeIconSize" format="float" />
+        <!-- twoPanelPortraitIconSize defaults to iconImageSize, if not specified -->
+        <attr name="twoPanelPortraitIconSize" format="float" />
+        <!-- twoPanelLandscapeIconSize defaults to landscapeIconSize, if not specified -->
+        <attr name="twoPanelLandscapeIconSize" format="float" />
+
         <attr name="iconTextSize" format="float" />
         <!-- landscapeIconTextSize defaults to iconTextSize, if not specified -->
         <attr name="landscapeIconTextSize" format="float" />
+        <!-- twoPanelPortraitIconTextSize defaults to iconTextSize, if not specified -->
+        <attr name="twoPanelPortraitIconTextSize" format="float" />
+        <!-- twoPanelLandscapeIconTextSize defaults to landscapeIconTextSize, if not specified -->
+        <attr name="twoPanelLandscapeIconTextSize" format="float" />
 
         <!-- If set, this display option is used to determine the default grid -->
         <attr name="canBeDefault" format="boolean|integer" >
diff --git a/res/values/colors.xml b/res/values/colors.xml
index 1b68fb6..5020127 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -36,15 +36,6 @@
 
     <color name="icon_background">#E0E0E0</color> <!-- Gray 300 -->
 
-    <color name="gesture_tutorial_ripple_color">#A0C2F9</color> <!-- Light Blue -->
-    <color name="gesture_tutorial_fake_task_view_color">#6DA1FF</color> <!-- Light Blue -->
-    <color name="fake_wallpaper_color_dark_mode">#000000</color> <!-- Black -->
-    <color name="fake_wallpaper_color_light_mode">#f9f9f9</color> <!-- White -->
-    <!-- Must contrast fake_wallpaper_color_dark_mode and fake_wallpaper_color_light_mode -->
-    <color name="gesture_tutorial_fake_previous_task_view_color">#3C4043</color> <!-- Gray -->
-    <color name="gesture_tutorial_action_button_label_color">#FF000000</color>
-    <color name="gesture_tutorial_primary_color">#B7F29F</color> <!-- Light Green -->
-
     <color name="popup_color_primary_light">#FFF</color>
     <color name="popup_color_secondary_light">#F1F3F4</color>
     <color name="popup_color_tertiary_light">#E0E0E0</color> <!-- Gray 300 -->
@@ -73,6 +64,8 @@
     <color name="folder_background_dark">#464746</color>
 
     <color name="folder_dot_color">?attr/colorPrimary</color>
+    <color name="folder_pagination_color_light">#ff006c5f</color>
+    <color name="folder_pagination_color_dark">#ffbfebe3</color>
 
     <color name="text_color_primary_dark">#FFFFFFFF</color>
     <color name="text_color_secondary_dark">#FFFFFFFF</color>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index da37250..86b4e71 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -143,8 +143,7 @@
     <dimen name="widget_cell_font_size">14sp</dimen>
 
     <dimen name="widget_tabs_button_horizontal_padding">4dp</dimen>
-    <dimen name="widget_tabs_horizontal_margin">32dp</dimen>
-    <dimen name="widget_apps_header_pill_height">48dp</dimen>
+    <dimen name="widget_tabs_horizontal_padding">16dp</dimen>
     <dimen name="widget_apps_tabs_vertical_padding">6dp</dimen>
 
     <dimen name="recommended_widgets_table_vertical_padding">8dp</dimen>
@@ -178,8 +177,6 @@
     <dimen name="widget_picker_education_tip_max_width">308dp</dimen>
     <dimen name="widget_picker_education_tip_min_margin">4dp</dimen>
 
-    <dimen name="widget_picker_view_pager_top_padding">10dp</dimen>
-
     <!-- Padding applied to shortcut previews -->
     <dimen name="shortcut_preview_padding_left">0dp</dimen>
     <dimen name="shortcut_preview_padding_right">0dp</dimen>
@@ -327,6 +324,7 @@
     <dimen name="task_thumbnail_icon_drawable_size">0dp</dimen>
     <dimen name="task_thumbnail_icon_drawable_size_grid">0dp</dimen>
     <dimen name="overview_task_margin">0dp</dimen>
+    <dimen name="overview_task_margin_focused">0dp</dimen>
     <dimen name="overview_task_margin_grid">0dp</dimen>
     <dimen name="overview_actions_margin_gesture">0dp</dimen>
     <dimen name="overview_actions_top_margin_gesture_grid_portrait">0dp</dimen>
diff --git a/res/values/id.xml b/res/values/id.xml
index 0e2dff0..ebc4075 100644
--- a/res/values/id.xml
+++ b/res/values/id.xml
@@ -17,6 +17,7 @@
 <resources>
     <item type="id" name="apps_list_view_work" />
     <item type="id" name="tag_widget_entry" />
+    <item type="id" name="view_type_widgets_space" />
     <item type="id" name="view_type_widgets_list" />
     <item type="id" name="view_type_widgets_header" />
     <item type="id" name="view_type_widgets_search_header" />
diff --git a/res/values/styles.xml b/res/values/styles.xml
index b7661b9..8ad4fcd 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -50,6 +50,7 @@
         <item name="workspaceStatusBarScrim">@drawable/workspace_bg</item>
         <item name="widgetsTheme">@style/WidgetContainerTheme</item>
         <item name="folderDotColor">@color/folder_dot_color</item>
+        <item name="folderPaginationColor">@color/folder_pagination_color_light</item>
         <item name="folderFillColor">@color/folder_background_light</item>
         <item name="folderIconBorderColor">?android:attr/colorPrimary</item>
         <item name="folderTextColor">@color/workspace_text_color_dark</item>
@@ -108,6 +109,7 @@
         <item name="popupShadeThird">@color/popup_shade_third_dark</item>
         <item name="widgetsTheme">@style/WidgetContainerTheme.Dark</item>
         <item name="folderDotColor">@color/folder_dot_color</item>
+        <item name="folderPaginationColor">@color/folder_pagination_color_dark</item>
         <item name="folderFillColor">@color/folder_background_dark</item>
         <item name="folderIconBorderColor">?android:attr/colorPrimary</item>
         <item name="folderTextColor">@color/workspace_text_color_light</item>
diff --git a/res/xml/default_workspace_5x5.xml b/res/xml/default_workspace_5x5.xml
index ccdde2c..b4ac8f6 100644
--- a/res/xml/default_workspace_5x5.xml
+++ b/res/xml/default_workspace_5x5.xml
@@ -94,4 +94,5 @@
         <favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_MARKET;end" />
         <favorite launcher:uri="market://details?id=com.android.launcher" />
     </resolve>
+
 </favorites>
diff --git a/res/xml/default_workspace_splitdisplay_5x5.xml b/res/xml/default_workspace_splitdisplay_5x5.xml
new file mode 100644
index 0000000..162367b
--- /dev/null
+++ b/res/xml/default_workspace_splitdisplay_5x5.xml
@@ -0,0 +1,107 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2009 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.
+-->
+
+<favorites xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3">
+
+    <!-- Hotseat (We use the screen as the position of the item in the hotseat) -->
+    <!-- Dialer, Messaging, [Maps/Music], Browser, Camera -->
+    <resolve
+        launcher:container="-101"
+        launcher:screen="0"
+        launcher:x="0"
+        launcher:y="0" >
+        <favorite launcher:uri="#Intent;action=android.intent.action.DIAL;end" />
+        <favorite launcher:uri="tel:123" />
+        <favorite launcher:uri="#Intent;action=android.intent.action.CALL_BUTTON;end" />
+    </resolve>
+
+    <resolve
+        launcher:container="-101"
+        launcher:screen="1"
+        launcher:x="1"
+        launcher:y="0" >
+        <favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_MESSAGING;end" />
+        <favorite launcher:uri="sms:" />
+        <favorite launcher:uri="smsto:" />
+        <favorite launcher:uri="mms:" />
+        <favorite launcher:uri="mmsto:" />
+    </resolve>
+
+    <resolve
+        launcher:container="-101"
+        launcher:screen="2"
+        launcher:x="2"
+        launcher:y="0" >
+        <favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_MAPS;end" />
+        <favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_MUSIC;end" />
+    </resolve>
+
+    <resolve
+        launcher:container="-101"
+        launcher:screen="3"
+        launcher:x="3"
+        launcher:y="0" >
+        <favorite
+            launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_BROWSER;end" />
+        <favorite launcher:uri="http://www.example.com/" />
+    </resolve>
+
+    <resolve
+        launcher:container="-101"
+        launcher:screen="4"
+        launcher:x="4"
+        launcher:y="0" >
+        <favorite launcher:uri="#Intent;action=android.media.action.STILL_IMAGE_CAMERA;end" />
+        <favorite launcher:uri="#Intent;action=android.intent.action.CAMERA_BUTTON;end" />
+    </resolve>
+
+    <!-- Bottom row -->
+    <resolve
+        launcher:screen="0"
+        launcher:x="0"
+        launcher:y="-1" >
+	    <favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_EMAIL;end" />
+	    <favorite launcher:uri="mailto:" />
+
+    </resolve>
+
+    <resolve
+        launcher:screen="0"
+        launcher:x="1"
+        launcher:y="-1" >
+	    <favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_GALLERY;end" />
+	    <favorite launcher:uri="#Intent;type=images/*;end" />
+
+    </resolve>
+
+    <resolve
+        launcher:screen="0"
+        launcher:x="4"
+        launcher:y="-1" >
+        <favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_MARKET;end" />
+        <favorite launcher:uri="market://details?id=com.android.launcher" />
+    </resolve>
+
+    <!-- Placeholder before we add page pairing in b/196376162 -->
+    <resolve
+        launcher:screen="1"
+        launcher:x="0"
+        launcher:y="-4" >
+        <favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_GALLERY;end" />
+        <favorite launcher:uri="#Intent;type=images/*;end" />
+    </resolve>
+
+</favorites>
diff --git a/res/xml/device_profiles.xml b/res/xml/device_profiles.xml
index 256999c..d8ee6f2 100644
--- a/res/xml/device_profiles.xml
+++ b/res/xml/device_profiles.xml
@@ -105,7 +105,8 @@
         launcher:numFolderColumns="4"
         launcher:numHotseatIcons="5"
         launcher:dbFile="launcher.db"
-        launcher:defaultLayoutId="@xml/default_workspace_5x5" >
+        launcher:defaultLayoutId="@xml/default_workspace_5x5"
+        launcher:defaultSplitDisplayLayoutId="@xml/default_workspace_splitdisplay_5x5" >
 
         <display-option
             launcher:name="Large Phone"
diff --git a/robolectric_tests/Android.bp b/robolectric_tests/Android.bp
index 9ed26ff..6473d00 100644
--- a/robolectric_tests/Android.bp
+++ b/robolectric_tests/Android.bp
@@ -40,7 +40,6 @@
     name: "LauncherRoboTests",
     srcs: [
         ":launcher3-robolectric-src",
-        ":launcher3-test-src-common",
     ],
     java_resources: [":launcher3-robolectric-resources"],
     static_libs: [
diff --git a/robolectric_tests/src/com/android/launcher3/ui/LauncherUIScrollTest.java b/robolectric_tests/src/com/android/launcher3/ui/LauncherUIScrollTest.java
deleted file mode 100644
index ea75548..0000000
--- a/robolectric_tests/src/com/android/launcher3/ui/LauncherUIScrollTest.java
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * 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.
- * 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.ui;
-
-import static com.android.launcher3.util.LauncherModelHelper.TEST_PACKAGE;
-import static com.android.launcher3.util.LauncherUIHelper.buildAndBindLauncher;
-import static com.android.launcher3.util.LauncherUIHelper.doLayout;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotEquals;
-
-import android.content.Context;
-import android.os.SystemClock;
-import android.provider.Settings;
-import android.view.InputDevice;
-import android.view.MotionEvent;
-import android.view.MotionEvent.PointerProperties;
-
-import com.android.launcher3.DeviceProfile;
-import com.android.launcher3.InvariantDeviceProfile;
-import com.android.launcher3.Launcher;
-import com.android.launcher3.LauncherState;
-import com.android.launcher3.folder.Folder;
-import com.android.launcher3.folder.FolderIcon;
-import com.android.launcher3.folder.FolderPagedView;
-import com.android.launcher3.util.LauncherLayoutBuilder;
-import com.android.launcher3.util.LauncherLayoutBuilder.FolderBuilder;
-import com.android.launcher3.util.LauncherModelHelper;
-import com.android.launcher3.widget.picker.WidgetsFullSheet;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.LooperMode;
-import org.robolectric.annotation.LooperMode.Mode;
-import org.robolectric.shadows.ShadowLooper;
-
-/**
- * Tests scroll behavior at various Launcher UI components
- */
-@RunWith(RobolectricTestRunner.class)
-@LooperMode(Mode.PAUSED)
-@org.junit.Ignore
-public class LauncherUIScrollTest {
-
-    private Context mTargetContext;
-    private InvariantDeviceProfile mIdp;
-    private LauncherModelHelper mModelHelper;
-
-    private LauncherLayoutBuilder mLayoutBuilder;
-
-    @Before
-    public void setup() throws Exception {
-        mModelHelper = new LauncherModelHelper();
-        mTargetContext = RuntimeEnvironment.application;
-        mIdp = InvariantDeviceProfile.INSTANCE.get(mTargetContext);
-
-        Settings.Global.putFloat(mTargetContext.getContentResolver(),
-                Settings.Global.WINDOW_ANIMATION_SCALE, 0);
-
-        mModelHelper.installApp(TEST_PACKAGE);
-        // LayoutBuilder with 3 workspace pages
-        mLayoutBuilder = new LauncherLayoutBuilder()
-                .atWorkspace(0,  mIdp.numRows - 1, 0).putApp(TEST_PACKAGE, TEST_PACKAGE)
-                .atWorkspace(0,  mIdp.numRows - 1, 1).putApp(TEST_PACKAGE, TEST_PACKAGE)
-                .atWorkspace(0,  mIdp.numRows - 1, 2).putApp(TEST_PACKAGE, TEST_PACKAGE);
-    }
-
-    @Test
-    public void testWorkspacePagesBound() throws Exception {
-        // Verify that the workspace if bound synchronously
-        Launcher launcher = loadLauncher();
-        assertEquals(3, launcher.getWorkspace().getPageCount());
-        assertEquals(0, launcher.getWorkspace().getCurrentPage());
-
-        launcher.dispatchGenericMotionEvent(createScrollEvent(-1));
-        assertNotEquals("Workspace was not scrolled",
-                0, launcher.getWorkspace().getNextPage());
-    }
-
-    @Test
-    public void testAllAppsScroll() throws Exception {
-        // Install 100 apps
-        for (int i = 0; i < 100; i++) {
-            mModelHelper.installApp(TEST_PACKAGE + i);
-        }
-
-        // Bind and open all-apps
-        Launcher launcher = loadLauncher();
-        launcher.getStateManager().goToState(LauncherState.ALL_APPS, false);
-        doLayout(launcher);
-
-        int currentScroll = launcher.getAppsView().getActiveRecyclerView().getCurrentScrollY();
-        launcher.dispatchGenericMotionEvent(createScrollEvent(-1));
-        int newScroll = launcher.getAppsView().getActiveRecyclerView().getCurrentScrollY();
-
-        assertNotEquals("All Apps was not scrolled", currentScroll, newScroll);
-        assertEquals("Workspace was scrolled", 0, launcher.getWorkspace().getNextPage());
-    }
-
-    @Test
-    public void testWidgetsListScroll() throws Exception {
-        // Install 100 widgets
-        for (int i = 0; i < 100; i++) {
-            mModelHelper.installCustomShortcut(TEST_PACKAGE + i, "shortcutProvider");
-        }
-
-        // Bind and open widgets
-        Launcher launcher = loadLauncher();
-        WidgetsFullSheet widgets = WidgetsFullSheet.show(launcher, false);
-        doLayout(launcher);
-
-        int currentScroll = widgets.getRecyclerView().getCurrentScrollY();
-        launcher.dispatchGenericMotionEvent(createScrollEvent(-1));
-        int newScroll = widgets.getRecyclerView().getCurrentScrollY();
-        assertNotEquals("Widgets was not scrolled", currentScroll, newScroll);
-        assertEquals("Workspace was scrolled", 0, launcher.getWorkspace().getNextPage());
-    }
-
-    @Test
-    public void testFolderPageScroll() throws Exception {
-        // Add a folder with multiple icons
-        FolderBuilder fb = mLayoutBuilder.atWorkspace(mIdp.numColumns / 2, mIdp.numRows / 2, 0)
-                .putFolder(0);
-        for (int i = 0; i < 100; i++) {
-            fb.addApp(TEST_PACKAGE, TEST_PACKAGE);
-        }
-
-        // Bind and open folder
-        Launcher launcher = loadLauncher();
-        doLayout(launcher);
-        launcher.getWorkspace().getFirstMatch((i, v) -> v instanceof FolderIcon).performClick();
-        ShadowLooper.idleMainLooper();
-        doLayout(launcher);
-        FolderPagedView folderPages = Folder.getOpen(launcher).getContent();
-
-        assertEquals(0, folderPages.getNextPage());
-        launcher.dispatchGenericMotionEvent(createScrollEvent(-1));
-        assertNotEquals("Folder page was not scrolled", 0, folderPages.getNextPage());
-        assertEquals("Workspace was scrolled", 0, launcher.getWorkspace().getNextPage());
-    }
-
-    private Launcher loadLauncher() throws Exception {
-        mModelHelper.setupDefaultLayoutProvider(mLayoutBuilder).loadModelSync();
-        return buildAndBindLauncher();
-    }
-
-    private static MotionEvent createScrollEvent(int scroll) {
-        DeviceProfile dp = InvariantDeviceProfile.INSTANCE
-                .get(RuntimeEnvironment.application).supportedProfiles.get(0);
-
-        final PointerProperties[] pointerProperties = new PointerProperties[1];
-        pointerProperties[0] = new PointerProperties();
-        pointerProperties[0].id = 0;
-        final MotionEvent.PointerCoords[] coords = new MotionEvent.PointerCoords[1];
-        coords[0] = new MotionEvent.PointerCoords();
-        coords[0].setAxisValue(MotionEvent.AXIS_VSCROLL, scroll);
-        coords[0].x = dp.widthPx / 2;
-        coords[0].y = dp.heightPx / 2;
-
-        final long time = SystemClock.uptimeMillis();
-        return MotionEvent.obtain(time, time, MotionEvent.ACTION_SCROLL, 1,
-                pointerProperties, coords, 0, 0, 1.0f, 1.0f, 0, 0,
-                InputDevice.SOURCE_CLASS_POINTER, 0);
-    }
-
-}
diff --git a/robolectric_tests/src/com/android/launcher3/widget/CachingWidgetPreviewLoaderTest.java b/robolectric_tests/src/com/android/launcher3/widget/CachingWidgetPreviewLoaderTest.java
deleted file mode 100644
index 1090d1e..0000000
--- a/robolectric_tests/src/com/android/launcher3/widget/CachingWidgetPreviewLoaderTest.java
+++ /dev/null
@@ -1,409 +0,0 @@
-/*
- * 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.widget;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.reset;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
-import static org.mockito.Mockito.when;
-
-import android.content.ComponentName;
-import android.graphics.Bitmap;
-import android.os.CancellationSignal;
-import android.os.UserHandle;
-import android.util.Size;
-
-import com.android.launcher3.DeviceProfile;
-import com.android.launcher3.InvariantDeviceProfile;
-import com.android.launcher3.icons.IconCache;
-import com.android.launcher3.model.WidgetItem;
-import com.android.launcher3.testing.TestActivity;
-import com.android.launcher3.widget.WidgetPreviewLoader.WidgetPreviewLoadedCallback;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Captor;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.Robolectric;
-import org.robolectric.RobolectricTestRunner;
-
-import java.util.Arrays;
-import java.util.Collections;
-
-@RunWith(RobolectricTestRunner.class)
-public class CachingWidgetPreviewLoaderTest {
-    private final Size SIZE_10_10 = new Size(10, 10);
-    private final Size SIZE_20_20 = new Size(20, 20);
-    private static final String TEST_PACKAGE = "com.example.test";
-    private final ComponentName TEST_PROVIDER =
-            new ComponentName(TEST_PACKAGE, ".WidgetProvider");
-    private final ComponentName TEST_PROVIDER2 =
-            new ComponentName(TEST_PACKAGE, ".WidgetProvider2");
-    private final Bitmap BITMAP = Bitmap.createBitmap(10, 10, Bitmap.Config.ARGB_8888);
-    private final Bitmap BITMAP2 = Bitmap.createBitmap(20, 20, Bitmap.Config.ARGB_8888);
-
-
-    @Mock private CancellationSignal mCancellationSignal;
-    @Mock private WidgetPreviewLoader mDelegate;
-    @Mock private IconCache mIconCache;
-    @Mock private DeviceProfile mDeviceProfile;
-    @Mock private LauncherAppWidgetProviderInfo mProviderInfo;
-    @Mock private LauncherAppWidgetProviderInfo mProviderInfo2;
-    @Mock private WidgetPreviewLoadedCallback mPreviewLoadedCallback;
-    @Mock private WidgetPreviewLoadedCallback mPreviewLoadedCallback2;
-    @Captor private ArgumentCaptor<WidgetPreviewLoadedCallback> mCallbackCaptor;
-
-    private TestActivity mTestActivity;
-    private CachingWidgetPreviewLoader mLoader;
-    private WidgetItem mWidgetItem;
-    private WidgetItem mWidgetItem2;
-
-    @Before
-    public void setUp() {
-        MockitoAnnotations.initMocks(this);
-        mLoader = new CachingWidgetPreviewLoader(mDelegate);
-
-        mTestActivity = Robolectric.buildActivity(TestActivity.class).setup().get();
-        mTestActivity.setDeviceProfile(mDeviceProfile);
-
-        when(mDelegate.loadPreview(any(), any(), any(), any())).thenReturn(mCancellationSignal);
-
-        mProviderInfo.provider = TEST_PROVIDER;
-        when(mProviderInfo.getProfile()).thenReturn(new UserHandle(0));
-
-        mProviderInfo2.provider = TEST_PROVIDER2;
-        when(mProviderInfo2.getProfile()).thenReturn(new UserHandle(0));
-
-        InvariantDeviceProfile testProfile = new InvariantDeviceProfile();
-        testProfile.numRows = 5;
-        testProfile.numColumns = 5;
-
-        mWidgetItem = new WidgetItem(mProviderInfo, testProfile, mIconCache);
-        mWidgetItem2 = new WidgetItem(mProviderInfo2, testProfile, mIconCache);
-    }
-
-    @Test
-    public void getPreview_notInCache_shouldReturnNull() {
-        assertThat(mLoader.getPreview(mWidgetItem, SIZE_10_10)).isNull();
-    }
-
-    @Test
-    public void getPreview_notInCache_shouldNotCallDelegate() {
-        mLoader.getPreview(mWidgetItem, SIZE_10_10);
-
-        verifyZeroInteractions(mDelegate);
-    }
-
-    @Test
-    public void getPreview_inCache_shouldReturnCachedBitmap() {
-        loadPreviewIntoCache(mWidgetItem, SIZE_10_10, BITMAP);
-
-        assertThat(mLoader.getPreview(mWidgetItem, SIZE_10_10)).isEqualTo(BITMAP);
-    }
-
-    @Test
-    public void getPreview_otherSizeInCache_shouldReturnNull() {
-        loadPreviewIntoCache(mWidgetItem, SIZE_10_10, BITMAP);
-
-        assertThat(mLoader.getPreview(mWidgetItem, SIZE_20_20)).isNull();
-    }
-
-    @Test
-    public void getPreview_otherItemInCache_shouldReturnNull() {
-        loadPreviewIntoCache(mWidgetItem, SIZE_10_10, BITMAP);
-
-        assertThat(mLoader.getPreview(mWidgetItem2, SIZE_10_10)).isNull();
-    }
-
-    @Test
-    public void getPreview_shouldStoreMultipleSizesPerItem() {
-        loadPreviewIntoCache(mWidgetItem, SIZE_10_10, BITMAP);
-        loadPreviewIntoCache(mWidgetItem, SIZE_20_20, BITMAP2);
-
-        assertThat(mLoader.getPreview(mWidgetItem, SIZE_10_10)).isEqualTo(BITMAP);
-        assertThat(mLoader.getPreview(mWidgetItem, SIZE_20_20)).isEqualTo(BITMAP2);
-    }
-
-    @Test
-    public void loadPreview_notInCache_shouldStartLoading() {
-        mLoader.loadPreview(mTestActivity, mWidgetItem, SIZE_10_10, mPreviewLoadedCallback);
-
-        verify(mDelegate).loadPreview(eq(mTestActivity), eq(mWidgetItem), eq(SIZE_10_10), any());
-        verifyZeroInteractions(mPreviewLoadedCallback);
-    }
-
-    @Test
-    public void loadPreview_thenLoaded_shouldCallBack() {
-        mLoader.loadPreview(mTestActivity, mWidgetItem, SIZE_10_10, mPreviewLoadedCallback);
-        verify(mDelegate).loadPreview(any(), any(), any(), mCallbackCaptor.capture());
-        WidgetPreviewLoadedCallback loaderCallback = mCallbackCaptor.getValue();
-
-        loaderCallback.onPreviewLoaded(BITMAP);
-
-        verify(mPreviewLoadedCallback).onPreviewLoaded(BITMAP);
-    }
-
-    @Test
-    public void loadPreview_thenCancelled_shouldCancelDelegateRequest() {
-        CancellationSignal cancellationSignal =
-                mLoader.loadPreview(mTestActivity, mWidgetItem, SIZE_10_10, mPreviewLoadedCallback);
-
-        cancellationSignal.cancel();
-
-        verify(mCancellationSignal).cancel();
-        verifyZeroInteractions(mPreviewLoadedCallback);
-        assertThat(mLoader.getPreview(mWidgetItem, SIZE_10_10)).isNull();
-    }
-
-    @Test
-    public void loadPreview_thenCancelled_otherCallListening_shouldNotCancelDelegateRequest() {
-        CancellationSignal cancellationSignal1 =
-                mLoader.loadPreview(mTestActivity, mWidgetItem, SIZE_10_10, mPreviewLoadedCallback);
-        mLoader.loadPreview(mTestActivity, mWidgetItem, SIZE_10_10, mPreviewLoadedCallback2);
-
-        cancellationSignal1.cancel();
-
-        verifyZeroInteractions(mCancellationSignal);
-    }
-
-    @Test
-    public void loadPreview_thenCancelled_otherCallListening_loaded_shouldCallBackToNonCancelled() {
-        CancellationSignal cancellationSignal1 =
-                mLoader.loadPreview(mTestActivity, mWidgetItem, SIZE_10_10, mPreviewLoadedCallback);
-        mLoader.loadPreview(mTestActivity, mWidgetItem, SIZE_10_10, mPreviewLoadedCallback2);
-        verify(mDelegate).loadPreview(any(), any(), any(), mCallbackCaptor.capture());
-        WidgetPreviewLoadedCallback loaderCallback = mCallbackCaptor.getValue();
-
-        cancellationSignal1.cancel();
-        loaderCallback.onPreviewLoaded(BITMAP);
-
-        verifyZeroInteractions(mPreviewLoadedCallback);
-        verify(mPreviewLoadedCallback2).onPreviewLoaded(BITMAP);
-        assertThat(mLoader.getPreview(mWidgetItem, SIZE_10_10)).isEqualTo(BITMAP);
-    }
-
-    @Test
-    public void loadPreview_thenCancelled_bothCallsCancelled_shouldCancelDelegateRequest() {
-        CancellationSignal cancellationSignal1 =
-                mLoader.loadPreview(mTestActivity, mWidgetItem, SIZE_10_10, mPreviewLoadedCallback);
-        CancellationSignal cancellationSignal2 =
-                mLoader.loadPreview(
-                        mTestActivity, mWidgetItem, SIZE_10_10, mPreviewLoadedCallback2);
-
-        cancellationSignal1.cancel();
-        cancellationSignal2.cancel();
-
-        verify(mCancellationSignal).cancel();
-        verifyZeroInteractions(mPreviewLoadedCallback);
-        verifyZeroInteractions(mPreviewLoadedCallback2);
-        assertThat(mLoader.getPreview(mWidgetItem, SIZE_10_10)).isNull();
-    }
-
-    @Test
-    public void loadPreview_multipleCallbacks_shouldOnlyCallDelegateOnce() {
-        mLoader.loadPreview(mTestActivity, mWidgetItem, SIZE_10_10, mPreviewLoadedCallback);
-        mLoader.loadPreview(mTestActivity, mWidgetItem, SIZE_10_10, mPreviewLoadedCallback2);
-
-        verify(mDelegate).loadPreview(any(), any(), any(), any());
-    }
-
-    @Test
-    public void loadPreview_multipleCallbacks_shouldForwardResultToEachCallback() {
-        mLoader.loadPreview(mTestActivity, mWidgetItem, SIZE_10_10, mPreviewLoadedCallback);
-        mLoader.loadPreview(mTestActivity, mWidgetItem, SIZE_10_10, mPreviewLoadedCallback2);
-
-        verify(mDelegate).loadPreview(any(), any(), any(), mCallbackCaptor.capture());
-        WidgetPreviewLoadedCallback loaderCallback = mCallbackCaptor.getValue();
-
-        loaderCallback.onPreviewLoaded(BITMAP);
-
-        verify(mPreviewLoadedCallback).onPreviewLoaded(BITMAP);
-        verify(mPreviewLoadedCallback2).onPreviewLoaded(BITMAP);
-    }
-
-    @Test
-    public void loadPreview_inCache_shouldCallBackImmediately() {
-        loadPreviewIntoCache(mWidgetItem, SIZE_10_10, BITMAP);
-        reset(mDelegate);
-
-        mLoader.loadPreview(mTestActivity, mWidgetItem, SIZE_10_10, mPreviewLoadedCallback);
-
-        verify(mPreviewLoadedCallback).onPreviewLoaded(BITMAP);
-        verifyZeroInteractions(mDelegate);
-    }
-
-    @Test
-    public void loadPreview_thenLoaded_thenCancelled_shouldNotRemovePreviewFromCache() {
-        CancellationSignal cancellationSignal =
-                mLoader.loadPreview(mTestActivity, mWidgetItem, SIZE_10_10, mPreviewLoadedCallback);
-        verify(mDelegate).loadPreview(any(), any(), any(), mCallbackCaptor.capture());
-        WidgetPreviewLoadedCallback loaderCallback = mCallbackCaptor.getValue();
-        loaderCallback.onPreviewLoaded(BITMAP);
-
-        cancellationSignal.cancel();
-
-        assertThat(mLoader.getPreview(mWidgetItem, SIZE_10_10)).isEqualTo(BITMAP);
-    }
-
-    @Test
-    public void isPreviewLoaded_notLoaded_shouldReturnFalse() {
-        assertThat(mLoader.isPreviewLoaded(mWidgetItem, SIZE_10_10)).isFalse();
-    }
-
-    @Test
-    public void isPreviewLoaded_otherSizeLoaded_shouldReturnFalse() {
-        loadPreviewIntoCache(mWidgetItem, SIZE_20_20, BITMAP);
-
-        assertThat(mLoader.isPreviewLoaded(mWidgetItem, SIZE_10_10)).isFalse();
-    }
-
-    @Test
-    public void isPreviewLoaded_otherItemLoaded_shouldReturnFalse() {
-        loadPreviewIntoCache(mWidgetItem2, SIZE_10_10, BITMAP);
-
-        assertThat(mLoader.isPreviewLoaded(mWidgetItem, SIZE_10_10)).isFalse();
-    }
-
-    @Test
-    public void isPreviewLoaded_loaded_shouldReturnTrue() {
-        loadPreviewIntoCache(mWidgetItem, SIZE_10_10, BITMAP);
-
-        assertThat(mLoader.isPreviewLoaded(mWidgetItem, SIZE_10_10)).isTrue();
-    }
-
-    @Test
-    public void clearPreviews_notInCache_shouldBeNoOp() {
-        mLoader.clearPreviews(Collections.singletonList(mWidgetItem));
-
-        assertThat(mLoader.isPreviewLoaded(mWidgetItem, SIZE_10_10)).isFalse();
-    }
-
-    @Test
-    public void clearPreviews_inCache_shouldRemovePreview() {
-        loadPreviewIntoCache(mWidgetItem, SIZE_10_10, BITMAP);
-
-        mLoader.clearPreviews(Collections.singletonList(mWidgetItem));
-
-        assertThat(mLoader.isPreviewLoaded(mWidgetItem, SIZE_10_10)).isFalse();
-    }
-
-    @Test
-    public void clearPreviews_inCache_multipleSizes_shouldRemoveAllSizes() {
-        loadPreviewIntoCache(mWidgetItem, SIZE_10_10, BITMAP);
-        loadPreviewIntoCache(mWidgetItem, SIZE_20_20, BITMAP);
-
-        mLoader.clearPreviews(Collections.singletonList(mWidgetItem));
-
-        assertThat(mLoader.isPreviewLoaded(mWidgetItem, SIZE_10_10)).isFalse();
-        assertThat(mLoader.isPreviewLoaded(mWidgetItem, SIZE_20_20)).isFalse();
-    }
-
-    @Test
-    public void clearPreviews_inCache_otherItems_shouldOnlyRemoveSpecifiedItems() {
-        loadPreviewIntoCache(mWidgetItem, SIZE_10_10, BITMAP);
-        loadPreviewIntoCache(mWidgetItem2, SIZE_10_10, BITMAP);
-
-        mLoader.clearPreviews(Collections.singletonList(mWidgetItem));
-
-        assertThat(mLoader.isPreviewLoaded(mWidgetItem, SIZE_10_10)).isFalse();
-        assertThat(mLoader.isPreviewLoaded(mWidgetItem2, SIZE_10_10)).isTrue();
-    }
-
-    @Test
-    public void clearPreviews_inCache_otherItems_shouldRemoveAllSpecifiedItems() {
-        loadPreviewIntoCache(mWidgetItem, SIZE_10_10, BITMAP);
-        loadPreviewIntoCache(mWidgetItem2, SIZE_10_10, BITMAP);
-
-        mLoader.clearPreviews(Arrays.asList(mWidgetItem, mWidgetItem2));
-
-        assertThat(mLoader.isPreviewLoaded(mWidgetItem, SIZE_10_10)).isFalse();
-        assertThat(mLoader.isPreviewLoaded(mWidgetItem2, SIZE_10_10)).isFalse();
-    }
-
-    @Test
-    public void clearPreviews_loading_shouldCancelLoad() {
-        mLoader.loadPreview(mTestActivity, mWidgetItem, SIZE_10_10, mPreviewLoadedCallback);
-
-        mLoader.clearPreviews(Collections.singletonList(mWidgetItem));
-
-        verify(mCancellationSignal).cancel();
-    }
-
-    @Test
-    public void clearAll_cacheEmpty_shouldBeNoOp() {
-        mLoader.clearAll();
-
-        assertThat(mLoader.isPreviewLoaded(mWidgetItem, SIZE_10_10)).isFalse();
-    }
-
-    @Test
-    public void clearAll_inCache_shouldRemovePreview() {
-        loadPreviewIntoCache(mWidgetItem, SIZE_10_10, BITMAP);
-
-        mLoader.clearAll();
-
-        assertThat(mLoader.isPreviewLoaded(mWidgetItem, SIZE_10_10)).isFalse();
-    }
-
-    @Test
-    public void clearAll_inCache_multipleSizes_shouldRemoveAllSizes() {
-        loadPreviewIntoCache(mWidgetItem, SIZE_10_10, BITMAP);
-        loadPreviewIntoCache(mWidgetItem, SIZE_20_20, BITMAP);
-
-        mLoader.clearAll();
-
-        assertThat(mLoader.isPreviewLoaded(mWidgetItem, SIZE_10_10)).isFalse();
-        assertThat(mLoader.isPreviewLoaded(mWidgetItem, SIZE_20_20)).isFalse();
-    }
-
-    @Test
-    public void clearAll_inCache_multipleItems_shouldRemoveAll() {
-        loadPreviewIntoCache(mWidgetItem, SIZE_10_10, BITMAP);
-        loadPreviewIntoCache(mWidgetItem, SIZE_20_20, BITMAP);
-        loadPreviewIntoCache(mWidgetItem2, SIZE_20_20, BITMAP);
-
-        mLoader.clearAll();
-
-        assertThat(mLoader.isPreviewLoaded(mWidgetItem, SIZE_10_10)).isFalse();
-        assertThat(mLoader.isPreviewLoaded(mWidgetItem, SIZE_20_20)).isFalse();
-        assertThat(mLoader.isPreviewLoaded(mWidgetItem2, SIZE_20_20)).isFalse();
-    }
-
-    @Test
-    public void clearAll_loading_shouldCancelLoad() {
-        mLoader.loadPreview(mTestActivity, mWidgetItem, SIZE_10_10, mPreviewLoadedCallback);
-
-        mLoader.clearAll();
-
-        verify(mCancellationSignal).cancel();
-    }
-
-    private void loadPreviewIntoCache(WidgetItem widgetItem, Size size, Bitmap bitmap) {
-        reset(mDelegate);
-        mLoader.loadPreview(mTestActivity, widgetItem, size, ignored -> {});
-        verify(mDelegate).loadPreview(any(), any(), any(), mCallbackCaptor.capture());
-        WidgetPreviewLoadedCallback loaderCallback = mCallbackCaptor.getValue();
-
-        loaderCallback.onPreviewLoaded(bitmap);
-    }
-}
diff --git a/src/com/android/launcher3/AbstractFloatingView.java b/src/com/android/launcher3/AbstractFloatingView.java
index 4979b40..e080537 100644
--- a/src/com/android/launcher3/AbstractFloatingView.java
+++ b/src/com/android/launcher3/AbstractFloatingView.java
@@ -64,7 +64,8 @@
             TYPE_OPTIONS_POPUP,
             TYPE_ICON_SURFACE,
             TYPE_PIN_WIDGET_FROM_EXTERNAL_POPUP,
-            TYPE_WIDGETS_EDUCATION_DIALOG
+            TYPE_WIDGETS_EDUCATION_DIALOG,
+            TYPE_TASKBAR_EDUCATION_DIALOG
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface FloatingViewType {}
@@ -87,18 +88,20 @@
 
     public static final int TYPE_PIN_WIDGET_FROM_EXTERNAL_POPUP = 1 << 14;
     public static final int TYPE_WIDGETS_EDUCATION_DIALOG = 1 << 15;
+    public static final int TYPE_TASKBAR_EDUCATION_DIALOG = 1 << 16;
 
     public static final int TYPE_ALL = TYPE_FOLDER | TYPE_ACTION_POPUP
             | TYPE_WIDGETS_BOTTOM_SHEET | TYPE_WIDGET_RESIZE_FRAME | TYPE_WIDGETS_FULL_SHEET
             | TYPE_ON_BOARD_POPUP | TYPE_DISCOVERY_BOUNCE | TYPE_TASK_MENU
             | TYPE_OPTIONS_POPUP | TYPE_SNACKBAR | TYPE_LISTENER | TYPE_ALL_APPS_EDU
             | TYPE_ICON_SURFACE | TYPE_DRAG_DROP_POPUP | TYPE_PIN_WIDGET_FROM_EXTERNAL_POPUP
-            | TYPE_WIDGETS_EDUCATION_DIALOG;
+            | TYPE_WIDGETS_EDUCATION_DIALOG | TYPE_TASKBAR_EDUCATION_DIALOG;
 
     // Type of popups which should be kept open during launcher rebind
     public static final int TYPE_REBIND_SAFE = TYPE_WIDGETS_FULL_SHEET
             | TYPE_WIDGETS_BOTTOM_SHEET | TYPE_ON_BOARD_POPUP | TYPE_DISCOVERY_BOUNCE
-            | TYPE_ALL_APPS_EDU | TYPE_ICON_SURFACE | TYPE_WIDGETS_EDUCATION_DIALOG;
+            | TYPE_ALL_APPS_EDU | TYPE_ICON_SURFACE | TYPE_WIDGETS_EDUCATION_DIALOG
+            | TYPE_TASKBAR_EDUCATION_DIALOG;
 
     // Usually we show the back button when a floating view is open. Instead, hide for these types.
     public static final int TYPE_HIDE_BACK_BUTTON = TYPE_ON_BOARD_POPUP | TYPE_DISCOVERY_BOUNCE
diff --git a/src/com/android/launcher3/BaseActivity.java b/src/com/android/launcher3/BaseActivity.java
index 9778b61..ec96c6d 100644
--- a/src/com/android/launcher3/BaseActivity.java
+++ b/src/com/android/launcher3/BaseActivity.java
@@ -145,6 +145,7 @@
     /**
      * Returns {@link StatsLogManager} for user event logging.
      */
+    @Override
     public StatsLogManager getStatsLogManager() {
         if (mStatsLogManager == null) {
             mStatsLogManager = StatsLogManager.newInstance(this);
diff --git a/src/com/android/launcher3/BubbleTextView.java b/src/com/android/launcher3/BubbleTextView.java
index 02fe7d9..353e52b 100644
--- a/src/com/android/launcher3/BubbleTextView.java
+++ b/src/com/android/launcher3/BubbleTextView.java
@@ -90,6 +90,8 @@
     private final PointF mTranslationForReorderBounce = new PointF(0, 0);
     private final PointF mTranslationForReorderPreview = new PointF(0, 0);
 
+    private final PointF mTranslationForMoveFromCenterAnimation = new PointF(0, 0);
+
     private float mScaleForReorderBounce = 1f;
 
     private static final Property<BubbleTextView, Float> DOT_SCALE_PROPERTY
@@ -800,8 +802,10 @@
     }
 
     private void updateTranslation() {
-        super.setTranslationX(mTranslationForReorderBounce.x + mTranslationForReorderPreview.x);
-        super.setTranslationY(mTranslationForReorderBounce.y + mTranslationForReorderPreview.y);
+        super.setTranslationX(mTranslationForReorderBounce.x + mTranslationForReorderPreview.x
+                + mTranslationForMoveFromCenterAnimation.x);
+        super.setTranslationY(mTranslationForReorderBounce.y + mTranslationForReorderPreview.y
+                + mTranslationForMoveFromCenterAnimation.y);
     }
 
     public void setReorderBounceOffset(float x, float y) {
@@ -834,6 +838,11 @@
         return mScaleForReorderBounce;
     }
 
+    public void setTranslationForMoveFromCenterAnimation(float x, float y) {
+        mTranslationForMoveFromCenterAnimation.set(x, y);
+        updateTranslation();
+    }
+
     public View getView() {
         return this;
     }
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index 7acec1f..b7d0481 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -17,7 +17,6 @@
 package com.android.launcher3;
 
 import static android.util.DisplayMetrics.DENSITY_DEVICE_STABLE;
-import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
 
 import static com.android.launcher3.ResourceUtils.pxFromDp;
 import static com.android.launcher3.Utilities.dpiFromPx;
@@ -33,11 +32,8 @@
 import android.graphics.Point;
 import android.graphics.PointF;
 import android.graphics.Rect;
-import android.hardware.display.DisplayManager;
 import android.util.DisplayMetrics;
 import android.view.Surface;
-import android.view.WindowInsets;
-import android.view.WindowManager;
 
 import com.android.launcher3.CellLayout.ContainerType;
 import com.android.launcher3.DevicePaddings.DevicePadding;
@@ -183,6 +179,7 @@
     // Overview
     public final boolean overviewShowAsGrid;
     public int overviewTaskMarginPx;
+    public int overviewTaskMarginGridPx;
     public int overviewTaskIconSizePx;
     public int overviewTaskIconDrawableSizePx;
     public int overviewTaskIconDrawableSizeGridPx;
@@ -214,6 +211,8 @@
 
      // Taskbar
     public boolean isTaskbarPresent;
+    // Whether Taskbar will inset the bottom of apps by taskbarSize.
+    public boolean isTaskbarPresentInApps;
     public int taskbarSize;
     // How much of the bottom inset is due to Taskbar rather than other system elements.
     public int nonOverlappingTaskbarInset;
@@ -221,6 +220,7 @@
     // DragController
     public int flingToDeleteThresholdVelocity;
 
+    /** TODO: Once we fully migrate to staged split, remove "isMultiWindowMode" */
     DeviceProfile(Context context, InvariantDeviceProfile inv, Info info, WindowBounds windowBounds,
             boolean isMultiWindowMode, boolean transposeLayoutWithOrientation,
             boolean useTwoPanels) {
@@ -248,7 +248,8 @@
         // Tablet UI does not support emulated landscape.
         isTablet = allowRotation && info.isTablet(windowBounds);
         isPhone = !isTablet;
-        isTwoPanels = isTablet && useTwoPanels;
+        isTwoPanels = isTablet && useTwoPanels
+                && (isLandscape || FeatureFlags.ENABLE_TWO_PANEL_HOME_IN_PORTRAIT.get());
 
         aspectRatio = ((float) Math.max(widthPx, heightPx)) / Math.min(widthPx, heightPx);
         boolean isTallDevice = Float.compare(aspectRatio, TALL_DEVICE_ASPECT_RATIO_THRESHOLD) >= 0;
@@ -267,13 +268,7 @@
             // Taskbar will be added later, but provides bottom insets that we should subtract
             // from availableHeightPx.
             taskbarSize = res.getDimensionPixelSize(R.dimen.taskbar_size);
-            WindowInsets windowInsets =
-                    context.createWindowContext(
-                            context.getSystemService(DisplayManager.class).getDisplay(mInfo.id),
-                            TYPE_APPLICATION, null)
-                    .getSystemService(WindowManager.class)
-                    .getCurrentWindowMetrics().getWindowInsets();
-            nonOverlappingTaskbarInset = taskbarSize - windowInsets.getSystemWindowInsetBottom();
+            nonOverlappingTaskbarInset = taskbarSize - windowBounds.insets.bottom;
             if (nonOverlappingTaskbarInset > 0) {
                 nonFinalAvailableHeightPx -= nonOverlappingTaskbarInset;
             }
@@ -361,8 +356,9 @@
 
         overviewShowAsGrid = isTablet && FeatureFlags.ENABLE_OVERVIEW_GRID.get();
         overviewTaskMarginPx = overviewShowAsGrid
-                ? res.getDimensionPixelSize(R.dimen.overview_task_margin_grid)
+                ? res.getDimensionPixelSize(R.dimen.overview_task_margin_focused)
                 : res.getDimensionPixelSize(R.dimen.overview_task_margin);
+        overviewTaskMarginGridPx = res.getDimensionPixelSize(R.dimen.overview_task_margin_grid);
         overviewTaskIconSizePx = res.getDimensionPixelSize(R.dimen.task_thumbnail_icon_size);
         overviewTaskIconDrawableSizePx =
                 res.getDimensionPixelSize(R.dimen.task_thumbnail_icon_drawable_size);
@@ -612,12 +608,30 @@
         iconScale = Math.min(1f, scale);
         cellScaleToFit = scale;
 
-
         // Workspace
         final boolean isVerticalLayout = isVerticalBarLayout();
-        float invIconSizeDp = isLandscape ? inv.landscapeIconSize : inv.iconSize;
+        float invIconSizeDp;
+        float invIconTextSizeSp;
+
+        if (isTwoPanels) {
+            if (isLandscape) {
+                invIconSizeDp = inv.twoPanelLandscapeIconSize;
+                invIconTextSizeSp = inv.twoPanelLandscapeIconTextSize;
+            } else {
+                invIconSizeDp = inv.twoPanelPortraitIconSize;
+                invIconTextSizeSp = inv.twoPanelPortraitIconTextSize;
+            }
+        } else {
+            if (isLandscape) {
+                invIconSizeDp = inv.landscapeIconSize;
+                invIconTextSizeSp = inv.landscapeIconTextSize;
+            } else {
+                invIconSizeDp = inv.iconSize;
+                invIconTextSizeSp = inv.iconTextSize;
+            }
+        }
+
         iconSizePx = Math.max(1, pxFromDp(invIconSizeDp, mMetrics, iconScale));
-        float invIconTextSizeSp = isLandscape ? inv.landscapeIconTextSize : inv.iconTextSize;
         iconTextSizePx = (int) (pxFromSp(invIconTextSizeSp, mMetrics) * iconScale);
         iconDrawablePaddingPx = (int) (iconDrawablePaddingOriginalPx * iconScale);
 
@@ -772,7 +786,7 @@
         Point padding = getTotalWorkspacePadding();
         // availableWidthPx is the screen width of the device. In 2 panels mode, each panel should
         // only have half of the screen width. In addition, there is only cellLayoutPadding in the
-        // left side of the left panel and the right side of the right panel. There is no
+        // left side of the left most panel and the right most side of the right panel. There is no
         // cellLayoutPadding in the middle.
         int screenWidthPx = isTwoPanels
                 ? availableWidthPx / 2 - padding.x - cellLayoutPaddingLeftRightPx
@@ -1071,6 +1085,7 @@
         writer.println(prefix + "\tnumShownHotseatIcons: " + numShownHotseatIcons);
 
         writer.println(prefix + "\tisTaskbarPresent:" + isTaskbarPresent);
+        writer.println(prefix + "\tisTaskbarPresentInApps:" + isTaskbarPresentInApps);
 
         writer.println(prefix + pxToDpStr("taskbarSize", taskbarSize));
         writer.println(prefix + pxToDpStr("nonOverlappingTaskbarInset",
diff --git a/src/com/android/launcher3/InvariantDeviceProfile.java b/src/com/android/launcher3/InvariantDeviceProfile.java
index 10b3f98..2e14823 100644
--- a/src/com/android/launcher3/InvariantDeviceProfile.java
+++ b/src/com/android/launcher3/InvariantDeviceProfile.java
@@ -35,6 +35,7 @@
 import android.text.TextUtils;
 import android.util.AttributeSet;
 import android.util.DisplayMetrics;
+import android.util.Log;
 import android.util.SparseArray;
 import android.util.TypedValue;
 import android.util.Xml;
@@ -68,6 +69,8 @@
 
     private static final int DEFAULT_TRUE = -1;
     private static final int DEFAULT_SPLIT_DISPLAY = 2;
+    private static final int GRID_ENABLED_ALL_DISPLAYS = 0;
+    private static final int GRID_ENABLED_SINGLE_DISPLAY = 1;
 
     private static final String KEY_IDP_GRID_NAME = "idp_grid_name";
 
@@ -94,12 +97,17 @@
     public int numFolderColumns;
     public float iconSize;
     public float landscapeIconSize;
+    public float twoPanelPortraitIconSize;
+    public float twoPanelLandscapeIconSize;
     public float landscapeIconTextSize;
+    public float twoPanelPortraitIconTextSize;
+    public float twoPanelLandscapeIconTextSize;
     public int iconBitmapSize;
     public int fillResIconDpi;
     public float iconTextSize;
     public float allAppsIconSize;
     public float allAppsIconTextSize;
+    public boolean isSplitDisplay;
 
     public float minCellHeight;
     public float minCellWidth;
@@ -157,9 +165,13 @@
         numFolderColumns = p.numFolderColumns;
         iconSize = p.iconSize;
         landscapeIconSize = p.landscapeIconSize;
+        twoPanelPortraitIconSize = p.twoPanelPortraitIconSize;
+        twoPanelLandscapeIconSize = p.twoPanelLandscapeIconSize;
         iconBitmapSize = p.iconBitmapSize;
         iconTextSize = p.iconTextSize;
         landscapeIconTextSize = p.landscapeIconTextSize;
+        twoPanelPortraitIconTextSize = p.twoPanelPortraitIconTextSize;
+        twoPanelLandscapeIconTextSize = p.twoPanelLandscapeIconTextSize;
         numShownHotseatIcons = p.numShownHotseatIcons;
         numDatabaseHotseatIcons = p.numDatabaseHotseatIcons;
         numAllAppsColumns = p.numAllAppsColumns;
@@ -272,14 +284,19 @@
         numFolderColumns = closestProfile.numFolderColumns;
         isScalable = closestProfile.isScalable;
         devicePaddingId = closestProfile.devicePaddingId;
+        this.isSplitDisplay = isSplitDisplay;
 
         mExtraAttrs = closestProfile.extraAttrs;
 
         iconSize = displayOption.iconSize;
         landscapeIconSize = displayOption.landscapeIconSize;
+        twoPanelPortraitIconSize = displayOption.twoPanelPortraitIconSize;
+        twoPanelLandscapeIconSize = displayOption.twoPanelLandscapeIconSize;
         iconBitmapSize = ResourceUtils.pxFromDp(iconSize, metrics);
         iconTextSize = displayOption.iconTextSize;
         landscapeIconTextSize = displayOption.landscapeIconTextSize;
+        twoPanelPortraitIconTextSize = displayOption.twoPanelPortraitIconTextSize;
+        twoPanelLandscapeIconTextSize = displayOption.twoPanelLandscapeIconTextSize;
         fillResIconDpi = getLauncherIconDensity(iconBitmapSize);
 
         minCellHeight = displayOption.minCellHeight;
@@ -378,16 +395,19 @@
                 if ((type == XmlPullParser.START_TAG)
                         && GridOption.TAG_NAME.equals(parser.getName())) {
 
-                    GridOption gridOption = new GridOption(context, Xml.asAttributeSet(parser));
-                    final int displayDepth = parser.getDepth();
-                    while (((type = parser.next()) != XmlPullParser.END_TAG ||
-                            parser.getDepth() > displayDepth)
-                            && type != XmlPullParser.END_DOCUMENT) {
-                        if ((type == XmlPullParser.START_TAG) && "display-option".equals(
-                                parser.getName())) {
-                            profiles.add(new DisplayOption(gridOption, context,
-                                    Xml.asAttributeSet(parser),
-                                    isSplitDisplay ? DEFAULT_SPLIT_DISPLAY : DEFAULT_TRUE));
+                    GridOption gridOption =
+                            new GridOption(context, Xml.asAttributeSet(parser), isSplitDisplay);
+                    if (gridOption.isEnabled) {
+                        final int displayDepth = parser.getDepth();
+                        while (((type = parser.next()) != XmlPullParser.END_TAG
+                                || parser.getDepth() > displayDepth)
+                                && type != XmlPullParser.END_DOCUMENT) {
+                            if ((type == XmlPullParser.START_TAG) && "display-option".equals(
+                                    parser.getName())) {
+                                profiles.add(new DisplayOption(gridOption, context,
+                                        Xml.asAttributeSet(parser),
+                                        isSplitDisplay ? DEFAULT_SPLIT_DISPLAY : DEFAULT_TRUE));
+                            }
                         }
                     }
                 }
@@ -399,7 +419,7 @@
         ArrayList<DisplayOption> filteredProfiles = new ArrayList<>();
         if (!TextUtils.isEmpty(gridName)) {
             for (DisplayOption option : profiles) {
-                if (gridName.equals(option.grid.name)) {
+                if (gridName.equals(option.grid.name) && option.grid.isEnabled) {
                     filteredProfiles.add(option);
                 }
             }
@@ -418,6 +438,32 @@
         return filteredProfiles;
     }
 
+    /**
+     * @return all the grid options that can be shown on the device
+     */
+    public List<GridOption> parseAllGridOptions(Context context) {
+        List<GridOption> result = new ArrayList<>();
+        try (XmlResourceParser parser = context.getResources().getXml(R.xml.device_profiles)) {
+            final int depth = parser.getDepth();
+            int type;
+            while (((type = parser.next()) != XmlPullParser.END_TAG
+                    || parser.getDepth() > depth) && type != XmlPullParser.END_DOCUMENT) {
+                if ((type == XmlPullParser.START_TAG)
+                        && GridOption.TAG_NAME.equals(parser.getName())) {
+                    GridOption option =
+                            new GridOption(context, Xml.asAttributeSet(parser), isSplitDisplay);
+                    if (option.isEnabled) {
+                        result.add(option);
+                    }
+                }
+            }
+        } catch (IOException | XmlPullParserException e) {
+            Log.e(TAG, "Error parsing device profile", e);
+            return Collections.emptyList();
+        }
+        return result;
+    }
+
     private int getLauncherIconDensity(int requiredSize) {
         // Densities typically defined by an app.
         int[] densityBuckets = new int[] {
@@ -579,6 +625,7 @@
         public final String name;
         public final int numRows;
         public final int numColumns;
+        public final boolean isEnabled;
 
         private final int numFolderRows;
         private final int numFolderColumns;
@@ -598,7 +645,7 @@
 
         private final SparseArray<TypedValue> extraAttrs;
 
-        public GridOption(Context context, AttributeSet attrs) {
+        public GridOption(Context context, AttributeSet attrs, boolean isSplitDisplay) {
             TypedArray a = context.obtainStyledAttributes(
                     attrs, R.styleable.GridDisplayOption);
             name = a.getString(R.styleable.GridDisplayOption_name);
@@ -606,8 +653,10 @@
             numColumns = a.getInt(R.styleable.GridDisplayOption_numColumns, 0);
 
             dbFile = a.getString(R.styleable.GridDisplayOption_dbFile);
-            defaultLayoutId = a.getResourceId(
-                    R.styleable.GridDisplayOption_defaultLayoutId, 0);
+            defaultLayoutId = a.getResourceId(isSplitDisplay && a.hasValue(
+                    R.styleable.GridDisplayOption_defaultSplitDisplayLayoutId)
+                    ? R.styleable.GridDisplayOption_defaultSplitDisplayLayoutId
+                    : R.styleable.GridDisplayOption_defaultLayoutId, 0);
             demoModeLayoutId = a.getResourceId(
                     R.styleable.GridDisplayOption_demoModeLayoutId, defaultLayoutId);
 
@@ -631,6 +680,12 @@
             devicePaddingId = a.getResourceId(
                     R.styleable.GridDisplayOption_devicePaddingId, 0);
 
+            final int enabledInt =
+                    a.getInteger(R.styleable.GridDisplayOption_gridEnabled,
+                            GRID_ENABLED_ALL_DISPLAYS);
+            isEnabled = enabledInt == GRID_ENABLED_ALL_DISPLAYS
+                    || enabledInt == GRID_ENABLED_SINGLE_DISPLAY && !isSplitDisplay;
+
             a.recycle();
             extraAttrs = Themes.createValueMap(context, attrs,
                     IntArray.wrap(R.styleable.GridDisplayOption));
@@ -653,7 +708,11 @@
         private float iconSize;
         private float iconTextSize;
         private float landscapeIconSize;
+        private float twoPanelPortraitIconSize;
+        private float twoPanelLandscapeIconSize;
         private float landscapeIconTextSize;
+        private float twoPanelPortraitIconTextSize;
+        private float twoPanelLandscapeIconTextSize;
         private float allAppsIconSize;
         private float allAppsIconTextSize;
 
@@ -676,9 +735,19 @@
             iconSize = a.getFloat(R.styleable.ProfileDisplayOption_iconImageSize, 0);
             landscapeIconSize = a.getFloat(R.styleable.ProfileDisplayOption_landscapeIconSize,
                     iconSize);
+            twoPanelPortraitIconSize = a.getFloat(
+                    R.styleable.ProfileDisplayOption_twoPanelPortraitIconSize, iconSize);
+            twoPanelLandscapeIconSize = a.getFloat(
+                    R.styleable.ProfileDisplayOption_twoPanelLandscapeIconSize,
+                    landscapeIconSize);
             iconTextSize = a.getFloat(R.styleable.ProfileDisplayOption_iconTextSize, 0);
             landscapeIconTextSize = a.getFloat(
                     R.styleable.ProfileDisplayOption_landscapeIconTextSize, iconTextSize);
+            twoPanelPortraitIconTextSize = a.getFloat(
+                    R.styleable.ProfileDisplayOption_twoPanelPortraitIconTextSize, iconTextSize);
+            twoPanelLandscapeIconTextSize = a.getFloat(
+                    R.styleable.ProfileDisplayOption_twoPanelLandscapeIconTextSize,
+                    landscapeIconTextSize);
 
             allAppsIconSize = a.getFloat(R.styleable.ProfileDisplayOption_allAppsIconSize,
                     iconSize);
@@ -704,9 +773,13 @@
         private DisplayOption multiply(float w) {
             iconSize *= w;
             landscapeIconSize *= w;
+            twoPanelPortraitIconSize *= w;
+            twoPanelLandscapeIconSize *= w;
             allAppsIconSize *= w;
             iconTextSize *= w;
             landscapeIconTextSize *= w;
+            twoPanelPortraitIconTextSize *= w;
+            twoPanelLandscapeIconTextSize *= w;
             allAppsIconTextSize *= w;
             minCellHeight *= w;
             minCellWidth *= w;
@@ -717,9 +790,13 @@
         private DisplayOption add(DisplayOption p) {
             iconSize += p.iconSize;
             landscapeIconSize += p.landscapeIconSize;
+            twoPanelPortraitIconSize += p.twoPanelPortraitIconSize;
+            twoPanelLandscapeIconSize += p.twoPanelLandscapeIconSize;
             allAppsIconSize += p.allAppsIconSize;
             iconTextSize += p.iconTextSize;
             landscapeIconTextSize += p.landscapeIconTextSize;
+            twoPanelPortraitIconTextSize += p.twoPanelPortraitIconTextSize;
+            twoPanelLandscapeIconTextSize += p.twoPanelLandscapeIconTextSize;
             allAppsIconTextSize += p.allAppsIconTextSize;
             minCellHeight += p.minCellHeight;
             minCellWidth += p.minCellWidth;
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 8249887..4d5cc5e 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -36,7 +36,6 @@
 import static com.android.launcher3.LauncherState.NO_SCALE;
 import static com.android.launcher3.LauncherState.SPRING_LOADED;
 import static com.android.launcher3.Utilities.postAsyncCallback;
-import static com.android.launcher3.WorkspaceLayoutManager.LEFT_PANEL_ID;
 import static com.android.launcher3.accessibility.LauncherAccessibilityDelegate.getSupportedActions;
 import static com.android.launcher3.dragndrop.DragLayer.ALPHA_INDEX_LAUNCHER_LOAD;
 import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_BACKGROUND;
@@ -1298,7 +1297,7 @@
             }
 
             if (!foundCellSpan) {
-                mWorkspace.onNoCellFound(layout);
+                mWorkspace.onNoCellFound(layout, info, /* logInstanceId= */ null);
                 return;
             }
 
@@ -1930,7 +1929,7 @@
 
     @Override
     public boolean dispatchKeyEvent(KeyEvent event) {
-        TestLogging.recordEvent(TestProtocol.SEQUENCE_MAIN, "Key event", event);
+        TestLogging.recordKeyEvent(TestProtocol.SEQUENCE_MAIN, "Key event", event);
         return (event.getKeyCode() == KeyEvent.KEYCODE_HOME) || super.dispatchKeyEvent(event);
     }
 
@@ -2099,19 +2098,12 @@
                 ? mWorkspace.getCurrentPageScreenIds() : mPagesToBindSynchronously;
         IntArray actualIds = new IntArray();
 
-        if (mDeviceProfile.isTwoPanels) {
-            actualIds.add(LEFT_PANEL_ID);
-        } else {
-            visibleIds.remove(LEFT_PANEL_ID);
-        }
         IntSet result = new IntSet();
         if (visibleIds.isEmpty()) {
             return result;
         }
         for (int id : orderedScreenIds.toArray()) {
-            if (id != LEFT_PANEL_ID) {
-                actualIds.add(id);
-            }
+            actualIds.add(id);
         }
         int firstId = visibleIds.getArray().get(0);
         if (actualIds.contains(firstId)) {
@@ -2119,7 +2111,7 @@
 
             if (mDeviceProfile.isTwoPanels) {
                 int index = actualIds.indexOf(firstId);
-                int nextIndex = ((int) (index / 2)) * 2;
+                int nextIndex = (index / 2) * 2;
                 if (nextIndex == index) {
                     nextIndex++;
                 }
@@ -2176,12 +2168,7 @@
 
     @Override
     public void bindScreens(IntArray orderedScreenIds) {
-        // Make sure the first screen is at the start if there's no widget panel,
-        // or on the second place if the first is the widget panel
-        boolean isLeftPanelShown =
-                mWorkspace.mWorkspaceScreens.containsKey(LEFT_PANEL_ID);
-        int firstScreenPosition = isLeftPanelShown && orderedScreenIds.size() > 1 ? 1 : 0;
-
+        int firstScreenPosition = 0;
         if (FeatureFlags.QSB_ON_FIRST_SCREEN &&
                 orderedScreenIds.indexOf(Workspace.FIRST_SCREEN_ID) != firstScreenPosition) {
             orderedScreenIds.removeValue(Workspace.FIRST_SCREEN_ID);
@@ -2207,11 +2194,6 @@
                 continue;
             }
 
-            if (screenId == LEFT_PANEL_ID) {
-                // No need to bind the left panel, as its always bound.
-                continue;
-            }
-
             mWorkspace.insertNewWorkspaceScreenBeforeEmptyScreen(screenId);
         }
     }
@@ -2287,11 +2269,6 @@
                 continue;
             }
 
-            // Skip if the item is on the left widget panel but the panel is not shown
-            if (item.screenId == LEFT_PANEL_ID && !getDeviceProfile().isTwoPanels) {
-                continue;
-            }
-
             final View view;
             switch (item.itemType) {
                 case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION:
diff --git a/src/com/android/launcher3/LauncherAppState.java b/src/com/android/launcher3/LauncherAppState.java
index 3d6be69..702b73a 100644
--- a/src/com/android/launcher3/LauncherAppState.java
+++ b/src/com/android/launcher3/LauncherAppState.java
@@ -48,7 +48,6 @@
 import com.android.launcher3.util.SettingsCache;
 import com.android.launcher3.util.SimpleBroadcastReceiver;
 import com.android.launcher3.util.Themes;
-import com.android.launcher3.widget.DatabaseWidgetPreviewLoader;
 import com.android.launcher3.widget.custom.CustomWidgetManager;
 
 public class LauncherAppState {
@@ -64,7 +63,6 @@
     private final LauncherModel mModel;
     private final IconProvider mIconProvider;
     private final IconCache mIconCache;
-    private final DatabaseWidgetPreviewLoader mWidgetCache;
     private final InvariantDeviceProfile mInvariantDeviceProfile;
     private final RunnableList mOnTerminateCallback = new RunnableList();
 
@@ -139,7 +137,6 @@
         mIconProvider =  new IconProvider(context, Themes.isThemedIconEnabled(context));
         mIconCache = new IconCache(mContext, mInvariantDeviceProfile,
                 iconCacheFileName, mIconProvider);
-        mWidgetCache = new DatabaseWidgetPreviewLoader(mContext, mIconCache);
         mModel = new LauncherModel(context, this, mIconCache, new AppFilter(mContext));
         mOnTerminateCallback.add(mIconCache::close);
     }
@@ -155,7 +152,6 @@
         LauncherIcons.clearPool();
         mIconCache.updateIconParams(
                 mInvariantDeviceProfile.fillResIconDpi, mInvariantDeviceProfile.iconBitmapSize);
-        mWidgetCache.refresh();
         mModel.forceReload();
     }
 
@@ -181,10 +177,6 @@
         return mModel;
     }
 
-    public DatabaseWidgetPreviewLoader getWidgetCache() {
-        return mWidgetCache;
-    }
-
     public InvariantDeviceProfile getInvariantDeviceProfile() {
         return mInvariantDeviceProfile;
     }
diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java
index 6966abf..7b6a5bf 100644
--- a/src/com/android/launcher3/LauncherModel.java
+++ b/src/com/android/launcher3/LauncherModel.java
@@ -72,6 +72,7 @@
 import java.util.List;
 import java.util.concurrent.CancellationException;
 import java.util.concurrent.Executor;
+import java.util.function.Consumer;
 import java.util.function.Supplier;
 
 /**
@@ -383,7 +384,13 @@
                     loaderResults.bindWidgets();
                     return true;
                 } else {
-                    startLoaderForResults(loaderResults);
+                    stopLoader();
+                    mLoaderTask = new LoaderTask(
+                            mApp, mBgAllAppsList, mBgDataModel, mModelDelegate, loaderResults);
+
+                    // Always post the loader task, instead of running directly
+                    // (even on same thread) so that we exit any nested synchronized blocks
+                    MODEL_EXECUTOR.post(mLoaderTask);
                 }
             }
         }
@@ -406,25 +413,17 @@
         }
     }
 
-    public void startLoaderForResults(LoaderResults results) {
+    /**
+     * Loads the model if not loaded
+     * @param callback called with the data model upon successful load or null on model thread.
+     */
+    public void loadAsync(Consumer<BgDataModel> callback) {
         synchronized (mLock) {
-            stopLoader();
-            mLoaderTask = new LoaderTask(
-                    mApp, mBgAllAppsList, mBgDataModel, mModelDelegate, results);
-
-            // Always post the loader task, instead of running directly (even on same thread) so
-            // that we exit any nested synchronized blocks
-            MODEL_EXECUTOR.post(mLoaderTask);
-        }
-    }
-
-    public void startLoaderForResultsIfNotLoaded(LoaderResults results) {
-        synchronized (mLock) {
-            if (!isModelLoaded()) {
-                Log.d(TAG, "Workspace not loaded, loading now");
-                startLoaderForResults(results);
+            if (!mModelLoaded && !mIsLoaderTaskRunning) {
+                startLoader();
             }
         }
+        MODEL_EXECUTOR.post(() -> callback.accept(isModelLoaded() ? mBgDataModel : null));
     }
 
     @Override
diff --git a/src/com/android/launcher3/PagedView.java b/src/com/android/launcher3/PagedView.java
index eb3f94c..696e897 100644
--- a/src/com/android/launcher3/PagedView.java
+++ b/src/com/android/launcher3/PagedView.java
@@ -289,7 +289,7 @@
         newPage = Utilities.boundToRange(newPage, 0, getPageCount() - 1);
 
         if (getPanelCount() > 1) {
-            // Always return left panel as new page
+            // Always return left most panel as new page
             newPage = getLeftmostVisiblePageForIndex(newPage);
         }
         return newPage;
@@ -774,7 +774,7 @@
 
         if (panelCount > 1) {
             for (int i = 0; i < childCount; i++) {
-                // In case we have multiple panels, always use left panel's page scroll for all
+                // In case we have multiple panels, always use left most panel's page scroll for all
                 // panels on the screen.
                 int adjustedScroll = outPageScrolls[getLeftmostVisiblePageForIndex(i)];
                 if (outPageScrolls[i] != adjustedScroll) {
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index 83ca08d..42b2033 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -16,8 +16,6 @@
 
 package com.android.launcher3;
 
-import static androidx.annotation.VisibleForTesting.PROTECTED;
-
 import static com.android.launcher3.LauncherAnimUtils.SPRING_LOADED_EXIT_DELAY;
 import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_APPLICATION;
 import static com.android.launcher3.LauncherState.ALL_APPS;
@@ -65,7 +63,7 @@
 import android.view.accessibility.AccessibilityNodeInfo;
 import android.widget.Toast;
 
-import androidx.annotation.VisibleForTesting;
+import androidx.annotation.Nullable;
 
 import com.android.launcher3.accessibility.AccessibleDragListenerAdapter;
 import com.android.launcher3.accessibility.WorkspaceAccessibilityHelper;
@@ -86,6 +84,7 @@
 import com.android.launcher3.icons.BitmapRenderer;
 import com.android.launcher3.icons.FastBitmapDrawable;
 import com.android.launcher3.logger.LauncherAtom;
+import com.android.launcher3.logging.InstanceId;
 import com.android.launcher3.logging.StatsLogManager;
 import com.android.launcher3.logging.StatsLogManager.LauncherEvent;
 import com.android.launcher3.model.data.AppInfo;
@@ -334,7 +333,8 @@
         int paddingBottom = grid.cellLayoutBottomPaddingPx;
 
         int panelCount = getPanelCount();
-        for (int i = mWorkspaceScreens.size() - 1; i >= 0; i--) {
+        int numberOfScreens = mScreenOrder.size();
+        for (int i = 0; i < numberOfScreens; i++) {
             int paddingLeft = paddingLeftRight;
             int paddingRight = paddingLeftRight;
             if (panelCount > 1) {
@@ -349,7 +349,9 @@
                     paddingRight = 0;
                 }
             }
-            mWorkspaceScreens.valueAt(i).setPadding(paddingLeft, 0, paddingRight, paddingBottom);
+            // SparseArrayMap doesn't keep the order
+            mWorkspaceScreens.get(mScreenOrder.get(i))
+                    .setPadding(paddingLeft, 0, paddingRight, paddingBottom);
         }
     }
 
@@ -462,7 +464,6 @@
     }
 
     @Override
-    @VisibleForTesting(otherwise = PROTECTED)
     public int getPanelCount() {
         return isTwoPanelEnabled() ? 2 : super.getPanelCount();
     }
@@ -552,9 +553,6 @@
         if (!FeatureFlags.QSB_ON_FIRST_SCREEN) {
             return;
         }
-        if (isTwoPanelEnabled()) {
-            insertNewWorkspaceScreen(Workspace.LEFT_PANEL_ID, getChildCount());
-        }
 
         // Add the first page
         CellLayout firstPage = insertNewWorkspaceScreen(Workspace.FIRST_SCREEN_ID, getChildCount());
@@ -688,8 +686,9 @@
         CellLayout finalScreen = mWorkspaceScreens.get(finalScreenId);
 
         // If the final screen is empty, convert it to the extra empty screen
-        if (finalScreen.getShortcutsAndWidgets().getChildCount() == 0 &&
-                !finalScreen.isDropPending()) {
+        if (finalScreen != null
+                && finalScreen.getShortcutsAndWidgets().getChildCount() == 0
+                && !finalScreen.isDropPending()) {
             mWorkspaceScreens.remove(finalScreenId);
             mScreenOrder.removeValue(finalScreenId);
 
@@ -1609,7 +1608,7 @@
 
             // Don't accept the drop if there's no room for the item
             if (!foundCell) {
-                onNoCellFound(dropTargetLayout);
+                onNoCellFound(dropTargetLayout, d.dragInfo, d.logInstanceId);
                 return false;
             }
         }
@@ -1911,7 +1910,7 @@
                             lp.cellX, lp.cellY, item.spanX, item.spanY);
                 } else {
                     if (!returnToOriginalCellToPreventShuffling) {
-                        onNoCellFound(dropTargetLayout);
+                        onNoCellFound(dropTargetLayout, d.dragInfo, d.logInstanceId);
                     }
                     if (mDragInfo.cell instanceof LauncherAppWidgetHostView) {
                         d.dragView.detachContentView(/* reattachToPreviousParent= */ true);
@@ -1979,10 +1978,16 @@
         }
     }
 
-    public void onNoCellFound(View dropTargetLayout) {
+    public void onNoCellFound(
+            View dropTargetLayout, ItemInfo itemInfo, @Nullable InstanceId logInstanceId) {
         int strId = mLauncher.isHotseatLayout(dropTargetLayout)
                 ? R.string.hotseat_out_of_space : R.string.out_of_space;
         Toast.makeText(mLauncher, mLauncher.getString(strId), Toast.LENGTH_SHORT).show();
+        StatsLogManager.StatsLogger logger = mStatsLogManager.logger().withItemInfo(itemInfo);
+        if (logInstanceId != null) {
+            logger = logger.withInstanceId(logInstanceId);
+        }
+        logger.log(LauncherEvent.LAUNCHER_ITEM_DROP_FAILED_INSUFFICIENT_SPACE);
     }
 
     /**
diff --git a/src/com/android/launcher3/WorkspaceLayoutManager.java b/src/com/android/launcher3/WorkspaceLayoutManager.java
index 326e3c3..d6302ce 100644
--- a/src/com/android/launcher3/WorkspaceLayoutManager.java
+++ b/src/com/android/launcher3/WorkspaceLayoutManager.java
@@ -32,8 +32,6 @@
     int EXTRA_EMPTY_SCREEN_ID = -201;
     // The is the first screen. It is always present, even if its empty.
     int FIRST_SCREEN_ID = 0;
-    // This panel is shown on the first page if the panel count is greater than 1.
-    int LEFT_PANEL_ID = -777;
 
     /**
      * At bind time, we use the rank (screenId) to compute x and y for hotseat items.
diff --git a/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java b/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java
index 0fb5e77..9faac5b 100644
--- a/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java
+++ b/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java
@@ -188,8 +188,7 @@
     private boolean itemSupportsAccessibleDrag(ItemInfo item) {
         if (item instanceof WorkspaceItemInfo) {
             // Support the action unless the item is in a context menu.
-            return (item.screenId >= 0 || item.screenId == Workspace.LEFT_PANEL_ID)
-                    && item.container != Favorites.CONTAINER_HOTSEAT_PREDICTION;
+            return item.screenId >= 0 && item.container != Favorites.CONTAINER_HOTSEAT_PREDICTION;
         }
         return (item instanceof LauncherAppWidgetInfo)
                 || (item instanceof FolderInfo);
diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java
index da701a8..74c7310 100644
--- a/src/com/android/launcher3/config/FeatureFlags.java
+++ b/src/com/android/launcher3/config/FeatureFlags.java
@@ -219,6 +219,9 @@
     public static final BooleanFlag ENABLE_TASKBAR = getDebugFlag(
             "ENABLE_TASKBAR", true, "Allows a system Taskbar to be shown on larger devices.");
 
+    public static final BooleanFlag ENABLE_TASKBAR_EDU = getDebugFlag("ENABLE_TASKBAR_EDU", false,
+            "Enables showing taskbar education the first time an app is opened.");
+
     public static final BooleanFlag ENABLE_OVERVIEW_GRID = getDebugFlag(
             "ENABLE_OVERVIEW_GRID", true, "Uses grid overview layout. "
             + "Only applicable on large screen devices.");
@@ -227,6 +230,10 @@
             "ENABLE_TWO_PANEL_HOME", true,
             "Uses two panel on home screen. Only applicable on large screen devices.");
 
+    public static final BooleanFlag ENABLE_TWO_PANEL_HOME_IN_PORTRAIT = getDebugFlag(
+            "ENABLE_TWO_PANEL_HOME_IN_PORTRAIT", true,
+            "Uses two panel on home screen in portrait if ENABLE_TWO_PANEL_HOME is enabled.");
+
     public static final BooleanFlag ENABLE_SCRIM_FOR_APP_LAUNCH = getDebugFlag(
             "ENABLE_SCRIM_FOR_APP_LAUNCH", false,
             "Enables scrim during app launch animation.");
diff --git a/src/com/android/launcher3/dragndrop/AddItemActivity.java b/src/com/android/launcher3/dragndrop/AddItemActivity.java
index 92ed18a..466b268 100644
--- a/src/com/android/launcher3/dragndrop/AddItemActivity.java
+++ b/src/com/android/launcher3/dragndrop/AddItemActivity.java
@@ -286,9 +286,7 @@
 
             @Override
             protected void onPostExecute(WidgetItem item) {
-                mWidgetCell.setPreviewSize(item);
-                mWidgetCell.applyFromCellItem(item, mApp.getWidgetCache());
-                mWidgetCell.ensurePreview();
+                mWidgetCell.applyFromCellItem(item);
             }
         }.executeOnExecutor(MODEL_EXECUTOR);
         // TODO: Create a worker looper executor and reuse that everywhere.
diff --git a/src/com/android/launcher3/graphics/GridCustomizationsProvider.java b/src/com/android/launcher3/graphics/GridCustomizationsProvider.java
index e4f5539..fc8d855 100644
--- a/src/com/android/launcher3/graphics/GridCustomizationsProvider.java
+++ b/src/com/android/launcher3/graphics/GridCustomizationsProvider.java
@@ -9,7 +9,6 @@
 import android.content.ContentProvider;
 import android.content.ContentValues;
 import android.content.pm.PackageManager;
-import android.content.res.XmlResourceParser;
 import android.database.Cursor;
 import android.database.MatrixCursor;
 import android.net.Uri;
@@ -23,23 +22,13 @@
 import android.os.Messenger;
 import android.util.ArrayMap;
 import android.util.Log;
-import android.util.Xml;
 
 import com.android.launcher3.InvariantDeviceProfile;
 import com.android.launcher3.InvariantDeviceProfile.GridOption;
-import com.android.launcher3.R;
 import com.android.launcher3.Utilities;
 import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.util.Executors;
 
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
 /**
  * Exposes various launcher grid options and allows the caller to change them.
  * APIs:
@@ -94,7 +83,7 @@
                 MatrixCursor cursor = new MatrixCursor(new String[] {
                         KEY_NAME, KEY_ROWS, KEY_COLS, KEY_PREVIEW_COUNT, KEY_IS_DEFAULT});
                 InvariantDeviceProfile idp = InvariantDeviceProfile.INSTANCE.get(getContext());
-                for (GridOption gridOption : parseAllGridOptions()) {
+                for (GridOption gridOption : idp.parseAllGridOptions(getContext())) {
                     cursor.newRow()
                             .add(KEY_NAME, gridOption.name)
                             .add(KEY_ROWS, gridOption.numRows)
@@ -116,25 +105,6 @@
         }
     }
 
-    private List<GridOption> parseAllGridOptions() {
-        List<GridOption> result = new ArrayList<>();
-        try (XmlResourceParser parser = getContext().getResources().getXml(R.xml.device_profiles)) {
-            final int depth = parser.getDepth();
-            int type;
-            while (((type = parser.next()) != XmlPullParser.END_TAG ||
-                    parser.getDepth() > depth) && type != XmlPullParser.END_DOCUMENT) {
-                if ((type == XmlPullParser.START_TAG)
-                        && GridOption.TAG_NAME.equals(parser.getName())) {
-                    result.add(new GridOption(getContext(), Xml.asAttributeSet(parser)));
-                }
-            }
-        } catch (IOException | XmlPullParserException e) {
-            Log.e(TAG, "Error parsing device profile", e);
-            return Collections.emptyList();
-        }
-        return result;
-    }
-
     @Override
     public String getType(Uri uri) {
         return "vnd.android.cursor.dir/launcher_grid";
@@ -155,9 +125,10 @@
         switch (uri.getPath()) {
             case KEY_DEFAULT_GRID: {
                 String gridName = values.getAsString(KEY_NAME);
+                InvariantDeviceProfile idp = InvariantDeviceProfile.INSTANCE.get(getContext());
                 // Verify that this is a valid grid option
                 GridOption match = null;
-                for (GridOption option : parseAllGridOptions()) {
+                for (GridOption option : idp.parseAllGridOptions(getContext())) {
                     if (option.name.equals(gridName)) {
                         match = option;
                         break;
@@ -167,8 +138,7 @@
                     return 0;
                 }
 
-                InvariantDeviceProfile.INSTANCE.get(getContext())
-                        .setCurrentGrid(getContext(), gridName);
+                idp.setCurrentGrid(getContext(), gridName);
                 return 1;
             }
             case ICON_THEMED:
diff --git a/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java b/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java
index bb726f8..a96de31 100644
--- a/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java
+++ b/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java
@@ -266,22 +266,22 @@
         mHotseat = mRootView.findViewById(R.id.hotseat);
         mHotseat.resetLayout(false);
 
-        if (mDp.isTwoPanels) {
-            CellLayout leftPanel = mRootView.findViewById(R.id.workspace_left);
-            leftPanel.setPadding(mDp.workspacePadding.left + mDp.cellLayoutPaddingLeftRightPx,
-                    mDp.workspacePadding.top,
-                    mDp.workspacePadding.right + mDp.cellLayoutPaddingLeftRightPx,
-                    mDp.workspacePadding.bottom);
-            mWorkspaceScreens.put(LEFT_PANEL_ID, leftPanel);
-        }
-
         CellLayout firstScreen = mRootView.findViewById(R.id.workspace);
         firstScreen.setPadding(mDp.workspacePadding.left + mDp.cellLayoutPaddingLeftRightPx,
                 mDp.workspacePadding.top,
-                mDp.workspacePadding.right + mDp.cellLayoutPaddingLeftRightPx,
+                mDp.workspacePadding.right,
                 mDp.workspacePadding.bottom);
         mWorkspaceScreens.put(FIRST_SCREEN_ID, firstScreen);
 
+        if (mDp.isTwoPanels) {
+            CellLayout rightPanel = mRootView.findViewById(R.id.workspace_right);
+            rightPanel.setPadding(mDp.workspacePadding.left,
+                    mDp.workspacePadding.top,
+                    mDp.workspacePadding.right + mDp.cellLayoutPaddingLeftRightPx,
+                    mDp.workspacePadding.bottom);
+            mWorkspaceScreens.put(PreviewSurfaceRenderer.SECOND_SCREEN_ID, rightPanel);
+        }
+
         if (Utilities.ATLEAST_S) {
             WallpaperColors wallpaperColors = wallpaperColorsOverride != null
                     ? wallpaperColorsOverride
diff --git a/src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java b/src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java
index c7448dc..af006d6 100644
--- a/src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java
+++ b/src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java
@@ -49,7 +49,6 @@
 import com.android.launcher3.model.GridSizeMigrationTaskV2;
 import com.android.launcher3.model.LoaderTask;
 import com.android.launcher3.model.ModelDelegate;
-import com.android.launcher3.model.ModelPreload;
 import com.android.launcher3.util.ComponentKey;
 import com.android.launcher3.util.RunnableList;
 import com.android.launcher3.util.Themes;
@@ -67,6 +66,9 @@
 
     private static final int FADE_IN_ANIMATION_DURATION = 200;
 
+    // The is the second screen. It is always present in two panel, even if its empty.
+    static final int SECOND_SCREEN_ID = 1;
+
     private static final String KEY_HOST_TOKEN = "host_token";
     private static final String KEY_VIEW_WIDTH = "width";
     private static final String KEY_VIEW_HEIGHT = "height";
@@ -164,11 +166,14 @@
                 @Override
                 public void run() {
                     DeviceProfile deviceProfile = mIdp.getDeviceProfile(previewContext);
-                    String query = (deviceProfile.isTwoPanels ? LauncherSettings.Favorites.SCREEN
-                            + " = " + Workspace.LEFT_PANEL_ID + " or " : "")
-                            + LauncherSettings.Favorites.SCREEN + " = " + Workspace.FIRST_SCREEN_ID
+                    String query =
+                            LauncherSettings.Favorites.SCREEN + " = " + Workspace.FIRST_SCREEN_ID
                             + " or " + LauncherSettings.Favorites.CONTAINER + " = "
                             + LauncherSettings.Favorites.CONTAINER_HOTSEAT;
+                    if (deviceProfile.isTwoPanels) {
+                        query += " or " + LauncherSettings.Favorites.SCREEN + " = "
+                                + SECOND_SCREEN_ID;
+                    }
                     loadWorkspace(new ArrayList<>(), LauncherSettings.Favorites.PREVIEW_CONTENT_URI,
                             query);
 
@@ -179,18 +184,13 @@
                 }
             }.run();
         } else {
-            new ModelPreload() {
-
-                @Override
-                public void onComplete(boolean isSuccess) {
-                    if (isSuccess) {
-                        MAIN_EXECUTOR.execute(() ->
-                                renderView(inflationContext, getBgDataModel(), null));
-                    } else {
-                        Log.e(TAG, "Model loading failed");
-                    }
+            LauncherAppState.getInstance(inflationContext).getModel().loadAsync(dataModel -> {
+                if (dataModel != null) {
+                    MAIN_EXECUTOR.execute(() -> renderView(inflationContext, dataModel, null));
+                } else {
+                    Log.e(TAG, "Model loading failed");
                 }
-            }.start(inflationContext);
+            });
         }
     }
 
diff --git a/src/com/android/launcher3/logging/StatsLogManager.java b/src/com/android/launcher3/logging/StatsLogManager.java
index 79e5b5d..d959ee2 100644
--- a/src/com/android/launcher3/logging/StatsLogManager.java
+++ b/src/com/android/launcher3/logging/StatsLogManager.java
@@ -486,7 +486,10 @@
         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)
+        LAUNCHER_TURN_OFF_WORK_APPS_TAP(839),
+
+        @UiEvent(doc = "Launcher item drop failed since there was not enough room on the screen.")
+        LAUNCHER_ITEM_DROP_FAILED_INSUFFICIENT_SPACE(872)
         ;
 
         // ADD MORE
diff --git a/src/com/android/launcher3/model/AddWorkspaceItemsTask.java b/src/com/android/launcher3/model/AddWorkspaceItemsTask.java
index 4f12d0b..a13fa55 100644
--- a/src/com/android/launcher3/model/AddWorkspaceItemsTask.java
+++ b/src/com/android/launcher3/model/AddWorkspaceItemsTask.java
@@ -16,7 +16,6 @@
 package com.android.launcher3.model;
 
 import static com.android.launcher3.WorkspaceLayoutManager.FIRST_SCREEN_ID;
-import static com.android.launcher3.WorkspaceLayoutManager.LEFT_PANEL_ID;
 
 import android.content.Intent;
 import android.content.pm.LauncherActivityInfo;
@@ -297,7 +296,7 @@
 
         int screenCount = workspaceScreens.size();
         // First check the preferred screen.
-        IntSet screensToExclude = IntSet.wrap(LEFT_PANEL_ID);
+        IntSet screensToExclude = new IntSet();
         if (FeatureFlags.QSB_ON_FIRST_SCREEN) {
             screensToExclude.add(FIRST_SCREEN_ID);
         }
diff --git a/src/com/android/launcher3/model/GridSizeMigrationTaskV2.java b/src/com/android/launcher3/model/GridSizeMigrationTaskV2.java
index e64b25c..e7d0749 100644
--- a/src/com/android/launcher3/model/GridSizeMigrationTaskV2.java
+++ b/src/com/android/launcher3/model/GridSizeMigrationTaskV2.java
@@ -38,7 +38,6 @@
 import com.android.launcher3.LauncherAppState;
 import com.android.launcher3.LauncherSettings;
 import com.android.launcher3.Utilities;
-import com.android.launcher3.Workspace;
 import com.android.launcher3.graphics.LauncherPreviewRenderer;
 import com.android.launcher3.model.data.ItemInfo;
 import com.android.launcher3.pm.InstallSessionHelper;
@@ -214,9 +213,6 @@
         // Migrate workspace.
         // First we create a collection of the screens
         List<Integer> screens = new ArrayList<>();
-        if (idp.getDeviceProfile(mContext).isTwoPanels) {
-            screens.add(Workspace.LEFT_PANEL_ID);
-        }
         for (int screenId = 0; screenId <= mDestReader.mLastScreenId; screenId++) {
             screens.add(screenId);
         }
diff --git a/src/com/android/launcher3/model/LoaderTask.java b/src/com/android/launcher3/model/LoaderTask.java
index 41a760b..f4a0eb8 100644
--- a/src/com/android/launcher3/model/LoaderTask.java
+++ b/src/com/android/launcher3/model/LoaderTask.java
@@ -16,7 +16,6 @@
 
 package com.android.launcher3.model;
 
-import static com.android.launcher3.WorkspaceLayoutManager.LEFT_PANEL_ID;
 import static com.android.launcher3.model.BgDataModel.Callbacks.FLAG_HAS_SHORTCUT_PERMISSION;
 import static com.android.launcher3.model.BgDataModel.Callbacks.FLAG_QUIET_MODE_CHANGE_PERMISSION;
 import static com.android.launcher3.model.BgDataModel.Callbacks.FLAG_QUIET_MODE_ENABLED;
@@ -179,11 +178,7 @@
         // Screen set is never empty
         IntArray allScreens = mBgDataModel.collectWorkspaceScreens();
         final int firstScreen = allScreens.get(0);
-
         IntSet firstScreens = IntSet.wrap(firstScreen);
-        if (firstScreen == LEFT_PANEL_ID && allScreens.size() >= 2) {
-            firstScreens.add(allScreens.get(1));
-        }
 
         filterCurrentWorkspaceItems(firstScreens, allItems, firstScreenItems,
                 new ArrayList<>() /* otherScreenItems are ignored */);
diff --git a/src/com/android/launcher3/model/ModelPreload.java b/src/com/android/launcher3/model/ModelPreload.java
deleted file mode 100644
index 756b7da..0000000
--- a/src/com/android/launcher3/model/ModelPreload.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2018 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.model;
-
-import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
-
-import android.content.Context;
-import android.util.Log;
-
-import androidx.annotation.WorkerThread;
-
-import com.android.launcher3.LauncherAppState;
-import com.android.launcher3.LauncherModel;
-import com.android.launcher3.LauncherModel.ModelUpdateTask;
-import com.android.launcher3.model.BgDataModel.Callbacks;
-
-import java.util.concurrent.Executor;
-
-/**
- * Utility class to preload LauncherModel
- */
-public class ModelPreload implements ModelUpdateTask {
-
-    private static final String TAG = "ModelPreload";
-
-    private LauncherAppState mApp;
-    private LauncherModel mModel;
-    private BgDataModel mBgDataModel;
-    private AllAppsList mAllAppsList;
-
-    @Override
-    public final void init(LauncherAppState app, LauncherModel model, BgDataModel dataModel,
-            AllAppsList allAppsList, Executor uiExecutor) {
-        mApp = app;
-        mModel = model;
-        mBgDataModel = dataModel;
-        mAllAppsList = allAppsList;
-    }
-
-    @Override
-    public final void run() {
-        mModel.startLoaderForResultsIfNotLoaded(
-                new LoaderResults(mApp, mBgDataModel, mAllAppsList, new Callbacks[0]));
-        MODEL_EXECUTOR.post(() -> {
-            Log.d(TAG, "Preload completed : " + mModel.isModelLoaded());
-            onComplete(mModel.isModelLoaded());
-        });
-    }
-
-    public BgDataModel getBgDataModel() {
-        return mBgDataModel;
-    }
-
-    /**
-     * Called when the task is complete
-     */
-    @WorkerThread
-    public void onComplete(boolean isSuccess) { }
-
-    public void start(Context context) {
-        LauncherAppState.getInstance(context).getModel().enqueueModelUpdateTask(this);
-    }
-}
\ No newline at end of file
diff --git a/src/com/android/launcher3/model/PackageUpdatedTask.java b/src/com/android/launcher3/model/PackageUpdatedTask.java
index 82b0f7c..83fb3d1 100644
--- a/src/com/android/launcher3/model/PackageUpdatedTask.java
+++ b/src/com/android/launcher3/model/PackageUpdatedTask.java
@@ -123,7 +123,6 @@
                         iconCache.updateIconsForPkg(packages[i], mUser);
                         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.
@@ -148,7 +147,6 @@
                 for (int i = 0; i < N; i++) {
                     if (DEBUG) Log.d(TAG, "mAllAppsList.removePackage " + packages[i]);
                     appsList.removePackage(packages[i], mUser);
-                    app.getWidgetCache().removePackage(packages[i], mUser);
                 }
                 flagOp = FlagOp.addFlag(WorkspaceItemInfo.FLAG_DISABLED_NOT_AVAILABLE);
                 break;
diff --git a/src/com/android/launcher3/pageindicators/PageIndicatorDots.java b/src/com/android/launcher3/pageindicators/PageIndicatorDots.java
index f7c730a..29eefe2 100644
--- a/src/com/android/launcher3/pageindicators/PageIndicatorDots.java
+++ b/src/com/android/launcher3/pageindicators/PageIndicatorDots.java
@@ -53,6 +53,9 @@
     private static final int ENTER_ANIMATION_STAGGERED_DELAY = 150;
     private static final int ENTER_ANIMATION_DURATION = 400;
 
+    private static final int DOT_ACTIVE_ALPHA = 255;
+    private static final int DOT_INACTIVE_ALPHA = 128;
+
     // This value approximately overshoots to 1.5 times the original size.
     private static final float ENTER_ANIMATION_OVERSHOOT_TENSION = 4.9f;
 
@@ -75,8 +78,6 @@
 
     private final Paint mCirclePaint;
     private final float mDotRadius;
-    private final int mActiveColor;
-    private final int mInActiveColor;
     private final boolean mIsRtl;
 
     private int mNumPages;
@@ -110,12 +111,10 @@
 
         mCirclePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
         mCirclePaint.setStyle(Style.FILL);
+        mCirclePaint.setColor(Themes.getAttrColor(context, R.attr.folderPaginationColor));
         mDotRadius = getResources().getDimension(R.dimen.page_indicator_dot_size) / 2;
         setOutlineProvider(new MyOutlineProver());
 
-        mActiveColor = Themes.getColorAccent(context);
-        mInActiveColor = Themes.getAttrColor(context, android.R.attr.colorControlHighlight);
-
         mIsRtl = Utilities.isRtl(getResources());
     }
 
@@ -253,18 +252,18 @@
                 circleGap = -circleGap;
             }
             for (int i = 0; i < mEntryAnimationRadiusFactors.length; i++) {
-                mCirclePaint.setColor(i == mActivePage ? mActiveColor : mInActiveColor);
+                mCirclePaint.setAlpha(i == mActivePage ? DOT_ACTIVE_ALPHA : DOT_INACTIVE_ALPHA);
                 canvas.drawCircle(x, y, mDotRadius * mEntryAnimationRadiusFactors[i], mCirclePaint);
                 x += circleGap;
             }
         } else {
-            mCirclePaint.setColor(mInActiveColor);
+            mCirclePaint.setAlpha(DOT_INACTIVE_ALPHA);
             for (int i = 0; i < mNumPages; i++) {
                 canvas.drawCircle(x, y, mDotRadius, mCirclePaint);
                 x += circleGap;
             }
 
-            mCirclePaint.setColor(mActiveColor);
+            mCirclePaint.setAlpha(DOT_ACTIVE_ALPHA);
             canvas.drawRoundRect(getActiveRect(), mDotRadius, mDotRadius, mCirclePaint);
         }
     }
diff --git a/src/com/android/launcher3/recyclerview/ViewHolderBinder.java b/src/com/android/launcher3/recyclerview/ViewHolderBinder.java
index 5b8d5bc..31436c4 100644
--- a/src/com/android/launcher3/recyclerview/ViewHolderBinder.java
+++ b/src/com/android/launcher3/recyclerview/ViewHolderBinder.java
@@ -17,8 +17,13 @@
 
 import android.view.ViewGroup;
 
+import androidx.annotation.IntDef;
 import androidx.recyclerview.widget.RecyclerView.ViewHolder;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.List;
+
 /**
  * Creates and populates views with data
  *
@@ -26,6 +31,15 @@
  * @param <V> A subclass of {@link ViewHolder} which holds references to views.
  */
 public interface ViewHolderBinder<T, V extends ViewHolder> {
+
+    int POSITION_DEFAULT = 0;
+    int POSITION_FIRST = 1 << 0;
+    int POSITION_LAST = 1 << 1;
+
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(value = {POSITION_DEFAULT, POSITION_FIRST, POSITION_LAST}, flag = true)
+    @interface ListPosition {}
+
     /**
      * Creates a new view, and attach it to the parent {@link ViewGroup}. Then, populates UI
      * references in a {@link ViewHolder}.
@@ -33,7 +47,7 @@
     V newViewHolder(ViewGroup parent);
 
     /** Populate UI references in {@link ViewHolder} with data. */
-    void bindViewHolder(V viewHolder, T data, int position);
+    void bindViewHolder(V viewHolder, T data, @ListPosition int position, List<Object> payloads);
 
     /**
      * Called when the view is recycled. Views are recycled in batches once they are sufficiently
diff --git a/src/com/android/launcher3/statemanager/StateManager.java b/src/com/android/launcher3/statemanager/StateManager.java
index b34af97..24d3fd4 100644
--- a/src/com/android/launcher3/statemanager/StateManager.java
+++ b/src/com/android/launcher3/statemanager/StateManager.java
@@ -18,6 +18,7 @@
 
 import static android.animation.ValueAnimator.areAnimatorsEnabled;
 
+import static com.android.launcher3.LauncherState.NORMAL;
 import static com.android.launcher3.anim.AnimatorPlaybackController.callListenerCommandRecursively;
 import static com.android.launcher3.states.StateAnimationConfig.SKIP_ALL_ANIMATIONS;
 
@@ -27,12 +28,14 @@
 import android.animation.AnimatorSet;
 import android.os.Handler;
 import android.os.Looper;
+import android.util.Log;
 
 import com.android.launcher3.anim.AnimationSuccessListener;
 import com.android.launcher3.anim.AnimatorPlaybackController;
 import com.android.launcher3.anim.PendingAnimation;
 import com.android.launcher3.states.StateAnimationConfig;
 import com.android.launcher3.states.StateAnimationConfig.AnimationFlags;
+import com.android.launcher3.testing.TestProtocol;
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
@@ -253,6 +256,9 @@
         if (listener != null) {
             animation.addListener(listener);
         }
+        if (TestProtocol.sDebugTracing && state == NORMAL) {
+            Log.d(TestProtocol.L3_SWIPE_TO_HOME, "goToStateAnimated: " + state);
+        }
         mUiHandler.post(new StartAnimRunnable(animation));
     }
 
@@ -328,11 +334,17 @@
             @Override
             public void onAnimationStart(Animator animation) {
                 // Change the internal state only when the transition actually starts
+                if (TestProtocol.sDebugTracing && state == NORMAL) {
+                    Log.d(TestProtocol.L3_SWIPE_TO_HOME, "onAnimationStart: " + state);
+                }
                 onStateTransitionStart(state);
             }
 
             @Override
             public void onAnimationSuccess(Animator animator) {
+                if (TestProtocol.sDebugTracing && state == NORMAL) {
+                    Log.d(TestProtocol.L3_SWIPE_TO_HOME, "onAnimationEnd: " + state);
+                }
                 onStateTransitionEnd(state);
             }
         };
diff --git a/src/com/android/launcher3/testing/TestInformationHandler.java b/src/com/android/launcher3/testing/TestInformationHandler.java
index bc5129d..86acff7 100644
--- a/src/com/android/launcher3/testing/TestInformationHandler.java
+++ b/src/com/android/launcher3/testing/TestInformationHandler.java
@@ -102,14 +102,22 @@
                         l -> WidgetsFullSheet.getWidgetsView(l).getCurrentScrollY());
             }
 
+            case TestProtocol.REQUEST_TARGET_INSETS: {
+                return getUIProperty(Bundle::putParcelable, activity -> {
+                    WindowInsets insets = activity.getWindow()
+                            .getDecorView().getRootWindowInsets();
+                    return Insets.max(
+                            insets.getSystemGestureInsets(),
+                            insets.getSystemWindowInsets());
+                }, this::getCurrentActivity);
+            }
+
             case TestProtocol.REQUEST_WINDOW_INSETS: {
-                return getUIProperty(Bundle::putParcelable, a -> {
-                    WindowInsets insets = a.getWindow()
+                return getUIProperty(Bundle::putParcelable, activity -> {
+                    WindowInsets insets = activity.getWindow()
                             .getDecorView().getRootWindowInsets();
                     return Insets.subtract(
-                            Insets.max(
-                                    insets.getSystemGestureInsets(),
-                                    insets.getSystemWindowInsets()),
+                            insets.getSystemWindowInsets(),
                             Insets.of(0, 0, 0, mDeviceProfile.nonOverlappingTaskbarInset));
                 }, this::getCurrentActivity);
             }
@@ -130,13 +138,18 @@
 
             case TestProtocol.REQUEST_IS_TWO_PANELS:
                 response.putBoolean(TestProtocol.TEST_INFO_RESPONSE_FIELD,
-                    mDeviceProfile.isTwoPanels);
+                        mDeviceProfile.isTwoPanels);
                 return response;
 
             case TestProtocol.REQUEST_SET_FORCE_PAUSE_TIMEOUT:
                 TestProtocol.sForcePauseTimeout = Long.parseLong(arg);
                 return response;
 
+            case TestProtocol.REQUEST_GET_HAD_NONTEST_EVENTS:
+                response.putBoolean(
+                        TestProtocol.TEST_INFO_RESPONSE_FIELD, TestLogging.sHadEventsNotFromTest);
+                return response;
+
             default:
                 return null;
         }
diff --git a/src/com/android/launcher3/testing/TestLogging.java b/src/com/android/launcher3/testing/TestLogging.java
index 51e0819..103b565 100644
--- a/src/com/android/launcher3/testing/TestLogging.java
+++ b/src/com/android/launcher3/testing/TestLogging.java
@@ -17,6 +17,8 @@
 package com.android.launcher3.testing;
 
 import android.util.Log;
+import android.view.InputEvent;
+import android.view.KeyEvent;
 import android.view.MotionEvent;
 
 import com.android.launcher3.Utilities;
@@ -25,6 +27,7 @@
 
 public final class TestLogging {
     private static BiConsumer<String, String> sEventConsumer;
+    public static boolean sHadEventsNotFromTest;
 
     private static void recordEventSlow(String sequence, String event) {
         Log.d(TestProtocol.TAPL_EVENTS_TAG, sequence + " / " + event);
@@ -46,9 +49,24 @@
         }
     }
 
+    private static void registerEventNotFromTest(InputEvent event) {
+        if (!sHadEventsNotFromTest && event.getDeviceId() != -1) {
+            sHadEventsNotFromTest = true;
+            Log.d(TestProtocol.PERMANENT_DIAG_TAG, "First event not from test: " + event);
+        }
+    }
+
+    public static void recordKeyEvent(String sequence, String message, KeyEvent event) {
+        if (Utilities.IS_RUNNING_IN_TEST_HARNESS) {
+            recordEventSlow(sequence, message + ": " + event);
+            registerEventNotFromTest(event);
+        }
+    }
+
     public static void recordMotionEvent(String sequence, String message, MotionEvent event) {
         if (Utilities.IS_RUNNING_IN_TEST_HARNESS && event.getAction() != MotionEvent.ACTION_MOVE) {
             recordEventSlow(sequence, message + ": " + event);
+            registerEventNotFromTest(event);
         }
     }
 
diff --git a/src/com/android/launcher3/testing/TestProtocol.java b/src/com/android/launcher3/testing/TestProtocol.java
index d73c4b4..c484811 100644
--- a/src/com/android/launcher3/testing/TestProtocol.java
+++ b/src/com/android/launcher3/testing/TestProtocol.java
@@ -86,6 +86,7 @@
     public static final String REQUEST_APP_LIST_FREEZE_FLAGS = "app-list-freeze-flags";
     public static final String REQUEST_APPS_LIST_SCROLL_Y = "apps-list-scroll-y";
     public static final String REQUEST_WIDGETS_SCROLL_Y = "widgets-scroll-y";
+    public static final String REQUEST_TARGET_INSETS = "target-insets";
     public static final String REQUEST_WINDOW_INSETS = "window-insets";
     public static final String REQUEST_PID = "pid";
     public static final String REQUEST_FORCE_GC = "gc";
@@ -93,6 +94,7 @@
     public static final String REQUEST_RECENT_TASKS_LIST = "recent-tasks-list";
     public static final String REQUEST_START_EVENT_LOGGING = "start-event-logging";
     public static final String REQUEST_GET_TEST_EVENTS = "get-test-events";
+    public static final String REQUEST_GET_HAD_NONTEST_EVENTS = "get-had-nontest-events";
     public static final String REQUEST_STOP_EVENT_LOGGING = "stop-event-logging";
     public static final String REQUEST_CLEAR_DATA = "clear-data";
     public static final String REQUEST_IS_TABLET = "is-tablet";
@@ -116,4 +118,6 @@
     public static final String WORK_PROFILE_REMOVED = "b/159671700";
     public static final String FALLBACK_ACTIVITY_NO_SET = "b/181019015";
     public static final String THIRD_PARTY_LAUNCHER_NOT_SET = "b/187080582";
+    public static final String TASK_VIEW_ID_CRASH = "b/195430732";
+    public static final String L3_SWIPE_TO_HOME = "b/192018189";
 }
diff --git a/src/com/android/launcher3/touch/LandscapePagedViewHandler.java b/src/com/android/launcher3/touch/LandscapePagedViewHandler.java
index 816e5dc..0304a4e 100644
--- a/src/com/android/launcher3/touch/LandscapePagedViewHandler.java
+++ b/src/com/android/launcher3/touch/LandscapePagedViewHandler.java
@@ -26,6 +26,7 @@
 import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_TYPE_MAIN;
 
 import android.content.res.Resources;
+import android.graphics.Point;
 import android.graphics.PointF;
 import android.graphics.Rect;
 import android.graphics.RectF;
@@ -35,12 +36,14 @@
 import android.view.Surface;
 import android.view.VelocityTracker;
 import android.view.View;
+import android.view.ViewGroup;
 import android.view.accessibility.AccessibilityEvent;
 import android.widget.LinearLayout;
 
 import com.android.launcher3.DeviceProfile;
 import com.android.launcher3.R;
 import com.android.launcher3.Utilities;
+import com.android.launcher3.util.SplitConfigurationOptions;
 import com.android.launcher3.util.SplitConfigurationOptions.SplitPositionOption;
 import com.android.launcher3.views.BaseDragLayer;
 
@@ -382,6 +385,47 @@
     }
 
     @Override
+    public void setSplitTaskSwipeRect(DeviceProfile dp, Rect outRect,
+            SplitConfigurationOptions.StagedSplitBounds splitInfo, int desiredStagePosition) {
+        float diff;
+        if (desiredStagePosition == SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT) {
+            diff = outRect.height() * (1f - splitInfo.mLeftTaskPercent);
+            outRect.bottom -= diff;
+        } else {
+            diff = outRect.height() * splitInfo.mLeftTaskPercent;
+            outRect.top += diff;
+        }
+    }
+
+    @Override
+    public void setLeashSplitOffset(Point splitOffset, DeviceProfile dp,
+            SplitConfigurationOptions.StagedSplitBounds splitInfo, int desiredStagePosition) {
+        if (desiredStagePosition == STAGE_POSITION_BOTTOM_OR_RIGHT) {
+            // The preview set is for the bottom/right, inset by top/left task
+            splitOffset.x = splitInfo.mLeftTopBounds.width() + splitInfo.mDividerBounds.width() / 2;
+        }
+    }
+
+    @Override
+    public void setGroupedTaskViewThumbnailBounds(View mSnapshotView, View mSnapshotView2,
+            View taskParent, SplitConfigurationOptions.StagedSplitBounds splitBoundsConfig,
+            DeviceProfile dp) {
+        int spaceAboveSnapshot = dp.overviewTaskThumbnailTopMarginPx;
+        int totalThumbnailHeight = taskParent.getHeight() - spaceAboveSnapshot;
+        int totalThumbnailWidth = taskParent.getWidth();
+        int dividerBar = splitBoundsConfig.mDividerBounds.width() / 2;
+        ViewGroup.LayoutParams primaryLp = mSnapshotView.getLayoutParams();
+        ViewGroup.LayoutParams secondaryLp = mSnapshotView2.getLayoutParams();
+
+        primaryLp.width = totalThumbnailWidth;
+        primaryLp.height = (int)(totalThumbnailHeight * splitBoundsConfig.mLeftTaskPercent);
+
+        secondaryLp.width = totalThumbnailWidth;
+        secondaryLp.height = totalThumbnailHeight - primaryLp.height - dividerBar;
+        mSnapshotView2.setTranslationY(primaryLp.height + spaceAboveSnapshot + dividerBar);
+    }
+
+    @Override
     public FloatProperty getSplitSelectTaskOffset(FloatProperty primary, FloatProperty secondary,
             DeviceProfile deviceProfile) {
         return primary;
diff --git a/src/com/android/launcher3/touch/PagedOrientationHandler.java b/src/com/android/launcher3/touch/PagedOrientationHandler.java
index dae2dde..5ef6950 100644
--- a/src/com/android/launcher3/touch/PagedOrientationHandler.java
+++ b/src/com/android/launcher3/touch/PagedOrientationHandler.java
@@ -19,6 +19,7 @@
 import android.content.res.Resources;
 import android.graphics.Canvas;
 import android.graphics.Matrix;
+import android.graphics.Point;
 import android.graphics.PointF;
 import android.graphics.Rect;
 import android.graphics.RectF;
@@ -31,6 +32,7 @@
 import android.widget.LinearLayout;
 
 import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.util.SplitConfigurationOptions;
 import com.android.launcher3.util.SplitConfigurationOptions.SplitPositionOption;
 import com.android.launcher3.util.SplitConfigurationOptions.StagePosition;
 
@@ -133,6 +135,34 @@
     void getFinalSplitPlaceholderBounds(int splitDividerSize, DeviceProfile dp,
             SplitPositionOption initialSplitOption, Rect out1, Rect out2);
 
+    /**
+     * @param outRect This is expected to be the rect that has the dimensions for a non-split,
+     *                fullscreen task in overview. This will directly be modified.
+     * @param desiredStagePosition Which stage position (topLeft/rightBottom) we want to resize
+     *                           outRect for
+     */
+    void setSplitTaskSwipeRect(DeviceProfile dp, Rect outRect,
+            SplitConfigurationOptions.StagedSplitBounds splitInfo,
+            @SplitConfigurationOptions.StagePosition int desiredStagePosition);
+
+    /**
+     * It's important to note that {@link #setSplitTaskSwipeRect(DeviceProfile, Rect,
+     * SplitConfigurationOptions.StagedSplitBounds, int)} above operates on the outRect based on
+     * launcher's coordinate system, meaning it will treat the outRect as portrait if home rotation
+     * is not allowed.
+     *
+     * However, here the splitOffset is from perspective of TaskViewSimulator, which is in display
+     * orientation coordinates. So, for example, for the fake landscape scenario, even though
+     * launcher is portrait, we inset the bottom/right task by an X coordinate instead of the
+     * usual Y
+     */
+    void setLeashSplitOffset(Point splitOffset, DeviceProfile dp,
+            SplitConfigurationOptions.StagedSplitBounds splitInfo,
+            @SplitConfigurationOptions.StagePosition int desiredStagePosition);
+
+    void setGroupedTaskViewThumbnailBounds(View mSnapshot1, View mSnapshot2, View taskParent,
+            SplitConfigurationOptions.StagedSplitBounds splitBoundsConfig, DeviceProfile dp);
+
     // Overview TaskMenuView methods
     float getTaskMenuX(float x, View thumbnailView, int overScroll);
     float getTaskMenuY(float y, View thumbnailView, int overScroll);
diff --git a/src/com/android/launcher3/touch/PortraitPagedViewHandler.java b/src/com/android/launcher3/touch/PortraitPagedViewHandler.java
index 1253589..bc3c0bf 100644
--- a/src/com/android/launcher3/touch/PortraitPagedViewHandler.java
+++ b/src/com/android/launcher3/touch/PortraitPagedViewHandler.java
@@ -25,6 +25,7 @@
 
 import android.content.res.Resources;
 import android.graphics.Matrix;
+import android.graphics.Point;
 import android.graphics.PointF;
 import android.graphics.Rect;
 import android.graphics.RectF;
@@ -34,12 +35,14 @@
 import android.view.Surface;
 import android.view.VelocityTracker;
 import android.view.View;
+import android.view.ViewGroup;
 import android.view.accessibility.AccessibilityEvent;
 import android.widget.LinearLayout;
 
 import com.android.launcher3.DeviceProfile;
 import com.android.launcher3.R;
 import com.android.launcher3.Utilities;
+import com.android.launcher3.util.SplitConfigurationOptions;
 import com.android.launcher3.util.SplitConfigurationOptions.SplitPositionOption;
 import com.android.launcher3.views.BaseDragLayer;
 
@@ -468,6 +471,77 @@
     }
 
     @Override
+    public void setSplitTaskSwipeRect(DeviceProfile dp, Rect outRect,
+            SplitConfigurationOptions.StagedSplitBounds splitInfo, int desiredStagePosition) {
+        boolean isLandscape = dp.isLandscape;
+        float diff;
+        if (desiredStagePosition == SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT) {
+            if (isLandscape) {
+                diff = outRect.width() * (1f - splitInfo.mLeftTaskPercent);
+                outRect.right -= diff;
+            } else {
+                diff = outRect.height() * (1f - splitInfo.mTopTaskPercent);
+                outRect.bottom -= diff;
+            }
+        } else {
+            if (isLandscape) {
+                diff = outRect.width() * splitInfo.mLeftTaskPercent;
+                outRect.left += diff;
+            } else {
+                diff = outRect.height() * splitInfo.mTopTaskPercent;
+                outRect.top += diff;
+            }
+        }
+    }
+
+    @Override
+    public void setLeashSplitOffset(Point splitOffset, DeviceProfile dp,
+            SplitConfigurationOptions.StagedSplitBounds splitInfo, int desiredStagePosition) {
+        if (desiredStagePosition == STAGE_POSITION_BOTTOM_OR_RIGHT) {
+            if (dp.isLandscape) {
+                splitOffset.x = splitInfo.mLeftTopBounds.width() +
+                        splitInfo.mDividerBounds.width() / 2;
+            } else {
+                splitOffset.y = splitInfo.mLeftTopBounds.height() +
+                        splitInfo.mDividerBounds.height() / 2;
+            }
+        }
+    }
+
+    @Override
+    public void setGroupedTaskViewThumbnailBounds(View mSnapshotView, View mSnapshotView2,
+            View taskParent, SplitConfigurationOptions.StagedSplitBounds splitBoundsConfig,
+            DeviceProfile dp) {
+        int spaceAboveSnapshot = dp.overviewTaskThumbnailTopMarginPx;
+        int totalThumbnailHeight = taskParent.getHeight() - spaceAboveSnapshot;
+        int totalThumbnailWidth = taskParent.getWidth();
+        int dividerBar = (dp.isLandscape ?
+                splitBoundsConfig.mDividerBounds.width() :
+                splitBoundsConfig.mDividerBounds.height())
+                / 2;
+        ViewGroup.LayoutParams primaryLp = mSnapshotView.getLayoutParams();
+        ViewGroup.LayoutParams secondaryLp = mSnapshotView2.getLayoutParams();
+
+        if (dp.isLandscape) {
+            primaryLp.height = totalThumbnailHeight;
+            primaryLp.width = (int)(totalThumbnailWidth * splitBoundsConfig.mLeftTaskPercent);
+
+            secondaryLp.height = totalThumbnailHeight;
+            secondaryLp.width = totalThumbnailWidth - primaryLp.width - dividerBar;
+            mSnapshotView2.setTranslationX(primaryLp.width + dividerBar);
+            mSnapshotView2.setTranslationY(spaceAboveSnapshot);
+        } else {
+            primaryLp.width = totalThumbnailWidth;
+            primaryLp.height = (int)(totalThumbnailHeight * splitBoundsConfig.mTopTaskPercent);
+
+            secondaryLp.width = totalThumbnailWidth;
+            secondaryLp.height = totalThumbnailHeight - primaryLp.height - dividerBar;
+            mSnapshotView2.setTranslationY(primaryLp.height + spaceAboveSnapshot + dividerBar);
+            mSnapshotView2.setTranslationX(0);
+        }
+    }
+
+    @Override
     public FloatProperty getSplitSelectTaskOffset(FloatProperty primary, FloatProperty secondary,
             DeviceProfile dp) {
         if (dp.isLandscape) { // or seascape
diff --git a/src/com/android/launcher3/util/HorizontalInsettableView.java b/src/com/android/launcher3/util/HorizontalInsettableView.java
new file mode 100644
index 0000000..7979bc0
--- /dev/null
+++ b/src/com/android/launcher3/util/HorizontalInsettableView.java
@@ -0,0 +1,35 @@
+/*
+ * 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.util;
+
+/**
+ * Allows the implementing view to add insets to the left and right.
+ */
+public interface HorizontalInsettableView {
+
+    /**
+     * Sets left and right insets for the view so it looks like the width of the view is
+     * reduced when inset is increased.
+     *
+     * The inset is calculated based on the width of the view: e.g. when the width of
+     * the view is 100px then if we apply 0.15f horizontal inset percentage the rendered width
+     * of the view will be 70px with 15px of padding on the left and right sides.
+     *
+     * @param insetPercentage width percentage to inset the content from the left and from the right
+     */
+    void setHorizontalInsets(float insetPercentage);
+
+}
diff --git a/src/com/android/launcher3/util/OnboardingPrefs.java b/src/com/android/launcher3/util/OnboardingPrefs.java
index 40bc9c3..cf1467a 100644
--- a/src/com/android/launcher3/util/OnboardingPrefs.java
+++ b/src/com/android/launcher3/util/OnboardingPrefs.java
@@ -38,6 +38,7 @@
     public static final String HOTSEAT_LONGPRESS_TIP_SEEN = "launcher.hotseat_longpress_tip_seen";
     public static final String SEARCH_EDU_SEEN = "launcher.search_edu_seen";
     public static final String SEARCH_SNACKBAR_COUNT = "launcher.keyboard_snackbar_count";
+    public static final String TASKBAR_EDU_SEEN = "launcher.taskbar_edu_seen";
 
     /**
      * Events that either have happened or have not (booleans).
@@ -45,7 +46,8 @@
     @StringDef(value = {
             HOME_BOUNCE_SEEN,
             HOTSEAT_LONGPRESS_TIP_SEEN,
-            SEARCH_EDU_SEEN
+            SEARCH_EDU_SEEN,
+            TASKBAR_EDU_SEEN
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface EventBoolKey {
diff --git a/src/com/android/launcher3/util/SplitConfigurationOptions.java b/src/com/android/launcher3/util/SplitConfigurationOptions.java
index 573c8bd..b07c21f 100644
--- a/src/com/android/launcher3/util/SplitConfigurationOptions.java
+++ b/src/com/android/launcher3/util/SplitConfigurationOptions.java
@@ -18,6 +18,8 @@
 
 import static java.lang.annotation.RetentionPolicy.SOURCE;
 
+import android.graphics.Rect;
+
 import androidx.annotation.IntDef;
 
 import java.lang.annotation.Retention;
@@ -82,4 +84,37 @@
             mStageType = stageType;
         }
     }
+
+    public static class StagedSplitBounds {
+        public final Rect mLeftTopBounds;
+        public final Rect mRightBottomBounds;
+        public final Rect mDividerBounds;
+        // This class is orientation-agnostic, so we compute both for later use
+        public final float mTopTaskPercent;
+        public final float mLeftTaskPercent;
+
+
+        public StagedSplitBounds(Rect leftTopBounds, Rect rightBottomBounds, Rect dividerBounds) {
+            mLeftTopBounds = leftTopBounds;
+            mRightBottomBounds = rightBottomBounds;
+            mDividerBounds = dividerBounds;
+            float totalHeight = mLeftTopBounds.height()
+                    + mRightBottomBounds.height()
+                    + mDividerBounds.height();
+            float totalWidth = mLeftTopBounds.width()
+                    + mRightBottomBounds.width()
+                    + mDividerBounds.width();
+
+            mLeftTaskPercent = mLeftTopBounds.width() / totalWidth;
+            mTopTaskPercent = mLeftTopBounds.height() / totalHeight;
+        }
+    }
+
+    public static class StagedSplitTaskPosition {
+        public int taskId = -1;
+        @StagePosition
+        public int stagePosition = STAGE_POSITION_UNDEFINED;
+        @StageType
+        public int stageType = STAGE_TYPE_UNDEFINED;
+    }
 }
diff --git a/src/com/android/launcher3/util/WallpaperOffsetInterpolator.java b/src/com/android/launcher3/util/WallpaperOffsetInterpolator.java
index b8554e4..c51f66f 100644
--- a/src/com/android/launcher3/util/WallpaperOffsetInterpolator.java
+++ b/src/com/android/launcher3/util/WallpaperOffsetInterpolator.java
@@ -63,31 +63,37 @@
      *
      * TODO: do different behavior if it's  a live wallpaper?
      */
-    private void wallpaperOffsetForScroll(int scroll, int numScrollingPages, final int[] out) {
+    private void wallpaperOffsetForScroll(int scroll, int numScrollableScreens, final int[] out) {
         out[1] = 1;
 
         // To match the default wallpaper behavior in the system, we default to either the left
         // or right edge on initialization
-        if (mLockedToDefaultPage || numScrollingPages <= 1) {
+        if (mLockedToDefaultPage || numScrollableScreens <= 1) {
             out[0] =  mIsRtl ? 1 : 0;
             return;
         }
 
         // Distribute the wallpaper parallax over a minimum of MIN_PARALLAX_PAGE_SPAN workspace
         // screens, not including the custom screen, and empty screens (if > MIN_PARALLAX_PAGE_SPAN)
-        int numPagesForWallpaperParallax = mWallpaperIsLiveWallpaper ? numScrollingPages :
-                        Math.max(MIN_PARALLAX_PAGE_SPAN, numScrollingPages);
+        int numScreensForWallpaperParallax = mWallpaperIsLiveWallpaper ? numScrollableScreens :
+                        Math.max(MIN_PARALLAX_PAGE_SPAN, numScrollableScreens);
 
         // Offset by the custom screen
-        int leftPageIndex;
-        int rightPageIndex;
-        if (mIsRtl) {
-            rightPageIndex = 0;
-            leftPageIndex = rightPageIndex + numScrollingPages - 1;
-        } else {
-            leftPageIndex = 0;
-            rightPageIndex = leftPageIndex + numScrollingPages - 1;
-        }
+
+        // Don't confuse screens & pages in this function. In a phone UI, we often use screens &
+        // pages interchangeably. However, in a n-panels UI, where n > 1, the screen in this class
+        // means the scrollable screen. Each screen can consist of at most n panels.
+        // Each panel has at most 1 page. Take 5 pages in 2 panels UI as an example, the Workspace
+        // looks as follow:
+        //
+        // S: scrollable screen, P: page, <E>: empty
+        //   S0        S1         S2
+        // _______   _______   ________
+        // |P0|P1|   |P2|P3|   |P4|<E>|
+        // ¯¯¯¯¯¯¯   ¯¯¯¯¯¯¯   ¯¯¯¯¯¯¯¯
+        int endIndex = getNumPagesExcludingEmpty() - 1;
+        final int leftPageIndex = mIsRtl ? endIndex : 0;
+        final int rightPageIndex = mIsRtl ? 0 : endIndex;
 
         // Calculate the scroll range
         int leftPageScrollX = mWorkspace.getScrollForPage(leftPageIndex);
@@ -103,34 +109,56 @@
         int adjustedScroll = scroll - leftPageScrollX -
                 mWorkspace.getLayoutTransitionOffsetForPage(0);
         adjustedScroll = Utilities.boundToRange(adjustedScroll, 0, scrollRange);
-        out[1] = (numPagesForWallpaperParallax - 1) * scrollRange;
+        out[1] = (numScreensForWallpaperParallax - 1) * scrollRange;
 
         // The offset is now distributed 0..1 between the left and right pages that we care about,
         // so we just map that between the pages that we are using for parallax
         int rtlOffset = 0;
         if (mIsRtl) {
             // In RTL, the pages are right aligned, so adjust the offset from the end
-            rtlOffset = out[1] - (numScrollingPages - 1) * scrollRange;
+            rtlOffset = out[1] - (numScrollableScreens - 1) * scrollRange;
         }
-        out[0] = rtlOffset + adjustedScroll * (numScrollingPages - 1);
+        out[0] = rtlOffset + adjustedScroll * (numScrollableScreens - 1);
     }
 
     public float wallpaperOffsetForScroll(int scroll) {
-        wallpaperOffsetForScroll(scroll, getNumScreensExcludingEmpty(), sTempInt);
+        wallpaperOffsetForScroll(scroll, getNumScrollableScreensExcludingEmpty(), sTempInt);
         return ((float) sTempInt[0]) / sTempInt[1];
     }
 
-    private int getNumScreensExcludingEmpty() {
-        int numScrollingPages = mWorkspace.getChildCount();
-        if (numScrollingPages >= MIN_PARALLAX_PAGE_SPAN && mWorkspace.hasExtraEmptyScreen()) {
-            return numScrollingPages - 1;
+    /**
+     * Returns the number of screens that can be scrolled.
+     *
+     * <p>In an usual phone UI, the number of scrollable screens is equal to the number of
+     * CellLayouts because each screen has exactly 1 CellLayout.
+     *
+     * <p>In a n-panels UI, a screen shows n panels. Each panel has at most 1 CellLayout. Take
+     * 2-panels UI as an example: let's say there are 5 CellLayouts in the Workspace. the number of
+     * scrollable screens will be 3 = ⌈5 / 2⌉.
+     */
+    private int getNumScrollableScreensExcludingEmpty() {
+        float numOfPages = getNumPagesExcludingEmpty();
+        return (int) Math.ceil(numOfPages / mWorkspace.getPanelCount());
+    }
+
+    /**
+     * Returns the number of non-empty pages in the Workspace.
+     *
+     * <p>If a user starts dragging on the rightmost (or leftmost in RTL), an empty CellLayout is
+     * added to the Workspace. This empty CellLayout add as a hover-over target for adding a new
+     * page. To avoid janky motion effect, we ignore this empty CellLayout.
+     */
+    private int getNumPagesExcludingEmpty() {
+        int numOfPages = mWorkspace.getChildCount();
+        if (numOfPages >= MIN_PARALLAX_PAGE_SPAN && mWorkspace.hasExtraEmptyScreen()) {
+            return numOfPages - 1;
         } else {
-            return numScrollingPages;
+            return numOfPages;
         }
     }
 
     public void syncWithScroll() {
-        int numScreens = getNumScreensExcludingEmpty();
+        int numScreens = getNumScrollableScreensExcludingEmpty();
         wallpaperOffsetForScroll(mWorkspace.getScrollX(), numScreens, sTempInt);
         Message msg = Message.obtain(mHandler, MSG_UPDATE_OFFSET, sTempInt[0], sTempInt[1],
                 mWindowToken);
diff --git a/src/com/android/launcher3/views/AbstractSlideInView.java b/src/com/android/launcher3/views/AbstractSlideInView.java
index 92ca8a1..8ac40b8 100644
--- a/src/com/android/launcher3/views/AbstractSlideInView.java
+++ b/src/com/android/launcher3/views/AbstractSlideInView.java
@@ -28,6 +28,7 @@
 import android.util.Property;
 import android.view.MotionEvent;
 import android.view.View;
+import android.view.ViewGroup;
 import android.view.animation.Interpolator;
 
 import com.android.launcher3.AbstractFloatingView;
@@ -68,7 +69,7 @@
     protected final SingleAxisSwipeDetector mSwipeDetector;
     protected final ObjectAnimator mOpenCloseAnimator;
 
-    protected View mContent;
+    protected ViewGroup mContent;
     protected final View mColorScrim;
     protected Interpolator mScrollInterpolator;
 
diff --git a/src/com/android/launcher3/views/ActivityContext.java b/src/com/android/launcher3/views/ActivityContext.java
index b95904e..c822213 100644
--- a/src/com/android/launcher3/views/ActivityContext.java
+++ b/src/com/android/launcher3/views/ActivityContext.java
@@ -27,6 +27,7 @@
 import com.android.launcher3.dot.DotInfo;
 import com.android.launcher3.dragndrop.DragController;
 import com.android.launcher3.folder.FolderIcon;
+import com.android.launcher3.logging.StatsLogManager;
 import com.android.launcher3.model.data.ItemInfo;
 import com.android.launcher3.util.ViewCache;
 
@@ -109,6 +110,10 @@
         return null;
     }
 
+    default StatsLogManager getStatsLogManager() {
+        return StatsLogManager.newInstance((Context) this);
+    }
+
     /**
      * Returns the ActivityContext associated with the given Context.
      */
diff --git a/src/com/android/launcher3/views/RecyclerViewFastScroller.java b/src/com/android/launcher3/views/RecyclerViewFastScroller.java
index 1c2534d..2b0f707 100644
--- a/src/com/android/launcher3/views/RecyclerViewFastScroller.java
+++ b/src/com/android/launcher3/views/RecyclerViewFastScroller.java
@@ -40,7 +40,6 @@
 import android.view.WindowInsets;
 import android.widget.TextView;
 
-import androidx.annotation.Nullable;
 import androidx.annotation.RequiresApi;
 import androidx.recyclerview.widget.RecyclerView;
 
@@ -131,7 +130,6 @@
 
     protected BaseRecyclerView mRv;
     private RecyclerView.OnScrollListener mOnScrollListener;
-    @Nullable private OnFastScrollChangeListener mOnFastScrollChangeListener;
 
     private int mDownX;
     private int mDownY;
@@ -208,7 +206,6 @@
             int rvCurrentOffsetY = mRv.getCurrentScrollY();
             if (mRvOffsetY != rvCurrentOffsetY) {
                 mRvOffsetY = mRv.getCurrentScrollY();
-                notifyScrollChanged();
             }
             return;
         }
@@ -216,7 +213,6 @@
         mThumbOffsetY = y;
         invalidate();
         mRvOffsetY = mRv.getCurrentScrollY();
-        notifyScrollChanged();
     }
 
     public int getThumbOffsetY() {
@@ -461,23 +457,4 @@
     public void setIsRecyclerViewFirstChildInParent(boolean isRecyclerViewFirstChildInParent) {
         mIsRecyclerViewFirstChildInParent = isRecyclerViewFirstChildInParent;
     }
-
-    public void setOnFastScrollChangeListener(
-            @Nullable OnFastScrollChangeListener onFastScrollChangeListener) {
-        mOnFastScrollChangeListener = onFastScrollChangeListener;
-    }
-
-    private void notifyScrollChanged() {
-        if (mOnFastScrollChangeListener != null) {
-            mOnFastScrollChangeListener.onScrollChanged();
-        }
-    }
-
-    /**
-     * A callback that is invoked when there is a scroll change in {@link RecyclerViewFastScroller}.
-     */
-    public interface OnFastScrollChangeListener {
-        /** Called when the recycler view scroll has changed. */
-        void onScrollChanged();
-    }
 }
diff --git a/src/com/android/launcher3/views/ScrimView.java b/src/com/android/launcher3/views/ScrimView.java
index 1eb79ad..4c0bfde 100644
--- a/src/com/android/launcher3/views/ScrimView.java
+++ b/src/com/android/launcher3/views/ScrimView.java
@@ -25,23 +25,27 @@
 import android.util.AttributeSet;
 import android.view.View;
 
+import androidx.annotation.NonNull;
 import androidx.core.graphics.ColorUtils;
 
 import com.android.launcher3.BaseActivity;
 import com.android.launcher3.Insettable;
 import com.android.launcher3.util.SystemUiController;
 
+import java.util.ArrayList;
+
 /**
  * Simple scrim which draws a flat color
  */
 public class ScrimView extends View implements Insettable {
     private static final float STATUS_BAR_COLOR_FORCE_UPDATE_THRESHOLD = 0.9f;
 
+    private final ArrayList<Runnable> mOpaquenessListeners = new ArrayList<>(1);
     private SystemUiController mSystemUiController;
-
     private ScrimDrawingController mDrawingController;
     private int mBackgroundColor;
     private boolean mIsVisible = true;
+    private boolean mLastDispatchedOpaqueness;
 
     public ScrimView(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -60,6 +64,7 @@
     @Override
     protected boolean onSetAlpha(int alpha) {
         updateSysUiColors();
+        dispatchVisibilityListenersIfNeeded();
         return super.onSetAlpha(alpha);
     }
 
@@ -67,6 +72,7 @@
     public void setBackgroundColor(int color) {
         mBackgroundColor = color;
         updateSysUiColors();
+        dispatchVisibilityListenersIfNeeded();
         super.setBackgroundColor(color);
     }
 
@@ -74,6 +80,7 @@
     public void onVisibilityAggregated(boolean isVisible) {
         super.onVisibilityAggregated(isVisible);
         mIsVisible = isVisible;
+        dispatchVisibilityListenersIfNeeded();
     }
 
     public boolean isFullyOpaque() {
@@ -108,6 +115,17 @@
         }
     }
 
+    private void dispatchVisibilityListenersIfNeeded() {
+        boolean fullyOpaque = isFullyOpaque();
+        if (mLastDispatchedOpaqueness == fullyOpaque) {
+            return;
+        }
+        mLastDispatchedOpaqueness = fullyOpaque;
+        for (int i = 0; i < mOpaquenessListeners.size(); i++) {
+            mOpaquenessListeners.get(i).run();
+        }
+    }
+
     private SystemUiController getSystemUiController() {
         if (mSystemUiController == null) {
             mSystemUiController = BaseActivity.fromContext(getContext()).getSystemUiController();
@@ -136,6 +154,22 @@
     }
 
     /**
+     * Registers a listener to be notified of whether the scrim is occluding other UI elements.
+     * @see #isFullyOpaque()
+     */
+    public void addOpaquenessListener(@NonNull Runnable listener) {
+        mOpaquenessListeners.add(listener);
+    }
+
+    /**
+     * Removes previously registered listener.
+     * @see #addOpaquenessListener(Runnable)
+     */
+    public void removeOpaquenessListener(@NonNull Runnable listener) {
+        mOpaquenessListeners.remove(listener);
+    }
+
+    /**
      * A Utility interface allowing for other surfaces to draw on ScrimView
      */
     public interface ScrimDrawingController {
diff --git a/src/com/android/launcher3/views/TopRoundedCornerView.java b/src/com/android/launcher3/views/TopRoundedCornerView.java
deleted file mode 100644
index 92cce92..0000000
--- a/src/com/android/launcher3/views/TopRoundedCornerView.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2018 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.views;
-
-import android.content.Context;
-import android.graphics.Canvas;
-import android.graphics.Path;
-import android.graphics.RectF;
-import android.util.AttributeSet;
-
-import com.android.launcher3.util.Themes;
-
-/**
- * View with top rounded corners.
- */
-public class TopRoundedCornerView extends SpringRelativeLayout {
-
-    private final RectF mRect = new RectF();
-    private final Path mClipPath = new Path();
-    private float[] mRadii;
-
-    public TopRoundedCornerView(Context context, AttributeSet attrs, int defStyleAttr) {
-        super(context, attrs, defStyleAttr);
-
-        float radius = Themes.getDialogCornerRadius(context);
-        mRadii = new float[] {radius, radius, radius, radius, 0, 0, 0, 0};
-    }
-
-    public TopRoundedCornerView(Context context, AttributeSet attrs) {
-        this(context, attrs, 0);
-    }
-
-    @Override
-    public void draw(Canvas canvas) {
-        canvas.save();
-        canvas.clipPath(mClipPath);
-        super.draw(canvas);
-        canvas.restore();
-    }
-
-    @Override
-    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
-        mRect.set(0, 0, getMeasuredWidth(), getMeasuredHeight());
-        mClipPath.reset();
-        mClipPath.addRoundRect(mRect, mRadii, Path.Direction.CW);
-    }
-}
diff --git a/src/com/android/launcher3/widget/CachingWidgetPreviewLoader.java b/src/com/android/launcher3/widget/CachingWidgetPreviewLoader.java
deleted file mode 100644
index afceadd..0000000
--- a/src/com/android/launcher3/widget/CachingWidgetPreviewLoader.java
+++ /dev/null
@@ -1,289 +0,0 @@
-/*
- * 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.widget;
-
-import android.graphics.Bitmap;
-import android.os.CancellationSignal;
-import android.util.Size;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.annotation.UiThread;
-import androidx.collection.ArrayMap;
-import androidx.collection.ArraySet;
-
-import com.android.launcher3.BaseActivity;
-import com.android.launcher3.model.WidgetItem;
-import com.android.launcher3.util.ComponentKey;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.stream.Collectors;
-
-/** Wrapper around {@link DatabaseWidgetPreviewLoader} that contains caching logic. */
-public class CachingWidgetPreviewLoader implements WidgetPreviewLoader {
-
-    @NonNull private final WidgetPreviewLoader mDelegate;
-    @NonNull private final Map<ComponentKey, Map<Size, CacheResult>> mCache = new ArrayMap<>();
-
-    public CachingWidgetPreviewLoader(@NonNull WidgetPreviewLoader delegate) {
-        mDelegate = delegate;
-    }
-
-    /** Returns whether the preview is loaded for the item and size. */
-    public boolean isPreviewLoaded(@NonNull WidgetItem item, @NonNull Size previewSize) {
-        return getPreview(item, previewSize) != null;
-    }
-
-    /** Returns the cached preview for the item and size, or null if there is none. */
-    @Nullable
-    public Bitmap getPreview(@NonNull WidgetItem item, @NonNull Size previewSize) {
-        CacheResult cacheResult = getCacheResult(item, previewSize);
-        if (cacheResult instanceof CacheResult.Loaded) {
-            return ((CacheResult.Loaded) cacheResult).mBitmap;
-        } else {
-            return null;
-        }
-    }
-
-    @NonNull
-    private CacheResult getCacheResult(@NonNull WidgetItem item, @NonNull Size previewSize) {
-        synchronized (mCache) {
-            Map<Size, CacheResult> cacheResults = mCache.get(toComponentKey(item));
-            if (cacheResults == null) {
-                return CacheResult.MISS;
-            }
-
-            return cacheResults.getOrDefault(previewSize, CacheResult.MISS);
-        }
-    }
-
-    /**
-     * Puts the result in the cache for the item and size. Returns the value previously in the
-     * cache, or null if there was none.
-     */
-    @Nullable
-    private CacheResult putCacheResult(
-            @NonNull WidgetItem item,
-            @NonNull Size previewSize,
-            @Nullable CacheResult cacheResult) {
-        ComponentKey key = toComponentKey(item);
-        synchronized (mCache) {
-            Map<Size, CacheResult> cacheResults = mCache.getOrDefault(key, new ArrayMap<>());
-            CacheResult previous;
-            if (cacheResult == null) {
-                previous = cacheResults.remove(previewSize);
-                if (cacheResults.isEmpty()) {
-                    mCache.remove(key);
-                } else {
-                    previous = cacheResults.put(previewSize, cacheResult);
-                    mCache.put(key, cacheResults);
-                }
-            } else {
-                previous = cacheResults.put(previewSize, cacheResult);
-                mCache.put(key, cacheResults);
-            }
-            return previous;
-        }
-    }
-
-    private void removeCacheResult(@NonNull WidgetItem item, @NonNull Size previewSize) {
-        ComponentKey key = toComponentKey(item);
-        synchronized (mCache) {
-            Map<Size, CacheResult> cacheResults = mCache.getOrDefault(key, new ArrayMap<>());
-            cacheResults.remove(previewSize);
-            mCache.put(key, cacheResults);
-        }
-    }
-
-    /**
-     * Gets the preview for the widget item and size, using the value in the cache if stored.
-     *
-     * @return a {@link CancellationSignal}, which can cancel the request before it loads
-     */
-    @Override
-    @UiThread
-    @NonNull
-    public CancellationSignal loadPreview(
-            @NonNull BaseActivity activity, @NonNull WidgetItem item, @NonNull Size previewSize,
-            @NonNull WidgetPreviewLoadedCallback callback) {
-        CancellationSignal signal = new CancellationSignal();
-        signal.setOnCancelListener(() -> {
-            synchronized (mCache) {
-                CacheResult cacheResult = getCacheResult(item, previewSize);
-                if (!(cacheResult instanceof CacheResult.Loading)) {
-                    // If the key isn't actively loading, then this is a no-op. Cancelling loading
-                    // shouldn't clear the cache if we've already loaded.
-                    return;
-                }
-
-                CacheResult.Loading prev = (CacheResult.Loading) cacheResult;
-                CacheResult.Loading updated = prev.withoutCallback(callback);
-
-                if (updated.mCallbacks.isEmpty()) {
-                    // If the last callback was removed, then cancel the underlying request in the
-                    // delegate.
-                    prev.mCancellationSignal.cancel();
-                    removeCacheResult(item, previewSize);
-                } else {
-                    // If there are other callbacks still active, then don't cancel the delegate's
-                    // request, just remove this callback from the set.
-                    putCacheResult(item, previewSize, updated);
-                }
-            }
-        });
-
-        synchronized (mCache) {
-            CacheResult cacheResult = getCacheResult(item, previewSize);
-            if (cacheResult instanceof CacheResult.Loaded) {
-                // If the bitmap is already present in the cache, invoke the callback immediately.
-                callback.onPreviewLoaded(((CacheResult.Loaded) cacheResult).mBitmap);
-                return signal;
-            }
-
-            if (cacheResult instanceof CacheResult.Loading) {
-                // If we're already loading the preview for this key, then just add the callback
-                // to the set we'll call after it loads.
-                CacheResult.Loading prev = (CacheResult.Loading) cacheResult;
-                putCacheResult(item, previewSize, prev.withCallback(callback));
-                return signal;
-            }
-
-            CancellationSignal delegateCancellationSignal =
-                    mDelegate.loadPreview(
-                            activity,
-                            item,
-                            previewSize,
-                            preview -> {
-                                CacheResult prev;
-                                synchronized (mCache) {
-                                    prev = putCacheResult(
-                                            item, previewSize, new CacheResult.Loaded(preview));
-                                }
-                                if (prev instanceof CacheResult.Loading) {
-                                    // Notify each stored callback that the preview has loaded.
-                                    ((CacheResult.Loading) prev).mCallbacks
-                                            .forEach(c -> c.onPreviewLoaded(preview));
-                                } else {
-                                    // If there isn't a loading object in the cache, then we were
-                                    // notified before adding this signal to the cache. Just
-                                    // call back to the provided callback, there can't be others.
-                                    callback.onPreviewLoaded(preview);
-                                }
-                            });
-            ArraySet<WidgetPreviewLoadedCallback> callbacks = new ArraySet<>();
-            callbacks.add(callback);
-            putCacheResult(
-                    item,
-                    previewSize,
-                    new CacheResult.Loading(delegateCancellationSignal, callbacks));
-        }
-
-        return signal;
-    }
-
-    /** Clears all cached previews for {@code items}, cancelling any in-progress preview loading. */
-    public void clearPreviews(Iterable<WidgetItem> items) {
-        List<CacheResult> previousCacheResults = new ArrayList<>();
-        synchronized (mCache) {
-            for (WidgetItem item : items) {
-                Map<Size, CacheResult> previousMap = mCache.remove(toComponentKey(item));
-                if (previousMap != null) {
-                    previousCacheResults.addAll(previousMap.values());
-                }
-            }
-        }
-
-        for (CacheResult previousCacheResult : previousCacheResults) {
-            if (previousCacheResult instanceof CacheResult.Loading) {
-                ((CacheResult.Loading) previousCacheResult).mCancellationSignal.cancel();
-            }
-        }
-    }
-
-    /** Clears all cached previews, cancelling any in-progress preview loading. */
-    public void clearAll() {
-        List<CacheResult> previousCacheResults;
-        synchronized (mCache) {
-            previousCacheResults =
-                    mCache
-                    .values()
-                    .stream()
-                    .flatMap(sizeToResult -> sizeToResult.values().stream())
-                    .collect(Collectors.toList());
-            mCache.clear();
-        }
-
-        for (CacheResult previousCacheResult : previousCacheResults) {
-            if (previousCacheResult instanceof CacheResult.Loading) {
-                ((CacheResult.Loading) previousCacheResult).mCancellationSignal.cancel();
-            }
-        }
-    }
-
-    private abstract static class CacheResult {
-        static final CacheResult MISS = new CacheResult() {};
-
-        static final class Loading extends CacheResult {
-            @NonNull final CancellationSignal mCancellationSignal;
-            @NonNull final Set<WidgetPreviewLoadedCallback> mCallbacks;
-
-            Loading(@NonNull CancellationSignal cancellationSignal,
-                    @NonNull Set<WidgetPreviewLoadedCallback> callbacks) {
-                mCancellationSignal = cancellationSignal;
-                mCallbacks = callbacks;
-            }
-
-            @NonNull
-            Loading withCallback(@NonNull WidgetPreviewLoadedCallback callback) {
-                if (mCallbacks.contains(callback)) return this;
-                Set<WidgetPreviewLoadedCallback> newCallbacks =
-                        new ArraySet<>(mCallbacks.size() + 1);
-                newCallbacks.addAll(mCallbacks);
-                newCallbacks.add(callback);
-                return new Loading(mCancellationSignal, newCallbacks);
-            }
-
-            @NonNull
-            Loading withoutCallback(@NonNull WidgetPreviewLoadedCallback callback) {
-                if (!mCallbacks.contains(callback)) return this;
-                Set<WidgetPreviewLoadedCallback> newCallbacks =
-                        new ArraySet<>(mCallbacks.size() - 1);
-                for (WidgetPreviewLoadedCallback existingCallback : mCallbacks) {
-                    if (!existingCallback.equals(callback)) {
-                        newCallbacks.add(existingCallback);
-                    }
-                }
-                return new Loading(mCancellationSignal, newCallbacks);
-            }
-        }
-
-        static final class Loaded extends CacheResult {
-            @NonNull final Bitmap mBitmap;
-
-            Loaded(@NonNull Bitmap bitmap) {
-                mBitmap = bitmap;
-            }
-        }
-    }
-
-    @NonNull
-    private static ComponentKey toComponentKey(@NonNull WidgetItem item) {
-        return new ComponentKey(item.componentName, item.user);
-    }
-}
diff --git a/src/com/android/launcher3/widget/DatabaseWidgetPreviewLoader.java b/src/com/android/launcher3/widget/DatabaseWidgetPreviewLoader.java
index 4ec7e60..aacb9c5 100644
--- a/src/com/android/launcher3/widget/DatabaseWidgetPreviewLoader.java
+++ b/src/com/android/launcher3/widget/DatabaseWidgetPreviewLoader.java
@@ -16,21 +16,10 @@
 package com.android.launcher3.widget;
 
 import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
-import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
 
-import android.content.ComponentName;
-import android.content.ContentValues;
 import android.content.Context;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.res.Resources;
-import android.database.Cursor;
-import android.database.SQLException;
-import android.database.sqlite.SQLiteDatabase;
 import android.graphics.Bitmap;
-import android.graphics.Bitmap.Config;
-import android.graphics.BitmapFactory;
 import android.graphics.Canvas;
 import android.graphics.Color;
 import android.graphics.Paint;
@@ -39,72 +28,40 @@
 import android.graphics.RectF;
 import android.graphics.drawable.Drawable;
 import android.os.AsyncTask;
-import android.os.CancellationSignal;
+import android.os.Handler;
 import android.os.Process;
-import android.os.UserHandle;
 import android.util.Log;
-import android.util.LongSparseArray;
-import android.util.Pair;
 import android.util.Size;
 
 import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
 
-import com.android.launcher3.BaseActivity;
 import com.android.launcher3.DeviceProfile;
-import com.android.launcher3.LauncherFiles;
+import com.android.launcher3.LauncherAppState;
 import com.android.launcher3.R;
 import com.android.launcher3.Utilities;
-import com.android.launcher3.icons.GraphicsUtils;
-import com.android.launcher3.icons.IconCache;
+import com.android.launcher3.icons.BitmapRenderer;
 import com.android.launcher3.icons.LauncherIcons;
 import com.android.launcher3.icons.ShadowGenerator;
+import com.android.launcher3.icons.cache.HandlerRunnable;
 import com.android.launcher3.model.WidgetItem;
 import com.android.launcher3.pm.ShortcutConfigActivityInfo;
-import com.android.launcher3.pm.UserCache;
-import com.android.launcher3.util.ComponentKey;
 import com.android.launcher3.util.Executors;
-import com.android.launcher3.util.PackageUserKey;
-import com.android.launcher3.util.Preconditions;
-import com.android.launcher3.util.SQLiteCacheHelper;
-import com.android.launcher3.util.Thunk;
+import com.android.launcher3.views.ActivityContext;
 import com.android.launcher3.widget.util.WidgetSizes;
 
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.WeakHashMap;
 import java.util.concurrent.ExecutionException;
+import java.util.function.Consumer;
 
-/** {@link WidgetPreviewLoader} that loads preview images from a {@link CacheDb}. */
-public class DatabaseWidgetPreviewLoader implements WidgetPreviewLoader {
+/** Utility class to load widget previews */
+public class DatabaseWidgetPreviewLoader {
 
     private static final String TAG = "WidgetPreviewLoader";
-    private static final boolean DEBUG = false;
-
-    private final HashMap<String, long[]> mPackageVersions = new HashMap<>();
-
-    /**
-     * Weak reference objects, do not prevent their referents from being made finalizable,
-     * finalized, and then reclaimed.
-     * Note: synchronized block used for this variable is expensive and the block should always
-     * be posted to a background thread.
-     */
-    @Thunk final Set<Bitmap> mUnusedBitmaps = Collections.newSetFromMap(new WeakHashMap<>());
 
     private final Context mContext;
-    private final IconCache mIconCache;
-    private final UserCache mUserCache;
-    private final CacheDb mDb;
     private final float mPreviewBoxCornerRadius;
 
-    public DatabaseWidgetPreviewLoader(Context context, IconCache iconCache) {
+    public DatabaseWidgetPreviewLoader(Context context) {
         mContext = context;
-        mIconCache = iconCache;
-        mUserCache = UserCache.INSTANCE.get(context);
-        mDb = new CacheDb(context);
         float previewCornerRadius = RoundedCornerEnforcement.computeEnforcedRadius(context);
         mPreviewBoxCornerRadius = previewCornerRadius > 0
                 ? previewCornerRadius
@@ -117,251 +74,29 @@
      *
      * @return a request id which can be used to cancel the request.
      */
-    @Override
     @NonNull
-    public CancellationSignal loadPreview(
-            @NonNull BaseActivity activity,
+    public HandlerRunnable loadPreview(
             @NonNull WidgetItem item,
             @NonNull Size previewSize,
-            @NonNull WidgetPreviewLoadedCallback callback) {
-        int previewWidth = previewSize.getWidth();
-        int previewHeight = previewSize.getHeight();
-        String size = previewWidth + "x" + previewHeight;
-        WidgetCacheKey key = new WidgetCacheKey(item.componentName, item.user, size);
-
-        PreviewLoadTask task =
-                new PreviewLoadTask(activity, key, item, previewWidth, previewHeight, callback);
-        task.executeOnExecutor(Executors.THREAD_POOL_EXECUTOR);
-
-        CancellationSignal signal = new CancellationSignal();
-        signal.setOnCancelListener(task);
-        return signal;
-    }
-
-    /** Clears the database storing previews. */
-    public void refresh() {
-        mDb.clear();
-    }
-
-    /**
-     * The DB holds the generated previews for various components. Previews can also have different
-     * sizes (landscape vs portrait).
-     */
-    private static class CacheDb extends SQLiteCacheHelper {
-        private static final int DB_VERSION = 9;
-
-        private static final String TABLE_NAME = "shortcut_and_widget_previews";
-        private static final String COLUMN_COMPONENT = "componentName";
-        private static final String COLUMN_USER = "profileId";
-        private static final String COLUMN_SIZE = "size";
-        private static final String COLUMN_PACKAGE = "packageName";
-        private static final String COLUMN_LAST_UPDATED = "lastUpdated";
-        private static final String COLUMN_VERSION = "version";
-        private static final String COLUMN_PREVIEW_BITMAP = "preview_bitmap";
-
-        CacheDb(Context context) {
-            super(context, LauncherFiles.WIDGET_PREVIEWS_DB, DB_VERSION, TABLE_NAME);
-        }
-
-        @Override
-        public void onCreateTable(SQLiteDatabase database) {
-            database.execSQL("CREATE TABLE IF NOT EXISTS "
-                    + TABLE_NAME
-                    + " ("
-                    + COLUMN_COMPONENT
-                    + " TEXT NOT NULL, "
-                    + COLUMN_USER
-                    + " INTEGER NOT NULL, "
-                    + COLUMN_SIZE
-                    + " TEXT NOT NULL, "
-                    + COLUMN_PACKAGE
-                    + " TEXT NOT NULL, "
-                    + COLUMN_LAST_UPDATED
-                    + " INTEGER NOT NULL DEFAULT 0, "
-                    + COLUMN_VERSION
-                    + " INTEGER NOT NULL DEFAULT 0, "
-                    + COLUMN_PREVIEW_BITMAP
-                    + " BLOB, "
-                    + "PRIMARY KEY ("
-                    + COLUMN_COMPONENT
-                    + ", "
-                    + COLUMN_USER
-                    + ", "
-                    + COLUMN_SIZE
-                    + ") "
-                    +
-                    ");");
-        }
-    }
-
-    @Thunk void writeToDb(WidgetCacheKey key, long[] versions, Bitmap preview) {
-        ContentValues values = new ContentValues();
-        values.put(CacheDb.COLUMN_COMPONENT, key.componentName.flattenToShortString());
-        values.put(CacheDb.COLUMN_USER, mUserCache.getSerialNumberForUser(key.user));
-        values.put(CacheDb.COLUMN_SIZE, key.mSize);
-        values.put(CacheDb.COLUMN_PACKAGE, key.componentName.getPackageName());
-        values.put(CacheDb.COLUMN_VERSION, versions[0]);
-        values.put(CacheDb.COLUMN_LAST_UPDATED, versions[1]);
-        values.put(CacheDb.COLUMN_PREVIEW_BITMAP, GraphicsUtils.flattenBitmap(preview));
-        mDb.insertOrReplace(values);
-    }
-
-    /** Removes the package from the preview database. */
-    public void removePackage(String packageName, UserHandle user) {
-        removePackage(packageName, user, mUserCache.getSerialNumberForUser(user));
-    }
-
-    /** Removes the package from the preview database. */
-    public void removePackage(String packageName, UserHandle user, long userSerial) {
-        synchronized (mPackageVersions) {
-            mPackageVersions.remove(packageName);
-        }
-
-        mDb.delete(
-                CacheDb.COLUMN_PACKAGE + " = ? AND " + CacheDb.COLUMN_USER + " = ?",
-                new String[]{packageName, Long.toString(userSerial)});
-    }
-
-    /**
-     * Updates the persistent DB:
-     *   1. Any preview generated for an old package version is removed
-     *   2. Any preview for an absent package is removed
-     * This ensures that we remove entries for packages which changed while the launcher was dead.
-     *
-     * @param packageUser if provided, specifies that list only contains previews for the
-     *                    given package/user, otherwise the list contains all previews
-     */
-    public void removeObsoletePreviews(ArrayList<? extends ComponentKey> list,
-            @Nullable PackageUserKey packageUser) {
-        Preconditions.assertWorkerThread();
-
-        LongSparseArray<HashSet<String>> validPackages = new LongSparseArray<>();
-
-        for (ComponentKey key : list) {
-            final long userId = mUserCache.getSerialNumberForUser(key.user);
-            HashSet<String> packages = validPackages.get(userId);
-            if (packages == null) {
-                packages = new HashSet<>();
-                validPackages.put(userId, packages);
-            }
-            packages.add(key.componentName.getPackageName());
-        }
-
-        LongSparseArray<HashSet<String>> packagesToDelete = new LongSparseArray<>();
-        long passedUserId = packageUser == null ? 0
-                : mUserCache.getSerialNumberForUser(packageUser.mUser);
-        Cursor c = null;
-        try {
-            c = mDb.query(
-                    new String[]{CacheDb.COLUMN_USER, CacheDb.COLUMN_PACKAGE,
-                            CacheDb.COLUMN_LAST_UPDATED, CacheDb.COLUMN_VERSION},
-                    null, null);
-            while (c.moveToNext()) {
-                long userId = c.getLong(0);
-                String pkg = c.getString(1);
-                long lastUpdated = c.getLong(2);
-                long version = c.getLong(3);
-
-                if (packageUser != null && (!pkg.equals(packageUser.mPackageName)
-                        || userId != passedUserId)) {
-                    // This preview is associated with a different package/user, no need to remove.
-                    continue;
-                }
-
-                HashSet<String> packages = validPackages.get(userId);
-                if (packages != null && packages.contains(pkg)) {
-                    long[] versions = getPackageVersion(pkg);
-                    if (versions[0] == version && versions[1] == lastUpdated) {
-                        // Every thing checks out
-                        continue;
-                    }
-                }
-
-                // We need to delete this package.
-                packages = packagesToDelete.get(userId);
-                if (packages == null) {
-                    packages = new HashSet<>();
-                    packagesToDelete.put(userId, packages);
-                }
-                packages.add(pkg);
-            }
-
-            for (int i = 0; i < packagesToDelete.size(); i++) {
-                long userId = packagesToDelete.keyAt(i);
-                UserHandle user = mUserCache.getUserForSerialNumber(userId);
-                for (String pkg : packagesToDelete.valueAt(i)) {
-                    removePackage(pkg, user, userId);
-                }
-            }
-        } catch (SQLException e) {
-            Log.e(TAG, "Error updating widget previews", e);
-        } finally {
-            if (c != null) {
-                c.close();
-            }
-        }
-    }
-
-    /**
-     * Reads the preview bitmap from the DB or null if the preview is not in the DB.
-     */
-    @Thunk Bitmap readFromDb(WidgetCacheKey key, Bitmap recycle, PreviewLoadTask loadTask) {
-        Cursor cursor = null;
-        try {
-            cursor = mDb.query(
-                    new String[]{CacheDb.COLUMN_PREVIEW_BITMAP},
-                    CacheDb.COLUMN_COMPONENT + " = ? AND " + CacheDb.COLUMN_USER + " = ? AND "
-                            + CacheDb.COLUMN_SIZE + " = ?",
-                    new String[]{
-                            key.componentName.flattenToShortString(),
-                            Long.toString(mUserCache.getSerialNumberForUser(key.user)),
-                            key.mSize
-                    });
-            // If cancelled, skip getting the blob and decoding it into a bitmap
-            if (loadTask.isCancelled()) {
-                return null;
-            }
-            if (cursor.moveToNext()) {
-                byte[] blob = cursor.getBlob(0);
-                BitmapFactory.Options opts = new BitmapFactory.Options();
-                opts.inBitmap = recycle;
-                try {
-                    if (!loadTask.isCancelled()) {
-                        return BitmapFactory.decodeByteArray(blob, 0, blob.length, opts);
-                    }
-                } catch (Exception e) {
-                    return null;
-                }
-            }
-        } catch (SQLException e) {
-            Log.w(TAG, "Error loading preview from DB", e);
-        } finally {
-            if (cursor != null) {
-                cursor.close();
-            }
-        }
-        return null;
+            @NonNull Consumer<Bitmap> callback) {
+        Handler handler = Executors.UI_HELPER_EXECUTOR.getHandler();
+        HandlerRunnable<Bitmap> request = new HandlerRunnable<>(handler,
+                () -> generatePreview(item, previewSize.getWidth(), previewSize.getHeight()),
+                MAIN_EXECUTOR,
+                callback);
+        Utilities.postAsyncCallback(handler, request);
+        return request;
     }
 
     /**
      * Returns a generated preview for a widget and if the preview should be saved in persistent
      * storage.
-     * @param launcher
-     * @param item
-     * @param recycle
-     * @param previewWidth
-     * @param previewHeight
-     * @return Pair<Bitmap, Boolean>
      */
-    private Pair<Bitmap, Boolean> generatePreview(BaseActivity launcher, WidgetItem item,
-            Bitmap recycle,
-            int previewWidth, int previewHeight) {
+    private Bitmap generatePreview(WidgetItem item, int previewWidth, int previewHeight) {
         if (item.widgetInfo != null) {
-            return generateWidgetPreview(launcher, item.widgetInfo,
-                    previewWidth, recycle, null);
+            return generateWidgetPreview(item.widgetInfo, previewWidth, null);
         } else {
-            return new Pair<>(generateShortcutPreview(launcher, item.activityInfo,
-                    previewWidth, previewHeight, recycle), false);
+            return generateShortcutPreview(item.activityInfo, previewWidth, previewHeight);
         }
     }
 
@@ -369,16 +104,12 @@
      * Generates the widget preview from either the {@link WidgetManagerHelper} or cache
      * and add badge at the bottom right corner.
      *
-     * @param launcher
      * @param info                        information about the widget
      * @param maxPreviewWidth             width of the preview on either workspace or tray
-     * @param preview                     bitmap that can be recycled
      * @param preScaledWidthOut           return the width of the returned bitmap
-     * @return Pair<Bitmap (the preview) , Boolean (should be stored in db)>
      */
-    public Pair<Bitmap, Boolean> generateWidgetPreview(BaseActivity launcher,
-            LauncherAppWidgetProviderInfo info,
-            int maxPreviewWidth, Bitmap preview, int[] preScaledWidthOut) {
+    public Bitmap generateWidgetPreview(LauncherAppWidgetProviderInfo info,
+            int maxPreviewWidth, int[] preScaledWidthOut) {
         // Load the preview image if possible
         if (maxPreviewWidth < 0) maxPreviewWidth = Integer.MAX_VALUE;
 
@@ -409,117 +140,97 @@
         int previewWidth;
         int previewHeight;
 
-        boolean savePreviewImage = widgetPreviewExists || info.previewImage == 0;
+        DeviceProfile dp = ActivityContext.lookupContext(mContext).getDeviceProfile();
 
         if (widgetPreviewExists && drawable.getIntrinsicWidth() > 0
                 && drawable.getIntrinsicHeight() > 0) {
             previewWidth = drawable.getIntrinsicWidth();
             previewHeight = drawable.getIntrinsicHeight();
         } else {
-            DeviceProfile dp = launcher.getDeviceProfile();
             Size widgetSize = WidgetSizes.getWidgetPaddedSizePx(mContext, info.provider, dp, spanX,
                     spanY);
             previewWidth = widgetSize.getWidth();
             previewHeight = widgetSize.getHeight();
         }
 
-        // Scale to fit width only - let the widget preview be clipped in the
-        // vertical dimension
-        float scale = 1f;
         if (preScaledWidthOut != null) {
             preScaledWidthOut[0] = previewWidth;
         }
-        if (previewWidth > maxPreviewWidth) {
-            scale = maxPreviewWidth / (float) (previewWidth);
-        }
+        // Scale to fit width only - let the widget preview be clipped in the
+        // vertical dimension
+        final float scale = previewWidth > maxPreviewWidth
+                ? (maxPreviewWidth / (float) (previewWidth)) : 1f;
         if (scale != 1f) {
             previewWidth = Math.max((int) (scale * previewWidth), 1);
             previewHeight = Math.max((int) (scale * previewHeight), 1);
         }
 
-        final Canvas c = new Canvas();
-        if (preview == null) {
-            // If no bitmap was provided, then allocate a new one with the right size.
-            preview = Bitmap.createBitmap(previewWidth, previewHeight, Config.ARGB_8888);
-            c.setBitmap(preview);
-        } else {
-            // If a bitmap was passed in, attempt to reconfigure the bitmap to the same dimensions
-            // as the preview.
-            try {
-                preview.reconfigure(previewWidth, previewHeight, preview.getConfig());
-            } catch (IllegalArgumentException e) {
-                // This occurs if the preview can't be reconfigured for any reason. In this case,
-                // allocate a new bitmap with the right size.
-                preview = Bitmap.createBitmap(previewWidth, previewHeight, Config.ARGB_8888);
-            }
+        final int previewWidthF = previewWidth;
+        final int previewHeightF = previewHeight;
+        final Drawable drawableF = drawable;
 
-            c.setBitmap(preview);
-            c.drawColor(0, PorterDuff.Mode.CLEAR);
-        }
-
-        // Draw the scaled preview into the final bitmap
-        if (widgetPreviewExists) {
-            drawable.setBounds(0, 0, previewWidth, previewHeight);
-            drawable.draw(c);
-        } else {
-            RectF boxRect;
-
-            // Draw horizontal and vertical lines to represent individual columns.
-            final Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);
-
-            if (Utilities.ATLEAST_S) {
-                boxRect = new RectF(/* left= */ 0, /* top= */ 0, /* right= */
-                        previewWidth, /* bottom= */ previewHeight);
-
-                p.setStyle(Paint.Style.FILL);
-                p.setColor(Color.WHITE);
-                float roundedCorner = mContext.getResources().getDimension(
-                        android.R.dimen.system_app_widget_background_radius);
-                c.drawRoundRect(boxRect, roundedCorner, roundedCorner, p);
+        return BitmapRenderer.createHardwareBitmap(previewWidth, previewHeight, c -> {
+            // Draw the scaled preview into the final bitmap
+            if (widgetPreviewExists) {
+                drawableF.setBounds(0, 0, previewWidthF, previewHeightF);
+                drawableF.draw(c);
             } else {
-                boxRect = drawBoxWithShadow(c, previewWidth, previewHeight);
-            }
+                RectF boxRect;
 
-            p.setStyle(Paint.Style.STROKE);
-            p.setStrokeWidth(mContext.getResources()
-                    .getDimension(R.dimen.widget_preview_cell_divider_width));
-            p.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
+                // Draw horizontal and vertical lines to represent individual columns.
+                final Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);
 
-            float t = boxRect.left;
-            float tileSize = boxRect.width() / spanX;
-            for (int i = 1; i < spanX; i++) {
-                t += tileSize;
-                c.drawLine(t, 0, t, previewHeight, p);
-            }
+                if (Utilities.ATLEAST_S) {
+                    boxRect = new RectF(/* left= */ 0, /* top= */ 0, /* right= */
+                            previewWidthF, /* bottom= */ previewHeightF);
 
-            t = boxRect.top;
-            tileSize = boxRect.height() / spanY;
-            for (int i = 1; i < spanY; i++) {
-                t += tileSize;
-                c.drawLine(0, t, previewWidth, t, p);
-            }
-
-            // Draw icon in the center.
-            try {
-                Drawable icon =
-                        mIconCache.getFullResIcon(info.provider.getPackageName(), info.icon);
-                if (icon != null) {
-                    int appIconSize = launcher.getDeviceProfile().iconSizePx;
-                    int iconSize = (int) Math.min(appIconSize * scale,
-                            Math.min(boxRect.width(), boxRect.height()));
-
-                    icon = mutateOnMainThread(icon);
-                    int hoffset = (previewWidth - iconSize) / 2;
-                    int yoffset = (previewHeight - iconSize) / 2;
-                    icon.setBounds(hoffset, yoffset, hoffset + iconSize, yoffset + iconSize);
-                    icon.draw(c);
+                    p.setStyle(Paint.Style.FILL);
+                    p.setColor(Color.WHITE);
+                    float roundedCorner = mContext.getResources().getDimension(
+                            android.R.dimen.system_app_widget_background_radius);
+                    c.drawRoundRect(boxRect, roundedCorner, roundedCorner, p);
+                } else {
+                    boxRect = drawBoxWithShadow(c, previewWidthF, previewHeightF);
                 }
-            } catch (Resources.NotFoundException e) {
-                savePreviewImage = false;
+
+                p.setStyle(Paint.Style.STROKE);
+                p.setStrokeWidth(mContext.getResources()
+                        .getDimension(R.dimen.widget_preview_cell_divider_width));
+                p.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
+
+                float t = boxRect.left;
+                float tileSize = boxRect.width() / spanX;
+                for (int i = 1; i < spanX; i++) {
+                    t += tileSize;
+                    c.drawLine(t, 0, t, previewHeightF, p);
+                }
+
+                t = boxRect.top;
+                tileSize = boxRect.height() / spanY;
+                for (int i = 1; i < spanY; i++) {
+                    t += tileSize;
+                    c.drawLine(0, t, previewWidthF, t, p);
+                }
+
+                // Draw icon in the center.
+                try {
+                    Drawable icon = LauncherAppState.getInstance(mContext).getIconCache()
+                            .getFullResIcon(info.provider.getPackageName(), info.icon);
+                    if (icon != null) {
+                        int appIconSize = dp.iconSizePx;
+                        int iconSize = (int) Math.min(appIconSize * scale,
+                                Math.min(boxRect.width(), boxRect.height()));
+
+                        icon = mutateOnMainThread(icon);
+                        int hoffset = (previewWidthF - iconSize) / 2;
+                        int yoffset = (previewHeightF - iconSize) / 2;
+                        icon.setBounds(hoffset, yoffset, hoffset + iconSize, yoffset + iconSize);
+                        icon.draw(c);
+                    }
+                } catch (Resources.NotFoundException e) {
+                }
             }
-            c.setBitmap(null);
-        }
-        return new Pair<>(preview, savePreviewImage);
+        });
     }
 
     private RectF drawBoxWithShadow(Canvas c, int width, int height) {
@@ -537,42 +248,29 @@
         return builder.bounds;
     }
 
-    private Bitmap generateShortcutPreview(BaseActivity launcher, ShortcutConfigActivityInfo info,
-            int maxWidth, int maxHeight, Bitmap preview) {
-        int iconSize = launcher.getDeviceProfile().allAppsIconSizePx;
-        int padding = launcher.getResources()
+    private Bitmap generateShortcutPreview(
+            ShortcutConfigActivityInfo info, int maxWidth, int maxHeight) {
+        int iconSize = ActivityContext.lookupContext(mContext).getDeviceProfile().allAppsIconSizePx;
+        int padding = mContext.getResources()
                 .getDimensionPixelSize(R.dimen.widget_preview_shortcut_padding);
 
         int size = iconSize + 2 * padding;
         if (maxHeight < size || maxWidth < size) {
             throw new RuntimeException("Max size is too small for preview");
         }
-        final Canvas c = new Canvas();
-        if (preview == null || preview.getWidth() < size || preview.getHeight() < size) {
-            preview = Bitmap.createBitmap(size, size, Config.ARGB_8888);
-            c.setBitmap(preview);
-        } else {
-            if (preview.getWidth() > size || preview.getHeight() > size) {
-                preview.reconfigure(size, size, preview.getConfig());
-            }
+        return BitmapRenderer.createHardwareBitmap(size, size, c -> {
+            drawBoxWithShadow(c, size, size);
 
-            // Reusing bitmap. Clear it.
-            c.setBitmap(preview);
-            c.drawColor(0, PorterDuff.Mode.CLEAR);
-        }
+            LauncherIcons li = LauncherIcons.obtain(mContext);
+            Drawable icon = li.createBadgedIconBitmap(
+                    mutateOnMainThread(info.getFullResIcon(
+                            LauncherAppState.getInstance(mContext).getIconCache())),
+                    Process.myUserHandle(), 0).newIcon(mContext);
+            li.recycle();
 
-        drawBoxWithShadow(c, size, size);
-
-        LauncherIcons li = LauncherIcons.obtain(mContext);
-        Drawable icon = li.createBadgedIconBitmap(
-                mutateOnMainThread(info.getFullResIcon(mIconCache)),
-                Process.myUserHandle(), 0).newIcon(launcher);
-        li.recycle();
-
-        icon.setBounds(padding, padding, padding + iconSize, padding + iconSize);
-        icon.draw(c);
-        c.setBitmap(null);
-        return preview;
+            icon.setBounds(padding, padding, padding + iconSize, padding + iconSize);
+            icon.draw(c);
+        });
     }
 
     private Drawable mutateOnMainThread(final Drawable drawable) {
@@ -585,206 +283,4 @@
             throw new RuntimeException(e);
         }
     }
-
-    /**
-     * @return an array of containing versionCode and lastUpdatedTime for the package.
-     */
-    @Thunk long[] getPackageVersion(String packageName) {
-        synchronized (mPackageVersions) {
-            long[] versions = mPackageVersions.get(packageName);
-            if (versions == null) {
-                versions = new long[2];
-                try {
-                    PackageInfo info = mContext.getPackageManager().getPackageInfo(packageName,
-                            PackageManager.GET_UNINSTALLED_PACKAGES);
-                    versions[0] = info.versionCode;
-                    versions[1] = info.lastUpdateTime;
-                } catch (NameNotFoundException e) {
-                    Log.e(TAG, "PackageInfo not found", e);
-                }
-                mPackageVersions.put(packageName, versions);
-            }
-            return versions;
-        }
-    }
-
-    private class PreviewLoadTask extends AsyncTask<Void, Void, Bitmap>
-            implements CancellationSignal.OnCancelListener {
-        @Thunk final WidgetCacheKey mKey;
-        private final WidgetItem mInfo;
-        private final int mPreviewHeight;
-        private final int mPreviewWidth;
-        private final WidgetPreviewLoadedCallback mCallback;
-        private final BaseActivity mActivity;
-        @Thunk long[] mVersions;
-        @Thunk Bitmap mBitmapToRecycle;
-
-        @Nullable private Bitmap mUnusedPreviewBitmap;
-        private boolean mSaveToDB = false;
-
-        PreviewLoadTask(BaseActivity activity, WidgetCacheKey key, WidgetItem info,
-                int previewWidth, int previewHeight, WidgetPreviewLoadedCallback callback) {
-            mActivity = activity;
-            mKey = key;
-            mInfo = info;
-            mPreviewHeight = previewHeight;
-            mPreviewWidth = previewWidth;
-            mCallback = callback;
-            if (DEBUG) {
-                Log.d(TAG, String.format("%s, %s, %d, %d",
-                        mKey, mInfo, mPreviewHeight, mPreviewWidth));
-            }
-        }
-
-        @Override
-        protected Bitmap doInBackground(Void... params) {
-            Bitmap unusedBitmap = null;
-
-            // If already cancelled before this gets to run in the background, then return early
-            if (isCancelled()) {
-                return null;
-            }
-            synchronized (mUnusedBitmaps) {
-                // Check if we can re-use a bitmap
-                for (Bitmap candidate : mUnusedBitmaps) {
-                    if (candidate != null && candidate.isMutable()
-                            && candidate.getWidth() == mPreviewWidth
-                            && candidate.getHeight() == mPreviewHeight) {
-                        unusedBitmap = candidate;
-                        mUnusedBitmaps.remove(unusedBitmap);
-                        break;
-                    }
-                }
-            }
-
-            // creating a bitmap is expensive. Do not do this inside synchronized block.
-            if (unusedBitmap == null) {
-                unusedBitmap = Bitmap.createBitmap(mPreviewWidth, mPreviewHeight, Config.ARGB_8888);
-            }
-            // If cancelled now, don't bother reading the preview from the DB
-            if (isCancelled()) {
-                return unusedBitmap;
-            }
-            Bitmap preview = readFromDb(mKey, unusedBitmap, this);
-            // Only consider generating the preview if we have not cancelled the task already
-            if (!isCancelled() && preview == null) {
-                // Fetch the version info before we generate the preview, so that, in-case the
-                // app was updated while we are generating the preview, we use the old version info,
-                // which would gets re-written next time.
-                boolean persistable = mInfo.activityInfo == null
-                        || mInfo.activityInfo.isPersistable();
-                mVersions = persistable ? getPackageVersion(mKey.componentName.getPackageName())
-                        : null;
-
-                // it's not in the db... we need to generate it
-                Pair<Bitmap, Boolean> pair = generatePreview(mActivity, mInfo, unusedBitmap,
-                        mPreviewWidth, mPreviewHeight);
-                preview = pair.first;
-
-                if (preview != unusedBitmap) {
-                    mUnusedPreviewBitmap = unusedBitmap;
-                }
-
-                this.mSaveToDB = pair.second;
-            }
-            return preview;
-        }
-
-        @Override
-        protected void onPostExecute(final Bitmap preview) {
-            mCallback.onPreviewLoaded(preview);
-
-            // Write the generated preview to the DB in the worker thread
-            if (mVersions != null) {
-                MODEL_EXECUTOR.post(new Runnable() {
-                    @Override
-                    public void run() {
-                        if (mUnusedPreviewBitmap != null) {
-                            // If we didn't end up using the bitmap, it can be added back into the
-                            // recycled set.
-                            synchronized (mUnusedBitmaps) {
-                                mUnusedBitmaps.add(mUnusedPreviewBitmap);
-                            }
-                        }
-
-                        if (!isCancelled() && mSaveToDB) {
-                            // If we are still using this preview, then write it to the DB and then
-                            // let the normal clear mechanism recycle the bitmap
-                            writeToDb(mKey, mVersions, preview);
-                            mBitmapToRecycle = preview;
-                        } else {
-                            // If we've already cancelled, then skip writing the bitmap to the DB
-                            // and manually add the bitmap back to the recycled set
-                            synchronized (mUnusedBitmaps) {
-                                mUnusedBitmaps.add(preview);
-                            }
-                        }
-                    }
-                });
-            } else {
-                // If we don't need to write to disk, then ensure the preview gets recycled by
-                // the normal clear mechanism
-                mBitmapToRecycle = preview;
-            }
-        }
-
-        @Override
-        protected void onCancelled(final Bitmap preview) {
-            // If we've cancelled while the task is running, then can return the bitmap to the
-            // recycled set immediately. Otherwise, it will be recycled after the preview is written
-            // to disk.
-            if (preview != null) {
-                MODEL_EXECUTOR.post(new Runnable() {
-                    @Override
-                    public void run() {
-                        synchronized (mUnusedBitmaps) {
-                            mUnusedBitmaps.add(preview);
-                        }
-                    }
-                });
-            }
-        }
-
-        @Override
-        public void onCancel() {
-            cancel(true);
-
-            // This only handles the case where the PreviewLoadTask is cancelled after the task has
-            // successfully completed (including having written to disk when necessary).  In the
-            // other cases where it is cancelled while the task is running, it will be cleaned up
-            // in the tasks's onCancelled() call, and if cancelled while the task is writing to
-            // disk, it will be cancelled in the task's onPostExecute() call.
-            if (mBitmapToRecycle != null) {
-                MODEL_EXECUTOR.post(new Runnable() {
-                    @Override
-                    public void run() {
-                        synchronized (mUnusedBitmaps) {
-                            mUnusedBitmaps.add(mBitmapToRecycle);
-                        }
-                        mBitmapToRecycle = null;
-                    }
-                });
-            }
-        }
-    }
-
-    private static final class WidgetCacheKey extends ComponentKey {
-
-        @Thunk final String mSize;
-
-        WidgetCacheKey(ComponentName componentName, UserHandle user, String size) {
-            super(componentName, user);
-            this.mSize = size;
-        }
-
-        @Override
-        public int hashCode() {
-            return super.hashCode() ^ mSize.hashCode();
-        }
-
-        @Override
-        public boolean equals(Object o) {
-            return super.equals(o) && ((WidgetCacheKey) o).mSize.equals(mSize);
-        }
-    }
 }
diff --git a/src/com/android/launcher3/widget/NavigableAppWidgetHostView.java b/src/com/android/launcher3/widget/NavigableAppWidgetHostView.java
index d12fe74..241c937 100644
--- a/src/com/android/launcher3/widget/NavigableAppWidgetHostView.java
+++ b/src/com/android/launcher3/widget/NavigableAppWidgetHostView.java
@@ -49,6 +49,8 @@
      */
     private final PointF mTranslationForCentering = new PointF(0, 0);
 
+    private final PointF mTranslationForMoveFromCenterAnimation = new PointF(0, 0);
+
     private final PointF mTranslationForReorderBounce = new PointF(0, 0);
     private final PointF mTranslationForReorderPreview = new PointF(0, 0);
     private float mScaleForReorderBounce = 1f;
@@ -167,9 +169,9 @@
 
     private void updateTranslation() {
         super.setTranslationX(mTranslationForReorderBounce.x + mTranslationForReorderPreview.x
-                + mTranslationForCentering.x);
+                + mTranslationForCentering.x + mTranslationForMoveFromCenterAnimation.x);
         super.setTranslationY(mTranslationForReorderBounce.y + mTranslationForReorderPreview.y
-                + mTranslationForCentering.y);
+                + mTranslationForCentering.y + mTranslationForMoveFromCenterAnimation.y);
     }
 
     public void setTranslationForCentering(float x, float y) {
@@ -177,6 +179,11 @@
         updateTranslation();
     }
 
+    public void setTranslationForMoveFromCenterAnimation(float x, float y) {
+        mTranslationForMoveFromCenterAnimation.set(x, y);
+        updateTranslation();
+    }
+
     public void setReorderBounceOffset(float x, float y) {
         mTranslationForReorderBounce.set(x, y);
         updateTranslation();
diff --git a/src/com/android/launcher3/widget/PendingAppWidgetHostView.java b/src/com/android/launcher3/widget/PendingAppWidgetHostView.java
index d3a0190..57a6d3f 100644
--- a/src/com/android/launcher3/widget/PendingAppWidgetHostView.java
+++ b/src/com/android/launcher3/widget/PendingAppWidgetHostView.java
@@ -85,7 +85,7 @@
         setBackgroundResource(R.drawable.pending_widget_bg);
         setWillNotDraw(false);
 
-        updateAppWidget(null);
+        super.updateAppWidget(null);
         setOnClickListener(ItemClickHandler.INSTANCE);
 
         if (info.pendingItemInfo == null) {
diff --git a/src/com/android/launcher3/widget/PendingItemDragHelper.java b/src/com/android/launcher3/widget/PendingItemDragHelper.java
index 991910d..2347d28 100644
--- a/src/com/android/launcher3/widget/PendingItemDragHelper.java
+++ b/src/com/android/launcher3/widget/PendingItemDragHelper.java
@@ -140,10 +140,9 @@
                         .addDragListener(new AppWidgetHostViewDragListener(launcher));
             }
             if (preview == null && mAppWidgetHostViewPreview == null) {
-                Drawable p = new FastBitmapDrawable(
-                        app.getWidgetCache().generateWidgetPreview(launcher,
-                                createWidgetInfo.info, maxWidth, null,
-                                previewSizeBeforeScale).first);
+                Drawable p = new FastBitmapDrawable(new DatabaseWidgetPreviewLoader(launcher)
+                        .generateWidgetPreview(
+                                createWidgetInfo.info, maxWidth, previewSizeBeforeScale));
                 if (RoundedCornerEnforcement.isRoundedCornerEnabled()) {
                     p = new RoundDrawableWrapper(p, mEnforcedRoundedCornersForWidget);
                 }
diff --git a/src/com/android/launcher3/widget/WidgetCell.java b/src/com/android/launcher3/widget/WidgetCell.java
index 167eb09..f1ac656 100644
--- a/src/com/android/launcher3/widget/WidgetCell.java
+++ b/src/com/android/launcher3/widget/WidgetCell.java
@@ -26,14 +26,12 @@
 import android.content.Context;
 import android.graphics.Bitmap;
 import android.graphics.drawable.Drawable;
-import android.os.CancellationSignal;
 import android.util.AttributeSet;
 import android.util.Log;
 import android.util.Size;
 import android.view.Gravity;
 import android.view.MotionEvent;
 import android.view.View;
-import android.view.View.OnLayoutChangeListener;
 import android.view.ViewGroup;
 import android.view.ViewPropertyAnimator;
 import android.view.accessibility.AccessibilityNodeInfo;
@@ -42,18 +40,22 @@
 import android.widget.RemoteViews;
 import android.widget.TextView;
 
+import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 
-import com.android.launcher3.BaseActivity;
 import com.android.launcher3.CheckLongPressHelper;
 import com.android.launcher3.DeviceProfile;
 import com.android.launcher3.Launcher;
 import com.android.launcher3.R;
 import com.android.launcher3.icons.FastBitmapDrawable;
 import com.android.launcher3.icons.RoundDrawableWrapper;
+import com.android.launcher3.icons.cache.HandlerRunnable;
 import com.android.launcher3.model.WidgetItem;
+import com.android.launcher3.views.ActivityContext;
 import com.android.launcher3.widget.util.WidgetSizes;
 
+import java.util.function.Consumer;
+
 /**
  * Represents the individual cell of the widget inside the widget tray. The preview is drawn
  * horizontally centered, and scaled down if needed.
@@ -63,7 +65,7 @@
  * transition from the view to drag view, so when adding padding support, DnD would need to
  * consider the appropriate scaling factor.
  */
-public class WidgetCell extends LinearLayout implements OnLayoutChangeListener {
+public class WidgetCell extends LinearLayout {
 
     private static final String TAG = "WidgetCell";
     private static final boolean DEBUG = false;
@@ -115,15 +117,12 @@
 
     protected WidgetItem mItem;
 
-    private WidgetPreviewLoader mWidgetPreviewLoader;
+    private final DatabaseWidgetPreviewLoader mWidgetPreviewLoader;
 
-    protected CancellationSignal mActiveRequest;
+    protected HandlerRunnable mActiveRequest;
     private boolean mAnimatePreview = true;
 
-    private boolean mApplyBitmapDeferred = false;
-    private Drawable mDeferredDrawable;
-
-    protected final BaseActivity mActivity;
+    protected final ActivityContext mActivity;
     private final CheckLongPressHelper mLongPressHelper;
     private final float mEnforcedCornerRadius;
 
@@ -143,7 +142,8 @@
     public WidgetCell(Context context, AttributeSet attrs, int defStyle) {
         super(context, attrs, defStyle);
 
-        mActivity = BaseActivity.fromContext(context);
+        mActivity = ActivityContext.lookupContext(context);
+        mWidgetPreviewLoader = new DatabaseWidgetPreviewLoader(context);
         mLongPressHelper = new CheckLongPressHelper(this);
         mLongPressHelper.setLongPressTimeoutFactor(1);
 
@@ -218,7 +218,36 @@
         this.mSourceContainer = sourceContainer;
     }
 
-    public void applyFromCellItem(WidgetItem item, WidgetPreviewLoader loader) {
+    /**
+     * Applies the item to this view
+     */
+    public void applyFromCellItem(WidgetItem item) {
+        applyFromCellItem(item, 1f);
+    }
+
+    /**
+     * Applies the item to this view
+     */
+    public void applyFromCellItem(WidgetItem item, float previewScale) {
+        applyFromCellItem(item, previewScale, this::applyPreview, null);
+    }
+
+    /**
+     * Applies the item to this view
+     * @param item item to apply
+     * @param previewScale factor to scale the preview
+     * @param callback callback when preview is loaded in case the preview is being loaded or cached
+     * @param cachedPreview previously cached preview bitmap is present
+     */
+    public void applyFromCellItem(WidgetItem item, float previewScale,
+            @NonNull Consumer<Bitmap> callback, @Nullable Bitmap cachedPreview) {
+        // setPreviewSize
+        DeviceProfile deviceProfile = mActivity.getDeviceProfile();
+        Size widgetSize = WidgetSizes.getWidgetItemSizePx(getContext(), deviceProfile, item);
+        mTargetPreviewWidth = widgetSize.getWidth();
+        mTargetPreviewHeight = widgetSize.getHeight();
+        mPreviewContainerScale = previewScale;
+
         applyPreviewOnAppWidgetHostView(item);
 
         Context context = getContext();
@@ -240,14 +269,14 @@
             }
         }
 
-        mWidgetPreviewLoader = loader;
         if (item.activityInfo != null) {
             setTag(new PendingAddShortcutInfo(item.activityInfo));
         } else {
             setTag(new PendingAddWidgetInfo(item.widgetInfo, mSourceContainer));
         }
-    }
 
+        ensurePreviewWithCallback(callback, cachedPreview);
+    }
 
     private void applyPreviewOnAppWidgetHostView(WidgetItem item) {
         if (mRemoteViewsPreview != null) {
@@ -294,41 +323,19 @@
         return mAppWidgetHostViewPreview;
     }
 
-    /**
-     * Sets if applying bitmap preview should be deferred. The UI will still load the bitmap, but
-     * will not cause invalidate, so that when deferring is disabled later, all the bitmaps are
-     * ready.
-     * This prevents invalidates while the animation is running.
-     */
-    public void setApplyBitmapDeferred(boolean isDeferred) {
-        if (mApplyBitmapDeferred != isDeferred) {
-            mApplyBitmapDeferred = isDeferred;
-            if (!mApplyBitmapDeferred && mDeferredDrawable != null) {
-                applyPreview(mDeferredDrawable);
-                mDeferredDrawable = null;
-            }
-        }
-    }
-
     public void setAnimatePreview(boolean shouldAnimate) {
         mAnimatePreview = shouldAnimate;
     }
 
-    public void applyPreview(Bitmap bitmap) {
-        FastBitmapDrawable drawable = new FastBitmapDrawable(bitmap);
-        applyPreview(new RoundDrawableWrapper(drawable, mEnforcedCornerRadius));
-    }
+    private void applyPreview(Bitmap bitmap) {
+        if (bitmap != null) {
+            Drawable drawable = new RoundDrawableWrapper(
+                    new FastBitmapDrawable(bitmap), mEnforcedCornerRadius);
 
-    private void applyPreview(Drawable drawable) {
-        if (mApplyBitmapDeferred) {
-            mDeferredDrawable = drawable;
-            return;
-        }
-        if (drawable != null) {
+            // Scale down the preview size if it's wider than the cell.
             float scale = 1f;
-            if (getWidth() > 0 && getHeight() > 0) {
-                // Scale down the preview size if it's wider than the cell.
-                float maxWidth = getWidth();
+            if (mTargetPreviewWidth > 0) {
+                float maxWidth = mTargetPreviewWidth;
                 float previewWidth = drawable.getIntrinsicWidth() * mPreviewContainerScale;
                 scale = Math.min(maxWidth / previewWidth, 1);
             }
@@ -349,6 +356,10 @@
         } else {
             mWidgetImageContainer.setAlpha(1f);
         }
+        if (mActiveRequest != null) {
+            mActiveRequest.cancel();
+            mActiveRequest = null;
+        }
     }
 
     private void setContainerSize(int width, int height) {
@@ -358,7 +369,13 @@
         mWidgetImageContainer.setLayoutParams(layoutParams);
     }
 
-    public void ensurePreview() {
+    /**
+     * Ensures that the preview is already loaded or being loaded. If the preview is not loaded,
+     * it applies the provided cachedPreview. If that is null, it starts a loader and notifies the
+     * callback on successful load.
+     */
+    private void ensurePreviewWithCallback(Consumer<Bitmap> callback,
+            @Nullable Bitmap cachedPreview) {
         if (mAppWidgetHostViewPreview != null) {
             int containerWidth = (int) (mTargetPreviewWidth * mPreviewContainerScale);
             int containerHeight = (int) (mTargetPreviewHeight * mPreviewContainerScale);
@@ -382,38 +399,18 @@
             mAppWidgetHostViewPreview.setLayoutParams(params);
             mWidgetImageContainer.addView(mAppWidgetHostViewPreview, /* index= */ 0);
             mWidgetImage.setVisibility(View.GONE);
-            applyPreview((Drawable) null);
+            applyPreview(null);
+            return;
+        }
+        if (cachedPreview != null) {
+            applyPreview(cachedPreview);
             return;
         }
         if (mActiveRequest != null) {
             return;
         }
         mActiveRequest = mWidgetPreviewLoader.loadPreview(
-                BaseActivity.fromContext(getContext()), mItem,
-                new Size(mTargetPreviewWidth, mTargetPreviewHeight),
-                this::applyPreview);
-    }
-
-    /** Sets the widget preview image size in number of cells. */
-    public Size setPreviewSize(WidgetItem widgetItem) {
-        return setPreviewSize(widgetItem, 1f);
-    }
-
-    /** Sets the widget preview image size, in number of cells, and preview scale. */
-    public Size setPreviewSize(WidgetItem widgetItem, float previewScale) {
-        DeviceProfile deviceProfile = mActivity.getDeviceProfile();
-        Size widgetSize = WidgetSizes.getWidgetItemSizePx(getContext(), deviceProfile, widgetItem);
-        mTargetPreviewWidth = widgetSize.getWidth();
-        mTargetPreviewHeight = widgetSize.getHeight();
-        mPreviewContainerScale = previewScale;
-        return widgetSize;
-    }
-
-    @Override
-    public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft,
-            int oldTop, int oldRight, int oldBottom) {
-        removeOnLayoutChangeListener(this);
-        ensurePreview();
+                mItem, new Size(mTargetPreviewWidth, mTargetPreviewHeight), callback);
     }
 
     @Override
@@ -429,17 +426,6 @@
         mLongPressHelper.cancelLongPress();
     }
 
-    /**
-     * Helper method to get the string info of the tag.
-     */
-    private String getTagToString() {
-        if (getTag() instanceof PendingAddWidgetInfo ||
-                getTag() instanceof PendingAddShortcutInfo) {
-            return getTag().toString();
-        }
-        return "";
-    }
-
     private static NavigableAppWidgetHostView createAppWidgetHostView(Context context) {
         return new NavigableAppWidgetHostView(context) {
             @Override
@@ -450,12 +436,7 @@
     }
 
     private static boolean isLauncherContext(Context context) {
-        try {
-            Launcher.getLauncher(context);
-            return true;
-        } catch (Exception e) {
-            return false;
-        }
+        return ActivityContext.lookupContext(context) instanceof Launcher;
     }
 
     @Override
@@ -483,6 +464,20 @@
         mAppWidgetHostViewPreview.measure(
                 makeMeasureSpec(MAX_MEASURE_SPEC_DIMENSION, MeasureSpec.UNSPECIFIED),
                 makeMeasureSpec(MAX_MEASURE_SPEC_DIMENSION, MeasureSpec.UNSPECIFIED));
+        if (mRemoteViewsPreview != null) {
+            // If RemoteViews contains multiple sizes, the best fit sized RemoteViews will be
+            // selected in onLayout. To work out the right measurement, let's layout and then
+            // measure again.
+            mAppWidgetHostViewPreview.layout(
+                    /* left= */ 0,
+                    /* top= */ 0,
+                    /* right= */ mTargetPreviewWidth,
+                    /* bottom= */ mTargetPreviewHeight);
+            mAppWidgetHostViewPreview.measure(
+                    makeMeasureSpec(mTargetPreviewWidth, MeasureSpec.UNSPECIFIED),
+                    makeMeasureSpec(mTargetPreviewHeight, MeasureSpec.UNSPECIFIED));
+
+        }
         View widgetContent = mAppWidgetHostViewPreview.getChildAt(0);
         int appWidgetContentWidth = widgetContent.getMeasuredWidth();
         int appWidgetContentHeight = widgetContent.getMeasuredHeight();
diff --git a/src/com/android/launcher3/widget/WidgetPreviewLoader.java b/src/com/android/launcher3/widget/WidgetPreviewLoader.java
deleted file mode 100644
index ff5c82f..0000000
--- a/src/com/android/launcher3/widget/WidgetPreviewLoader.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * 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.widget;
-
-import android.graphics.Bitmap;
-import android.os.CancellationSignal;
-import android.util.Size;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.UiThread;
-
-import com.android.launcher3.BaseActivity;
-import com.android.launcher3.model.WidgetItem;
-
-/** Asynchronous loader of preview bitmaps for {@link WidgetItem}s. */
-public interface WidgetPreviewLoader {
-    /**
-     * Loads a widget preview and calls back to {@code callback} when complete.
-     *
-     * @return a {@link CancellationSignal} which can be used to cancel the request.
-     */
-    @NonNull
-    @UiThread
-    CancellationSignal loadPreview(
-            @NonNull BaseActivity activity,
-            @NonNull WidgetItem item,
-            @NonNull Size previewSize,
-            @NonNull WidgetPreviewLoadedCallback callback);
-
-    /** Callback class for requests to {@link WidgetPreviewLoader}. */
-    interface WidgetPreviewLoadedCallback {
-        void onPreviewLoaded(@NonNull Bitmap preview);
-    }
-}
diff --git a/src/com/android/launcher3/widget/WidgetsBottomSheet.java b/src/com/android/launcher3/widget/WidgetsBottomSheet.java
index 6beff3a..bb4638a 100644
--- a/src/com/android/launcher3/widget/WidgetsBottomSheet.java
+++ b/src/com/android/launcher3/widget/WidgetsBottomSheet.java
@@ -37,7 +37,6 @@
 import android.widget.TextView;
 
 import com.android.launcher3.DeviceProfile;
-import com.android.launcher3.LauncherAppState;
 import com.android.launcher3.R;
 import com.android.launcher3.anim.PendingAnimation;
 import com.android.launcher3.model.WidgetItem;
@@ -199,11 +198,7 @@
             tableRow.setGravity(Gravity.TOP);
             row.forEach(widgetItem -> {
                 WidgetCell widget = addItemCell(tableRow);
-                widget.setPreviewSize(widgetItem);
-                widget.applyFromCellItem(widgetItem, LauncherAppState.getInstance(mActivityContext)
-                        .getWidgetCache());
-                widget.ensurePreview();
-                widget.setVisibility(View.VISIBLE);
+                widget.applyFromCellItem(widgetItem);
             });
             widgetsTable.addView(tableRow);
         });
diff --git a/src/com/android/launcher3/widget/model/WidgetListSpaceEntry.java b/src/com/android/launcher3/widget/model/WidgetListSpaceEntry.java
new file mode 100644
index 0000000..e62425f
--- /dev/null
+++ b/src/com/android/launcher3/widget/model/WidgetListSpaceEntry.java
@@ -0,0 +1,37 @@
+/*
+ * 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.widget.model;
+
+import com.android.launcher3.model.data.PackageItemInfo;
+
+import java.util.Collections;
+
+/**
+ * Entry representing the top empty space
+ */
+public class WidgetListSpaceEntry extends WidgetsListBaseEntry {
+
+    public WidgetListSpaceEntry() {
+        super(new PackageItemInfo(""), "", Collections.EMPTY_LIST);
+        mPkgItem.title = "";
+    }
+
+    @Override
+    public int getRank() {
+        return RANK_WIDGETS_TOP_SPACE;
+    }
+}
diff --git a/src/com/android/launcher3/widget/model/WidgetsListBaseEntry.java b/src/com/android/launcher3/widget/model/WidgetsListBaseEntry.java
index abc79ff..1d1c9dc 100644
--- a/src/com/android/launcher3/widget/model/WidgetsListBaseEntry.java
+++ b/src/com/android/launcher3/widget/model/WidgetsListBaseEntry.java
@@ -73,11 +73,13 @@
     }
 
     @Retention(SOURCE)
-    @IntDef({RANK_WIDGETS_LIST_HEADER, RANK_WIDGETS_LIST_SEARCH_HEADER, RANK_WIDGETS_LIST_CONTENT})
+    @IntDef({RANK_WIDGETS_TOP_SPACE, RANK_WIDGETS_LIST_HEADER, RANK_WIDGETS_LIST_SEARCH_HEADER,
+            RANK_WIDGETS_LIST_CONTENT})
     public @interface Rank {
     }
 
-    public static final int RANK_WIDGETS_LIST_HEADER = 1;
-    public static final int RANK_WIDGETS_LIST_SEARCH_HEADER = 2;
-    public static final int RANK_WIDGETS_LIST_CONTENT = 3;
+    public static final int RANK_WIDGETS_TOP_SPACE = 1;
+    public static final int RANK_WIDGETS_LIST_HEADER = 2;
+    public static final int RANK_WIDGETS_LIST_SEARCH_HEADER = 3;
+    public static final int RANK_WIDGETS_LIST_CONTENT = 4;
 }
diff --git a/src/com/android/launcher3/widget/picker/SearchAndRecommendationsScrollController.java b/src/com/android/launcher3/widget/picker/SearchAndRecommendationsScrollController.java
index 6643779..716dcf3 100644
--- a/src/com/android/launcher3/widget/picker/SearchAndRecommendationsScrollController.java
+++ b/src/com/android/launcher3/widget/picker/SearchAndRecommendationsScrollController.java
@@ -15,297 +15,148 @@
  */
 package com.android.launcher3.widget.picker;
 
-import android.animation.ValueAnimator;
-import android.graphics.Point;
+import static com.android.launcher3.anim.AnimatorListeners.forEndCallback;
+
+import android.animation.Animator;
+import android.animation.ObjectAnimator;
+import android.util.FloatProperty;
 import android.view.MotionEvent;
 import android.view.View;
-import android.view.ViewGroup.MarginLayoutParams;
-import android.widget.RelativeLayout;
+import android.view.ViewGroup;
 import android.widget.TextView;
 
+import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
+import androidx.recyclerview.widget.RecyclerView;
 
-import com.android.launcher3.views.RecyclerViewFastScroller;
-import com.android.launcher3.widget.picker.WidgetsFullSheet.SearchAndRecommendationViewHolder;
-import com.android.launcher3.workprofile.PersonalWorkPagedView;
+import com.android.launcher3.R;
+import com.android.launcher3.widget.picker.WidgetsSpaceViewHolderBinder.EmptySpaceView;
+import com.android.launcher3.widget.picker.search.WidgetsSearchBar;
 
 /**
  * A controller which measures & updates {@link WidgetsFullSheet}'s views padding, margin and
  * vertical displacement upon scrolling.
  */
 final class SearchAndRecommendationsScrollController implements
-        RecyclerViewFastScroller.OnFastScrollChangeListener, ValueAnimator.AnimatorUpdateListener {
-    private final boolean mHasWorkProfile;
-    private final SearchAndRecommendationViewHolder mViewHolder;
-    private final View mSearchAndRecommendationViewParent;
-    private final WidgetsRecyclerView mPrimaryRecyclerView;
-    private final WidgetsRecyclerView mSearchRecyclerView;
-    private final TextView mNoWidgetsView;
-    private final int mTabsHeight;
-    private final ValueAnimator mAnimator = ValueAnimator.ofInt(0, 0);
-    private final Point mTempOffset = new Point();
-    private int mBottomInset;
+        RecyclerView.OnChildAttachStateChangeListener {
 
-    // The following are only non null if mHasWorkProfile is true.
-    @Nullable private final WidgetsRecyclerView mWorkRecyclerView;
-    @Nullable private final View mPrimaryWorkTabsView;
-    @Nullable private final PersonalWorkPagedView mPrimaryWorkViewPager;
+    private static final FloatProperty<SearchAndRecommendationsScrollController> SCROLL_OFFSET =
+            new FloatProperty<SearchAndRecommendationsScrollController>("scrollAnimOffset") {
+        @Override
+        public void setValue(SearchAndRecommendationsScrollController controller, float offset) {
+            controller.mScrollOffset = offset;
+            controller.updateHeaderScroll();
+        }
+
+        @Override
+        public Float get(SearchAndRecommendationsScrollController controller) {
+            return controller.mScrollOffset;
+        }
+    };
+
+    private static final MotionEventProxyMethod INTERCEPT_PROXY = ViewGroup::onInterceptTouchEvent;
+    private static final MotionEventProxyMethod TOUCH_PROXY = ViewGroup::onTouchEvent;
+
+    final SearchAndRecommendationsView mContainer;
+    final View mSearchBarContainer;
+    final WidgetsSearchBar mSearchBar;
+    final TextView mHeaderTitle;
+    final WidgetsRecommendationTableLayout mRecommendedWidgetsTable;
+    @Nullable final View mTabBar;
 
     private WidgetsRecyclerView mCurrentRecyclerView;
-    private int mCurrentRecyclerViewScrollY = 0;
+    private EmptySpaceView mCurrentEmptySpaceView;
 
-    private OnContentChangeListener mOnContentChangeListener = () -> onScrollChanged();
-
-    /**
-     * The vertical distance, in pixels, until the search is pinned at the top of the screen when
-     * the user scrolls down the recycler view.
-     */
-    private int mCollapsibleHeightForSearch = 0;
-    /**
-     * The vertical distance, in pixels, until the recommendation table disappears from the top of
-     * the screen when the user scrolls down the recycler view.
-     */
-    private int mCollapsibleHeightForRecommendation = 0;
-    /**
-     * The vertical distance, in pixels, until the tabs is pinned at the top of the screen when the
-     * user scrolls down the recycler view.
-     *
-     * <p>Always 0 if there is no work profile.
-     */
-    private int mCollapsibleHeightForTabs = 0;
+    private float mLastScroll = 0;
+    private float mScrollOffset = 0;
+    private Animator mOffsetAnimator;
 
     private boolean mShouldForwardToRecyclerView = false;
 
+    private int mHeaderHeight;
+
     SearchAndRecommendationsScrollController(
-            boolean hasWorkProfile,
-            int tabsHeight,
-            SearchAndRecommendationViewHolder viewHolder,
-            WidgetsRecyclerView primaryRecyclerView,
-            @Nullable WidgetsRecyclerView workRecyclerView,
-            WidgetsRecyclerView searchRecyclerView,
-            @Nullable View personalWorkTabsView,
-            @Nullable PersonalWorkPagedView primaryWorkViewPager,
-            TextView noWidgetsView) {
-        mHasWorkProfile = hasWorkProfile;
-        mViewHolder = viewHolder;
-        mViewHolder.mContainer.setSearchAndRecommendationScrollController(this);
-        mSearchAndRecommendationViewParent = (View) mViewHolder.mContainer.getParent();
-        mPrimaryRecyclerView = primaryRecyclerView;
-        mWorkRecyclerView = workRecyclerView;
-        mSearchRecyclerView = searchRecyclerView;
-        mPrimaryWorkTabsView = personalWorkTabsView;
-        mPrimaryWorkViewPager = primaryWorkViewPager;
-        mTabsHeight = tabsHeight;
-        mNoWidgetsView = noWidgetsView;
-        setCurrentRecyclerView(mPrimaryRecyclerView, /* animateReset= */ false);
+            SearchAndRecommendationsView searchAndRecommendationContainer) {
+        mContainer = searchAndRecommendationContainer;
+        mSearchBarContainer = mContainer.findViewById(R.id.search_bar_container);
+        mSearchBar = mContainer.findViewById(R.id.widgets_search_bar);
+        mHeaderTitle = mContainer.findViewById(R.id.title);
+        mRecommendedWidgetsTable = mContainer.findViewById(R.id.recommended_widget_table);
+        mTabBar = mContainer.findViewById(R.id.tabs);
+
+        mContainer.setSearchAndRecommendationScrollController(this);
     }
 
     public void setCurrentRecyclerView(WidgetsRecyclerView currentRecyclerView) {
-        setCurrentRecyclerView(currentRecyclerView, /* animateReset= */ true);
-    }
-
-    /** Sets the current active {@link WidgetsRecyclerView}. */
-    private void setCurrentRecyclerView(WidgetsRecyclerView currentRecyclerView,
-            boolean animateReset) {
-        if (mCurrentRecyclerView == currentRecyclerView) {
-            return;
-        }
+        boolean animateReset = mCurrentRecyclerView != null;
         if (mCurrentRecyclerView != null) {
-            mCurrentRecyclerView.setOnContentChangeListener(null);
+            mCurrentRecyclerView.removeOnChildAttachStateChangeListener(this);
         }
         mCurrentRecyclerView = currentRecyclerView;
-        mCurrentRecyclerView.setOnContentChangeListener(mOnContentChangeListener);
+        mCurrentRecyclerView.addOnChildAttachStateChangeListener(this);
+        findCurrentEmptyView();
         reset(animateReset);
     }
 
-    /**
-     * Updates padding of {@link WidgetsFullSheet} contents to include {@code bottomInset} wherever
-     * necessary.
-     */
-    public boolean updateBottomInset(int bottomInset) {
-        mBottomInset = bottomInset;
-        return updateMarginAndPadding();
+    public int getHeaderHeight() {
+        return mHeaderHeight;
+    }
+
+    private void updateHeaderScroll() {
+        mLastScroll = getCurrentScroll();
+        mHeaderTitle.setTranslationY(mLastScroll);
+        mRecommendedWidgetsTable.setTranslationY(mLastScroll);
+
+        float searchYDisplacement = Math.max(mLastScroll, -mSearchBarContainer.getTop());
+        mSearchBarContainer.setTranslationY(searchYDisplacement);
+
+        if (mTabBar != null) {
+            float tabsDisplacement = Math.max(mLastScroll, -mTabBar.getTop()
+                    + mSearchBarContainer.getHeight());
+            mTabBar.setTranslationY(tabsDisplacement);
+        }
+    }
+
+    private float getCurrentScroll() {
+        return mScrollOffset + (mCurrentEmptySpaceView == null ? 0 : mCurrentEmptySpaceView.getY());
     }
 
     /**
-     * Updates the margin and padding of {@link WidgetsFullSheet} to accumulate collapsible views.
+     * Updates the scrollable header height
      *
-     * @return {@code true} if margins or/and padding of views in the search and recommendations
-     * container have been updated.
+     * @return {@code true} if the header height or dependent property changed.
      */
-    public boolean updateMarginAndPadding() {
-        boolean hasMarginOrPaddingUpdated = false;
-        mCollapsibleHeightForSearch = measureHeightWithVerticalMargins(mViewHolder.mHeaderTitle);
-        mCollapsibleHeightForRecommendation =
-                measureHeightWithVerticalMargins(mViewHolder.mHeaderTitle)
-                        + measureHeightWithVerticalMargins(mViewHolder.mCollapseHandle)
-                        + measureHeightWithVerticalMargins((View) mViewHolder.mSearchBarContainer)
-                        + measureHeightWithVerticalMargins(mViewHolder.mRecommendedWidgetsTable);
+    public boolean updateHeaderHeight() {
+        boolean hasSizeUpdated = false;
 
-        int topContainerHeight = measureHeightWithVerticalMargins(mViewHolder.mContainer);
-        int noWidgetsViewHeight =  topContainerHeight - mBottomInset;
-
-        if (mHasWorkProfile) {
-            mCollapsibleHeightForTabs = measureHeightWithVerticalMargins(mViewHolder.mHeaderTitle)
-                    + measureHeightWithVerticalMargins(mViewHolder.mRecommendedWidgetsTable);
-            // In a work profile setup, the full widget sheet contains the following views:
-            //           ------- (pinned)           -|
-            //          Widgets (collapsible)       -|---> LinearLayout for search & recommendations
-            //          Search bar (pinned)         -|
-            //  Widgets recommendation (collapsible)-|
-            //      Personal | Work (pinned)
-            //           View Pager
-            //
-            // Views after the search & recommendations are not bound by RelativelyLayout param.
-            // To position them on the expected location, padding & margin are added to these views
-
-            // Tabs should have a padding of the height of the search & recommendations container.
-            RelativeLayout.LayoutParams tabsLayoutParams =
-                    (RelativeLayout.LayoutParams) mPrimaryWorkTabsView.getLayoutParams();
-            tabsLayoutParams.topMargin = topContainerHeight;
-            mPrimaryWorkTabsView.setLayoutParams(tabsLayoutParams);
-
-            // Instead of setting the top offset directly, we split the top offset into two values:
-            // 1. topOffsetAfterAllViewsCollapsed: this is the top offset after all collapsible
-            //    views are no longer visible on the screen.
-            //    This value is set as the margin for the view pager.
-            // 2. mMaxCollapsibleDistance
-            //    This value is set as the padding for the recycler views in order to work with
-            //    clipToPadding="false", which is an attribute for not showing top / bottom padding
-            //    when a recycler view has not reached the top or bottom of the list.
-            //    e.g. a list of 10 entries, only 3 entries are visible at a time.
-            //         case 1: recycler view is scrolled to the top. Top padding is visible/
-            //         (top padding)
-            //         item 1
-            //         item 2
-            //         item 3
-            //
-            //         case 2: recycler view is scrolled to the middle. No padding is visible.
-            //         item 4
-            //         item 5
-            //         item 6
-            //
-            //         case 3: recycler view is scrolled to the end. bottom padding is visible.
-            //         item 8
-            //         item 9
-            //         item 10
-            //         (bottom padding): not set in this case.
-            //
-            // When the views are first inflated, the sum of topOffsetAfterAllViewsCollapsed and
-            // mMaxCollapsibleDistance should equal to the top container height.
-            int topOffsetAfterAllViewsCollapsed =
-                    topContainerHeight + mTabsHeight - mCollapsibleHeightForTabs;
-
-            if (mPrimaryWorkTabsView.getVisibility() == View.VISIBLE) {
-                noWidgetsViewHeight += mTabsHeight;
-            }
-
-            RelativeLayout.LayoutParams viewPagerLayoutParams =
-                    (RelativeLayout.LayoutParams) mPrimaryWorkViewPager.getLayoutParams();
-            if (viewPagerLayoutParams.topMargin != topOffsetAfterAllViewsCollapsed) {
-                viewPagerLayoutParams.topMargin = topOffsetAfterAllViewsCollapsed;
-                mPrimaryWorkViewPager.setLayoutParams(viewPagerLayoutParams);
-                hasMarginOrPaddingUpdated = true;
-            }
-
-            if (mPrimaryRecyclerView.getPaddingTop() != mCollapsibleHeightForTabs) {
-                mPrimaryRecyclerView.setPadding(
-                        mPrimaryRecyclerView.getPaddingLeft(),
-                        mCollapsibleHeightForTabs,
-                        mPrimaryRecyclerView.getPaddingRight(),
-                        mPrimaryRecyclerView.getPaddingBottom());
-                hasMarginOrPaddingUpdated = true;
-            }
-            if (mWorkRecyclerView.getPaddingTop() != mCollapsibleHeightForTabs) {
-                mWorkRecyclerView.setPadding(
-                        mWorkRecyclerView.getPaddingLeft(),
-                        mCollapsibleHeightForTabs,
-                        mWorkRecyclerView.getPaddingRight(),
-                        mWorkRecyclerView.getPaddingBottom());
-                hasMarginOrPaddingUpdated = true;
-            }
-        } else {
-            if (mPrimaryRecyclerView.getPaddingTop() != topContainerHeight) {
-                mPrimaryRecyclerView.setPadding(
-                        mPrimaryRecyclerView.getPaddingLeft(),
-                        topContainerHeight,
-                        mPrimaryRecyclerView.getPaddingRight(),
-                        mPrimaryRecyclerView.getPaddingBottom());
-                hasMarginOrPaddingUpdated = true;
-            }
-        }
-        if (mSearchRecyclerView.getPaddingTop() != topContainerHeight) {
-            mSearchRecyclerView.setPadding(
-                    mSearchRecyclerView.getPaddingLeft(),
-                    topContainerHeight,
-                    mSearchRecyclerView.getPaddingRight(),
-                    mSearchRecyclerView.getPaddingBottom());
-            hasMarginOrPaddingUpdated = true;
-        }
-        if (mNoWidgetsView.getPaddingTop() != noWidgetsViewHeight) {
-            mNoWidgetsView.setPadding(
-                    mNoWidgetsView.getPaddingLeft(),
-                    noWidgetsViewHeight,
-                    mNoWidgetsView.getPaddingRight(),
-                    mNoWidgetsView.getPaddingBottom());
-            hasMarginOrPaddingUpdated = true;
-        }
-        return hasMarginOrPaddingUpdated;
-    }
-
-    @Override
-    public void onScrollChanged() {
-        int recyclerViewYOffset = mCurrentRecyclerView.getCurrentScrollY();
-        if (recyclerViewYOffset < 0) return;
-        mCurrentRecyclerViewScrollY = recyclerViewYOffset;
-        if (mAnimator.isStarted()) {
-            mAnimator.cancel();
-        }
-        applyVerticalTransition();
-    }
-
-    /**
-     * Changes the displacement of collapsible views (e.g. title & widget recommendations) and fixed
-     * views (e.g. recycler views, tabs) upon scrolling / content changes in the recycler view.
-     */
-    private void applyVerticalTransition() {
-        if (mCollapsibleHeightForRecommendation > 0) {
-            int yDisplacement = Math.max(-mCurrentRecyclerViewScrollY,
-                    -mCollapsibleHeightForRecommendation);
-            mViewHolder.mHeaderTitle.setTranslationY(yDisplacement);
-            mViewHolder.mRecommendedWidgetsTable.setTranslationY(yDisplacement);
+        int headerHeight = mContainer.getMeasuredHeight();
+        if (headerHeight != mHeaderHeight) {
+            mHeaderHeight = headerHeight;
+            hasSizeUpdated = true;
         }
 
-        if (mCollapsibleHeightForSearch > 0) {
-            int searchYDisplacement = Math.max(-mCurrentRecyclerViewScrollY,
-                    -mCollapsibleHeightForSearch);
-            mViewHolder.mSearchBarContainer.setTranslationY(searchYDisplacement);
+        if (mCurrentEmptySpaceView != null
+                && mCurrentEmptySpaceView.setFixedHeight(mHeaderHeight)) {
+            hasSizeUpdated = true;
         }
-
-        if (mHasWorkProfile && mCollapsibleHeightForTabs > 0) {
-            int yDisplacementForTabs = Math.max(-mCurrentRecyclerViewScrollY,
-                    -mCollapsibleHeightForTabs);
-            mPrimaryWorkTabsView.setTranslationY(yDisplacementForTabs);
-        }
+        return hasSizeUpdated;
     }
 
     /** Resets any previous view translation. */
     public void reset(boolean animate) {
-        if (mCurrentRecyclerViewScrollY == 0) {
-            return;
-        }
-        if (mAnimator.isStarted()) {
-            mAnimator.cancel();
+        if (mOffsetAnimator != null) {
+            mOffsetAnimator.cancel();
+            mOffsetAnimator = null;
         }
 
-        if (animate) {
-            mAnimator.setIntValues(mCurrentRecyclerViewScrollY, 0);
-            mAnimator.addUpdateListener(this);
-            mAnimator.setDuration(300);
-            mAnimator.start();
+        mScrollOffset = 0;
+        if (!animate) {
+            updateHeaderScroll();
         } else {
-            mCurrentRecyclerViewScrollY = 0;
-            applyVerticalTransition();
+            float startValue = mLastScroll - getCurrentScroll();
+            mOffsetAnimator = ObjectAnimator.ofFloat(this, SCROLL_OFFSET, startValue, 0);
+            mOffsetAnimator.addListener(forEndCallback(() -> mOffsetAnimator = null));
+            mOffsetAnimator.start();
         }
     }
 
@@ -313,61 +164,60 @@
      * Returns {@code true} if a touch event should be intercepted by this controller.
      */
     public boolean onInterceptTouchEvent(MotionEvent event) {
-        calculateMotionEventOffset(mTempOffset);
-        event.offsetLocation(mTempOffset.x, mTempOffset.y);
-        try {
-            mShouldForwardToRecyclerView = mCurrentRecyclerView.onInterceptTouchEvent(event);
-            return mShouldForwardToRecyclerView;
-        } finally {
-            event.offsetLocation(-mTempOffset.x, -mTempOffset.y);
-        }
+        return (mShouldForwardToRecyclerView = proxyMotionEvent(event, INTERCEPT_PROXY));
     }
 
     /**
      * Returns {@code true} if this controller has intercepted and consumed a touch event.
      */
     public boolean onTouchEvent(MotionEvent event) {
-        if (mShouldForwardToRecyclerView) {
-            calculateMotionEventOffset(mTempOffset);
-            event.offsetLocation(mTempOffset.x, mTempOffset.y);
-            try {
-                return mCurrentRecyclerView.onTouchEvent(event);
-            } finally {
-                event.offsetLocation(-mTempOffset.x, -mTempOffset.y);
-            }
-        }
-        return false;
+        return mShouldForwardToRecyclerView && proxyMotionEvent(event, TOUCH_PROXY);
     }
 
-    private void calculateMotionEventOffset(Point p) {
-        p.x = mViewHolder.mContainer.getLeft() - mCurrentRecyclerView.getLeft()
-                - mSearchAndRecommendationViewParent.getLeft();
-        p.y = mViewHolder.mContainer.getTop() - mCurrentRecyclerView.getTop()
-                - mSearchAndRecommendationViewParent.getTop();
-    }
-
-    /** private the height, in pixel, + the vertical margins of a given view. */
-    private static int measureHeightWithVerticalMargins(View view) {
-        if (view.getVisibility() != View.VISIBLE) {
-            return 0;
+    private boolean proxyMotionEvent(MotionEvent event, MotionEventProxyMethod method) {
+        float dx = mCurrentRecyclerView.getLeft() - mContainer.getLeft();
+        float dy = mCurrentRecyclerView.getTop() - mContainer.getTop();
+        event.offsetLocation(dx, dy);
+        try {
+            return method.proxyEvent(mCurrentRecyclerView, event);
+        } finally {
+            event.offsetLocation(-dx, -dy);
         }
-        MarginLayoutParams marginLayoutParams = (MarginLayoutParams) view.getLayoutParams();
-        return view.getMeasuredHeight() + marginLayoutParams.bottomMargin
-                + marginLayoutParams.topMargin;
     }
 
     @Override
-    public void onAnimationUpdate(ValueAnimator animation) {
-        mCurrentRecyclerViewScrollY = (Integer) animation.getAnimatedValue();
-        applyVerticalTransition();
+    public void onChildViewAttachedToWindow(@NonNull View view) {
+        if (view instanceof EmptySpaceView) {
+            findCurrentEmptyView();
+        }
     }
 
-    /**
-     * A listener to be notified when there is a content change in the recycler view that may affect
-     * the relative position of the search and recommendation container.
-     */
-    public interface OnContentChangeListener {
-        /** Notifies a content change in the recycler view. */
-        void onContentChanged();
+    @Override
+    public void onChildViewDetachedFromWindow(@NonNull View view) {
+        if (view == mCurrentEmptySpaceView) {
+            findCurrentEmptyView();
+        }
+    }
+
+    private void findCurrentEmptyView() {
+        if (mCurrentEmptySpaceView != null) {
+            mCurrentEmptySpaceView.setOnYChangeCallback(null);
+            mCurrentEmptySpaceView = null;
+        }
+        int childCount = mCurrentRecyclerView.getChildCount();
+        for (int i = 0; i < childCount; i++) {
+            View view = mCurrentRecyclerView.getChildAt(i);
+            if (view instanceof EmptySpaceView) {
+                mCurrentEmptySpaceView = (EmptySpaceView) view;
+                mCurrentEmptySpaceView.setFixedHeight(getHeaderHeight());
+                mCurrentEmptySpaceView.setOnYChangeCallback(this::updateHeaderScroll);
+                return;
+            }
+        }
+    }
+
+    private interface MotionEventProxyMethod {
+
+        boolean proxyEvent(ViewGroup view, MotionEvent event);
     }
 }
diff --git a/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java b/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java
index be83f9a..09f0299 100644
--- a/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java
+++ b/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java
@@ -57,13 +57,12 @@
 import com.android.launcher3.model.WidgetItem;
 import com.android.launcher3.views.ArrowTipView;
 import com.android.launcher3.views.RecyclerViewFastScroller;
-import com.android.launcher3.views.TopRoundedCornerView;
+import com.android.launcher3.views.SpringRelativeLayout;
 import com.android.launcher3.views.WidgetsEduView;
 import com.android.launcher3.widget.BaseWidgetSheet;
 import com.android.launcher3.widget.LauncherAppWidgetHost.ProviderChangedListener;
 import com.android.launcher3.widget.model.WidgetsListBaseEntry;
 import com.android.launcher3.widget.picker.search.SearchModeListener;
-import com.android.launcher3.widget.picker.search.WidgetsSearchBar;
 import com.android.launcher3.widget.util.WidgetsTableUtils;
 import com.android.launcher3.workprofile.PersonalWorkPagedView;
 import com.android.launcher3.workprofile.PersonalWorkSlidingTabStrip.OnActivePageChangedListener;
@@ -79,7 +78,6 @@
 public class WidgetsFullSheet extends BaseWidgetSheet
         implements ProviderChangedListener, OnActivePageChangedListener,
         WidgetsRecyclerView.HeaderViewDimensionsProvider, SearchModeListener {
-    private static final String TAG = WidgetsFullSheet.class.getSimpleName();
 
     private static final long DEFAULT_OPEN_DURATION = 267;
     private static final long FADE_IN_DURATION = 150;
@@ -149,8 +147,6 @@
             };
 
     private final int mTabsHeight;
-    private final int mViewPagerTopPadding;
-    private final int mSearchAndRecommendationContainerBottomMargin;
     private final int mWidgetSheetContentHorizontalPadding;
 
     @Nullable private WidgetsRecyclerView mCurrentWidgetsRecyclerView;
@@ -158,10 +154,8 @@
     private boolean mIsInSearchMode;
     private boolean mIsNoWidgetsViewNeeded;
     private int mMaxSpansPerRow = DEFAULT_MAX_HORIZONTAL_SPANS;
-    private View mTabsView;
     private TextView mNoWidgetsView;
-    private SearchAndRecommendationViewHolder mSearchAndRecommendationViewHolder;
-    private SearchAndRecommendationsScrollController mSearchAndRecommendationsScrollController;
+    private SearchAndRecommendationsScrollController mSearchScrollController;
 
     public WidgetsFullSheet(Context context, AttributeSet attrs, int defStyleAttr) {
         super(context, attrs, defStyleAttr);
@@ -174,14 +168,6 @@
         mTabsHeight = mHasWorkProfile
                 ? resources.getDimensionPixelSize(R.dimen.all_apps_header_pill_height)
                 : 0;
-        mViewPagerTopPadding = mHasWorkProfile
-                ? getContext().getResources()
-                    .getDimensionPixelSize(R.dimen.widget_picker_view_pager_top_padding)
-                : 0;
-        mSearchAndRecommendationContainerBottomMargin = resources.getDimensionPixelSize(
-                mHasWorkProfile
-                        ? R.dimen.search_and_recommended_widgets_container_small_bottom_margin
-                        : R.dimen.search_and_recommended_widgets_container_bottom_margin);
         mWidgetSheetContentHorizontalPadding = 2 * resources.getDimensionPixelSize(
                 R.dimen.widget_cell_horizontal_padding);
     }
@@ -194,12 +180,11 @@
     protected void onFinishInflate() {
         super.onFinishInflate();
         mContent = findViewById(R.id.container);
-        TopRoundedCornerView springLayout = (TopRoundedCornerView) mContent;
 
         LayoutInflater layoutInflater = LayoutInflater.from(getContext());
         int contentLayoutRes = mHasWorkProfile ? R.layout.widgets_full_sheet_paged_view
                 : R.layout.widgets_full_sheet_recyclerview;
-        layoutInflater.inflate(contentLayoutRes, springLayout, true);
+        layoutInflater.inflate(contentLayoutRes, mContent, true);
 
         RecyclerViewFastScroller fastScroller = findViewById(R.id.fast_scroller);
         mAdapters.get(AdapterHolder.PRIMARY).setup(findViewById(R.id.primary_widgets_list_view));
@@ -209,7 +194,6 @@
             mViewPager.initParentViews(this);
             mViewPager.getPageIndicator().setOnActivePageChangedListener(this);
             mViewPager.getPageIndicator().setActiveMarker(AdapterHolder.PRIMARY);
-            mTabsView = findViewById(R.id.tabs);
             findViewById(R.id.tab_personal)
                     .setOnClickListener((View view) -> mViewPager.snapToPage(0));
             findViewById(R.id.tab_work)
@@ -220,33 +204,18 @@
             mViewPager = null;
         }
 
-        layoutInflater.inflate(R.layout.widgets_full_sheet_search_and_recommendations, springLayout,
-                true);
         mNoWidgetsView = findViewById(R.id.no_widgets_text);
-        mSearchAndRecommendationViewHolder = new SearchAndRecommendationViewHolder(
+        mSearchScrollController = new SearchAndRecommendationsScrollController(
                 findViewById(R.id.search_and_recommendations_container));
-        TopRoundedCornerView.LayoutParams layoutParams =
-                (TopRoundedCornerView.LayoutParams)
-                        mSearchAndRecommendationViewHolder.mContainer.getLayoutParams();
-        layoutParams.bottomMargin = mSearchAndRecommendationContainerBottomMargin;
-        mSearchAndRecommendationViewHolder.mContainer.setLayoutParams(layoutParams);
-        mSearchAndRecommendationsScrollController = new SearchAndRecommendationsScrollController(
-                mHasWorkProfile,
-                mTabsHeight,
-                mSearchAndRecommendationViewHolder,
-                findViewById(R.id.primary_widgets_list_view),
-                mHasWorkProfile ? findViewById(R.id.work_widgets_list_view) : null,
-                findViewById(R.id.search_widgets_list_view),
-                mTabsView,
-                mViewPager,
-                mNoWidgetsView);
-        fastScroller.setOnFastScrollChangeListener(mSearchAndRecommendationsScrollController);
-
+        mSearchScrollController.setCurrentRecyclerView(
+                findViewById(R.id.primary_widgets_list_view));
+        mSearchScrollController.mRecommendedWidgetsTable.setWidgetCellLongClickListener(this);
+        mSearchScrollController.mRecommendedWidgetsTable.setWidgetCellOnClickListener(this);
 
         onRecommendedWidgetsBound();
         onWidgetsBound();
 
-        mSearchAndRecommendationViewHolder.mSearchBar.initialize(
+        mSearchScrollController.mSearchBar.initialize(
                 mActivityContext.getPopupDataProvider(), /* searchModeListener= */ this);
 
         setUpEducationViewsIfNeeded();
@@ -270,12 +239,13 @@
             reset();
             resetExpandedHeaders();
             mCurrentWidgetsRecyclerView = recyclerView;
-            mSearchAndRecommendationsScrollController.setCurrentRecyclerView(recyclerView);
+            mSearchScrollController.setCurrentRecyclerView(recyclerView);
         }
     }
 
     private void updateRecyclerViewVisibility(AdapterHolder adapterHolder) {
-        boolean isWidgetAvailable = adapterHolder.mWidgetsListAdapter.getItemCount() > 0;
+        // The first item is always an empty space entry. Look for any more items.
+        boolean isWidgetAvailable = adapterHolder.mWidgetsListAdapter.hasVisibleEntries();
         adapterHolder.mWidgetsRecyclerView.setVisibility(isWidgetAvailable ? VISIBLE : GONE);
 
         mNoWidgetsView.setText(
@@ -291,7 +261,7 @@
             mAdapters.get(AdapterHolder.WORK).mWidgetsRecyclerView.scrollToTop();
         }
         mAdapters.get(AdapterHolder.SEARCH).mWidgetsRecyclerView.scrollToTop();
-        mSearchAndRecommendationsScrollController.reset(/* animate= */ true);
+        mSearchScrollController.reset(/* animate= */ true);
     }
 
     @VisibleForTesting
@@ -340,7 +310,8 @@
         if (mHasWorkProfile) {
             setBottomPadding(mAdapters.get(AdapterHolder.WORK).mWidgetsRecyclerView, insets.bottom);
         }
-        mSearchAndRecommendationsScrollController.updateBottomInset(insets.bottom);
+        ((MarginLayoutParams) mNoWidgetsView.getLayoutParams()).bottomMargin = insets.bottom;
+
         if (insets.bottom > 0) {
             setupNavBarColor();
         } else {
@@ -360,7 +331,7 @@
 
     @Override
     protected void onContentHorizontalMarginChanged(int contentHorizontalMarginInPx) {
-        setContentViewChildHorizontalMargin(mSearchAndRecommendationViewHolder.mContainer,
+        setContentViewChildHorizontalMargin(mSearchScrollController.mContainer,
                 contentHorizontalMarginInPx);
         if (mViewPager == null) {
             setContentViewChildHorizontalMargin(
@@ -385,14 +356,14 @@
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
         doMeasure(widthMeasureSpec, heightMeasureSpec);
 
-        if (mSearchAndRecommendationsScrollController.updateMarginAndPadding()) {
+        if (mSearchScrollController.updateHeaderHeight()) {
             doMeasure(widthMeasureSpec, heightMeasureSpec);
         }
 
         if (updateMaxSpansPerRow()) {
             doMeasure(widthMeasureSpec, heightMeasureSpec);
 
-            if (mSearchAndRecommendationsScrollController.updateMarginAndPadding()) {
+            if (mSearchScrollController.updateHeaderHeight()) {
                 doMeasure(widthMeasureSpec, heightMeasureSpec);
             }
         }
@@ -455,7 +426,7 @@
 
         if (mHasWorkProfile) {
             mViewPager.setVisibility(VISIBLE);
-            mTabsView.setVisibility(VISIBLE);
+            mSearchScrollController.mTabBar.setVisibility(VISIBLE);
             AdapterHolder workUserAdapterHolder = mAdapters.get(AdapterHolder.WORK);
             workUserAdapterHolder.mWidgetsListAdapter.setWidgets(allWidgets);
             onActivePageChanged(mViewPager.getCurrentPage());
@@ -465,9 +436,9 @@
         // Update recommended widgets section so that it occupies appropriate space on screen to
         // leave enough space for presence/absence of mNoWidgetsView.
         boolean isNoWidgetsViewNeeded =
-                mAdapters.get(AdapterHolder.PRIMARY).mWidgetsListAdapter.getItemCount() == 0
+                !mAdapters.get(AdapterHolder.PRIMARY).mWidgetsListAdapter.hasVisibleEntries()
                         || (mHasWorkProfile && mAdapters.get(AdapterHolder.WORK)
-                                .mWidgetsListAdapter.getItemCount() == 0);
+                        .mWidgetsListAdapter.hasVisibleEntries());
         if (mIsNoWidgetsViewNeeded != isNoWidgetsViewNeeded) {
             mIsNoWidgetsViewNeeded = isNoWidgetsViewNeeded;
             onRecommendedWidgetsBound();
@@ -491,8 +462,6 @@
             mViewPager.snapToPage(AdapterHolder.PRIMARY);
         }
         attachScrollbarToRecyclerView(mAdapters.get(AdapterHolder.PRIMARY).mWidgetsRecyclerView);
-
-        mSearchAndRecommendationsScrollController.updateMarginAndPadding();
     }
 
     @Override
@@ -505,10 +474,10 @@
     private void setViewVisibilityBasedOnSearch(boolean isInSearchMode) {
         mIsInSearchMode = isInSearchMode;
         if (isInSearchMode) {
-            mSearchAndRecommendationViewHolder.mRecommendedWidgetsTable.setVisibility(GONE);
+            mSearchScrollController.mRecommendedWidgetsTable.setVisibility(GONE);
             if (mHasWorkProfile) {
                 mViewPager.setVisibility(GONE);
-                mTabsView.setVisibility(GONE);
+                mSearchScrollController.mTabBar.setVisibility(GONE);
             } else {
                 mAdapters.get(AdapterHolder.PRIMARY).mWidgetsRecyclerView.setVisibility(GONE);
             }
@@ -536,8 +505,7 @@
         }
         List<WidgetItem> recommendedWidgets =
                 mActivityContext.getPopupDataProvider().getRecommendedWidgets();
-        WidgetsRecommendationTableLayout table =
-                mSearchAndRecommendationViewHolder.mRecommendedWidgetsTable;
+        WidgetsRecommendationTableLayout table = mSearchScrollController.mRecommendedWidgetsTable;
         if (recommendedWidgets.size() > 0) {
             float noWidgetsViewHeight = 0;
             if (mIsNoWidgetsViewNeeded) {
@@ -554,7 +522,7 @@
                     makeMeasureSpec(mActivityContext.getDeviceProfile().availableHeightPx,
                             MeasureSpec.EXACTLY));
             float maxTableHeight = (mContent.getMeasuredHeight()
-                    - mTabsHeight - mViewPagerTopPadding - getHeaderViewHeight()
+                    - mTabsHeight - getHeaderViewHeight()
                     - noWidgetsViewHeight) * RECOMMENDATION_TABLE_HEIGHT_RATIO;
 
             List<ArrayList<WidgetItem>> recommendedWidgetsInTable =
@@ -617,10 +585,10 @@
                 mNoIntercept = !getRecyclerView().shouldContainerScroll(ev, getPopupContainer());
             }
 
-            if (mSearchAndRecommendationViewHolder.mSearchBar.isSearchBarFocused()
+            if (mSearchScrollController.mSearchBar.isSearchBarFocused()
                     && !getPopupContainer().isEventOverView(
-                            mSearchAndRecommendationViewHolder.mSearchBarContainer, ev)) {
-                mSearchAndRecommendationViewHolder.mSearchBar.clearSearchBarFocus();
+                    mSearchScrollController.mSearchBarContainer, ev)) {
+                mSearchScrollController.mSearchBar.clearSearchBarFocus();
             }
         }
         return super.onControllerInterceptTouchEvent(ev);
@@ -661,10 +629,8 @@
 
     @Override
     public int getHeaderViewHeight() {
-        return measureHeightWithVerticalMargins(mSearchAndRecommendationViewHolder.mCollapseHandle)
-                + measureHeightWithVerticalMargins(mSearchAndRecommendationViewHolder.mHeaderTitle)
-                + measureHeightWithVerticalMargins(
-                        (View) mSearchAndRecommendationViewHolder.mSearchBarContainer);
+        return measureHeightWithVerticalMargins(mSearchScrollController.mHeaderTitle)
+                + measureHeightWithVerticalMargins(mSearchScrollController.mSearchBarContainer);
     }
 
     /** private the height, in pixel, + the vertical margins of a given view. */
@@ -681,14 +647,14 @@
     protected void onConfigurationChanged(Configuration newConfig) {
         super.onConfigurationChanged(newConfig);
         if (mIsInSearchMode) {
-            mSearchAndRecommendationViewHolder.mSearchBar.reset();
+            mSearchScrollController.mSearchBar.reset();
         }
     }
 
     @Override
     public boolean onBackPressed() {
         if (mIsInSearchMode) {
-            mSearchAndRecommendationViewHolder.mSearchBar.reset();
+            mSearchScrollController.mSearchBar.reset();
             return true;
         }
         return super.onBackPressed();
@@ -701,11 +667,10 @@
     }
 
     @Nullable private View getViewToShowEducationTip() {
-        if (mSearchAndRecommendationViewHolder.mRecommendedWidgetsTable.getVisibility() == VISIBLE
-                && mSearchAndRecommendationViewHolder.mRecommendedWidgetsTable.getChildCount() > 0
-        ) {
-            return ((ViewGroup) mSearchAndRecommendationViewHolder.mRecommendedWidgetsTable
-                    .getChildAt(0)).getChildAt(0);
+        if (mSearchScrollController.mRecommendedWidgetsTable.getVisibility() == VISIBLE
+                && mSearchScrollController.mRecommendedWidgetsTable.getChildCount() > 0) {
+            return ((ViewGroup) mSearchScrollController.mRecommendedWidgetsTable.getChildAt(0))
+                    .getChildAt(0);
         }
 
         AdapterHolder adapterHolder = mAdapters.get(mIsInSearchMode
@@ -722,7 +687,7 @@
                         .findFirst()
                         .orElse(null);
         if (viewHolderForTip != null) {
-            return ((ViewGroup) viewHolderForTip.mTableContainer.getChildAt(0)).getChildAt(0);
+            return ((ViewGroup) viewHolderForTip.tableContainer.getChildAt(0)).getChildAt(0);
         }
 
         return null;
@@ -780,8 +745,8 @@
             mWidgetsListAdapter = new WidgetsListAdapter(
                     context,
                     LayoutInflater.from(context),
-                    apps.getWidgetCache(),
                     apps.getIconCache(),
+                    this::getEmptySpaceHeight,
                     /* iconClickListener= */ WidgetsFullSheet.this,
                     /* iconLongClickListener= */ WidgetsFullSheet.this);
             mWidgetsListAdapter.setHasStableIds(true);
@@ -801,46 +766,24 @@
             mWidgetsListItemAnimator.setSupportsChangeAnimations(false);
         }
 
+        private int getEmptySpaceHeight() {
+            return mSearchScrollController.getHeaderHeight();
+        }
+
         void setup(WidgetsRecyclerView recyclerView) {
             mWidgetsRecyclerView = recyclerView;
             mWidgetsRecyclerView.setAdapter(mWidgetsListAdapter);
             mWidgetsRecyclerView.setItemAnimator(mWidgetsListItemAnimator);
             mWidgetsRecyclerView.setHeaderViewDimensionsProvider(WidgetsFullSheet.this);
             mWidgetsRecyclerView.setEdgeEffectFactory(
-                    ((TopRoundedCornerView) mContent).createEdgeEffectFactory());
+                    ((SpringRelativeLayout) mContent).createEdgeEffectFactory());
             // Recycler view binds to fast scroller when it is attached to screen. Make sure
             // search recycler view is bound to fast scroller if user is in search mode at the time
             // of attachment.
             if (mAdapterType == PRIMARY || mAdapterType == WORK) {
                 mWidgetsRecyclerView.addOnAttachStateChangeListener(mBindScrollbarInSearchMode);
             }
-            mWidgetsListAdapter.setApplyBitmapDeferred(false, mWidgetsRecyclerView);
             mWidgetsListAdapter.setMaxHorizontalSpansPerRow(mMaxSpansPerRow);
         }
     }
-
-    final class SearchAndRecommendationViewHolder {
-        final SearchAndRecommendationsView mContainer;
-        final View mCollapseHandle;
-        final View mSearchBarContainer;
-        final WidgetsSearchBar mSearchBar;
-        final TextView mHeaderTitle;
-        final WidgetsRecommendationTableLayout mRecommendedWidgetsTable;
-
-        SearchAndRecommendationViewHolder(
-                SearchAndRecommendationsView searchAndRecommendationContainer) {
-            mContainer = searchAndRecommendationContainer;
-            mCollapseHandle = mContainer.findViewById(R.id.collapse_handle);
-            mSearchBarContainer = mContainer.findViewById(R.id.search_bar_container);
-            mSearchBar = mContainer.findViewById(R.id.widgets_search_bar);
-            mHeaderTitle = mContainer.findViewById(R.id.title);
-            mRecommendedWidgetsTable = mContainer.findViewById(R.id.recommended_widget_table);
-            mRecommendedWidgetsTable.setWidgetCellOnTouchListener((view, event) -> {
-                getRecyclerView().onTouchEvent(event);
-                return false;
-            });
-            mRecommendedWidgetsTable.setWidgetCellLongClickListener(WidgetsFullSheet.this);
-            mRecommendedWidgetsTable.setWidgetCellOnClickListener(WidgetsFullSheet.this);
-        }
-    }
 }
diff --git a/src/com/android/launcher3/widget/picker/WidgetsListAdapter.java b/src/com/android/launcher3/widget/picker/WidgetsListAdapter.java
index 1125b82..d52134c 100644
--- a/src/com/android/launcher3/widget/picker/WidgetsListAdapter.java
+++ b/src/com/android/launcher3/widget/picker/WidgetsListAdapter.java
@@ -16,19 +16,20 @@
 package com.android.launcher3.widget.picker;
 
 import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_WIDGETSTRAY_APP_EXPANDED;
+import static com.android.launcher3.recyclerview.ViewHolderBinder.POSITION_DEFAULT;
+import static com.android.launcher3.recyclerview.ViewHolderBinder.POSITION_FIRST;
+import static com.android.launcher3.recyclerview.ViewHolderBinder.POSITION_LAST;
 
 import android.content.Context;
 import android.graphics.Rect;
 import android.os.Process;
 import android.util.Log;
-import android.util.Size;
 import android.util.SparseArray;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.View.OnClickListener;
 import android.view.View.OnLongClickListener;
 import android.view.ViewGroup;
-import android.widget.TableRow;
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
@@ -38,32 +39,27 @@
 import androidx.recyclerview.widget.RecyclerView.LayoutParams;
 import androidx.recyclerview.widget.RecyclerView.ViewHolder;
 
-import com.android.launcher3.BaseActivity;
-import com.android.launcher3.DeviceProfile;
-import com.android.launcher3.Launcher;
 import com.android.launcher3.R;
 import com.android.launcher3.icons.IconCache;
-import com.android.launcher3.model.WidgetItem;
 import com.android.launcher3.model.data.PackageItemInfo;
 import com.android.launcher3.recyclerview.ViewHolderBinder;
 import com.android.launcher3.util.LabelComparator;
 import com.android.launcher3.util.PackageUserKey;
-import com.android.launcher3.widget.CachingWidgetPreviewLoader;
-import com.android.launcher3.widget.DatabaseWidgetPreviewLoader;
-import com.android.launcher3.widget.WidgetCell;
-import com.android.launcher3.widget.WidgetPreviewLoader.WidgetPreviewLoadedCallback;
+import com.android.launcher3.views.ActivityContext;
+import com.android.launcher3.widget.model.WidgetListSpaceEntry;
 import com.android.launcher3.widget.model.WidgetsListBaseEntry;
 import com.android.launcher3.widget.model.WidgetsListContentEntry;
 import com.android.launcher3.widget.model.WidgetsListHeaderEntry;
 import com.android.launcher3.widget.model.WidgetsListSearchHeaderEntry;
-import com.android.launcher3.widget.util.WidgetSizes;
 
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.Comparator;
 import java.util.List;
 import java.util.Map;
 import java.util.OptionalInt;
+import java.util.function.IntSupplier;
 import java.util.function.Predicate;
 import java.util.stream.Collectors;
 import java.util.stream.IntStream;
@@ -84,20 +80,18 @@
     private static final boolean DEBUG = false;
 
     /** Uniquely identifies widgets list view type within the app. */
+    private static final int VIEW_TYPE_WIDGETS_SPACE = R.id.view_type_widgets_space;
     private static final int VIEW_TYPE_WIDGETS_LIST = R.id.view_type_widgets_list;
     private static final int VIEW_TYPE_WIDGETS_HEADER = R.id.view_type_widgets_header;
     private static final int VIEW_TYPE_WIDGETS_SEARCH_HEADER = R.id.view_type_widgets_search_header;
 
     private final Context mContext;
-    private final Launcher mLauncher;
-    private final CachingWidgetPreviewLoader mCachingPreviewLoader;
     private final WidgetsDiffReporter mDiffReporter;
     private final SparseArray<ViewHolderBinder> mViewHolderBinders = new SparseArray<>();
-    private final WidgetsListTableViewHolderBinder mWidgetsListTableViewHolderBinder;
     private final WidgetListBaseRowEntryComparator mRowComparator =
             new WidgetListBaseRowEntryComparator();
 
-    private List<WidgetsListBaseEntry> mAllEntries = new ArrayList<>();
+    private final List<WidgetsListBaseEntry> mAllEntries = new ArrayList<>();
     private ArrayList<WidgetsListBaseEntry> mVisibleEntries = new ArrayList<>();
     @Nullable private PackageUserKey mWidgetsContentVisiblePackageUserKey = null;
 
@@ -109,42 +103,36 @@
     @Nullable private Predicate<WidgetsListBaseEntry> mFilter = null;
     @Nullable private RecyclerView mRecyclerView;
     @Nullable private PackageUserKey mPendingClickHeader;
-    private final int mShortcutPreviewPadding;
     private final int mSpacingBetweenEntries;
     private int mMaxSpanSize = 4;
 
-    private final WidgetPreviewLoadedCallback mPreviewLoadedCallback =
-            ignored -> updateVisibleEntries();
-
     public WidgetsListAdapter(Context context, LayoutInflater layoutInflater,
-            DatabaseWidgetPreviewLoader widgetPreviewLoader, IconCache iconCache,
+            IconCache iconCache, IntSupplier emptySpaceHeightProvider,
             OnClickListener iconClickListener, OnLongClickListener iconLongClickListener) {
         mContext = context;
-        mLauncher = Launcher.getLauncher(context);
-        mCachingPreviewLoader = new CachingWidgetPreviewLoader(widgetPreviewLoader);
         mDiffReporter = new WidgetsDiffReporter(iconCache, this);
         WidgetsListDrawableFactory listDrawableFactory = new WidgetsListDrawableFactory(context);
-        mWidgetsListTableViewHolderBinder = new WidgetsListTableViewHolderBinder(
-                layoutInflater, iconClickListener, iconLongClickListener,
-                mCachingPreviewLoader, listDrawableFactory, /* listAdapter= */ this);
-        mViewHolderBinders.put(VIEW_TYPE_WIDGETS_LIST, mWidgetsListTableViewHolderBinder);
+
+        mViewHolderBinders.put(
+                VIEW_TYPE_WIDGETS_LIST,
+                new WidgetsListTableViewHolderBinder(
+                        layoutInflater, iconClickListener, iconLongClickListener,
+                        listDrawableFactory));
         mViewHolderBinders.put(
                 VIEW_TYPE_WIDGETS_HEADER,
                 new WidgetsListHeaderViewHolderBinder(
                         layoutInflater,
                         /* onHeaderClickListener= */ this,
-                        listDrawableFactory,
-                        /* listAdapter= */ this));
+                        listDrawableFactory));
         mViewHolderBinders.put(
                 VIEW_TYPE_WIDGETS_SEARCH_HEADER,
                 new WidgetsListSearchHeaderViewHolderBinder(
                         layoutInflater,
                         /* onHeaderClickListener= */ this,
-                        listDrawableFactory,
-                        /* listAdapter= */ this));
-        mShortcutPreviewPadding =
-                2 * context.getResources()
-                        .getDimensionPixelSize(R.dimen.widget_preview_shortcut_padding);
+                        listDrawableFactory));
+        mViewHolderBinders.put(
+                VIEW_TYPE_WIDGETS_SPACE,
+                new WidgetsSpaceViewHolderBinder(emptySpaceHeightProvider));
         mSpacingBetweenEntries =
                 context.getResources().getDimensionPixelSize(R.dimen.widget_list_entry_spacing);
     }
@@ -178,33 +166,19 @@
         mFilter = filter;
     }
 
-    /**
-     * Defers applying bitmap on all the {@link WidgetCell} in the {@param rv}.
-     *
-     * @see WidgetCell#setApplyBitmapDeferred(boolean)
-     */
-    public void setApplyBitmapDeferred(boolean isDeferred, RecyclerView rv) {
-        mWidgetsListTableViewHolderBinder.setApplyBitmapDeferred(isDeferred);
-
-        for (int i = rv.getChildCount() - 1; i >= 0; i--) {
-            ViewHolder viewHolder = rv.getChildViewHolder(rv.getChildAt(i));
-            if (viewHolder.getItemViewType() == VIEW_TYPE_WIDGETS_LIST) {
-                WidgetsRowViewHolder holder = (WidgetsRowViewHolder) viewHolder;
-                for (int j = holder.mTableContainer.getChildCount() - 1; j >= 0; j--) {
-                    TableRow row =  (TableRow) holder.mTableContainer.getChildAt(j);
-                    for (int k = row.getChildCount() - 1; k >= 0; k--) {
-                        ((WidgetCell) row.getChildAt(k)).setApplyBitmapDeferred(isDeferred);
-                    }
-                }
-            }
-        }
-    }
-
     @Override
     public int getItemCount() {
         return mVisibleEntries.size();
     }
 
+    /**
+     * Returns true if the adapter has entries which will be visible to the user
+     */
+    public boolean hasVisibleEntries() {
+        // Account for the 1st space entry
+        return getItemCount() > 1;
+    }
+
     /** Returns all items that will be drawn in a recycler view. */
     public List<WidgetsListBaseEntry> getItems() {
         return mVisibleEntries;
@@ -217,9 +191,9 @@
 
     /** Updates the widget list based on {@code tempEntries}. */
     public void setWidgets(List<WidgetsListBaseEntry> tempEntries) {
-        mCachingPreviewLoader.clearAll();
-        mAllEntries = tempEntries.stream().sorted(mRowComparator)
-                .collect(Collectors.toList());
+        mAllEntries.clear();
+        mAllEntries.add(new WidgetListSpaceEntry());
+        tempEntries.stream().sorted(mRowComparator).forEach(mAllEntries::add);
         if (shouldClearVisibleEntries()) {
             mVisibleEntries.clear();
         }
@@ -230,15 +204,10 @@
     public void setWidgetsOnSearch(List<WidgetsListBaseEntry> searchResults) {
         // Forget the expanded package every time widget list is refreshed in search mode.
         mWidgetsContentVisiblePackageUserKey = null;
-        cancelLoadingPreviews();
         setWidgets(searchResults);
     }
 
     private void updateVisibleEntries() {
-        // If not all previews are ready, then defer this update and try again after the preview
-        // loads.
-        if (!ensureAllPreviewsReady()) return;
-
         // Get the current top of the header with the matching key before adjusting the visible
         // entries.
         OptionalInt previousPositionForPackageUserKey =
@@ -247,8 +216,9 @@
                 getOffsetForPosition(previousPositionForPackageUserKey);
 
         List<WidgetsListBaseEntry> newVisibleEntries = mAllEntries.stream()
-                .filter(entry -> (mFilter == null || mFilter.test(entry))
+                .filter(entry -> ((mFilter == null || mFilter.test(entry))
                         && mHeaderAndSelectedContentFilter.test(entry))
+                        || entry instanceof WidgetListSpaceEntry)
                 .map(entry -> {
                     if (entry instanceof WidgetsListBaseEntry.Header<?>
                             && matchesKey(entry, mWidgetsContentVisiblePackageUserKey)) {
@@ -275,54 +245,6 @@
         }
     }
 
-    /**
-     * Checks that all preview images are loaded and starts loading for those that aren't ready.
-     *
-     * @return true if all previews are ready and the data can be updated, false otherwise.
-     */
-    private boolean ensureAllPreviewsReady() {
-        boolean allReady = true;
-        BaseActivity activity = BaseActivity.fromContext(mContext);
-        for (WidgetsListBaseEntry entry : mAllEntries) {
-            if (!(entry instanceof WidgetsListContentEntry)) continue;
-
-            WidgetsListContentEntry contentEntry = (WidgetsListContentEntry) entry;
-            if (!matchesKey(entry, mWidgetsContentVisiblePackageUserKey)) {
-                // If the entry isn't visible, clear any loaded previews.
-                mCachingPreviewLoader.clearPreviews(contentEntry.mWidgets);
-                continue;
-            }
-
-            for (int i = 0; i < entry.mWidgets.size(); i++) {
-                WidgetItem widgetItem = entry.mWidgets.get(i);
-                DeviceProfile deviceProfile = activity.getDeviceProfile();
-                Size widgetSize = WidgetSizes.getWidgetItemSizePx(mContext, deviceProfile,
-                        widgetItem);
-                if (widgetItem.isShortcut()) {
-                    widgetSize =
-                            new Size(
-                                    widgetSize.getWidth() + mShortcutPreviewPadding,
-                                    widgetSize.getHeight() + mShortcutPreviewPadding);
-                }
-
-                if (widgetItem.hasPreviewLayout()
-                        || mCachingPreviewLoader.isPreviewLoaded(widgetItem, widgetSize)) {
-                    // The widget is ready if it can be rendered with a preview layout or if its
-                    // preview bitmap is in the cache.
-                    continue;
-                }
-
-                // If we've reached this point, we should load the preview for the widget.
-                allReady = false;
-                mCachingPreviewLoader.loadPreview(
-                        activity,
-                        widgetItem,
-                        widgetSize,
-                        mPreviewLoadedCallback);
-            }
-        }
-        return allReady;
-    }
 
     /** Returns whether {@code entry} matches {@code key}. */
     private static boolean isHeaderForPackageUserKey(
@@ -343,16 +265,26 @@
     public void resetExpandedHeader() {
         if (mWidgetsContentVisiblePackageUserKey != null) {
             mWidgetsContentVisiblePackageUserKey = null;
-            cancelLoadingPreviews();
             updateVisibleEntries();
         }
     }
 
     @Override
-    public void onBindViewHolder(ViewHolder holder, int pos) {
+    public void onBindViewHolder(ViewHolder holder, int position) {
+        onBindViewHolder(holder, position, Collections.EMPTY_LIST);
+    }
+
+    @Override
+    public void onBindViewHolder(ViewHolder holder, int pos, List<Object> payloads) {
         ViewHolderBinder viewHolderBinder = mViewHolderBinders.get(getItemViewType(pos));
         WidgetsListBaseEntry entry = mVisibleEntries.get(pos);
-        viewHolderBinder.bindViewHolder(holder, mVisibleEntries.get(pos), pos);
+
+        // The first entry has an empty space, count from second entries.
+        int listPos = (pos > 1) ? POSITION_DEFAULT : POSITION_FIRST;
+        if (pos == (getItemCount() - 1)) {
+            listPos |= POSITION_LAST;
+        }
+        viewHolderBinder.bindViewHolder(holder, mVisibleEntries.get(pos), listPos, payloads);
         holder.itemView.setTag(R.id.tag_widget_entry, entry);
     }
 
@@ -395,6 +327,8 @@
             return VIEW_TYPE_WIDGETS_HEADER;
         } else if (entry instanceof WidgetsListSearchHeaderEntry) {
             return VIEW_TYPE_WIDGETS_SEARCH_HEADER;
+        } else if (entry instanceof WidgetListSpaceEntry) {
+            return VIEW_TYPE_WIDGETS_SPACE;
         }
         throw new UnsupportedOperationException("ViewHolderBinder not found for " + entry);
     }
@@ -404,11 +338,10 @@
         // Ignore invalid clicks, such as collapsing a package that isn't currently expanded.
         if (!showWidgets && !packageUserKey.equals(mWidgetsContentVisiblePackageUserKey)) return;
 
-        cancelLoadingPreviews();
-
         if (showWidgets) {
             mWidgetsContentVisiblePackageUserKey = packageUserKey;
-            mLauncher.getStatsLogManager().logger().log(LAUNCHER_WIDGETSTRAY_APP_EXPANDED);
+            ActivityContext.lookupContext(mContext)
+                    .getStatsLogManager().logger().log(LAUNCHER_WIDGETSTRAY_APP_EXPANDED);
         } else {
             mWidgetsContentVisiblePackageUserKey = null;
         }
@@ -420,16 +353,6 @@
         updateVisibleEntries();
     }
 
-    private void cancelLoadingPreviews() {
-        mCachingPreviewLoader.clearAll();
-    }
-
-    /** Returns the position of the currently expanded header, or empty if it's not present. */
-    public OptionalInt getSelectedHeaderPosition() {
-        if (mWidgetsContentVisiblePackageUserKey == null) return OptionalInt.empty();
-        return getPositionForPackageUserKey(mWidgetsContentVisiblePackageUserKey);
-    }
-
     /**
      * Returns the position of {@code key} in {@link #mVisibleEntries}, or  empty if it's not
      * present.
diff --git a/src/com/android/launcher3/widget/picker/WidgetsListHeaderViewHolderBinder.java b/src/com/android/launcher3/widget/picker/WidgetsListHeaderViewHolderBinder.java
index 2f8f1ba..fadb637 100644
--- a/src/com/android/launcher3/widget/picker/WidgetsListHeaderViewHolderBinder.java
+++ b/src/com/android/launcher3/widget/picker/WidgetsListHeaderViewHolderBinder.java
@@ -23,6 +23,8 @@
 import com.android.launcher3.util.PackageUserKey;
 import com.android.launcher3.widget.model.WidgetsListHeaderEntry;
 
+import java.util.List;
+
 /**
  * Binds data from {@link WidgetsListHeaderEntry} to UI elements in {@link WidgetsListHeaderHolder}.
  */
@@ -31,16 +33,13 @@
     private final LayoutInflater mLayoutInflater;
     private final OnHeaderClickListener mOnHeaderClickListener;
     private final WidgetsListDrawableFactory mListDrawableFactory;
-    private final WidgetsListAdapter mWidgetsListAdapter;
 
     public WidgetsListHeaderViewHolderBinder(LayoutInflater layoutInflater,
             OnHeaderClickListener onHeaderClickListener,
-            WidgetsListDrawableFactory listDrawableFactory,
-            WidgetsListAdapter listAdapter) {
+            WidgetsListDrawableFactory listDrawableFactory) {
         mLayoutInflater = layoutInflater;
         mOnHeaderClickListener = onHeaderClickListener;
         mListDrawableFactory = listDrawableFactory;
-        mWidgetsListAdapter = listAdapter;
     }
 
     @Override
@@ -53,14 +52,14 @@
 
     @Override
     public void bindViewHolder(WidgetsListHeaderHolder viewHolder, WidgetsListHeaderEntry data,
-            int position) {
+            @ListPosition int position, List<Object> payloads) {
         WidgetsListHeader widgetsListHeader = viewHolder.mWidgetsListHeader;
         widgetsListHeader.applyFromItemInfoWithIcon(data);
         widgetsListHeader.setExpanded(data.isWidgetListShown());
         widgetsListHeader.setListDrawableState(
                 WidgetsListDrawableState.obtain(
-                        /* isFirst= */ position == 0,
-                        /* isLast= */ position == mWidgetsListAdapter.getItemCount() - 1,
+                        (position & POSITION_FIRST) != 0,
+                        (position & POSITION_LAST) != 0,
                         /* isExpanded= */ data.isWidgetListShown()));
         widgetsListHeader.setOnExpandChangeListener(isExpanded ->
                 mOnHeaderClickListener.onHeaderClicked(
diff --git a/src/com/android/launcher3/widget/picker/WidgetsListLayoutManager.java b/src/com/android/launcher3/widget/picker/WidgetsListLayoutManager.java
deleted file mode 100644
index 2b7f544..0000000
--- a/src/com/android/launcher3/widget/picker/WidgetsListLayoutManager.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * 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.widget.picker;
-
-import android.content.Context;
-
-import androidx.annotation.Nullable;
-import androidx.recyclerview.widget.LinearLayoutManager;
-import androidx.recyclerview.widget.RecyclerView;
-
-import com.android.launcher3.widget.picker.SearchAndRecommendationsScrollController.OnContentChangeListener;
-
-/**
- * A layout manager for the {@link WidgetsRecyclerView}.
- *
- * {@link #setOnContentChangeListener(OnContentChangeListener)} can be used to register a callback
- * for when the content of the layout manager has changed, following measurement and animation.
- */
-public final class WidgetsListLayoutManager extends LinearLayoutManager {
-    @Nullable
-    private OnContentChangeListener mOnContentChangeListener;
-
-    public WidgetsListLayoutManager(Context context) {
-        super(context);
-    }
-
-    @Override
-    public void onLayoutCompleted(RecyclerView.State state) {
-        super.onLayoutCompleted(state);
-        if (mOnContentChangeListener != null) {
-            mOnContentChangeListener.onContentChanged();
-        }
-    }
-
-    public void setOnContentChangeListener(@Nullable OnContentChangeListener listener) {
-        mOnContentChangeListener = listener;
-    }
-}
diff --git a/src/com/android/launcher3/widget/picker/WidgetsListSearchHeaderViewHolderBinder.java b/src/com/android/launcher3/widget/picker/WidgetsListSearchHeaderViewHolderBinder.java
index 31dd9ee..bff43c1 100644
--- a/src/com/android/launcher3/widget/picker/WidgetsListSearchHeaderViewHolderBinder.java
+++ b/src/com/android/launcher3/widget/picker/WidgetsListSearchHeaderViewHolderBinder.java
@@ -24,6 +24,8 @@
 import com.android.launcher3.widget.model.WidgetsListHeaderEntry;
 import com.android.launcher3.widget.model.WidgetsListSearchHeaderEntry;
 
+import java.util.List;
+
 /**
  * Binds data from {@link WidgetsListHeaderEntry} to UI elements in {@link WidgetsListHeaderHolder}.
  */
@@ -32,16 +34,13 @@
     private final LayoutInflater mLayoutInflater;
     private final OnHeaderClickListener mOnHeaderClickListener;
     private final WidgetsListDrawableFactory mListDrawableFactory;
-    private final WidgetsListAdapter mWidgetsListAdapter;
 
     public WidgetsListSearchHeaderViewHolderBinder(LayoutInflater layoutInflater,
             OnHeaderClickListener onHeaderClickListener,
-            WidgetsListDrawableFactory listDrawableFactory,
-            WidgetsListAdapter listAdapter) {
+            WidgetsListDrawableFactory listDrawableFactory) {
         mLayoutInflater = layoutInflater;
         mOnHeaderClickListener = onHeaderClickListener;
         mListDrawableFactory = listDrawableFactory;
-        mWidgetsListAdapter = listAdapter;
     }
 
     @Override
@@ -54,14 +53,14 @@
 
     @Override
     public void bindViewHolder(WidgetsListSearchHeaderHolder viewHolder,
-            WidgetsListSearchHeaderEntry data, int position) {
+            WidgetsListSearchHeaderEntry data, @ListPosition int position, List<Object> payloads) {
         WidgetsListHeader widgetsListHeader = viewHolder.mWidgetsListHeader;
         widgetsListHeader.applyFromItemInfoWithIcon(data);
         widgetsListHeader.setExpanded(data.isWidgetListShown());
         widgetsListHeader.setListDrawableState(
                 WidgetsListDrawableState.obtain(
-                        /* isFirst= */ position == 0,
-                        /* isLast= */ position == mWidgetsListAdapter.getItemCount() - 1,
+                        (position & POSITION_FIRST) != 0,
+                        (position & POSITION_LAST) != 0,
                         /* isExpanded= */ data.isWidgetListShown()));
         widgetsListHeader.setOnExpandChangeListener(isExpanded ->
                 mOnHeaderClickListener.onHeaderClicked(isExpanded,
diff --git a/src/com/android/launcher3/widget/picker/WidgetsListTableViewHolderBinder.java b/src/com/android/launcher3/widget/picker/WidgetsListTableViewHolderBinder.java
index 9c06558..8c9ff09 100644
--- a/src/com/android/launcher3/widget/picker/WidgetsListTableViewHolderBinder.java
+++ b/src/com/android/launcher3/widget/picker/WidgetsListTableViewHolderBinder.java
@@ -20,7 +20,7 @@
 
 import android.graphics.Bitmap;
 import android.util.Log;
-import android.util.Size;
+import android.util.Pair;
 import android.view.Gravity;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -33,7 +33,6 @@
 import com.android.launcher3.R;
 import com.android.launcher3.model.WidgetItem;
 import com.android.launcher3.recyclerview.ViewHolderBinder;
-import com.android.launcher3.widget.CachingWidgetPreviewLoader;
 import com.android.launcher3.widget.WidgetCell;
 import com.android.launcher3.widget.model.WidgetsListContentEntry;
 import com.android.launcher3.widget.util.WidgetsTableUtils;
@@ -53,32 +52,16 @@
     private final OnClickListener mIconClickListener;
     private final OnLongClickListener mIconLongClickListener;
     private final WidgetsListDrawableFactory mListDrawableFactory;
-    private final CachingWidgetPreviewLoader mWidgetPreviewLoader;
-    private final WidgetsListAdapter mWidgetsListAdapter;
-    private boolean mApplyBitmapDeferred = false;
 
     public WidgetsListTableViewHolderBinder(
             LayoutInflater layoutInflater,
             OnClickListener iconClickListener,
             OnLongClickListener iconLongClickListener,
-            CachingWidgetPreviewLoader widgetPreviewLoader,
-            WidgetsListDrawableFactory listDrawableFactory,
-            WidgetsListAdapter listAdapter) {
+            WidgetsListDrawableFactory listDrawableFactory) {
         mLayoutInflater = layoutInflater;
         mIconClickListener = iconClickListener;
         mIconLongClickListener = iconLongClickListener;
-        mWidgetPreviewLoader = widgetPreviewLoader;
         mListDrawableFactory = listDrawableFactory;
-        mWidgetsListAdapter = listAdapter;
-    }
-
-    /**
-     * Defers applying bitmap on all the {@link WidgetCell} at
-     * {@link #bindViewHolder(WidgetsRowViewHolder, WidgetsListContentEntry, int)} if
-     * {@code applyBitmapDeferred} is {@code true}.
-     */
-    public void setApplyBitmapDeferred(boolean applyBitmapDeferred) {
-        mApplyBitmapDeferred = applyBitmapDeferred;
     }
 
     @Override
@@ -90,27 +73,30 @@
         WidgetsRowViewHolder viewHolder =
                 new WidgetsRowViewHolder(mLayoutInflater.inflate(
                         R.layout.widgets_table_container, parent, false));
-        viewHolder.mTableContainer.setBackgroundDrawable(
+        viewHolder.tableContainer.setBackgroundDrawable(
                 mListDrawableFactory.createContentBackgroundDrawable());
         return viewHolder;
     }
 
     @Override
     public void bindViewHolder(WidgetsRowViewHolder holder, WidgetsListContentEntry entry,
-            int position) {
-        WidgetsListTableView table = holder.mTableContainer;
+            @ListPosition int position, List<Object> payloads) {
+        for (Object payload : payloads) {
+            Pair<WidgetItem, Bitmap> pair = (Pair) payload;
+            holder.previewCache.put(pair.first, pair.second);
+        }
+
+        WidgetsListTableView table = holder.tableContainer;
         if (DEBUG) {
             Log.d(TAG, String.format("onBindViewHolder [widget#=%d, table.getChildCount=%d]",
                     entry.mWidgets.size(), table.getChildCount()));
         }
-
-        table.setListDrawableState(
-                position == mWidgetsListAdapter.getItemCount() - 1 ? LAST : MIDDLE);
-
+        table.setListDrawableState(((position & POSITION_LAST) != 0) ? LAST : MIDDLE);
         List<ArrayList<WidgetItem>> widgetItemsTable =
                 WidgetsTableUtils.groupWidgetItemsIntoTable(
                         entry.mWidgets, entry.getMaxSpanSizeInCells());
         recycleTableBeforeBinding(table, widgetItemsTable);
+
         // Bind the widget items.
         for (int i = 0; i < widgetItemsTable.size(); i++) {
             List<WidgetItem> widgetItemsPerRow = widgetItemsTable.get(i);
@@ -120,16 +106,17 @@
                 WidgetCell widget = (WidgetCell) row.getChildAt(j);
                 widget.clear();
                 WidgetItem widgetItem = widgetItemsPerRow.get(j);
-                Size previewSize = widget.setPreviewSize(widgetItem);
-                widget.applyFromCellItem(widgetItem, mWidgetPreviewLoader);
-                widget.setApplyBitmapDeferred(mApplyBitmapDeferred);
-                Bitmap preview = mWidgetPreviewLoader.getPreview(widgetItem, previewSize);
-                if (preview == null) {
-                    widget.ensurePreview();
-                } else {
-                    widget.applyPreview(preview);
-                }
                 widget.setVisibility(View.VISIBLE);
+
+                // When preview loads, notify adapter to rebind the item and possibly animate
+                widget.applyFromCellItem(widgetItem, 1f,
+                        bitmap -> {
+                        if (holder.getBindingAdapter() != null) {
+                            holder.getBindingAdapter().notifyItemChanged(
+                                    holder.getBindingAdapterPosition(),
+                                    Pair.create(widgetItem, bitmap));
+                            }
+                        }, holder.previewCache.get(widgetItem));
             }
         }
     }
@@ -170,6 +157,7 @@
                     View preview = widget.findViewById(R.id.widget_preview_container);
                     preview.setOnClickListener(mIconClickListener);
                     preview.setOnLongClickListener(mIconLongClickListener);
+                    widget.setAnimatePreview(false);
                     tableRow.addView(widget);
                 }
             }
@@ -178,9 +166,10 @@
 
     @Override
     public void unbindViewHolder(WidgetsRowViewHolder holder) {
-        int numOfRows = holder.mTableContainer.getChildCount();
+        int numOfRows = holder.tableContainer.getChildCount();
+        holder.previewCache.clear();
         for (int i = 0; i < numOfRows; i++) {
-            TableRow tableRow = (TableRow) holder.mTableContainer.getChildAt(i);
+            TableRow tableRow = (TableRow) holder.tableContainer.getChildAt(i);
             int numOfCols = tableRow.getChildCount();
             for (int j = 0; j < numOfCols; j++) {
                 WidgetCell widget = (WidgetCell) tableRow.getChildAt(j);
diff --git a/src/com/android/launcher3/widget/picker/WidgetsRecommendationTableLayout.java b/src/com/android/launcher3/widget/picker/WidgetsRecommendationTableLayout.java
index 0b8ca34..c986007 100644
--- a/src/com/android/launcher3/widget/picker/WidgetsRecommendationTableLayout.java
+++ b/src/com/android/launcher3/widget/picker/WidgetsRecommendationTableLayout.java
@@ -32,7 +32,6 @@
 
 import com.android.launcher3.DeviceProfile;
 import com.android.launcher3.Launcher;
-import com.android.launcher3.LauncherAppState;
 import com.android.launcher3.R;
 import com.android.launcher3.model.WidgetItem;
 import com.android.launcher3.widget.WidgetCell;
@@ -53,7 +52,6 @@
     private float mRecommendationTableMaxHeight = Float.MAX_VALUE;
     @Nullable private OnLongClickListener mWidgetCellOnLongClickListener;
     @Nullable private OnClickListener mWidgetCellOnClickListener;
-    @Nullable private OnTouchListener mWidgetCellOnTouchListener;
 
     public WidgetsRecommendationTableLayout(Context context) {
         this(context, /* attrs= */ null);
@@ -79,11 +77,6 @@
         mWidgetCellOnClickListener = widgetCellOnClickListener;
     }
 
-    /** Sets a {@link android.view.View.OnTouchListener} for all widget cells in this table. */
-    public void setWidgetCellOnTouchListener(OnTouchListener widgetCellOnTouchListener) {
-        mWidgetCellOnTouchListener = widgetCellOnTouchListener;
-    }
-
     /**
      * Sets a list of recommended widgets that would like to be displayed in this table within the
      * desired {@code recommendationTableMaxHeight}.
@@ -115,10 +108,7 @@
 
             for (WidgetItem widgetItem : widgetItems) {
                 WidgetCell widgetCell = addItemCell(tableRow);
-                widgetCell.setPreviewSize(widgetItem, data.mPreviewScale);
-                widgetCell.applyFromCellItem(widgetItem,
-                        LauncherAppState.getInstance(getContext()).getWidgetCache());
-                widgetCell.ensurePreview();
+                widgetCell.applyFromCellItem(widgetItem, data.mPreviewScale);
             }
             addView(tableRow);
         }
@@ -129,7 +119,6 @@
         WidgetCell widget = (WidgetCell) LayoutInflater.from(
                 getContext()).inflate(R.layout.widget_cell, parent, false);
 
-        widget.setOnTouchListener(mWidgetCellOnTouchListener);
         View previewContainer = widget.findViewById(R.id.widget_preview_container);
         previewContainer.setOnClickListener(mWidgetCellOnClickListener);
         previewContainer.setOnLongClickListener(mWidgetCellOnLongClickListener);
diff --git a/src/com/android/launcher3/widget/picker/WidgetsRecyclerView.java b/src/com/android/launcher3/widget/picker/WidgetsRecyclerView.java
index 7671841..f780f03 100644
--- a/src/com/android/launcher3/widget/picker/WidgetsRecyclerView.java
+++ b/src/com/android/launcher3/widget/picker/WidgetsRecyclerView.java
@@ -23,7 +23,6 @@
 import android.view.View;
 import android.widget.TableLayout;
 
-import androidx.annotation.Nullable;
 import androidx.recyclerview.widget.LinearLayoutManager;
 import androidx.recyclerview.widget.RecyclerView;
 import androidx.recyclerview.widget.RecyclerView.OnItemTouchListener;
@@ -32,11 +31,12 @@
 import com.android.launcher3.DeviceProfile;
 import com.android.launcher3.R;
 import com.android.launcher3.views.ActivityContext;
+import com.android.launcher3.widget.model.WidgetListSpaceEntry;
 import com.android.launcher3.widget.model.WidgetsListBaseEntry;
 import com.android.launcher3.widget.model.WidgetsListContentEntry;
 import com.android.launcher3.widget.model.WidgetsListHeaderEntry;
 import com.android.launcher3.widget.model.WidgetsListSearchHeaderEntry;
-import com.android.launcher3.widget.picker.SearchAndRecommendationsScrollController.OnContentChangeListener;
+import com.android.launcher3.widget.picker.WidgetsSpaceViewHolderBinder.EmptySpaceView;
 
 /**
  * The widgets recycler view.
@@ -50,10 +50,13 @@
     private final Point mFastScrollerOffset = new Point();
     private boolean mTouchDownOnScroller;
     private HeaderViewDimensionsProvider mHeaderViewDimensionsProvider;
+
+    // Cached sizes
     private int mLastVisibleWidgetContentTableHeight = 0;
     private int mWidgetHeaderHeight = 0;
+    private int mWidgetEmptySpaceHeight = 0;
+
     private final int mSpacingBetweenEntries;
-    @Nullable private OnContentChangeListener mOnContentChangeListener;
 
     public WidgetsRecyclerView(Context context) {
         this(context, null);
@@ -82,9 +85,7 @@
         super.onFinishInflate();
         // create a layout manager with Launcher's context so that scroll position
         // can be preserved during screen rotation.
-        WidgetsListLayoutManager layoutManager = new WidgetsListLayoutManager(getContext());
-        layoutManager.setOnContentChangeListener(mOnContentChangeListener);
-        setLayoutManager(layoutManager);
+        setLayoutManager(new LinearLayoutManager(getContext()));
     }
 
     @Override
@@ -169,10 +170,12 @@
                 // This assumes there is ever only one content shown in this recycler view.
                 mLastVisibleWidgetContentTableHeight = view.getMeasuredHeight();
             } else if (view instanceof WidgetsListHeader
-                    && mLastVisibleWidgetContentTableHeight == 0
+                    && mWidgetHeaderHeight == 0
                     && view.getMeasuredHeight() > 0) {
                 // This assumes all header views are of the same height.
                 mWidgetHeaderHeight = view.getMeasuredHeight();
+            } else if (view instanceof EmptySpaceView && view.getMeasuredHeight() > 0) {
+                mWidgetEmptySpaceHeight = view.getMeasuredHeight();
             }
         }
 
@@ -251,14 +254,6 @@
         scrollToPosition(0);
     }
 
-    public void setOnContentChangeListener(@Nullable OnContentChangeListener listener) {
-        mOnContentChangeListener = listener;
-        WidgetsListLayoutManager layoutManager = (WidgetsListLayoutManager) getLayoutManager();
-        if (layoutManager != null) {
-            layoutManager.setOnContentChangeListener(listener);
-        }
-    }
-
     /**
      * Returns the sum of the height, in pixels, of this list adapter's items from index 0 until
      * {@code untilIndex}.
@@ -283,6 +278,8 @@
                 }
             } else if (entry instanceof WidgetsListContentEntry) {
                 totalItemsHeight += mLastVisibleWidgetContentTableHeight;
+            } else if (entry instanceof WidgetListSpaceEntry) {
+                totalItemsHeight += mWidgetEmptySpaceHeight;
             } else {
                 throw new UnsupportedOperationException("Can't estimate height for " + entry);
             }
diff --git a/src/com/android/launcher3/widget/picker/WidgetsRowViewHolder.java b/src/com/android/launcher3/widget/picker/WidgetsRowViewHolder.java
index 618e2cb..fe2d84b 100644
--- a/src/com/android/launcher3/widget/picker/WidgetsRowViewHolder.java
+++ b/src/com/android/launcher3/widget/picker/WidgetsRowViewHolder.java
@@ -15,20 +15,26 @@
  */
 package com.android.launcher3.widget.picker;
 
+import android.graphics.Bitmap;
 import android.view.View;
 
 import androidx.recyclerview.widget.RecyclerView.ViewHolder;
 
 import com.android.launcher3.R;
+import com.android.launcher3.model.WidgetItem;
+
+import java.util.HashMap;
+import java.util.Map;
 
 /** A {@link ViewHolder} for showing widgets of an app in the full widget picker. */
 public final class WidgetsRowViewHolder extends ViewHolder {
 
-    public final WidgetsListTableView mTableContainer;
+    public final WidgetsListTableView tableContainer;
+    public final Map<WidgetItem, Bitmap> previewCache = new HashMap<>();
 
     public WidgetsRowViewHolder(View v) {
         super(v);
 
-        mTableContainer = v.findViewById(R.id.widgets_table);
+        tableContainer = v.findViewById(R.id.widgets_table);
     }
 }
diff --git a/src/com/android/launcher3/widget/picker/WidgetsSpaceViewHolderBinder.java b/src/com/android/launcher3/widget/picker/WidgetsSpaceViewHolderBinder.java
new file mode 100644
index 0000000..1aa5753
--- /dev/null
+++ b/src/com/android/launcher3/widget/picker/WidgetsSpaceViewHolderBinder.java
@@ -0,0 +1,115 @@
+/*
+ * 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.widget.picker;
+
+import static android.view.View.MeasureSpec.EXACTLY;
+import static android.view.View.MeasureSpec.makeMeasureSpec;
+
+import android.content.Context;
+import android.view.View;
+import android.view.ViewGroup;
+
+import androidx.recyclerview.widget.RecyclerView.ViewHolder;
+
+import com.android.launcher3.recyclerview.ViewHolderBinder;
+import com.android.launcher3.widget.model.WidgetListSpaceEntry;
+
+import java.util.List;
+import java.util.function.IntSupplier;
+
+/**
+ * {@link ViewHolderBinder} for binding the top empty space
+ */
+public class WidgetsSpaceViewHolderBinder
+        implements ViewHolderBinder<WidgetListSpaceEntry, ViewHolder> {
+
+    private final IntSupplier mEmptySpaceHeightProvider;
+
+    public WidgetsSpaceViewHolderBinder(IntSupplier emptySpaceHeightProvider) {
+        mEmptySpaceHeightProvider = emptySpaceHeightProvider;
+    }
+
+    @Override
+    public ViewHolder newViewHolder(ViewGroup parent) {
+        return new ViewHolder(new EmptySpaceView(parent.getContext())) { };
+    }
+
+    @Override
+    public void bindViewHolder(ViewHolder holder, WidgetListSpaceEntry data,
+            @ListPosition int position, List<Object> payloads) {
+        ((EmptySpaceView) holder.itemView).setFixedHeight(mEmptySpaceHeightProvider.getAsInt());
+    }
+
+    /**
+     * Empty view which allows listening for 'Y' changes
+     */
+    public static class EmptySpaceView extends View {
+
+        private Runnable mOnYChangeCallback;
+        private int mHeight = 0;
+
+        private EmptySpaceView(Context context) {
+            super(context);
+            animate().setUpdateListener(v -> notifyYChanged());
+        }
+
+        /**
+         * Sets the height for the empty view
+         * @return true if the height changed, false otherwise
+         */
+        public boolean setFixedHeight(int height) {
+            if (mHeight != height) {
+                mHeight = height;
+                requestLayout();
+                return true;
+            }
+            return false;
+        }
+
+        @Override
+        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+            super.onMeasure(widthMeasureSpec, makeMeasureSpec(mHeight, EXACTLY));
+        }
+
+        public void setOnYChangeCallback(Runnable callback) {
+            mOnYChangeCallback = callback;
+        }
+
+        @Override
+        protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+            super.onLayout(changed, left, top, right, bottom);
+            notifyYChanged();
+        }
+
+        @Override
+        public void offsetTopAndBottom(int offset) {
+            super.offsetTopAndBottom(offset);
+            notifyYChanged();
+        }
+
+        @Override
+        public void setTranslationY(float translationY) {
+            super.setTranslationY(translationY);
+            notifyYChanged();
+        }
+
+        private void notifyYChanged() {
+            if (mOnYChangeCallback != null) {
+                mOnYChangeCallback.run();
+            }
+        }
+    }
+}
diff --git a/src_shortcuts_overrides/com/android/launcher3/model/WidgetsModel.java b/src_shortcuts_overrides/com/android/launcher3/model/WidgetsModel.java
index 631067b..12e9e1e 100644
--- a/src_shortcuts_overrides/com/android/launcher3/model/WidgetsModel.java
+++ b/src_shortcuts_overrides/com/android/launcher3/model/WidgetsModel.java
@@ -150,7 +150,6 @@
             }
         }
 
-        app.getWidgetCache().removeObsoletePreviews(widgetsAndShortcuts, packageUser);
         return updatedItems;
     }
 
diff --git a/tests/Android.bp b/tests/Android.bp
index da55c28..aeddc4c 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -20,7 +20,78 @@
     default_applicable_licenses: ["packages_apps_Launcher3_license"],
 }
 
+// Source code used for test
 filegroup {
-    name: "launcher3-test-src-common",
-    srcs: ["src_common/**/*.java"],
+    name: "launcher-tests-src",
+    srcs: ["src/**/*.java"],
+}
+
+// Source code used for oop test helpers
+filegroup {
+    name: "launcher-oop-tests-src",
+    srcs: [
+      "src/com/android/launcher3/ui/AbstractLauncherUiTest.java",
+      "src/com/android/launcher3/ui/ActivityLeakTracker.java",
+      "src/com/android/launcher3/ui/PortraitLandscapeRunner.java",
+      "src/com/android/launcher3/util/Wait.java",
+      "src/com/android/launcher3/util/WidgetUtils.java",
+      "src/com/android/launcher3/util/rule/FailureWatcher.java",
+      "src/com/android/launcher3/util/rule/LauncherActivityRule.java",
+      "src/com/android/launcher3/util/rule/ScreenRecordRule.java",
+      "src/com/android/launcher3/util/rule/ShellCommandRule.java",
+      "src/com/android/launcher3/util/rule/SimpleActivityRule.java",
+      "src/com/android/launcher3/util/rule/TestStabilityRule.java",
+      "src/com/android/launcher3/ui/TaplTestsLauncher3.java",
+      "src/com/android/launcher3/testcomponent/BaseTestingActivity.java",
+      "src/com/android/launcher3/testcomponent/CustomShortcutConfigActivity.java",
+      "src/com/android/launcher3/testcomponent/TestCommandReceiver.java",
+      "src/com/android/launcher3/testcomponent/TestLauncherActivity.java",
+    ],
+}
+
+// Library with all the dependencies for building quickstep
+android_library {
+    name: "Launcher3TestLib",
+    srcs: [ ],
+    resource_dirs: ["res"],
+    static_libs: [
+        "launcher-aosp-tapl",
+        "androidx.test.core",
+        "androidx.test.runner",
+        "androidx.test.rules",
+        "androidx.test.ext.junit",
+        "androidx.test.espresso.core",
+        "androidx.test.espresso.contrib",
+        "androidx.test.espresso.intents",
+        "androidx.test.uiautomator_uiautomator",
+        "mockito-target-inline-minus-junit4",
+        "launcher_log_protos_lite",
+        "truth-prebuilt"
+    ],
+    manifest: "AndroidManifest-common.xml",
+    platform_apis: true,
+}
+
+android_test {
+    name: "Launcher3Tests",
+    srcs: [
+        ":launcher-tests-src",
+    ],
+    static_libs: ["Launcher3TestLib"],
+    libs: [
+        "android.test.base",
+        "android.test.runner",
+        "android.test.mock",
+    ],
+    jni_libs: [
+        "libdexmakerjvmtiagent",
+        "libstaticjvmtiagent",
+    ],
+    use_embedded_native_libs: false,
+    compile_multilib: "both",
+    instrumentation_for: "Launcher3",
+    manifest: "AndroidManifest.xml",
+    platform_apis: true,
+    test_config: "Launcher3Tests.xml",
+    data: [":Launcher3"]
 }
diff --git a/tests/Android.mk b/tests/Android.mk
deleted file mode 100644
index 6adc685..0000000
--- a/tests/Android.mk
+++ /dev/null
@@ -1,54 +0,0 @@
-# Copyright (C) 2015 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.
-#
-
-LOCAL_PATH := $(call my-dir)
-
-#
-# Build rule for Launcher3Tests
-#
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := tests
-LOCAL_STATIC_JAVA_LIBRARIES := \
-    androidx.test.runner \
-    androidx.test.rules \
-    androidx.test.uiautomator_uiautomator \
-    mockito-target-minus-junit4 \
-    launcher_log_protos_lite
-
-LOCAL_PRIVATE_PLATFORM_APIS := true
-LOCAL_STATIC_JAVA_LIBRARIES += launcher-aosp-tapl
-
-LOCAL_SRC_FILES := \
-	$(call all-java-files-under, src) \
-	$(call all-java-files-under, src_common)
-
-
-LOCAL_FULL_LIBS_MANIFEST_FILES := $(LOCAL_PATH)/AndroidManifest-common.xml
-
-LOCAL_PACKAGE_NAME := Launcher3Tests
-
-LOCAL_INSTRUMENTATION_FOR := Launcher3
-
-LOCAL_TEST_CONFIG := Launcher3Tests.xml
-
-LOCAL_COMPATIBILITY_SUPPORT_FILES := $(call intermediates-dir-for,APPS,Launcher3)/package.apk:Launcher3.apk
-
-LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
-LOCAL_LICENSE_CONDITIONS := notice
-LOCAL_NOTICE_FILE := $(LOCAL_PATH)/../NOTICE
-include $(BUILD_PACKAGE)
-
-include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/AndroidManifest-common.xml b/tests/AndroidManifest-common.xml
index 918ec4a..8222f75 100644
--- a/tests/AndroidManifest-common.xml
+++ b/tests/AndroidManifest-common.xml
@@ -24,7 +24,7 @@
     <uses-permission android:name="android.permission.READ_LOGS"/>
     <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS"/>
 
-    <application android:debuggable="true">
+    <application android:debuggable="true" android:extractNativeLibs="true">
         <uses-library android:name="android.test.runner"/>
 
         <receiver
diff --git a/robolectric_tests/src/com/android/launcher3/folder/FolderNameProviderTest.java b/tests/src/com/android/launcher3/folder/FolderNameProviderTest.java
similarity index 90%
rename from robolectric_tests/src/com/android/launcher3/folder/FolderNameProviderTest.java
rename to tests/src/com/android/launcher3/folder/FolderNameProviderTest.java
index 2a94d9b..23e6235 100644
--- a/robolectric_tests/src/com/android/launcher3/folder/FolderNameProviderTest.java
+++ b/tests/src/com/android/launcher3/folder/FolderNameProviderTest.java
@@ -15,6 +15,8 @@
  */
 package com.android.launcher3.folder;
 
+import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
+
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 
@@ -23,6 +25,9 @@
 import android.content.Intent;
 import android.os.UserHandle;
 
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
 import com.android.launcher3.model.data.AppInfo;
 import com.android.launcher3.model.data.WorkspaceItemInfo;
 import com.android.launcher3.util.Executors;
@@ -30,15 +35,11 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.LooperMode;
-import org.robolectric.annotation.LooperMode.Mode;
 
 import java.util.ArrayList;
 
-@RunWith(RobolectricTestRunner.class)
-@LooperMode(Mode.PAUSED)
+@SmallTest
+@RunWith(AndroidJUnit4.class)
 public final class FolderNameProviderTest {
     private Context mContext;
     private WorkspaceItemInfo mItem1;
@@ -46,7 +47,7 @@
 
     @Before
     public void setUp() {
-        mContext = RuntimeEnvironment.application;
+        mContext = getApplicationContext();
         mItem1 = new WorkspaceItemInfo(new AppInfo(
                 new ComponentName("a.b.c", "a.b.c/a.b.c.d"),
                 "title1",
diff --git a/robolectric_tests/src/com/android/launcher3/logging/FileLogTest.java b/tests/src/com/android/launcher3/logging/FileLogTest.java
similarity index 89%
rename from robolectric_tests/src/com/android/launcher3/logging/FileLogTest.java
rename to tests/src/com/android/launcher3/logging/FileLogTest.java
index 01b23ba..e5f8cec 100644
--- a/robolectric_tests/src/com/android/launcher3/logging/FileLogTest.java
+++ b/tests/src/com/android/launcher3/logging/FileLogTest.java
@@ -1,16 +1,17 @@
 package com.android.launcher3.logging;
 
+import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
+
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.LooperMode;
-import org.robolectric.annotation.LooperMode.Mode;
 
 import java.io.File;
 import java.io.PrintWriter;
@@ -20,8 +21,8 @@
 /**
  * Tests for {@link FileLog}
  */
-@RunWith(RobolectricTestRunner.class)
-@LooperMode(Mode.PAUSED)
+@SmallTest
+@RunWith(AndroidJUnit4.class)
 public class FileLogTest {
 
     private File mTempDir;
@@ -29,7 +30,7 @@
     public void setUp() {
         int count = 0;
         do {
-            mTempDir = new File(RuntimeEnvironment.application.getCacheDir(),
+            mTempDir = new File(getApplicationContext().getCacheDir(),
                     "log-test-" + (count++));
         } while (!mTempDir.mkdir());
 
diff --git a/robolectric_tests/src/com/android/launcher3/popup/PopupPopulatorTest.java b/tests/src/com/android/launcher3/popup/PopupPopulatorTest.java
similarity index 95%
rename from robolectric_tests/src/com/android/launcher3/popup/PopupPopulatorTest.java
rename to tests/src/com/android/launcher3/popup/PopupPopulatorTest.java
index 83bf7da..6764e09 100644
--- a/robolectric_tests/src/com/android/launcher3/popup/PopupPopulatorTest.java
+++ b/tests/src/com/android/launcher3/popup/PopupPopulatorTest.java
@@ -16,6 +16,8 @@
 
 package com.android.launcher3.popup;
 
+import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
+
 import static com.android.launcher3.popup.PopupPopulator.MAX_SHORTCUTS;
 import static com.android.launcher3.popup.PopupPopulator.NUM_DYNAMIC;
 
@@ -27,10 +29,11 @@
 
 import android.content.pm.ShortcutInfo;
 
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
 
 import java.util.ArrayList;
 import java.util.Collections;
@@ -39,7 +42,8 @@
 /**
  * Tests the sorting and filtering of shortcuts in {@link PopupPopulator}.
  */
-@RunWith(RobolectricTestRunner.class)
+@SmallTest
+@RunWith(AndroidJUnit4.class)
 public class PopupPopulatorTest {
 
     @Test
@@ -137,7 +141,7 @@
 
     private ShortcutInfo createInfo(boolean isStatic, int rank) {
         ShortcutInfo info = spy(new ShortcutInfo.Builder(
-                RuntimeEnvironment.application, generateId(isStatic, rank))
+                getApplicationContext(), generateId(isStatic, rank))
                 .setRank(rank)
                 .build());
         doReturn(isStatic).when(info).isDeclaredInManifest();
diff --git a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
index 0d5b9ad..1a6ce8c 100644
--- a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
+++ b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
@@ -52,7 +52,6 @@
 import com.android.launcher3.LauncherSettings;
 import com.android.launcher3.LauncherState;
 import com.android.launcher3.Utilities;
-import com.android.launcher3.common.WidgetUtils;
 import com.android.launcher3.model.data.ItemInfo;
 import com.android.launcher3.statemanager.StateManager;
 import com.android.launcher3.tapl.LauncherInstrumentation;
@@ -63,6 +62,7 @@
 import com.android.launcher3.util.LooperExecutor;
 import com.android.launcher3.util.PackageManagerHelper;
 import com.android.launcher3.util.Wait;
+import com.android.launcher3.util.WidgetUtils;
 import com.android.launcher3.util.rule.FailureWatcher;
 import com.android.launcher3.util.rule.LauncherActivityRule;
 import com.android.launcher3.util.rule.ScreenRecordRule;
diff --git a/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java b/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java
index 4beb617..881f50c 100644
--- a/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java
+++ b/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java
@@ -36,7 +36,6 @@
 import com.android.launcher3.tapl.AppIconMenuItem;
 import com.android.launcher3.tapl.Widgets;
 import com.android.launcher3.tapl.Workspace;
-import com.android.launcher3.util.rule.ScreenRecordRule.ScreenRecord;
 import com.android.launcher3.views.OptionsPopupView;
 import com.android.launcher3.widget.picker.WidgetsFullSheet;
 import com.android.launcher3.widget.picker.WidgetsRecyclerView;
@@ -97,7 +96,6 @@
     }
 
     @Test
-    @ScreenRecord //b/187080582
     public void testDevicePressMenu() throws Exception {
         mDevice.pressMenu();
         mDevice.waitForIdle();
diff --git a/tests/src/com/android/launcher3/ui/widget/AddWidgetTest.java b/tests/src/com/android/launcher3/ui/widget/AddWidgetTest.java
index 2e8048a..dad4f2b 100644
--- a/tests/src/com/android/launcher3/ui/widget/AddWidgetTest.java
+++ b/tests/src/com/android/launcher3/ui/widget/AddWidgetTest.java
@@ -27,7 +27,6 @@
 import com.android.launcher3.tapl.Widget;
 import com.android.launcher3.ui.AbstractLauncherUiTest;
 import com.android.launcher3.ui.TestViewHelpers;
-import com.android.launcher3.util.rule.ScreenRecordRule.ScreenRecord;
 import com.android.launcher3.util.rule.ShellCommandRule;
 import com.android.launcher3.widget.LauncherAppWidgetProviderInfo;
 
@@ -81,7 +80,6 @@
      */
     @Test
     @PortraitLandscape
-    @ScreenRecord //b/195263971
     public void testDragCustomShortcut() throws Throwable {
         clearHomescreen();
         mDevice.pressHome();
diff --git a/tests/src/com/android/launcher3/ui/widget/BindWidgetTest.java b/tests/src/com/android/launcher3/ui/widget/BindWidgetTest.java
index 9c6c317..fa39ce0 100644
--- a/tests/src/com/android/launcher3/ui/widget/BindWidgetTest.java
+++ b/tests/src/com/android/launcher3/ui/widget/BindWidgetTest.java
@@ -17,7 +17,7 @@
 
 import static androidx.test.InstrumentationRegistry.getTargetContext;
 
-import static com.android.launcher3.common.WidgetUtils.createWidgetInfo;
+import static com.android.launcher3.util.WidgetUtils.createWidgetInfo;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
diff --git a/tests/src/com/android/launcher3/util/ActivityContextWrapper.java b/tests/src/com/android/launcher3/util/ActivityContextWrapper.java
new file mode 100644
index 0000000..2618a2e
--- /dev/null
+++ b/tests/src/com/android/launcher3/util/ActivityContextWrapper.java
@@ -0,0 +1,62 @@
+/*
+ * 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.util;
+
+import android.content.Context;
+import android.content.ContextWrapper;
+import android.view.ContextThemeWrapper;
+
+import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.InvariantDeviceProfile;
+import com.android.launcher3.views.ActivityContext;
+import com.android.launcher3.views.BaseDragLayer;
+
+/**
+ * {@link ContextWrapper} with internal Launcher interface for testing
+ */
+public class ActivityContextWrapper extends ContextThemeWrapper implements ActivityContext {
+
+    private final DeviceProfile mProfile;
+    private final MyDragLayer mMyDragLayer;
+
+    public ActivityContextWrapper(Context base) {
+        super(base, android.R.style.Theme_DeviceDefault);
+        mProfile = InvariantDeviceProfile.INSTANCE.get(base).getDeviceProfile(base).copy(base);
+        mMyDragLayer = new MyDragLayer(this);
+    }
+
+    @Override
+    public BaseDragLayer getDragLayer() {
+        return mMyDragLayer;
+    }
+
+    @Override
+    public DeviceProfile getDeviceProfile() {
+        return mProfile;
+    }
+
+    private static class MyDragLayer extends BaseDragLayer<ActivityContextWrapper> {
+
+        MyDragLayer(Context context) {
+            super(context, null, 1);
+        }
+
+        @Override
+        public void recreateControllers() {
+            mControllers = new TouchController[0];
+        }
+    }
+}
diff --git a/robolectric_tests/src/com/android/launcher3/util/GridOccupancyTest.java b/tests/src/com/android/launcher3/util/GridOccupancyTest.java
similarity index 92%
rename from robolectric_tests/src/com/android/launcher3/util/GridOccupancyTest.java
rename to tests/src/com/android/launcher3/util/GridOccupancyTest.java
index 2f3fc37..b498077 100644
--- a/robolectric_tests/src/com/android/launcher3/util/GridOccupancyTest.java
+++ b/tests/src/com/android/launcher3/util/GridOccupancyTest.java
@@ -4,14 +4,17 @@
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
 
 /**
  * Unit tests for {@link GridOccupancy}
  */
-@RunWith(RobolectricTestRunner.class)
+@SmallTest
+@RunWith(AndroidJUnit4.class)
 public class GridOccupancyTest {
 
     @Test
diff --git a/robolectric_tests/src/com/android/launcher3/util/IntArrayTest.java b/tests/src/com/android/launcher3/util/IntArrayTest.java
similarity index 86%
rename from robolectric_tests/src/com/android/launcher3/util/IntArrayTest.java
rename to tests/src/com/android/launcher3/util/IntArrayTest.java
index c08e198..a3c7007 100644
--- a/robolectric_tests/src/com/android/launcher3/util/IntArrayTest.java
+++ b/tests/src/com/android/launcher3/util/IntArrayTest.java
@@ -17,14 +17,17 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
 
 /**
- * Robolectric unit tests for {@link IntArray}
+ * Unit tests for {@link IntArray}
  */
-@RunWith(RobolectricTestRunner.class)
+@SmallTest
+@RunWith(AndroidJUnit4.class)
 public class IntArrayTest {
 
     @Test
diff --git a/robolectric_tests/src/com/android/launcher3/util/IntSetTest.java b/tests/src/com/android/launcher3/util/IntSetTest.java
similarity index 91%
rename from robolectric_tests/src/com/android/launcher3/util/IntSetTest.java
rename to tests/src/com/android/launcher3/util/IntSetTest.java
index 7a8c00b..cdb2891 100644
--- a/robolectric_tests/src/com/android/launcher3/util/IntSetTest.java
+++ b/tests/src/com/android/launcher3/util/IntSetTest.java
@@ -21,14 +21,17 @@
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
 
 /**
- * Robolectric unit tests for {@link IntSet}
+ * Unit tests for {@link IntSet}
  */
-@RunWith(RobolectricTestRunner.class)
+@SmallTest
+@RunWith(AndroidJUnit4.class)
 public class IntSetTest {
 
     @Test
diff --git a/tests/src/com/android/launcher3/util/Wait.java b/tests/src/com/android/launcher3/util/Wait.java
index fe6143c..8b5e197 100644
--- a/tests/src/com/android/launcher3/util/Wait.java
+++ b/tests/src/com/android/launcher3/util/Wait.java
@@ -52,7 +52,7 @@
             throw new RuntimeException(t);
         }
         Log.d("Wait", "atMost: timed out: " + SystemClock.uptimeMillis());
-        launcher.checkForAnomaly();
+        launcher.checkForAnomaly(false);
         Assert.fail(message.get());
     }
 
diff --git a/tests/src_common/com/android/launcher3/common/WidgetUtils.java b/tests/src/com/android/launcher3/util/WidgetUtils.java
similarity index 82%
rename from tests/src_common/com/android/launcher3/common/WidgetUtils.java
rename to tests/src/com/android/launcher3/util/WidgetUtils.java
index 97500e3..6fc8491 100644
--- a/tests/src_common/com/android/launcher3/common/WidgetUtils.java
+++ b/tests/src/com/android/launcher3/util/WidgetUtils.java
@@ -13,19 +13,25 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.android.launcher3.common;
+package com.android.launcher3.util;
+
+import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
+import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
 
 import static com.android.launcher3.WorkspaceLayoutManager.FIRST_SCREEN_ID;
 
 import android.appwidget.AppWidgetHost;
+import android.appwidget.AppWidgetManager;
+import android.appwidget.AppWidgetProviderInfo;
+import android.content.ComponentName;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.os.Bundle;
+import android.os.Process;
 
 import com.android.launcher3.LauncherSettings;
 import com.android.launcher3.model.data.ItemInfo;
 import com.android.launcher3.model.data.LauncherAppWidgetInfo;
-import com.android.launcher3.util.ContentWriter;
 import com.android.launcher3.widget.LauncherAppWidgetHost;
 import com.android.launcher3.widget.LauncherAppWidgetProviderInfo;
 import com.android.launcher3.widget.PendingAddWidgetInfo;
@@ -102,4 +108,17 @@
         resolver.insert(LauncherSettings.Favorites.CONTENT_URI,
                 writer.getValues(targetContext));
     }
+
+
+    /**
+     * Creates a {@link AppWidgetProviderInfo} for the provided component name
+     */
+    public static AppWidgetProviderInfo createAppWidgetProviderInfo(ComponentName cn) {
+        AppWidgetProviderInfo info = AppWidgetManager.getInstance(getApplicationContext())
+                .getInstalledProvidersForPackage(
+                        getInstrumentation().getContext().getPackageName(), Process.myUserHandle())
+                .get(0);
+        info.provider = cn;
+        return info;
+    }
 }
diff --git a/tests/src/com/android/launcher3/util/rule/FailureWatcher.java b/tests/src/com/android/launcher3/util/rule/FailureWatcher.java
index 5fbf847..fae55cc 100644
--- a/tests/src/com/android/launcher3/util/rule/FailureWatcher.java
+++ b/tests/src/com/android/launcher3/util/rule/FailureWatcher.java
@@ -13,6 +13,7 @@
 
 import org.junit.rules.TestWatcher;
 import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
 
 import java.io.File;
 import java.io.FileOutputStream;
@@ -29,6 +30,7 @@
     public FailureWatcher(UiDevice device, LauncherInstrumentation launcher) {
         mDevice = device;
         mLauncher = launcher;
+        Log.d("b/196820244", "FailureWatcher.ctor", new Exception());
     }
 
     @Override
@@ -38,12 +40,36 @@
     }
 
     @Override
+    public Statement apply(Statement base, Description description) {
+        return new Statement() {
+            @Override
+            public void evaluate() throws Throwable {
+                try {
+                    Log.d("b/196820244", "Before evaluate");
+                    FailureWatcher.super.apply(base, description).evaluate();
+                    Log.d("b/196820244", "After evaluate");
+                } finally {
+                    if (mLauncher.hadNontestEvents()) {
+                        throw new AssertionError(
+                                "Launcher received events not sent by the test. This may mean "
+                                        + "that the touch screen of the lab device has sent false"
+                                        + " events. See the logcat for TaplEvents tag and look "
+                                        + "for events with deviceId != -1");
+                    }
+                }
+            }
+        };
+    }
+
+    @Override
     protected void failed(Throwable e, Description description) {
         onError(mDevice, description, e);
     }
 
     public static void onError(UiDevice device, Description description, Throwable e) {
+        Log.d("b/196820244", "onError 1");
         if (device == null) return;
+        Log.d("b/196820244", "onError 2");
         final File parentFile = getInstrumentation().getTargetContext().getFilesDir();
         final File sceenshot = new File(parentFile,
                 "TestScreenshot-" + description.getMethodName() + ".png");
diff --git a/tests/src/com/android/launcher3/util/rule/ShellCommandRule.java b/tests/src/com/android/launcher3/util/rule/ShellCommandRule.java
index 2b2fef4..08953fc 100644
--- a/tests/src/com/android/launcher3/util/rule/ShellCommandRule.java
+++ b/tests/src/com/android/launcher3/util/rule/ShellCommandRule.java
@@ -21,7 +21,6 @@
 
 import android.content.ComponentName;
 import android.content.pm.ActivityInfo;
-import android.util.Log;
 
 import androidx.annotation.Nullable;
 import androidx.test.InstrumentationRegistry;
@@ -103,8 +102,6 @@
      */
     public static ShellCommandRule setDefaultLauncher() {
         final ActivityInfo launcher = getLauncherInMyProcess();
-        Log.d("b/187080582", "Launcher: " + new ComponentName(launcher.packageName, launcher.name)
-                .flattenToString());
         return new ShellCommandRule(getLauncherCommand(launcher), null, true, () ->
                 Assert.assertEquals("Setting default launcher failed",
                         new ComponentName(launcher.packageName, launcher.name)
diff --git a/robolectric_tests/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfoTest.java b/tests/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfoTest.java
similarity index 96%
rename from robolectric_tests/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfoTest.java
rename to tests/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfoTest.java
index a6f892c..24ae583 100644
--- a/robolectric_tests/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfoTest.java
+++ b/tests/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfoTest.java
@@ -15,6 +15,8 @@
  */
 package com.android.launcher3.widget;
 
+import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
+
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.ArgumentMatchers.any;
@@ -25,6 +27,9 @@
 import android.graphics.Point;
 import android.graphics.Rect;
 
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
 import com.android.launcher3.DeviceProfile;
 import com.android.launcher3.InvariantDeviceProfile;
 
@@ -32,15 +37,13 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
 
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 
-@RunWith(RobolectricTestRunner.class)
+@SmallTest
+@RunWith(AndroidJUnit4.class)
 public final class LauncherAppWidgetProviderInfoTest {
 
     private static final int CELL_SIZE = 50;
@@ -51,8 +54,7 @@
 
     @Before
     public void setUp() {
-        MockitoAnnotations.initMocks(this);
-        mContext = RuntimeEnvironment.application;
+        mContext = getApplicationContext();
     }
 
     @Test
@@ -260,6 +262,7 @@
             return null;
         }).when(profile).getCellSize(any(Point.class));
         Mockito.when(profile.getCellSize()).thenReturn(new Point(CELL_SIZE, CELL_SIZE));
+        Mockito.when(profile.shouldInsetWidgets()).thenReturn(true);
 
         InvariantDeviceProfile idp = new InvariantDeviceProfile();
         List<DeviceProfile> supportedProfiles = new ArrayList<>(idp.supportedProfiles);
diff --git a/robolectric_tests/src/com/android/launcher3/widget/picker/WidgetsDiffReporterTest.java b/tests/src/com/android/launcher3/widget/picker/WidgetsDiffReporterTest.java
similarity index 95%
rename from robolectric_tests/src/com/android/launcher3/widget/picker/WidgetsDiffReporterTest.java
rename to tests/src/com/android/launcher3/widget/picker/WidgetsDiffReporterTest.java
index b9f183c..6232938 100644
--- a/robolectric_tests/src/com/android/launcher3/widget/picker/WidgetsDiffReporterTest.java
+++ b/tests/src/com/android/launcher3/widget/picker/WidgetsDiffReporterTest.java
@@ -15,13 +15,16 @@
  */
 package com.android.launcher3.widget.picker;
 
+import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
+
+import static com.android.launcher3.util.WidgetUtils.createAppWidgetProviderInfo;
+
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyZeroInteractions;
-import static org.robolectric.Shadows.shadowOf;
 
 import android.appwidget.AppWidgetProviderInfo;
 import android.content.ComponentName;
@@ -30,6 +33,8 @@
 import android.os.UserHandle;
 
 import androidx.recyclerview.widget.RecyclerView;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
 
 import com.android.launcher3.InvariantDeviceProfile;
 import com.android.launcher3.icons.BitmapInfo;
@@ -48,15 +53,12 @@
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.shadows.ShadowPackageManager;
-import org.robolectric.util.ReflectionHelpers;
 
 import java.util.ArrayList;
 import java.util.List;
 
-@RunWith(RobolectricTestRunner.class)
+@SmallTest
+@RunWith(AndroidJUnit4.class)
 public final class WidgetsDiffReporterTest {
     private static final String TEST_PACKAGE_PREFIX = "com.android.test";
     private static final WidgetListBaseRowEntryComparator COMPARATOR =
@@ -87,7 +89,7 @@
                 .getComponent().getPackageName())
                 .when(mIconCache).getTitleNoCache(any());
 
-        mContext = RuntimeEnvironment.application;
+        mContext = getApplicationContext();
         mWidgetsDiffReporter = new WidgetsDiffReporter(mIconCache, mAdapter);
         mHeaderA = createWidgetsHeaderEntry(TEST_PACKAGE_PREFIX + "A",
                 /* appName= */ "A", /* numOfWidgets= */ 3);
@@ -294,14 +296,10 @@
     }
 
     private List<WidgetItem> generateWidgetItems(String packageName, int numOfWidgets) {
-        ShadowPackageManager packageManager = shadowOf(mContext.getPackageManager());
         ArrayList<WidgetItem> widgetItems = new ArrayList<>();
         for (int i = 0; i < numOfWidgets; i++) {
             ComponentName cn = ComponentName.createRelative(packageName, ".SampleWidget" + i);
-            AppWidgetProviderInfo widgetInfo = new AppWidgetProviderInfo();
-            widgetInfo.provider = cn;
-            ReflectionHelpers.setField(widgetInfo, "providerInfo",
-                    packageManager.addReceiverIfNotPresent(cn));
+            AppWidgetProviderInfo widgetInfo = createAppWidgetProviderInfo(cn);
 
             WidgetItem widgetItem = new WidgetItem(
                     LauncherAppWidgetProviderInfo.fromProviderInfo(mContext, widgetInfo),
diff --git a/robolectric_tests/src/com/android/launcher3/widget/picker/WidgetsListAdapterTest.java b/tests/src/com/android/launcher3/widget/picker/WidgetsListAdapterTest.java
similarity index 91%
rename from robolectric_tests/src/com/android/launcher3/widget/picker/WidgetsListAdapterTest.java
rename to tests/src/com/android/launcher3/widget/picker/WidgetsListAdapterTest.java
index c730fc0..44d6964 100644
--- a/robolectric_tests/src/com/android/launcher3/widget/picker/WidgetsListAdapterTest.java
+++ b/tests/src/com/android/launcher3/widget/picker/WidgetsListAdapterTest.java
@@ -15,12 +15,13 @@
  */
 package com.android.launcher3.widget.picker;
 
+import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
+
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Matchers.eq;
 import static org.mockito.Matchers.isNull;
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.verify;
-import static org.robolectric.Shadows.shadowOf;
 
 import android.appwidget.AppWidgetProviderInfo;
 import android.content.ComponentName;
@@ -31,6 +32,8 @@
 import android.view.LayoutInflater;
 
 import androidx.recyclerview.widget.RecyclerView;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
 
 import com.android.launcher3.InvariantDeviceProfile;
 import com.android.launcher3.icons.BitmapInfo;
@@ -38,8 +41,9 @@
 import com.android.launcher3.icons.IconCache;
 import com.android.launcher3.model.WidgetItem;
 import com.android.launcher3.model.data.PackageItemInfo;
+import com.android.launcher3.util.ActivityContextWrapper;
 import com.android.launcher3.util.PackageUserKey;
-import com.android.launcher3.widget.DatabaseWidgetPreviewLoader;
+import com.android.launcher3.util.WidgetUtils;
 import com.android.launcher3.widget.LauncherAppWidgetProviderInfo;
 import com.android.launcher3.widget.model.WidgetsListBaseEntry;
 import com.android.launcher3.widget.model.WidgetsListContentEntry;
@@ -51,20 +55,20 @@
 import org.mockito.Mock;
 import org.mockito.Mockito;
 import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.shadows.ShadowPackageManager;
-import org.robolectric.util.ReflectionHelpers;
 
 import java.util.ArrayList;
 import java.util.List;
 
-@RunWith(RobolectricTestRunner.class)
+/**
+ * Unit tests for WidgetsListAdapter
+ * Note that all indices matching are shifted by 1 to account for the empty space at the start.
+ */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
 public final class WidgetsListAdapterTest {
     private static final String TEST_PACKAGE_PLACEHOLDER = "com.google.test";
 
     @Mock private LayoutInflater mMockLayoutInflater;
-    @Mock private DatabaseWidgetPreviewLoader mMockWidgetCache;
     @Mock private RecyclerView.AdapterDataObserver mListener;
     @Mock private IconCache mIconCache;
 
@@ -76,13 +80,13 @@
     @Before
     public void setup() {
         MockitoAnnotations.initMocks(this);
-        mContext = RuntimeEnvironment.application;
+        mContext = new ActivityContextWrapper(getApplicationContext());
         mTestProfile = new InvariantDeviceProfile();
         mTestProfile.numRows = 5;
         mTestProfile.numColumns = 5;
         mUserHandle = Process.myUserHandle();
-        mAdapter = new WidgetsListAdapter(mContext, mMockLayoutInflater, mMockWidgetCache,
-                mIconCache, null, null);
+        mAdapter = new WidgetsListAdapter(mContext, mMockLayoutInflater,
+                mIconCache, () -> 0, null, null);
         mAdapter.registerAdapterDataObserver(mListener);
 
         doAnswer(invocation -> ((ComponentWithLabel) invocation.getArgument(0))
@@ -102,7 +106,7 @@
         mAdapter.setWidgets(generateSampleMap(1));
         mAdapter.setWidgets(generateSampleMap(2));
 
-        verify(mListener).onItemRangeInserted(eq(1), eq(1));
+        verify(mListener).onItemRangeInserted(eq(2), eq(1));
     }
 
     @Test
@@ -110,7 +114,7 @@
         mAdapter.setWidgets(generateSampleMap(2));
         mAdapter.setWidgets(generateSampleMap(1));
 
-        verify(mListener).onItemRangeRemoved(eq(1), eq(1));
+        verify(mListener).onItemRangeRemoved(eq(2), eq(1));
     }
 
     @Test
@@ -118,7 +122,7 @@
         mAdapter.setWidgets(generateSampleMap(1));
         mAdapter.setWidgets(generateSampleMap(1));
 
-        verify(mListener).onItemRangeChanged(eq(0), eq(1), isNull());
+        verify(mListener).onItemRangeChanged(eq(1), eq(1), isNull());
     }
 
     @Test
@@ -137,7 +141,7 @@
         // THEN the visible entries list becomes:
         // [com.google.test0, com.google.test1, com.google.test1 content, com.google.test2]
         // com.google.test.1 content is inserted into position 2.
-        verify(mListener).onItemRangeInserted(eq(2), eq(1));
+        verify(mListener).onItemRangeInserted(eq(3), eq(1));
     }
 
     @Test
@@ -165,7 +169,7 @@
         mAdapter.setWidgets(allEntries);
 
         // THEN the onItemRangeChanged is invoked for "com.google.test1 content" at index 2.
-        verify(mListener).onItemRangeChanged(eq(2), eq(1), isNull());
+        verify(mListener).onItemRangeChanged(eq(3), eq(1), isNull());
     }
 
     @Test
@@ -196,15 +200,16 @@
                 allAppsWithWidgets.get(6), allAppsWithWidgets.get(7));
         mAdapter.setWidgets(newList);
 
+        // Account for 1st items as empty space
         // Computation logic                           | [Intermediate list during computation]
         // THEN B <> C < 0, removed B from index 1     | [A, E]
-        verify(mListener).onItemRangeRemoved(/* positionStart= */ 1, /* itemCount= */ 1);
+        verify(mListener).onItemRangeRemoved(/* positionStart= */ 2, /* itemCount= */ 1);
         // THEN E <> C > 0, C inserted to index 1      | [A, C, E]
-        verify(mListener).onItemRangeInserted(/* positionStart= */ 1, /* itemCount= */ 1);
-        // THEN E <> D > 0, D inserted to index 2      | [A, C, D, E]
         verify(mListener).onItemRangeInserted(/* positionStart= */ 2, /* itemCount= */ 1);
+        // THEN E <> D > 0, D inserted to index 2      | [A, C, D, E]
+        verify(mListener).onItemRangeInserted(/* positionStart= */ 3, /* itemCount= */ 1);
         // THEN E <> null = -1, E deleted from index 3 | [A, C, D]
-        verify(mListener).onItemRangeRemoved(/* positionStart= */ 3, /* itemCount= */ 1);
+        verify(mListener).onItemRangeRemoved(/* positionStart= */ 4, /* itemCount= */ 1);
     }
 
     @Test
@@ -227,8 +232,8 @@
 
         // THEN expanded app is reset and the visible entries list becomes:
         // [com.google.test0, com.google.test1, com.google.test2]
-        verify(mListener).onItemRangeChanged(eq(1), eq(1), isNull());
-        verify(mListener).onItemRangeRemoved(/* positionStart= */ 2, /* itemCount= */ 1);
+        verify(mListener).onItemRangeChanged(eq(2), eq(1), isNull());
+        verify(mListener).onItemRangeRemoved(/* positionStart= */ 3, /* itemCount= */ 1);
     }
 
     /**
@@ -265,14 +270,10 @@
     }
 
     private List<WidgetItem> generateWidgetItems(String packageName, int numOfWidgets) {
-        ShadowPackageManager packageManager = shadowOf(mContext.getPackageManager());
         ArrayList<WidgetItem> widgetItems = new ArrayList<>();
         for (int i = 0; i < numOfWidgets; i++) {
             ComponentName cn = ComponentName.createRelative(packageName, ".SampleWidget" + i);
-            AppWidgetProviderInfo widgetInfo = new AppWidgetProviderInfo();
-            widgetInfo.provider = cn;
-            ReflectionHelpers.setField(widgetInfo, "providerInfo",
-                    packageManager.addReceiverIfNotPresent(cn));
+            AppWidgetProviderInfo widgetInfo = WidgetUtils.createAppWidgetProviderInfo(cn);
 
             widgetItems.add(new WidgetItem(
                     LauncherAppWidgetProviderInfo.fromProviderInfo(mContext, widgetInfo),
diff --git a/robolectric_tests/src/com/android/launcher3/widget/picker/WidgetsListHeaderViewHolderBinderTest.java b/tests/src/com/android/launcher3/widget/picker/WidgetsListHeaderViewHolderBinderTest.java
similarity index 71%
rename from robolectric_tests/src/com/android/launcher3/widget/picker/WidgetsListHeaderViewHolderBinderTest.java
rename to tests/src/com/android/launcher3/widget/picker/WidgetsListHeaderViewHolderBinderTest.java
index 81b0c5f..969c12a 100644
--- a/robolectric_tests/src/com/android/launcher3/widget/picker/WidgetsListHeaderViewHolderBinderTest.java
+++ b/tests/src/com/android/launcher3/widget/picker/WidgetsListHeaderViewHolderBinderTest.java
@@ -15,13 +15,16 @@
  */
 package com.android.launcher3.widget.picker;
 
+import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
+
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.verify;
-import static org.robolectric.Shadows.shadowOf;
+
+import static java.util.Collections.EMPTY_LIST;
 
 import android.appwidget.AppWidgetProviderInfo;
 import android.content.ComponentName;
@@ -31,7 +34,9 @@
 import android.widget.FrameLayout;
 import android.widget.TextView;
 
-import com.android.launcher3.DeviceProfile;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
 import com.android.launcher3.InvariantDeviceProfile;
 import com.android.launcher3.R;
 import com.android.launcher3.icons.BitmapInfo;
@@ -39,29 +44,23 @@
 import com.android.launcher3.icons.IconCache;
 import com.android.launcher3.model.WidgetItem;
 import com.android.launcher3.model.data.PackageItemInfo;
-import com.android.launcher3.testing.TestActivity;
+import com.android.launcher3.util.ActivityContextWrapper;
 import com.android.launcher3.util.PackageUserKey;
-import com.android.launcher3.widget.DatabaseWidgetPreviewLoader;
+import com.android.launcher3.util.WidgetUtils;
 import com.android.launcher3.widget.LauncherAppWidgetProviderInfo;
 import com.android.launcher3.widget.model.WidgetsListHeaderEntry;
 
-import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
-import org.robolectric.Robolectric;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.android.controller.ActivityController;
-import org.robolectric.shadows.ShadowPackageManager;
-import org.robolectric.util.ReflectionHelpers;
 
 import java.util.ArrayList;
 import java.util.List;
 
-@RunWith(RobolectricTestRunner.class)
+@SmallTest
+@RunWith(AndroidJUnit4.class)
 public final class WidgetsListHeaderViewHolderBinderTest {
     private static final String TEST_PACKAGE = "com.google.test";
     private static final String APP_NAME = "Test app";
@@ -69,65 +68,41 @@
     private Context mContext;
     private WidgetsListHeaderViewHolderBinder mViewHolderBinder;
     private InvariantDeviceProfile mTestProfile;
-    // Replace ActivityController with ActivityScenario, which is the recommended way for activity
-    // testing.
-    private ActivityController<TestActivity> mActivityController;
-    private TestActivity mTestActivity;
 
     @Mock
     private IconCache mIconCache;
     @Mock
-    private DeviceProfile mDeviceProfile;
-    @Mock
-    private DatabaseWidgetPreviewLoader mWidgetPreviewLoader;
-    @Mock
     private OnHeaderClickListener mOnHeaderClickListener;
 
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
-        mContext = RuntimeEnvironment.application;
+
+        mContext = new ActivityContextWrapper(getApplicationContext());
         mTestProfile = new InvariantDeviceProfile();
         mTestProfile.numRows = 5;
         mTestProfile.numColumns = 5;
 
-        mActivityController = Robolectric.buildActivity(TestActivity.class);
-        mTestActivity = mActivityController.setup().get();
-        mTestActivity.setDeviceProfile(mDeviceProfile);
-
         doAnswer(invocation -> {
             ComponentWithLabel componentWithLabel = (ComponentWithLabel) invocation.getArgument(0);
             return componentWithLabel.getComponent().getShortClassName();
         }).when(mIconCache).getTitleNoCache(any());
-
-        WidgetsListAdapter widgetsListAdapter = new WidgetsListAdapter(mContext,
-                LayoutInflater.from(mTestActivity),
-                mWidgetPreviewLoader,
-                mIconCache,
-                /* iconClickListener= */ view -> {},
-                /* iconLongClickListener= */ view -> false);
         mViewHolderBinder = new WidgetsListHeaderViewHolderBinder(
-                LayoutInflater.from(mTestActivity),
+                LayoutInflater.from(mContext),
                 mOnHeaderClickListener,
-                new WidgetsListDrawableFactory(mTestActivity),
-                widgetsListAdapter);
-    }
-
-    @After
-    public void tearDown() {
-        mActivityController.destroy();
+                new WidgetsListDrawableFactory(mContext));
     }
 
     @Test
     public void bindViewHolder_appWith3Widgets_shouldShowTheCorrectAppNameAndSubtitle() {
         WidgetsListHeaderHolder viewHolder = mViewHolderBinder.newViewHolder(
-                new FrameLayout(mTestActivity));
+                new FrameLayout(mContext));
         WidgetsListHeader widgetsListHeader = viewHolder.mWidgetsListHeader;
         WidgetsListHeaderEntry entry = generateSampleAppHeader(
                 APP_NAME,
                 TEST_PACKAGE,
                 /* numOfWidgets= */ 3);
-        mViewHolderBinder.bindViewHolder(viewHolder, entry, /* position= */ 0);
+        mViewHolderBinder.bindViewHolder(viewHolder, entry, /* position= */ 0, EMPTY_LIST);
 
         TextView appTitle = widgetsListHeader.findViewById(R.id.app_title);
         TextView appSubtitle = widgetsListHeader.findViewById(R.id.app_subtitle);
@@ -138,14 +113,14 @@
     @Test
     public void bindViewHolder_shouldAttachOnHeaderClickListener() {
         WidgetsListHeaderHolder viewHolder = mViewHolderBinder.newViewHolder(
-                new FrameLayout(mTestActivity));
+                new FrameLayout(mContext));
         WidgetsListHeader widgetsListHeader = viewHolder.mWidgetsListHeader;
         WidgetsListHeaderEntry entry = generateSampleAppHeader(
                 APP_NAME,
                 TEST_PACKAGE,
                 /* numOfWidgets= */ 3);
 
-        mViewHolderBinder.bindViewHolder(viewHolder, entry, /* position= */ 0);
+        mViewHolderBinder.bindViewHolder(viewHolder, entry, /* position= */ 0, EMPTY_LIST);
         widgetsListHeader.callOnClick();
 
         verify(mOnHeaderClickListener).onHeaderClicked(eq(true),
@@ -164,14 +139,10 @@
     }
 
     private List<WidgetItem> generateWidgetItems(String packageName, int numOfWidgets) {
-        ShadowPackageManager packageManager = shadowOf(mContext.getPackageManager());
         ArrayList<WidgetItem> widgetItems = new ArrayList<>();
         for (int i = 0; i < numOfWidgets; i++) {
             ComponentName cn = ComponentName.createRelative(packageName, ".SampleWidget" + i);
-            AppWidgetProviderInfo widgetInfo = new AppWidgetProviderInfo();
-            widgetInfo.provider = cn;
-            ReflectionHelpers.setField(widgetInfo, "providerInfo",
-                    packageManager.addReceiverIfNotPresent(cn));
+            AppWidgetProviderInfo widgetInfo = WidgetUtils.createAppWidgetProviderInfo(cn);
 
             widgetItems.add(new WidgetItem(
                     LauncherAppWidgetProviderInfo.fromProviderInfo(mContext, widgetInfo),
diff --git a/robolectric_tests/src/com/android/launcher3/widget/picker/WidgetsListSearchHeaderViewHolderBinderTest.java b/tests/src/com/android/launcher3/widget/picker/WidgetsListSearchHeaderViewHolderBinderTest.java
similarity index 71%
rename from robolectric_tests/src/com/android/launcher3/widget/picker/WidgetsListSearchHeaderViewHolderBinderTest.java
rename to tests/src/com/android/launcher3/widget/picker/WidgetsListSearchHeaderViewHolderBinderTest.java
index a0ba7c3..453f4fb 100644
--- a/robolectric_tests/src/com/android/launcher3/widget/picker/WidgetsListSearchHeaderViewHolderBinderTest.java
+++ b/tests/src/com/android/launcher3/widget/picker/WidgetsListSearchHeaderViewHolderBinderTest.java
@@ -15,13 +15,16 @@
  */
 package com.android.launcher3.widget.picker;
 
+import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
+
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.verify;
-import static org.robolectric.Shadows.shadowOf;
+
+import static java.util.Collections.EMPTY_LIST;
 
 import android.appwidget.AppWidgetProviderInfo;
 import android.content.ComponentName;
@@ -31,7 +34,9 @@
 import android.widget.FrameLayout;
 import android.widget.TextView;
 
-import com.android.launcher3.DeviceProfile;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
 import com.android.launcher3.InvariantDeviceProfile;
 import com.android.launcher3.R;
 import com.android.launcher3.icons.BitmapInfo;
@@ -39,29 +44,23 @@
 import com.android.launcher3.icons.IconCache;
 import com.android.launcher3.model.WidgetItem;
 import com.android.launcher3.model.data.PackageItemInfo;
-import com.android.launcher3.testing.TestActivity;
+import com.android.launcher3.util.ActivityContextWrapper;
 import com.android.launcher3.util.PackageUserKey;
-import com.android.launcher3.widget.DatabaseWidgetPreviewLoader;
+import com.android.launcher3.util.WidgetUtils;
 import com.android.launcher3.widget.LauncherAppWidgetProviderInfo;
 import com.android.launcher3.widget.model.WidgetsListSearchHeaderEntry;
 
-import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
-import org.robolectric.Robolectric;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.android.controller.ActivityController;
-import org.robolectric.shadows.ShadowPackageManager;
-import org.robolectric.util.ReflectionHelpers;
 
 import java.util.ArrayList;
 import java.util.List;
 
-@RunWith(RobolectricTestRunner.class)
+@SmallTest
+@RunWith(AndroidJUnit4.class)
 public final class WidgetsListSearchHeaderViewHolderBinderTest {
     private static final String TEST_PACKAGE = "com.google.test";
     private static final String APP_NAME = "Test app";
@@ -69,65 +68,40 @@
     private Context mContext;
     private WidgetsListSearchHeaderViewHolderBinder mViewHolderBinder;
     private InvariantDeviceProfile mTestProfile;
-    // Replace ActivityController with ActivityScenario, which is the recommended way for activity
-    // testing.
-    private ActivityController<TestActivity> mActivityController;
-    private TestActivity mTestActivity;
 
     @Mock
     private IconCache mIconCache;
     @Mock
-    private DeviceProfile mDeviceProfile;
-    @Mock
-    private DatabaseWidgetPreviewLoader mWidgetPreviewLoader;
-    @Mock
     private OnHeaderClickListener mOnHeaderClickListener;
 
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
-        mContext = RuntimeEnvironment.application;
+        mContext = new ActivityContextWrapper(getApplicationContext());
         mTestProfile = new InvariantDeviceProfile();
         mTestProfile.numRows = 5;
         mTestProfile.numColumns = 5;
 
-        mActivityController = Robolectric.buildActivity(TestActivity.class);
-        mTestActivity = mActivityController.setup().get();
-        mTestActivity.setDeviceProfile(mDeviceProfile);
-
         doAnswer(invocation -> {
             ComponentWithLabel componentWithLabel = (ComponentWithLabel) invocation.getArgument(0);
             return componentWithLabel.getComponent().getShortClassName();
         }).when(mIconCache).getTitleNoCache(any());
-
-        WidgetsListAdapter widgetsListAdapter = new WidgetsListAdapter(mContext,
-                LayoutInflater.from(mTestActivity),
-                mWidgetPreviewLoader,
-                mIconCache,
-                /* iconClickListener= */ view -> {},
-                /* iconLongClickListener= */ view -> false);
         mViewHolderBinder = new WidgetsListSearchHeaderViewHolderBinder(
-                LayoutInflater.from(mTestActivity),
+                LayoutInflater.from(mContext),
                 mOnHeaderClickListener,
-                new WidgetsListDrawableFactory(mTestActivity),
-                widgetsListAdapter);
-    }
-
-    @After
-    public void tearDown() {
-        mActivityController.destroy();
+                new WidgetsListDrawableFactory(mContext));
     }
 
     @Test
     public void bindViewHolder_appWith3Widgets_shouldShowTheCorrectAppNameAndSubtitle() {
         WidgetsListSearchHeaderHolder viewHolder = mViewHolderBinder.newViewHolder(
-                new FrameLayout(mTestActivity));
+                new FrameLayout(mContext));
         WidgetsListHeader widgetsListHeader = viewHolder.mWidgetsListHeader;
         WidgetsListSearchHeaderEntry entry = generateSampleSearchHeader(
                 APP_NAME,
                 TEST_PACKAGE,
                 /* numOfWidgets= */ 3);
-        mViewHolderBinder.bindViewHolder(viewHolder, entry, /* position= */ 0);
+        mViewHolderBinder.bindViewHolder(viewHolder, entry, /* position= */ 0, EMPTY_LIST);
 
         TextView appTitle = widgetsListHeader.findViewById(R.id.app_title);
         TextView appSubtitle = widgetsListHeader.findViewById(R.id.app_subtitle);
@@ -139,14 +113,14 @@
     @Test
     public void bindViewHolder_shouldAttachOnHeaderClickListener() {
         WidgetsListSearchHeaderHolder viewHolder = mViewHolderBinder.newViewHolder(
-                new FrameLayout(mTestActivity));
+                new FrameLayout(mContext));
         WidgetsListHeader widgetsListHeader = viewHolder.mWidgetsListHeader;
         WidgetsListSearchHeaderEntry entry = generateSampleSearchHeader(
                 APP_NAME,
                 TEST_PACKAGE,
                 /* numOfWidgets= */ 3);
 
-        mViewHolderBinder.bindViewHolder(viewHolder, entry, /* position= */ 0);
+        mViewHolderBinder.bindViewHolder(viewHolder, entry, /* position= */ 0, EMPTY_LIST);
         widgetsListHeader.callOnClick();
 
         verify(mOnHeaderClickListener).onHeaderClicked(eq(true),
@@ -165,14 +139,10 @@
     }
 
     private List<WidgetItem> generateWidgetItems(String packageName, int numOfWidgets) {
-        ShadowPackageManager packageManager = shadowOf(mContext.getPackageManager());
         ArrayList<WidgetItem> widgetItems = new ArrayList<>();
         for (int i = 0; i < numOfWidgets; i++) {
             ComponentName cn = ComponentName.createRelative(packageName, ".SampleWidget" + i);
-            AppWidgetProviderInfo widgetInfo = new AppWidgetProviderInfo();
-            widgetInfo.provider = cn;
-            ReflectionHelpers.setField(widgetInfo, "providerInfo",
-                    packageManager.addReceiverIfNotPresent(cn));
+            AppWidgetProviderInfo widgetInfo = WidgetUtils.createAppWidgetProviderInfo(cn);
 
             widgetItems.add(new WidgetItem(
                     LauncherAppWidgetProviderInfo.fromProviderInfo(mContext, widgetInfo),
diff --git a/robolectric_tests/src/com/android/launcher3/widget/picker/WidgetsListTableViewHolderBinderTest.java b/tests/src/com/android/launcher3/widget/picker/WidgetsListTableViewHolderBinderTest.java
similarity index 67%
rename from robolectric_tests/src/com/android/launcher3/widget/picker/WidgetsListTableViewHolderBinderTest.java
rename to tests/src/com/android/launcher3/widget/picker/WidgetsListTableViewHolderBinderTest.java
index 8f9d132..5816b77 100644
--- a/robolectric_tests/src/com/android/launcher3/widget/picker/WidgetsListTableViewHolderBinderTest.java
+++ b/tests/src/com/android/launcher3/widget/picker/WidgetsListTableViewHolderBinderTest.java
@@ -15,13 +15,14 @@
  */
 package com.android.launcher3.widget.picker;
 
-import static android.os.Looper.getMainLooper;
+import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
 
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.doAnswer;
-import static org.robolectric.Shadows.shadowOf;
+
+import static java.util.Collections.EMPTY_LIST;
 
 import android.appwidget.AppWidgetProviderInfo;
 import android.content.ComponentName;
@@ -35,7 +36,9 @@
 import android.widget.TableRow;
 import android.widget.TextView;
 
-import com.android.launcher3.DeviceProfile;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
 import com.android.launcher3.InvariantDeviceProfile;
 import com.android.launcher3.R;
 import com.android.launcher3.icons.BitmapInfo;
@@ -43,30 +46,24 @@
 import com.android.launcher3.icons.IconCache;
 import com.android.launcher3.model.WidgetItem;
 import com.android.launcher3.model.data.PackageItemInfo;
-import com.android.launcher3.testing.TestActivity;
-import com.android.launcher3.widget.CachingWidgetPreviewLoader;
-import com.android.launcher3.widget.DatabaseWidgetPreviewLoader;
+import com.android.launcher3.util.ActivityContextWrapper;
+import com.android.launcher3.util.Executors;
+import com.android.launcher3.util.WidgetUtils;
 import com.android.launcher3.widget.LauncherAppWidgetProviderInfo;
 import com.android.launcher3.widget.WidgetCell;
 import com.android.launcher3.widget.model.WidgetsListContentEntry;
 
-import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
-import org.robolectric.Robolectric;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.android.controller.ActivityController;
-import org.robolectric.shadows.ShadowPackageManager;
-import org.robolectric.util.ReflectionHelpers;
 
 import java.util.ArrayList;
 import java.util.List;
 
-@RunWith(RobolectricTestRunner.class)
+@SmallTest
+@RunWith(AndroidJUnit4.class)
 public final class WidgetsListTableViewHolderBinderTest {
     private static final String TEST_PACKAGE = "com.google.test";
     private static final String APP_NAME = "Test app";
@@ -74,10 +71,6 @@
     private Context mContext;
     private WidgetsListTableViewHolderBinder mViewHolderBinder;
     private InvariantDeviceProfile mTestProfile;
-    // Replace ActivityController with ActivityScenario, which is the recommended way for activity
-    // testing.
-    private ActivityController<TestActivity> mActivityController;
-    private TestActivity mTestActivity;
 
     @Mock
     private OnLongClickListener mOnLongClickListener;
@@ -85,63 +78,42 @@
     private OnClickListener mOnIconClickListener;
     @Mock
     private IconCache mIconCache;
-    @Mock
-    private DatabaseWidgetPreviewLoader mWidgetPreviewLoader;
-    @Mock
-    private DeviceProfile mDeviceProfile;
 
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
-        mContext = RuntimeEnvironment.application;
+        mContext = new ActivityContextWrapper(getApplicationContext());
         mTestProfile = new InvariantDeviceProfile();
         mTestProfile.numRows = 5;
         mTestProfile.numColumns = 5;
 
-        mActivityController = Robolectric.buildActivity(TestActivity.class);
-        mTestActivity = mActivityController.setup().get();
-        mTestActivity.setDeviceProfile(mDeviceProfile);
-
         doAnswer(invocation -> {
             ComponentWithLabel componentWithLabel = (ComponentWithLabel) invocation.getArgument(0);
             return componentWithLabel.getComponent().getShortClassName();
         }).when(mIconCache).getTitleNoCache(any());
 
-        WidgetsListAdapter widgetsListAdapter = new WidgetsListAdapter(mContext,
-                LayoutInflater.from(mTestActivity),
-                mWidgetPreviewLoader,
-                mIconCache,
-                /* iconClickListener= */ view -> {},
-                /* iconLongClickListener= */ view -> false);
         mViewHolderBinder = new WidgetsListTableViewHolderBinder(
-                LayoutInflater.from(mTestActivity),
+                LayoutInflater.from(mContext),
                 mOnIconClickListener,
                 mOnLongClickListener,
-                new CachingWidgetPreviewLoader(mWidgetPreviewLoader),
-                new WidgetsListDrawableFactory(mTestActivity),
-                widgetsListAdapter);
-    }
-
-    @After
-    public void tearDown() {
-        mActivityController.destroy();
+                new WidgetsListDrawableFactory(mContext));
     }
 
     @Test
-    public void bindViewHolder_appWith3Widgets_shouldHave3Widgets() {
+    public void bindViewHolder_appWith3Widgets_shouldHave3Widgets() throws Exception {
         WidgetsRowViewHolder viewHolder = mViewHolderBinder.newViewHolder(
-                new FrameLayout(mTestActivity));
+                new FrameLayout(mContext));
         WidgetsListContentEntry entry = generateSampleAppWithWidgets(
                 APP_NAME,
                 TEST_PACKAGE,
                 /* numOfWidgets= */ 3);
-        mViewHolderBinder.bindViewHolder(viewHolder, entry, /* position= */ 0);
-        shadowOf(getMainLooper()).idle();
+        mViewHolderBinder.bindViewHolder(viewHolder, entry, /* position= */ 0, EMPTY_LIST);
+        Executors.MAIN_EXECUTOR.submit(() -> { }).get();
 
         // THEN the table container has one row, which contains 3 widgets.
         // View:  .SampleWidget0 | .SampleWidget1 | .SampleWidget2
-        assertThat(viewHolder.mTableContainer.getChildCount()).isEqualTo(1);
-        TableRow row = (TableRow) viewHolder.mTableContainer.getChildAt(0);
+        assertThat(viewHolder.tableContainer.getChildCount()).isEqualTo(1);
+        TableRow row = (TableRow) viewHolder.tableContainer.getChildAt(0);
         assertThat(row.getChildCount()).isEqualTo(3);
         // Widget 0 label is .SampleWidget0.
         assertWidgetCellWithLabel(row.getChildAt(0), ".SampleWidget0");
@@ -159,18 +131,15 @@
 
         return new WidgetsListContentEntry(appInfo,
                 /* titleSectionName= */ "",
-                generateWidgetItems(packageName, numOfWidgets));
+                generateWidgetItems(packageName, numOfWidgets),
+                Integer.MAX_VALUE);
     }
 
     private List<WidgetItem> generateWidgetItems(String packageName, int numOfWidgets) {
-        ShadowPackageManager packageManager = shadowOf(mContext.getPackageManager());
         ArrayList<WidgetItem> widgetItems = new ArrayList<>();
         for (int i = 0; i < numOfWidgets; i++) {
             ComponentName cn = ComponentName.createRelative(packageName, ".SampleWidget" + i);
-            AppWidgetProviderInfo widgetInfo = new AppWidgetProviderInfo();
-            widgetInfo.provider = cn;
-            ReflectionHelpers.setField(widgetInfo, "providerInfo",
-                    packageManager.addReceiverIfNotPresent(cn));
+            AppWidgetProviderInfo widgetInfo = WidgetUtils.createAppWidgetProviderInfo(cn);
 
             widgetItems.add(new WidgetItem(
                     LauncherAppWidgetProviderInfo.fromProviderInfo(mContext, widgetInfo),
diff --git a/robolectric_tests/src/com/android/launcher3/widget/picker/model/WidgetsListContentEntryTest.java b/tests/src/com/android/launcher3/widget/picker/model/WidgetsListContentEntryTest.java
similarity index 92%
rename from robolectric_tests/src/com/android/launcher3/widget/picker/model/WidgetsListContentEntryTest.java
rename to tests/src/com/android/launcher3/widget/picker/model/WidgetsListContentEntryTest.java
index 106cac0..4b61b2c 100644
--- a/robolectric_tests/src/com/android/launcher3/widget/picker/model/WidgetsListContentEntryTest.java
+++ b/tests/src/com/android/launcher3/widget/picker/model/WidgetsListContentEntryTest.java
@@ -15,15 +15,20 @@
  */
 package com.android.launcher3.widget.picker.model;
 
+import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
+
+import static com.android.launcher3.util.WidgetUtils.createAppWidgetProviderInfo;
+
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.doAnswer;
-import static org.robolectric.Shadows.shadowOf;
 
 import android.appwidget.AppWidgetProviderInfo;
 import android.content.ComponentName;
-import android.content.Context;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
 
 import com.android.launcher3.InvariantDeviceProfile;
 import com.android.launcher3.icons.ComponentWithLabel;
@@ -38,16 +43,13 @@
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.shadows.ShadowPackageManager;
-import org.robolectric.util.ReflectionHelpers;
 
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
-@RunWith(RobolectricTestRunner.class)
+@SmallTest
+@RunWith(AndroidJUnit4.class)
 public final class WidgetsListContentEntryTest {
     private static final String PACKAGE_NAME = "com.android.test";
     private static final String PACKAGE_NAME_2 = "com.android.test2";
@@ -60,7 +62,6 @@
 
     @Mock private IconCache mIconCache;
 
-    private Context mContext;
     private InvariantDeviceProfile mTestProfile;
 
     @Before
@@ -71,7 +72,6 @@
         mWidgetsToLabels.put(mWidget2, "Dog");
         mWidgetsToLabels.put(mWidget3, "Bird");
 
-        mContext = RuntimeEnvironment.application;
         mTestProfile = new InvariantDeviceProfile();
         mTestProfile.numRows = 5;
         mTestProfile.numColumns = 5;
@@ -242,17 +242,12 @@
         assertThat(widgetsListRowEntry1.equals(widgetsListRowEntry2)).isTrue();
     }
 
-
     private WidgetItem createWidgetItem(ComponentName componentName, int spanX, int spanY) {
         String label = mWidgetsToLabels.get(componentName);
-        ShadowPackageManager packageManager = shadowOf(mContext.getPackageManager());
-        AppWidgetProviderInfo widgetInfo = new AppWidgetProviderInfo();
-        widgetInfo.provider = componentName;
-        ReflectionHelpers.setField(widgetInfo, "providerInfo",
-                packageManager.addReceiverIfNotPresent(componentName));
+        AppWidgetProviderInfo widgetInfo = createAppWidgetProviderInfo(componentName);
 
         LauncherAppWidgetProviderInfo launcherAppWidgetProviderInfo =
-                LauncherAppWidgetProviderInfo.fromProviderInfo(mContext, widgetInfo);
+                LauncherAppWidgetProviderInfo.fromProviderInfo(getApplicationContext(), widgetInfo);
         launcherAppWidgetProviderInfo.spanX = spanX;
         launcherAppWidgetProviderInfo.spanY = spanY;
         launcherAppWidgetProviderInfo.label = label;
diff --git a/robolectric_tests/src/com/android/launcher3/widget/picker/search/SimpleWidgetsSearchAlgorithmTest.java b/tests/src/com/android/launcher3/widget/picker/search/SimpleWidgetsSearchAlgorithmTest.java
similarity index 90%
rename from robolectric_tests/src/com/android/launcher3/widget/picker/search/SimpleWidgetsSearchAlgorithmTest.java
rename to tests/src/com/android/launcher3/widget/picker/search/SimpleWidgetsSearchAlgorithmTest.java
index 36b6f01..c862d6b 100644
--- a/robolectric_tests/src/com/android/launcher3/widget/picker/search/SimpleWidgetsSearchAlgorithmTest.java
+++ b/tests/src/com/android/launcher3/widget/picker/search/SimpleWidgetsSearchAlgorithmTest.java
@@ -16,7 +16,10 @@
 
 package com.android.launcher3.widget.picker.search;
 
-import static android.os.Looper.getMainLooper;
+import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
+
+import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
+import static com.android.launcher3.util.WidgetUtils.createAppWidgetProviderInfo;
 
 import static org.junit.Assert.assertEquals;
 import static org.mockito.ArgumentMatchers.any;
@@ -25,7 +28,6 @@
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.verify;
-import static org.robolectric.Shadows.shadowOf;
 
 import android.appwidget.AppWidgetProviderInfo;
 import android.content.ComponentName;
@@ -33,6 +35,9 @@
 import android.graphics.Bitmap;
 import android.os.UserHandle;
 
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
 import com.android.launcher3.InvariantDeviceProfile;
 import com.android.launcher3.icons.BitmapInfo;
 import com.android.launcher3.icons.ComponentWithLabel;
@@ -52,16 +57,13 @@
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.shadows.ShadowPackageManager;
-import org.robolectric.util.ReflectionHelpers;
 
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 
-@RunWith(RobolectricTestRunner.class)
+@SmallTest
+@RunWith(AndroidJUnit4.class)
 public class SimpleWidgetsSearchAlgorithmTest {
 
     @Mock private IconCache mIconCache;
@@ -82,7 +84,7 @@
     private SearchCallback<WidgetsListBaseEntry> mSearchCallback;
 
     @Before
-    public void setUp() {
+    public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
         doAnswer(invocation -> {
             ComponentWithLabel componentWithLabel = (ComponentWithLabel) invocation.getArgument(0);
@@ -91,7 +93,7 @@
         mTestProfile = new InvariantDeviceProfile();
         mTestProfile.numRows = 5;
         mTestProfile.numColumns = 5;
-        mContext = RuntimeEnvironment.application;
+        mContext = getApplicationContext();
 
         mCalendarHeaderEntry =
                 createWidgetsHeaderEntry("com.example.android.Calendar", "Calendar", 2);
@@ -102,8 +104,8 @@
         mClockHeaderEntry = createWidgetsHeaderEntry("com.example.android.Clock", "Clock", 3);
         mClockContentEntry = createWidgetsContentEntry("com.example.android.Clock", "Clock", 3);
 
-
-        mSimpleWidgetsSearchAlgorithm = new SimpleWidgetsSearchAlgorithm(mDataProvider);
+        mSimpleWidgetsSearchAlgorithm = MAIN_EXECUTOR.submit(
+                () -> new SimpleWidgetsSearchAlgorithm(mDataProvider)).get();
         doReturn(Collections.EMPTY_LIST).when(mDataProvider).getAllWidgets();
     }
 
@@ -156,13 +158,13 @@
     }
 
     @Test
-    public void doSearch_shouldInformCallback() {
+    public void doSearch_shouldInformCallback() throws Exception {
         doReturn(List.of(mCalendarHeaderEntry, mCalendarContentEntry, mCameraHeaderEntry,
                 mCameraContentEntry, mClockHeaderEntry, mClockContentEntry))
                 .when(mDataProvider)
                 .getAllWidgets();
         mSimpleWidgetsSearchAlgorithm.doSearch("Ca", mSearchCallback);
-        shadowOf(getMainLooper()).idle();
+        MAIN_EXECUTOR.submit(() -> { }).get();
         verify(mSearchCallback).onSearchResult(
                 matches("Ca"), argThat(a -> a != null && !a.isEmpty()));
     }
@@ -195,14 +197,10 @@
     }
 
     private List<WidgetItem> generateWidgetItems(String packageName, int numOfWidgets) {
-        ShadowPackageManager packageManager = shadowOf(mContext.getPackageManager());
         ArrayList<WidgetItem> widgetItems = new ArrayList<>();
         for (int i = 0; i < numOfWidgets; i++) {
             ComponentName cn = ComponentName.createRelative(packageName, ".SampleWidget" + i);
-            AppWidgetProviderInfo widgetInfo = new AppWidgetProviderInfo();
-            widgetInfo.provider = cn;
-            ReflectionHelpers.setField(widgetInfo, "providerInfo",
-                    packageManager.addReceiverIfNotPresent(cn));
+            AppWidgetProviderInfo widgetInfo = createAppWidgetProviderInfo(cn);
 
             WidgetItem widgetItem = new WidgetItem(
                     LauncherAppWidgetProviderInfo.fromProviderInfo(mContext, widgetInfo),
diff --git a/robolectric_tests/src/com/android/launcher3/widget/picker/search/WidgetsSearchBarControllerTest.java b/tests/src/com/android/launcher3/widget/picker/search/WidgetsSearchBarControllerTest.java
similarity index 83%
rename from robolectric_tests/src/com/android/launcher3/widget/picker/search/WidgetsSearchBarControllerTest.java
rename to tests/src/com/android/launcher3/widget/picker/search/WidgetsSearchBarControllerTest.java
index 7ac879a..583d37f 100644
--- a/robolectric_tests/src/com/android/launcher3/widget/picker/search/WidgetsSearchBarControllerTest.java
+++ b/tests/src/com/android/launcher3/widget/picker/search/WidgetsSearchBarControllerTest.java
@@ -16,39 +16,38 @@
 
 package com.android.launcher3.widget.picker.search;
 
+import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
+
 import static org.junit.Assert.assertEquals;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyNoMoreInteractions;
 
+import android.content.Context;
 import android.view.View;
 import android.widget.ImageButton;
 
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
 import com.android.launcher3.ExtendedEditText;
 import com.android.launcher3.search.SearchAlgorithm;
-import com.android.launcher3.testing.TestActivity;
 import com.android.launcher3.widget.model.WidgetsListBaseEntry;
 
-import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
-import org.robolectric.Robolectric;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.android.controller.ActivityController;
 
 import java.util.ArrayList;
 
-@RunWith(RobolectricTestRunner.class)
+@SmallTest
+@RunWith(AndroidJUnit4.class)
 public class WidgetsSearchBarControllerTest {
 
     private WidgetsSearchBarController mController;
-    // TODO: Replace ActivityController with ActivityScenario, which is the recommended way for
-    // activity testing.
-    private ActivityController<TestActivity> mActivityController;
     private ExtendedEditText mEditText;
     private ImageButton mCancelButton;
     @Mock
@@ -59,20 +58,14 @@
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
-        mActivityController = Robolectric.buildActivity(TestActivity.class);
-        TestActivity testActivity = mActivityController.setup().get();
+        Context context = getApplicationContext();
 
-        mEditText = new ExtendedEditText(testActivity);
-        mCancelButton = new ImageButton(testActivity);
+        mEditText = new ExtendedEditText(context);
+        mCancelButton = new ImageButton(context);
         mController = new WidgetsSearchBarController(
                 mSearchAlgorithm, mEditText, mCancelButton, mSearchModeListener);
     }
 
-    @After
-    public void tearDown() {
-        mActivityController.destroy();
-    }
-
     @Test
     public void onSearchResult_shouldInformSearchModeListener() {
         ArrayList<WidgetsListBaseEntry> entries = new ArrayList<>();
diff --git a/robolectric_tests/src/com/android/launcher3/widget/picker/util/WidgetsTableUtilsTest.java b/tests/src/com/android/launcher3/widget/picker/util/WidgetsTableUtilsTest.java
similarity index 89%
rename from robolectric_tests/src/com/android/launcher3/widget/picker/util/WidgetsTableUtilsTest.java
rename to tests/src/com/android/launcher3/widget/picker/util/WidgetsTableUtilsTest.java
index 56d7d68..d6da776 100644
--- a/robolectric_tests/src/com/android/launcher3/widget/picker/util/WidgetsTableUtilsTest.java
+++ b/tests/src/com/android/launcher3/widget/picker/util/WidgetsTableUtilsTest.java
@@ -15,11 +15,14 @@
  */
 package com.android.launcher3.widget.picker.util;
 
+import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
+
+import static com.android.launcher3.util.WidgetUtils.createAppWidgetProviderInfo;
+
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.doAnswer;
-import static org.robolectric.Shadows.shadowOf;
 
 import android.appwidget.AppWidgetProviderInfo;
 import android.content.ComponentName;
@@ -29,6 +32,9 @@
 import android.graphics.drawable.Drawable;
 import android.os.UserHandle;
 
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
 import com.android.launcher3.InvariantDeviceProfile;
 import com.android.launcher3.icons.ComponentWithLabel;
 import com.android.launcher3.icons.IconCache;
@@ -42,15 +48,12 @@
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.shadows.ShadowPackageManager;
-import org.robolectric.util.ReflectionHelpers;
 
 import java.util.ArrayList;
 import java.util.List;
 
-@RunWith(RobolectricTestRunner.class)
+@SmallTest
+@RunWith(AndroidJUnit4.class)
 public final class WidgetsTableUtilsTest {
     private static final String TEST_PACKAGE = "com.google.test";
 
@@ -73,7 +76,7 @@
     public void setUp() {
         MockitoAnnotations.initMocks(this);
 
-        mContext = RuntimeEnvironment.application;
+        mContext = getApplicationContext();
 
         mTestProfile = new InvariantDeviceProfile();
         mTestProfile.numRows = 5;
@@ -152,16 +155,14 @@
         ArrayList<WidgetItem> widgetItems = new ArrayList<>();
         widgetSizes.stream().forEach(
                 widgetSize -> {
-                    ShadowPackageManager packageManager = shadowOf(mContext.getPackageManager());
-                    AppWidgetProviderInfo info = new AppWidgetProviderInfo();
-                    info.provider = ComponentName.createRelative(TEST_PACKAGE,
-                            ".WidgetProvider_" + widgetSize.x + "x" + widgetSize.y);
+                    AppWidgetProviderInfo info = createAppWidgetProviderInfo(
+                            ComponentName.createRelative(
+                                    TEST_PACKAGE,
+                                    ".WidgetProvider_" + widgetSize.x + "x" + widgetSize.y));
                     LauncherAppWidgetProviderInfo widgetInfo =
                             LauncherAppWidgetProviderInfo.fromProviderInfo(mContext, info);
                     widgetInfo.spanX = widgetSize.x;
                     widgetInfo.spanY = widgetSize.y;
-                    ReflectionHelpers.setField(widgetInfo, "providerInfo",
-                            packageManager.addReceiverIfNotPresent(widgetInfo.provider));
                     widgetItems.add(new WidgetItem(widgetInfo, mTestProfile, mIconCache));
                 }
         );
diff --git a/tests/src_common/README.md b/tests/src_common/README.md
deleted file mode 100644
index 2bc9e73..0000000
--- a/tests/src_common/README.md
+++ /dev/null
@@ -1 +0,0 @@
-Common source code used by both android tests and robolectric tests
\ No newline at end of file
diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
index abcc778..f1fe508 100644
--- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
+++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
@@ -80,6 +80,7 @@
 import java.util.Deque;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
 import java.util.function.Consumer;
 import java.util.function.Function;
@@ -96,7 +97,7 @@
     private static final String TAG = "Tapl";
     private static final int ZERO_BUTTON_STEPS_FROM_BACKGROUND_TO_HOME = 20;
     private static final int GESTURE_STEP_MS = 16;
-    private static final long FORCE_PAUSE_TIMEOUT_MS = 700;
+    private static final long FORCE_PAUSE_TIMEOUT_MS = TimeUnit.SECONDS.toMillis(2);
 
     static final Pattern EVENT_TOUCH_DOWN = getTouchEventPattern("ACTION_DOWN");
     static final Pattern EVENT_TOUCH_UP = getTouchEventPattern("ACTION_UP");
@@ -247,11 +248,24 @@
         if (pm.getComponentEnabledSetting(cn) != COMPONENT_ENABLED_STATE_ENABLED) {
             if (TestHelpers.isInLauncherProcess()) {
                 pm.setComponentEnabledSetting(cn, COMPONENT_ENABLED_STATE_ENABLED, DONT_KILL_APP);
+                // b/195031154
+                SystemClock.sleep(5000);
             } else {
                 try {
                     final int userId = ContextUtils.getUserId(getContext());
+                    final String launcherPidCommand = "pidof " + pi.packageName;
+                    final String initialPid = mDevice.executeShellCommand(launcherPidCommand)
+                            .replaceAll("\\s", "");
                     mDevice.executeShellCommand(
                             "pm enable --user " + userId + " " + cn.flattenToString());
+                    // Wait for Launcher restart after enabling test provider.
+                    for (int i = 0; i < 100; ++i) {
+                        final String currentPid = mDevice.executeShellCommand(launcherPidCommand)
+                                .replaceAll("\\s", "");
+                        if (!currentPid.isEmpty() && !currentPid.equals(initialPid)) break;
+                        if (i == 99) fail("Launcher didn't restart after enabling test provider");
+                        SystemClock.sleep(100);
+                    }
                 } catch (IOException e) {
                     fail(e.toString());
                 }
@@ -288,6 +302,11 @@
     }
 
     Insets getTargetInsets() {
+        return getTestInfo(TestProtocol.REQUEST_TARGET_INSETS)
+                .getParcelable(TestProtocol.TEST_INFO_RESPONSE_FIELD);
+    }
+
+    Insets getWindowInsets() {
         return getTestInfo(TestProtocol.REQUEST_WINDOW_INSETS)
                 .getParcelable(TestProtocol.TEST_INFO_RESPONSE_FIELD);
     }
@@ -299,13 +318,18 @@
 
     public boolean isTwoPanels() {
         return getTestInfo(TestProtocol.REQUEST_IS_TWO_PANELS)
-            .getBoolean(TestProtocol.TEST_INFO_RESPONSE_FIELD);
+                .getBoolean(TestProtocol.TEST_INFO_RESPONSE_FIELD);
     }
 
     private void setForcePauseTimeout(long timeout) {
         getTestInfo(TestProtocol.REQUEST_SET_FORCE_PAUSE_TIMEOUT, Long.toString(timeout));
     }
 
+    public boolean hadNontestEvents() {
+        return getTestInfo(TestProtocol.REQUEST_GET_HAD_NONTEST_EVENTS)
+                .getBoolean(TestProtocol.TEST_INFO_RESPONSE_FIELD);
+    }
+
     void setActiveContainer(VisibleContainer container) {
         sActiveContainer = new WeakReference<>(container);
     }
@@ -368,7 +392,7 @@
         }
     }
 
-    private String getSystemAnomalyMessage() {
+    private String getSystemAnomalyMessage(boolean ignoreNavmodeChangeStates) {
         try {
             {
                 final StringBuilder sb = new StringBuilder();
@@ -391,16 +415,18 @@
 
             if (hasSystemUiObject("keyguard_status_view")) return "Phone is locked";
 
-            final String visibleApps = mDevice.findObjects(getAnyObjectSelector())
-                    .stream()
-                    .map(LauncherInstrumentation::getApplicationPackageSafe)
-                    .distinct()
-                    .filter(pkg -> pkg != null)
-                    .collect(Collectors.joining(","));
-            if (SYSTEMUI_PACKAGE.equals(visibleApps)) return "Only System UI views are visible";
+            if (!ignoreNavmodeChangeStates) {
+                final String visibleApps = mDevice.findObjects(getAnyObjectSelector())
+                        .stream()
+                        .map(LauncherInstrumentation::getApplicationPackageSafe)
+                        .distinct()
+                        .filter(pkg -> pkg != null)
+                        .collect(Collectors.joining(","));
+                if (SYSTEMUI_PACKAGE.equals(visibleApps)) return "Only System UI views are visible";
 
-            if (!mDevice.wait(Until.hasObject(getAnyObjectSelector()), WAIT_TIME_MS)) {
-                return "Screen is empty";
+                if (!mDevice.wait(Until.hasObject(getAnyObjectSelector()), WAIT_TIME_MS)) {
+                    return "Screen is empty";
+                }
             }
 
             final String navigationModeError = getNavigationModeMismatchError(true);
@@ -412,8 +438,12 @@
         return null;
     }
 
-    public void checkForAnomaly() {
-        final String systemAnomalyMessage = getSystemAnomalyMessage();
+    private void checkForAnomaly() {
+        checkForAnomaly(false);
+    }
+
+    public void checkForAnomaly(boolean ignoreNavmodeChangeStates) {
+        final String systemAnomalyMessage = getSystemAnomalyMessage(ignoreNavmodeChangeStates);
         if (systemAnomalyMessage != null) {
             Assert.fail(formatSystemHealthMessage(formatErrorWithEvents(
                     "http://go/tapl : Tests are broken by a non-Launcher system error: "
@@ -611,9 +641,7 @@
     }
 
     private String getNavigationButtonResPackage() {
-        return isTablet() && getNavigationModel() == NavigationModel.THREE_BUTTON ?
-                getLauncherPackageName() :
-                SYSTEMUI_PACKAGE;
+        return isTablet() ? getLauncherPackageName() : SYSTEMUI_PACKAGE;
     }
 
     private UiObject2 verifyContainerType(ContainerType containerType) {
@@ -744,11 +772,11 @@
                 boolean gestureStartFromLauncher = isTablet()
                         ? !isLauncher3() || hasLauncherObject(WORKSPACE_RES_ID)
                         : isLauncherVisible();
-                GestureScope gestureScope = gestureStartFromLauncher
-                        ? GestureScope.INSIDE_TO_OUTSIDE
-                        : GestureScope.OUTSIDE_WITH_PILFER;
 
                 if (hasLauncherObject(CONTEXT_MENU_RES_ID)) {
+                    GestureScope gestureScope = gestureStartFromLauncher
+                            ? (isTablet() ? GestureScope.INSIDE : GestureScope.INSIDE_TO_OUTSIDE)
+                            : GestureScope.OUTSIDE_WITH_PILFER;
                     linearGesture(
                             displaySize.x / 2, displaySize.y - 1,
                             displaySize.x / 2, 0,
@@ -757,9 +785,6 @@
                     try (LauncherInstrumentation.Closable c1 = addContextLayer(
                             "Swiped up from context menu to home")) {
                         waitUntilLauncherObjectGone(CONTEXT_MENU_RES_ID);
-                        // Swiping up can temporarily bring Nexus Launcher if the current
-                        // Launcher is a Launcher3 one. Wait for the current launcher to reappear.
-                        SystemClock.sleep(5000); // b/187080582
                         waitForLauncherObject(getAnyObjectSelector());
                     }
                 }
@@ -774,7 +799,8 @@
                             displaySize.x / 2, displaySize.y - 1,
                             displaySize.x / 2, 0,
                             ZERO_BUTTON_STEPS_FROM_BACKGROUND_TO_HOME, NORMAL_STATE_ORDINAL,
-                            gestureScope);
+                            gestureStartFromLauncher ? GestureScope.INSIDE_TO_OUTSIDE
+                                    : GestureScope.OUTSIDE_WITH_PILFER);
                 }
             } else {
                 log("Hierarchy before clicking home:");
@@ -1009,6 +1035,15 @@
         }
     }
 
+    List<UiObject2> getChildren(UiObject2 container) {
+        try {
+            return container.getChildren();
+        } catch (StaleObjectException e) {
+            fail("The container disappeared from screen");
+            return null;
+        }
+    }
+
     private boolean hasLauncherObject(String resId) {
         return mDevice.hasObject(getLauncherObjectSelector(resId));
     }
@@ -1128,7 +1163,7 @@
     }
 
     int getBottomGestureSize() {
-        return Math.max(getTargetInsets().bottom, ResourceUtils.getNavbarSize(
+        return Math.max(getWindowInsets().bottom, ResourceUtils.getNavbarSize(
                 ResourceUtils.NAVBAR_BOTTOM_GESTURE_SIZE, getResources())) + 1;
     }
 
@@ -1324,13 +1359,6 @@
         }
 
         final MotionEvent event = getMotionEvent(downTime, currentTime, action, point.x, point.y);
-        // b/190748682
-        switch (action) {
-            case MotionEvent.ACTION_DOWN:
-            case MotionEvent.ACTION_UP:
-                log("b/190748682: injecting " + event);
-                break;
-        }
         assertTrue("injectInputEvent failed",
                 mInstrumentation.getUiAutomation().injectInputEvent(event, true, false));
         event.recycle();
diff --git a/tests/tapl/com/android/launcher3/tapl/Widgets.java b/tests/tapl/com/android/launcher3/tapl/Widgets.java
index 99d9889..6e7264a 100644
--- a/tests/tapl/com/android/launcher3/tapl/Widgets.java
+++ b/tests/tapl/com/android/launcher3/tapl/Widgets.java
@@ -116,9 +116,9 @@
                     "widget_preview");
             int i = 0;
             for (; ; ) {
-                final Collection<UiObject2> tableRows = widgetsContainer.getChildren();
+                final Collection<UiObject2> tableRows = mLauncher.getChildren(widgetsContainer);
                 for (UiObject2 row : tableRows) {
-                    final Collection<UiObject2> widgetCells = row.getChildren();
+                    final Collection<UiObject2> widgetCells = mLauncher.getChildren(row);
                     for (UiObject2 widget : widgetCells) {
                         final UiObject2 label = mLauncher.findObjectInContainer(widget,
                                 labelSelector);