Merge "Adjust where the back button is rendered for new SUW requirements." into main
diff --git a/Android.bp b/Android.bp
index 877f7bb..c4ea48a 100644
--- a/Android.bp
+++ b/Android.bp
@@ -75,7 +75,7 @@
         "androidx.test.uiautomator_uiautomator",
         "androidx.preference_preference",
         "SystemUISharedLib",
-        "animationlib",
+        "//frameworks/libs/systemui:animationlib",
         "launcher-testing-shared",
     ],
     srcs: [
@@ -150,9 +150,9 @@
         "androidx.cardview_cardview",
         "androidx.window_window",
         "com.google.android.material_material",
-        "iconloader_base",
-        "view_capture",
-        "animationlib",
+        "//frameworks/libs/systemui:iconloader_base",
+        "//frameworks/libs/systemui:view_capture",
+        "//frameworks/libs/systemui:animationlib",
         "SystemUI-statsd",
         "launcher-testing-shared",
         "androidx.lifecycle_lifecycle-common-java8",
diff --git a/OWNERS b/OWNERS
index efcf9f3..654493f 100644
--- a/OWNERS
+++ b/OWNERS
@@ -39,5 +39,12 @@
 patmanning@google.com
 helencheuk@google.com
 
+# Widget Picker team
+shamalip@google.com
+zakcohen@google.com
+
 per-file FeatureFlags.java, globs = set noparent
 per-file FeatureFlags.java = sunnygoyal@google.com, winsonc@google.com, adamcohen@google.com, hyunyoungs@google.com, captaincole@google.com
+
+per-file DeviceConfigWrapper.java, globs = set noparent
+per-file DeviceConfigWrapper.java = sunnygoyal@google.com, winsonc@google.com, adamcohen@google.com, hyunyoungs@google.com
diff --git a/go/quickstep/res/values-ne/strings.xml b/go/quickstep/res/values-ne/strings.xml
index 11a70dd..cee6603 100644
--- a/go/quickstep/res/values-ne/strings.xml
+++ b/go/quickstep/res/values-ne/strings.xml
@@ -8,7 +8,7 @@
     <string name="dialog_acknowledge" msgid="2804025517675853172">"बुझेँ"</string>
     <string name="dialog_cancel" msgid="6464336969134856366">"रद्द गर्नुहोस्"</string>
     <string name="dialog_settings" msgid="6564397136021186148">"सेटिङ"</string>
-    <string name="niu_actions_confirmation_title" msgid="3863451714863526143">"स्क्रिनमा देखिने पाठ अनुवाद गरियोस् वा पढेर सुनाइयोस्"</string>
+    <string name="niu_actions_confirmation_title" msgid="3863451714863526143">"स्क्रिनमा देखिने पाठ अनुवाद गर्नुहोस् वा पढेर सुनाइयोस्"</string>
     <string name="niu_actions_confirmation_text" msgid="2105271481950866089">"तपाईंको स्क्रिनमा देखिने पाठ, वेब ठेगाना र स्क्रिनसटलगायतका जानकारी Google सँग सेयर गर्न सकिन्छ।\n\nकुन कुन जानकारी सेयर गर्न दिने भन्ने सेटिङ बदल्न "<b>"सेटिङ &gt; एप &gt; डिफल्ट एप &gt; डिजिटल सहायक एप"</b>" मा जानुहोस्।"</string>
     <string name="assistant_not_selected_title" msgid="5017072974603345228">"तपाईं यो सुविधा चलाउन चाहनुहुन्छ भने कुनै सहायक छनौट गर्नुहोस्"</string>
     <string name="assistant_not_selected_text" msgid="3244613673884359276">"तपाईं आफ्नो स्क्रिनमा देखिने पाठ सुन्न वा अनुवाद गर्न चाहनुहुन्छ भने सेटिङमा गई कुनै डिजिटल सहायक एप छनौट गर्नुहोस्"</string>
diff --git a/quickstep/res/drawable/bg_overview_clear_all_button.xml b/quickstep/res/drawable/bg_overview_clear_all_button.xml
index f3ff6ce..143761f 100644
--- a/quickstep/res/drawable/bg_overview_clear_all_button.xml
+++ b/quickstep/res/drawable/bg_overview_clear_all_button.xml
@@ -20,7 +20,7 @@
     <item>
         <shape android:shape="rectangle"
             android:tint="?colorButtonNormal">
-            <corners android:radius="24dp" />
+            <corners android:radius="@dimen/recents_clear_all_outline_radius" />
             <solid android:color="?androidprv:attr/materialColorSurfaceBright"/>
         </shape>
     </item>
diff --git a/quickstep/res/layout/overview_actions_container.xml b/quickstep/res/layout/overview_actions_container.xml
index 5d489f5..d086da4 100644
--- a/quickstep/res/layout/overview_actions_container.xml
+++ b/quickstep/res/layout/overview_actions_container.xml
@@ -21,10 +21,9 @@
 
     <LinearLayout
         android:id="@+id/action_buttons"
-        android:layout_width="match_parent"
+        android:layout_width="wrap_content"
         android:layout_height="@dimen/overview_actions_height"
-        android:layout_gravity="bottom"
-        android:gravity="center_horizontal"
+        android:layout_gravity="bottom|center_horizontal"
         android:orientation="horizontal">
 
         <Button
@@ -36,17 +35,12 @@
             android:text="@string/action_screenshot"
             android:theme="@style/ThemeControlHighlightWorkspaceColor" />
 
-        <Space
-            android:id="@+id/action_split_space"
-            android:layout_width="@dimen/overview_actions_button_spacing"
-            android:layout_height="1dp"
-            android:visibility="gone" />
-
         <Button
             android:id="@+id/action_split"
             style="@style/OverviewActionButton"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
+            android:layout_marginStart="@dimen/overview_actions_button_spacing"
             android:text="@string/action_split"
             android:theme="@style/ThemeControlHighlightWorkspaceColor"
             android:visibility="gone" />
diff --git a/quickstep/res/layout/overview_clear_all_button.xml b/quickstep/res/layout/overview_clear_all_button.xml
index da94c3a..3380ea4 100644
--- a/quickstep/res/layout/overview_clear_all_button.xml
+++ b/quickstep/res/layout/overview_clear_all_button.xml
@@ -17,10 +17,12 @@
 <com.android.quickstep.views.ClearAllButton
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
+    xmlns:launcher="http://schemas.android.com/apk/res-auto"
     style="@style/OverviewClearAllButton"
     android:id="@+id/clear_all"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:text="@string/recents_clear_all"
     android:textColor="?androidprv:attr/materialColorOnSurface"
+    launcher:focusBorderColor="?androidprv:attr/materialColorOutline"
     android:textSize="14sp" />
\ No newline at end of file
diff --git a/quickstep/res/layout/task_menu_with_arrow.xml b/quickstep/res/layout/task_menu_with_arrow.xml
index 38573fd..c9108a5 100644
--- a/quickstep/res/layout/task_menu_with_arrow.xml
+++ b/quickstep/res/layout/task_menu_with_arrow.xml
@@ -23,11 +23,17 @@
     android:orientation="vertical"
     android:visibility="invisible">
 
-    <LinearLayout
-        android:id="@+id/menu_option_layout"
+    <ScrollView
         android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:orientation="vertical"
-        android:showDividers="middle" />
+        android:layout_height="wrap_content">
+
+        <LinearLayout
+            android:id="@+id/menu_option_layout"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:orientation="vertical"
+            android:showDividers="middle" />
+
+    </ScrollView>
 
 </com.android.quickstep.views.TaskMenuViewWithArrow>
\ No newline at end of file
diff --git a/quickstep/res/layout/taskbar_edu_circle_to_search.xml b/quickstep/res/layout/taskbar_edu_circle_to_search.xml
new file mode 100644
index 0000000..6c95f25
--- /dev/null
+++ b/quickstep/res/layout/taskbar_edu_circle_to_search.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2024 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="wrap_content"
+    android:layout_height="wrap_content">
+
+    <TextView
+        android:id="@+id/title"
+        style="@style/TextAppearance.TaskbarEduTooltip.Title"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:text="@string/taskbar_edu_circle_to_search_title"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent"
+        app:layout_constraintBottom_toTopOf="@+id/circle_to_search_animation" />
+
+    <com.airbnb.lottie.LottieAnimationView
+        android:id="@+id/circle_to_search_animation"
+        android:layout_width="@dimen/taskbar_edu_swipe_lottie_width"
+        android:layout_height="@dimen/taskbar_edu_swipe_lottie_height"
+        android:layout_marginTop="@dimen/taskbar_edu_tooltip_vertical_margin"
+        app:layout_constraintBottom_toTopOf="@id/circle_to_search_text"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/title"
+        app:lottie_rawRes="@raw/taskbar_edu_circle_to_search"
+        app:lottie_autoPlay="true"
+        app:lottie_loop="true" />
+
+    <TextView
+        android:id="@+id/circle_to_search_text"
+        style="@style/TextAppearance.TaskbarEduTooltip.Subtext"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:gravity="center"
+        android:textSize="@dimen/taskbar_edu_circle_to_search_subtitle_text_size"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/circle_to_search_animation"
+        app:layout_constraintBottom_toBottomOf="parent" />
+
+</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/quickstep/res/raw/taskbar_edu_circle_to_search.json b/quickstep/res/raw/taskbar_edu_circle_to_search.json
new file mode 100644
index 0000000..0dcccd6
--- /dev/null
+++ b/quickstep/res/raw/taskbar_edu_circle_to_search.json
@@ -0,0 +1 @@
+{"v":"5.12.1","fr":60,"ip":0,"op":431,"w":348,"h":218,"nm":"Omni_EDU_05_matted","ddd":0,"assets":[{"id":"comp_0","nm":"Omni_EDU_05","fr":60,"layers":[{"ddd":0,"ind":1,"ty":4,"nm":".black","cl":"black","parent":2,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":-140,"ix":10},"p":{"a":0,"k":[0,0,0],"ix":2,"l":2},"a":{"a":0,"k":[0,-48,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0,0],"y":[1,1]},"o":{"x":[0.2,0.2],"y":[0,0]},"t":174,"s":[0,0]},{"i":{"x":[0,0],"y":[1,1]},"o":{"x":[0.167,0.167],"y":[0,0]},"t":192,"s":[17,17]},{"i":{"x":[0.999,0.999],"y":[1,1]},"o":{"x":[0.3,0.3],"y":[0,0]},"t":237,"s":[17,17]},{"t":249,"s":[0,0]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,-48],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":174,"op":249,"st":40,"ct":1,"bm":0},{"ddd":0,"ind":2,"ty":3,"nm":"c2s null","parent":12,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":193,"s":[-56.933,-189.286,0],"to":[-0.023,-0.021,0],"ti":[0.092,0.088,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":194,"s":[-57.069,-189.414,0],"to":[-0.092,-0.088,0],"ti":[0.189,0.184,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":195,"s":[-57.488,-189.813,0],"to":[-0.189,-0.184,0],"ti":[0.29,0.293,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":196,"s":[-58.204,-190.519,0],"to":[-0.29,-0.293,0],"ti":[0.392,0.419,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":197,"s":[-59.226,-191.574,0],"to":[-0.392,-0.419,0],"ti":[0.492,0.566,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":198,"s":[-60.555,-193.035,0],"to":[-0.492,-0.566,0],"ti":[0.582,0.741,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":199,"s":[-62.177,-194.971,0],"to":[-0.582,-0.741,0],"ti":[0.641,0.957,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":200,"s":[-64.048,-197.48,0],"to":[-0.641,-0.957,0],"ti":[0.644,1.22,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":201,"s":[-66.021,-200.712,0],"to":[-0.644,-1.22,0],"ti":[0.59,1.52,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":202,"s":[-67.912,-204.803,0],"to":[-0.59,-1.52,0],"ti":[0.478,1.841,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":203,"s":[-69.561,-209.83,0],"to":[-0.478,-1.841,0],"ti":[0.309,2.174,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":204,"s":[-70.781,-215.849,0],"to":[-0.309,-2.174,0],"ti":[0.095,2.509,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":205,"s":[-71.414,-222.876,0],"to":[-0.095,-2.509,0],"ti":[-0.149,2.838,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":206,"s":[-71.348,-230.903,0],"to":[0.149,-2.838,0],"ti":[-0.493,3.137,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":207,"s":[-70.519,-239.902,0],"to":[0.493,-3.137,0],"ti":[-0.971,3.37,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":208,"s":[-68.392,-249.724,0],"to":[0.971,-3.37,0],"ti":[-1.521,3.501,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":209,"s":[-64.693,-260.12,0],"to":[1.521,-3.501,0],"ti":[-2.183,3.438,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":210,"s":[-59.267,-270.731,0],"to":[2.183,-3.438,0],"ti":[-3.014,2.996,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":211,"s":[-51.596,-280.747,0],"to":[3.014,-2.996,0],"ti":[-3.718,2.327,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":212,"s":[-41.184,-288.709,0],"to":[3.718,-2.327,0],"ti":[-4.093,1.634,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":213,"s":[-29.289,-294.708,0],"to":[4.093,-1.634,0],"ti":[-4.243,0.814,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":214,"s":[-16.628,-298.511,0],"to":[4.243,-0.814,0],"ti":[-4.168,-0.028,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":215,"s":[-3.828,-299.591,0],"to":[4.168,0.028,0],"ti":[-3.907,-0.628,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":216,"s":[8.377,-298.344,0],"to":[3.907,0.628,0],"ti":[-3.551,-1.009,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":217,"s":[19.614,-295.822,0],"to":[3.551,1.009,0],"ti":[-3.138,-1.314,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":218,"s":[29.681,-292.288,0],"to":[3.138,1.314,0],"ti":[-2.68,-1.566,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":219,"s":[38.443,-287.941,0],"to":[2.68,1.566,0],"ti":[-2.137,-1.816,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":220,"s":[45.761,-282.889,0],"to":[2.137,1.816,0],"ti":[-1.616,-1.954,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":221,"s":[51.267,-277.046,0],"to":[1.616,1.954,0],"ti":[-1.251,-1.903,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":222,"s":[55.456,-271.165,0],"to":[1.251,1.903,0],"ti":[-0.99,-1.774,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":223,"s":[58.77,-265.626,0],"to":[0.99,1.774,0],"ti":[-0.752,-1.637,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":224,"s":[61.394,-260.52,0],"to":[0.752,1.637,0],"ti":[-0.54,-1.496,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":225,"s":[63.282,-255.805,0],"to":[0.54,1.496,0],"ti":[-0.388,-1.34,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":226,"s":[64.634,-251.545,0],"to":[0.388,1.34,0],"ti":[-0.278,-1.183,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":227,"s":[65.61,-247.762,0],"to":[0.278,1.183,0],"ti":[-0.195,-1.031,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":228,"s":[66.303,-244.447,0],"to":[0.195,1.031,0],"ti":[-0.13,-0.885,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":229,"s":[66.778,-241.579,0],"to":[0.13,0.885,0],"ti":[-0.081,-0.748,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":230,"s":[67.085,-239.135,0],"to":[0.081,0.748,0],"ti":[-0.045,-0.619,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":231,"s":[67.265,-237.089,0],"to":[0.045,0.619,0],"ti":[-0.02,-0.498,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":232,"s":[67.354,-235.418,0],"to":[0.02,0.498,0],"ti":[-0.004,-0.385,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":233,"s":[67.382,-234.099,0],"to":[0.004,0.385,0],"ti":[0.004,-0.279,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":234,"s":[67.377,-233.109,0],"to":[-0.004,0.279,0],"ti":[0.006,-0.18,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":235,"s":[67.358,-232.425,0],"to":[-0.006,0.18,0],"ti":[0.004,-0.087,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":236,"s":[67.341,-232.028,0],"to":[-0.004,0.087,0],"ti":[0.001,-0.021,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":237,"s":[67.335,-231.9,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":248,"s":[67.335,-231.9,0],"to":[-0.008,0.042,0],"ti":[0.033,-0.177,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":249,"s":[67.289,-231.647,0],"to":[-0.033,0.177,0],"ti":[0.079,-0.372,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":250,"s":[67.135,-230.84,0],"to":[-0.079,0.372,0],"ti":[0.155,-0.591,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":251,"s":[66.815,-229.413,0],"to":[-0.155,0.591,0],"ti":[0.268,-0.834,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":252,"s":[66.203,-227.297,0],"to":[-0.268,0.834,0],"ti":[0.413,-1.109,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":253,"s":[65.206,-224.409,0],"to":[-0.413,1.109,0],"ti":[0.247,-0.628,0]},{"t":254,"s":[63.723,-220.641,0]}],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"ip":193,"op":264,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":".black","cl":"black","parent":12,"sr":1,"ks":{"o":{"a":0,"k":90,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.149,"y":0.701},"o":{"x":0.4,"y":0.002},"t":248,"s":[-8.212,-253.668,0],"to":[0,0,0],"ti":[0,0,0]},{"t":263,"s":[0,-227,0]}],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.149,"y":0.701},"o":{"x":0.4,"y":0.002},"t":248,"s":[{"i":[[3.564,-2.549],[3.809,-1.264],[12.238,3.984],[8.325,10.606],[-0.214,12.436],[-2.655,8.03],[-10.533,8.871],[-9.434,2.582],[-8.48,-3.643],[-9.227,-13.6],[-1.802,-9.359],[2.171,-9.596]],"o":[[-3.564,2.549],[-12.609,4.183],[-12.52,-4.076],[-7.722,-9.838],[0.146,-8.454],[4.364,-13.197],[5.142,-4.331],[9.891,-2.707],[11.828,5.081],[4.099,6.042],[2.254,11.707],[-3.907,17.266]],"v":[[53.514,60.456],[41.519,66.798],[2.462,64.221],[-33.286,39.729],[-45.626,-0.393],[-41.723,-21.691],[-18.543,-58.238],[5.442,-69.196],[39.994,-68.523],[68.082,-43.976],[77.052,-19.838],[77.406,14.145]],"c":true}]},{"t":263,"s":[{"i":[[7.701,-4.092],[8.127,0],[7.226,4.357],[4.092,7.701],[0,8.127],[-4.357,7.226],[-7.701,4.092],[-8.127,0],[-7.226,-4.357],[-4.092,-7.701],[0,-8.127],[4.357,-7.226]],"o":[[-6.709,3.565],[-9.053,0],[-7.447,-4.489],[-3.565,-6.709],[0,-9.053],[4.489,-7.447],[6.709,-3.565],[9.053,0],[7.447,4.489],[3.565,6.709],[0,9.053],[-4.489,7.447]],"v":[[22.492,42.415],[0,48],[-24.747,41.137],[-42.415,22.492],[-48,0],[-41.137,-24.747],[-22.492,-42.415],[0,-48],[24.747,-41.137],[42.415,-22.492],[48,0],[41.137,24.747]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0,0,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":2,"lj":2,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":78.63,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Vector 303","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":0,"k":100,"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.4],"y":[1]},"o":{"x":[0.5],"y":[0]},"t":193,"s":[0]},{"t":237,"s":[63],"h":1},{"i":{"x":[0.149],"y":[0.701]},"o":{"x":[0.4],"y":[0.002]},"t":248,"s":[63]},{"t":263,"s":[100]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":3,"nm":"Trim Paths 2","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":193,"op":263,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":".black","cl":"black","parent":12,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":277,"s":[0]},{"t":289,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.2,"y":0},"t":263,"s":[2.625,-203,0],"to":[0,0,0],"ti":[0,0,0]},{"t":299,"s":[2.625,-221,0]}],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-1.5,1.3],[0,0],[0,0],[0,0],[-0.65,1.45],[-0.25,1.6],[0,0],[2.65,-2.25],[3.6,0],[2.9,2.85],[0,4.05],[-2.85,2.85],[-4.1,0],[-1.1,-0.3],[-1,-0.5],[0,0],[1.7,0.5],[1.8,0],[3.75,-3.75],[0,-5.3],[-3.75,-3.75],[-5.4,0],[-2,0.7]],"o":[[0,0],[0,0],[0,0],[1.05,-1.35],[0.7,-1.5],[0,0],[-0.7,3.35],[-2.6,2.2],[-4.1,0],[-2.85,-2.9],[0,-4.05],[2.9,-2.9],[1.2,0],[1.1,0.25],[0,0],[-1.45,-0.85],[-1.65,-0.5],[-5.35,0],[-3.75,3.75],[0,5.3],[3.75,3.75],[2.25,0],[2,-0.75]],"v":[[1.35,9.863],[21.075,29.587],[24.375,26.288],[4.575,6.637],[7.125,2.438],[8.55,-2.213],[3.975,-2.213],[-1.05,6.188],[-10.35,9.488],[-20.85,5.212],[-25.125,-5.213],[-20.85,-15.562],[-10.35,-19.913],[-6.9,-19.462],[-3.75,-18.337],[-0.45,-21.637],[-5.175,-23.663],[-10.35,-24.413],[-24,-18.788],[-29.625,-5.213],[-24,8.363],[-10.275,13.988],[-3.9,12.938]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[-3.05,-3.05],[0,-4.4],[-3.05,3.05],[-4.4,0],[3.05,3.05],[0,4.4],[3.05,-3.05],[4.4,0]],"o":[[3.05,3.05],[0,-4.4],[3.05,-3.05],[-4.4,0],[-3.05,-3.05],[0,4.4],[-3.05,3.05],[4.4,0]],"v":[[9.3,-9.262],[13.875,1.913],[18.45,-9.262],[29.625,-13.837],[18.45,-18.413],[13.875,-29.587],[9.3,-18.413],[-1.875,-13.837]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"icon","np":4,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":263,"op":431,"st":60,"ct":1,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":".black","cl":"black","parent":12,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":270,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.2,"y":0},"t":263,"s":[0,-227,0],"to":[0,0,0],"ti":[0,0,0]},{"t":299,"s":[-100,-161,0]}],"ix":2,"l":2},"a":{"a":0,"k":[11,11,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.2,"y":0},"t":263,"s":[{"i":[[0,0],[7.26,-4.415],[4.064,-7.787],[0,-8]],"o":[[-9.118,0],[-7.478,4.547],[-3.462,6.633],[0,0]],"v":[[11,-37],[-13.903,-30.043],[-31.581,-11.176],[-37,11]],"c":false}]},{"t":290,"s":[{"i":[[0,0],[0,0],[0,-7.732],[0,0]],"o":[[0,0],[-7.732,0],[0,0],[0,0]],"v":[[11,-11],[3,-11],[-11,3],[-11,11]],"c":false}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0,0,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Handle Top Left","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":263,"op":431,"st":63,"ct":1,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":".black","cl":"black","parent":12,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":180,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.2,"y":0},"t":263,"s":[0,-227,0],"to":[0,0,0],"ti":[0,0,0]},{"t":299,"s":[100,-161,0]}],"ix":2,"l":2},"a":{"a":0,"k":[11,11,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.2,"y":0},"t":263,"s":[{"i":[[0,0],[7.26,-4.415],[4.064,-7.787],[0,-8]],"o":[[-9.118,0],[-7.478,4.547],[-3.462,6.633],[0,0]],"v":[[11,-37],[-13.903,-30.043],[-31.581,-11.176],[-37,11]],"c":false}]},{"t":290,"s":[{"i":[[0,0],[0,0],[0,-7.732],[0,0]],"o":[[0,0],[-7.732,0],[0,0],[0,0]],"v":[[11,-11],[3,-11],[-11,3],[-11,11]],"c":false}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0,0,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Handle Top Left","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":263,"op":431,"st":63,"ct":1,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":".black","cl":"black","parent":12,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":90,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.2,"y":0},"t":263,"s":[0,-227,0],"to":[0,0,0],"ti":[0,0,0]},{"t":299,"s":[100,-279,0]}],"ix":2,"l":2},"a":{"a":0,"k":[11,11,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.2,"y":0},"t":263,"s":[{"i":[[0,0],[7.26,-4.415],[4.064,-7.787],[0,-8]],"o":[[-9.118,0],[-7.478,4.547],[-3.462,6.633],[0,0]],"v":[[11,-37],[-13.903,-30.043],[-31.581,-11.176],[-37,11]],"c":false}]},{"t":290,"s":[{"i":[[0,0],[0,0],[0,-7.732],[0,0]],"o":[[0,0],[-7.732,0],[0,0],[0,0]],"v":[[11,-11],[3,-11],[-11,3],[-11,11]],"c":false}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0,0,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Handle Top Left","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":263,"op":431,"st":63,"ct":1,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":".black","cl":"black","parent":12,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.2,"y":0},"t":263,"s":[0,-227,0],"to":[0,0,0],"ti":[0,0,0]},{"t":299,"s":[-100,-279,0]}],"ix":2,"l":2},"a":{"a":0,"k":[11,11,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.2,"y":0},"t":263,"s":[{"i":[[0,0],[7.26,-4.415],[4.064,-7.787],[0,-8]],"o":[[-9.118,0],[-7.478,4.547],[-3.462,6.633],[0,0]],"v":[[11,-37],[-13.903,-30.043],[-31.581,-11.176],[-37,11]],"c":false}]},{"t":290,"s":[{"i":[[0,0],[0,0],[0,-7.732],[0,0]],"o":[[0,0],[-7.732,0],[0,0],[0,0]],"v":[[11,-11],[3,-11],[-11,3],[-11,11]],"c":false}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0,0,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Handle Top Left","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":263,"op":431,"st":63,"ct":1,"bm":0},{"ddd":0,"ind":9,"ty":0,"nm":"Search","parent":12,"refId":"comp_1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.2,"y":0},"t":263,"s":[0,-166,0],"to":[0,0,0],"ti":[0,0,0]},{"t":299,"s":[0,-109,0]}],"ix":2,"l":2},"a":{"a":0,"k":[83,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"w":166,"h":45,"ip":135,"op":319,"st":135,"ct":1,"bm":0},{"ddd":0,"ind":10,"ty":0,"nm":"Flower","parent":12,"refId":"comp_2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-2.5,-209,0],"ix":2,"l":2},"a":{"a":0,"k":[109,115,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"w":219,"h":231,"ip":122,"op":431,"st":122,"ct":1,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":".blue50","cl":"blue50","parent":12,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":266,"s":[0]},{"t":278,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.2,"y":0},"t":263,"s":[0,-227,0],"to":[0,0,0],"ti":[0,0,0]},{"t":299,"s":[0,-220,0]}],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":1,"k":[{"i":{"x":[0,0],"y":[1,1]},"o":{"x":[0.2,0.2],"y":[0,0]},"t":263,"s":[92,92]},{"t":299,"s":[240,158]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":1,"k":[{"i":{"x":[0],"y":[1]},"o":{"x":[0.2],"y":[0]},"t":263,"s":[46]},{"t":299,"s":[12]}],"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.909803921569,0.941176470588,0.996078431373,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":263,"op":431,"st":60,"ct":1,"bm":0},{"ddd":0,"ind":12,"ty":3,"nm":"pan up","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.15,"y":1},"o":{"x":0.653,"y":0},"t":99,"s":[174,109,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.15,"y":0.15},"o":{"x":0.546,"y":0.546},"t":169,"s":[174,327,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.15,"y":1},"o":{"x":0.653,"y":0},"t":357,"s":[174,327,0],"to":[0,0,0],"ti":[0,0,0]},{"t":427,"s":[174,109,0]}],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"ef":[{"ty":5,"nm":"Void","np":19,"mn":"Pseudo/250958","ix":1,"en":1,"ef":[{"ty":0,"nm":"Width","mn":"Pseudo/250958-0001","ix":1,"v":{"a":0,"k":100,"ix":1}},{"ty":0,"nm":"Height","mn":"Pseudo/250958-0002","ix":2,"v":{"a":0,"k":100,"ix":2}},{"ty":0,"nm":"Offset X","mn":"Pseudo/250958-0003","ix":3,"v":{"a":0,"k":0,"ix":3}},{"ty":0,"nm":"Offset Y","mn":"Pseudo/250958-0004","ix":4,"v":{"a":0,"k":0,"ix":4}},{"ty":0,"nm":"Roundness","mn":"Pseudo/250958-0005","ix":5,"v":{"a":0,"k":0,"ix":5}},{"ty":6,"nm":"About","mn":"Pseudo/250958-0006","ix":6,"v":0},{"ty":6,"nm":"Plague of null layers.","mn":"Pseudo/250958-0007","ix":7,"v":0},{"ty":6,"nm":"Void","mn":"Pseudo/250958-0008","ix":8,"v":0},{"ty":6,"nm":"Following projects","mn":"Pseudo/250958-0009","ix":9,"v":0},{"ty":6,"nm":"Void","mn":"Pseudo/250958-0010","ix":10,"v":0},{"ty":6,"nm":"through time.","mn":"Pseudo/250958-0011","ix":11,"v":0},{"ty":6,"nm":"Void","mn":"Pseudo/250958-0012","ix":12,"v":0},{"ty":6,"nm":"Be free of the past.","mn":"Pseudo/250958-0013","ix":13,"v":0},{"ty":6,"nm":"Void","mn":"Pseudo/250958-0014","ix":14,"v":0},{"ty":6,"nm":"Copyright 2023 Battle Axe Inc","mn":"Pseudo/250958-0015","ix":15,"v":0},{"ty":6,"nm":"Void","mn":"Pseudo/250958-0016","ix":16,"v":0},{"ty":6,"nm":"Void","mn":"Pseudo/250958-0017","ix":17,"v":0}]}],"ip":0,"op":431,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":"long Press Over - Outward","parent":12,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":33,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":95,"s":[100]},{"t":113,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,38,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.1,0.1],"y":[1,1]},"o":{"x":[0.05,0.05],"y":[0.7,0.7]},"t":83,"s":[116,116]},{"t":113,"s":[136,136]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Long Pres Over","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":83,"op":431,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":"long Press Over","parent":12,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":33,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":83,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":86,"s":[100]},{"t":95,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,38,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.999,0.999],"y":[1,1]},"o":{"x":[0.001,0.001],"y":[0,0]},"t":33,"s":[40,40]},{"i":{"x":[0.8,0.8],"y":[0.15,0.15]},"o":{"x":[0.3,0.3],"y":[0,0]},"t":83,"s":[120,120]},{"t":101,"s":[40,40]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Long Pres Over","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":30,"op":431,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":15,"ty":0,"nm":"Action Key","parent":12,"refId":"comp_3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-11.539,38,0],"ix":2,"l":2},"a":{"a":0,"k":[53.5,53.5,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"w":107,"h":107,"ip":0,"op":431,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":16,"ty":4,"nm":"long Press Under","parent":12,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":30,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":42,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":83,"s":[100]},{"t":95,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,38,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0,0],"y":[1,1]},"o":{"x":[0.2,0.2],"y":[0,0]},"t":30,"s":[96,96]},{"i":{"x":[0.833,0.833],"y":[1,1]},"o":{"x":[0.167,0.167],"y":[0,0]},"t":66,"s":[120,120]},{"i":{"x":[0.999,0.999],"y":[1,1]},"o":{"x":[0.3,0.3],"y":[0,0]},"t":83,"s":[120,120]},{"t":101,"s":[106,106]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.823529422283,0.890196084976,0.988235294819,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Long Press Under","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":30,"op":431,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":17,"ty":4,"nm":".grey800","cl":"grey800","parent":12,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,38,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[348,142],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.235294118524,0.250980407,0.262745112181,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Grey800","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":431,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":18,"ty":4,"nm":".blue100","cl":"blue100","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[174,109,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[348,218],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.823529411765,0.890196078431,0.988235294118,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":431,"st":0,"ct":1,"bm":0}]},{"id":"comp_1","nm":"SearchPill","fr":60,"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"superG","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":11,"s":[0]},{"t":17,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"k":[{"s":[-3.898,0.128,0],"t":0,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-4.239,0.128,0],"t":1,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-5.311,0.128,0],"t":2,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-7.286,0.128,0],"t":3,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-10.519,0.128,0],"t":4,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-15.81,0.128,0],"t":5,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-25.898,0.128,0],"t":6,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-37.431,0.128,0],"t":7,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-43.055,0.128,0],"t":8,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-46.404,0.128,0],"t":9,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-48.712,0.128,0],"t":10,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-50.434,0.128,0],"t":11,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-51.781,0.128,0],"t":12,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-52.869,0.128,0],"t":13,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-53.768,0.128,0],"t":14,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-54.522,0.128,0],"t":15,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-55.162,0.128,0],"t":16,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-55.71,0.128,0],"t":17,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-56.182,0.128,0],"t":18,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-56.591,0.128,0],"t":19,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-56.947,0.128,0],"t":20,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-57.257,0.128,0],"t":21,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-57.526,0.128,0],"t":22,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-57.761,0.128,0],"t":23,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-57.965,0.128,0],"t":24,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-58.142,0.128,0],"t":25,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-58.295,0.128,0],"t":26,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-58.425,0.128,0],"t":27,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-58.537,0.128,0],"t":28,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-58.63,0.128,0],"t":29,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-58.707,0.128,0],"t":30,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-58.769,0.128,0],"t":31,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-58.818,0.128,0],"t":32,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-58.854,0.128,0],"t":33,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-58.853,0.128,0],"t":129,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-58.679,0.128,0],"t":130,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-58.301,0.128,0],"t":131,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-57.701,0.128,0],"t":132,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-57.039,0.128,0],"t":133,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-56.46,0.128,0],"t":134,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-55.983,0.128,0],"t":135,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-55.588,0.128,0],"t":136,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-55.255,0.128,0],"t":137,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-54.97,0.128,0],"t":138,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-54.723,0.128,0],"t":139,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-54.507,0.128,0],"t":140,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-54.316,0.128,0],"t":141,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-54.147,0.128,0],"t":142,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-53.996,0.128,0],"t":143,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-53.861,0.128,0],"t":144,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-53.74,0.128,0],"t":145,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-53.631,0.128,0],"t":146,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-53.534,0.128,0],"t":147,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-53.446,0.128,0],"t":148,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-53.367,0.128,0],"t":149,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-53.297,0.128,0],"t":150,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-53.234,0.128,0],"t":151,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-53.178,0.128,0],"t":152,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-53.128,0.128,0],"t":153,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-53.084,0.128,0],"t":154,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-53.046,0.128,0],"t":155,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-53.012,0.128,0],"t":156,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-52.96,0.128,0],"t":158,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[-52.913,0.128,0],"t":161,"i":{"x":1,"y":1},"o":{"x":0,"y":0}}],"l":2},"a":{"a":0,"k":[24.102,22.628,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[1.788,0],[0.959,-2.878],[0,0],[-4.737,0],[-2.091,-1.959]],"o":[[-1.262,-1.202],[-3.161,0],[0,0],[1.99,-3.959],[3.272,0],[0,0]],"v":[[6.004,1.712],[1.358,-0.106],[-5.439,4.903],[-9.458,1.783],[1.358,-4.903],[9.458,-1.742]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.917647063732,0.262745112181,0.207843139768,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[23.001,15.411],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"g-red","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-0.808],[-0.252,-0.727],[0,0],[0,1.959],[-0.828,1.636],[0,0],[0,0]],"o":[[0,0.808],[0,0],[-0.828,-1.636],[0,-1.959],[0,0],[0,0],[-0.242,0.727]],"v":[[2.277,0],[2.661,2.313],[-1.358,5.434],[-2.661,0],[-1.358,-5.434],[2.661,-5.434],[2.661,-2.313]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.976470589638,0.670588254929,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[14.901,22.628],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"g-yellow","np":1,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[3.272,0],[1.99,3.959],[0,0],[0,0],[-3.161,0],[-1.091,0.727]],"o":[[-2,1.848],[-4.737,0],[0,0],[0,0],[0.959,2.878],[1.636,0],[0,0]],"v":[[9.413,1.964],[1.404,4.903],[-9.413,-1.783],[-9.413,-4.903],[-5.393,-4.903],[1.404,0.106],[5.514,-1.066]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.203921571374,0.658823549747,0.32549020648,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[22.955,29.844],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"g-green","np":1,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,-0.798],[2.283,-2.111],[0,0],[0,0],[-0.293,1.495],[0,0],[0,0]],"o":[[0.121,0.737],[0,3.686],[0,0],[0,0],[1.273,-0.858],[0,0],[0,0],[0,0]],"v":[[5.61,-5.6],[5.802,-3.308],[2.207,5.6],[-1.692,5.6],[-1.692,2.57],[0.732,-1.045],[-5.802,-1.045],[-5.802,-5.6]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.258823543787,0.521568655968,0.956862747669,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[30.161,26.208],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"g-blue","np":1,"cix":2,"bm":0,"ix":4,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":1200,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"mic","parent":3,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":11,"s":[0]},{"t":17,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"k":[{"s":[2.7,0.705,0],"t":0,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[3.041,0.705,0],"t":1,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[4.113,0.705,0],"t":2,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[6.088,0.705,0],"t":3,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[9.321,0.705,0],"t":4,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[14.611,0.705,0],"t":5,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[24.7,0.705,0],"t":6,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[36.233,0.705,0],"t":7,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[41.857,0.705,0],"t":8,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[45.206,0.705,0],"t":9,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[47.514,0.705,0],"t":10,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[49.235,0.705,0],"t":11,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[50.583,0.705,0],"t":12,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[51.671,0.705,0],"t":13,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[52.569,0.705,0],"t":14,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[53.323,0.705,0],"t":15,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[53.963,0.705,0],"t":16,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[54.511,0.705,0],"t":17,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[54.984,0.705,0],"t":18,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[55.393,0.705,0],"t":19,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[55.749,0.705,0],"t":20,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[56.058,0.705,0],"t":21,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[56.328,0.705,0],"t":22,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[56.563,0.705,0],"t":23,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[56.767,0.705,0],"t":24,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[56.944,0.705,0],"t":25,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[57.096,0.705,0],"t":26,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[57.227,0.705,0],"t":27,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[57.338,0.705,0],"t":28,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[57.431,0.705,0],"t":29,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[57.509,0.705,0],"t":30,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[57.571,0.705,0],"t":31,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[57.62,0.705,0],"t":32,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[57.656,0.705,0],"t":33,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[57.655,0.705,0],"t":129,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[57.48,0.705,0],"t":130,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[57.103,0.705,0],"t":131,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[56.503,0.705,0],"t":132,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[55.841,0.705,0],"t":133,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[55.262,0.705,0],"t":134,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[54.785,0.705,0],"t":135,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[54.39,0.705,0],"t":136,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[54.057,0.705,0],"t":137,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[53.772,0.705,0],"t":138,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[53.525,0.705,0],"t":139,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[53.309,0.705,0],"t":140,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[53.118,0.705,0],"t":141,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[52.949,0.705,0],"t":142,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[52.798,0.705,0],"t":143,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[52.663,0.705,0],"t":144,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[52.542,0.705,0],"t":145,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[52.433,0.705,0],"t":146,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[52.335,0.705,0],"t":147,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[52.248,0.705,0],"t":148,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[52.169,0.705,0],"t":149,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[52.098,0.705,0],"t":150,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[52.035,0.705,0],"t":151,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[51.979,0.705,0],"t":152,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[51.929,0.705,0],"t":153,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[51.886,0.705,0],"t":154,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[51.847,0.705,0],"t":155,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[51.814,0.705,0],"t":156,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[51.786,0.705,0],"t":157,"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"s":[51.742,0.705,0],"t":159,"i":{"x":1,"y":1},"o":{"x":0,"y":0}}],"l":2},"a":{"a":0,"k":[140.7,23.205,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-1.688,0],[0,0],[0.012,3.389],[0,0],[4.735,0],[1.554,1.554]],"o":[[1.113,1.113],[0,0],[3.377,0],[0,0],[0,4.723],[-2.361,0],[0,0]],"v":[[-5.573,0.049],[-1.242,1.848],[-1.242,1.848],[4.851,-4.282],[7.298,-4.282],[-1.242,4.282],[-7.298,1.774]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.917647063732,0.262745112181,0.207843139768,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[141.954,27.475],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"mic-red","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,2.361],[0,0],[0,0],[-1.101,-1.113],[0,0]],"o":[[0,0],[0,0],[0,1.688],[0,0],[-1.554,-1.554]],"v":[[-2.117,-3.028],[0.33,-3.028],[0.33,-3.028],[2.117,1.303],[0.392,3.028]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.976470589638,0.670588254929,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[134.264,26.233],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"mic-yellow","np":1,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[1.224,-1.884],[-1.224,-1.884],[-1.224,1.884],[1.224,1.884]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.203921571374,0.658823549747,0.32549020648,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[140.712,33.556],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"mic-green","np":1,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[2.031,0],[0,0],[0,2.031],[0,0],[-2.031,0],[0,-2.031]],"o":[[0,2.031],[0,0],[-2.031,0],[0,0],[0,-2.031],[2.031,0],[0,0]],"v":[[3.658,4.282],[0,7.953],[0,7.953],[-3.671,4.282],[-3.671,-4.282],[0,-7.953],[3.671,-4.282]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.258823543787,0.521568655968,0.956862747669,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[140.712,18.923],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"mic-blue","np":1,"cix":2,"bm":0,"ix":4,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":1200,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":".grey800","cl":"grey800","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":3,"s":[0]},{"t":12,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[83,22.5,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":1,"k":[{"i":{"x":[0.8,0.8],"y":[0.15,1]},"o":{"x":[0.3,0.3],"y":[0,0]},"t":0,"s":[56,45]},{"i":{"x":[0.1,0.1],"y":[1,1]},"o":{"x":[0.05,0.05],"y":[0.7,0]},"t":6,"s":[100,45]},{"i":{"x":[0.833,0.833],"y":[1,1]},"o":{"x":[0.167,0.167],"y":[0,0]},"t":36,"s":[166,45]},{"i":{"x":[0,0],"y":[1,1]},"o":{"x":[0.2,0.2],"y":[0,0]},"t":128,"s":[166,45]},{"t":164,"s":[154,45]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":87,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.235294118524,0.250980407,0.262745112181,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Grey 800","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":1200,"st":0,"ct":1,"bm":0}]},{"id":"comp_2","nm":"Flower","fr":60,"layers":[{"ddd":0,"ind":1,"ty":4,"nm":".grey700","cl":"grey700","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[109.453,193.777,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[36.517,1.481],[-36.517,1.481]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.372549027205,0.388235300779,0.407843142748,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":2,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Union 2","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[5.448,5.448],"ix":2},"p":{"a":0,"k":[-12.903,0.471],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"d":1,"ty":"el","s":{"a":0,"k":[5.448,5.448],"ix":2},"p":{"a":0,"k":[9.094,0.471],"ix":3},"nm":"Ellipse Path 2","mn":"ADBE Vector Shape - Ellipse","hd":false},{"d":1,"ty":"el","s":{"a":0,"k":[5.448,5.448],"ix":2},"p":{"a":0,"k":[2.554,0.471],"ix":3},"nm":"Ellipse Path 3","mn":"ADBE Vector Shape - Ellipse","hd":false},{"d":1,"ty":"el","s":{"a":0,"k":[6.588,6.588],"ix":2},"p":{"a":0,"k":[-8.927,-0.099],"ix":3},"nm":"Ellipse Path 4","mn":"ADBE Vector Shape - Ellipse","hd":false},{"d":1,"ty":"el","s":{"a":0,"k":[6.588,6.588],"ix":2},"p":{"a":0,"k":[5.118,-0.099],"ix":3},"nm":"Ellipse Path 5","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.372549027205,0.388235300779,0.407843142748,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,-0.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Union","np":7,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":1200,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":".black","cl":"black","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[64.952,63.598,0],"ix":2,"l":2},"a":{"a":0,"k":[24.952,23.598,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-1.753,0],[0,1.753],[1.753,0],[0,-1.753]],"o":[[1.753,0],[0,-1.753],[-1.753,0],[0,1.753]],"v":[[0,3.174],[3.174,0],[0,-3.174],[-3.174,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[21.137,19.31],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"flower 1","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-1.753,0],[0,1.753],[1.753,0],[0,-1.753]],"o":[[1.753,0],[0,-1.753],[-1.753,0],[0,1.753]],"v":[[0,3.174],[3.174,0],[0,-3.174],[-3.174,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[28.767,23.097],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"flower 2","np":1,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-1.753,0],[0,1.753],[1.753,0],[0,-1.753]],"o":[[1.753,0],[0,-1.753],[-1.753,0],[0,1.753]],"v":[[0,3.174],[3.174,0],[0,-3.174],[-3.174,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Vector","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[21.75,27.886],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"flower 3","np":1,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":1200,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":".yellow400","cl":"yellow400","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[63.114,63.125,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[1.392,1.281],[2.395,-2.283],[1.893,0.223],[0.557,-3.174],[1.726,-0.891],[-1.504,-2.896],[0.835,-1.671],[-2.951,-1.504],[-0.278,-1.782],[-3.341,0.446],[-1.392,-1.281],[-2.395,2.283],[-1.893,-0.278],[-0.557,3.174],[-1.726,0.891],[1.504,2.896],[-0.835,1.671],[2.951,1.504],[0.334,1.838],[3.341,-0.446]],"o":[[-2.45,-2.283],[-1.392,1.337],[-3.341,-0.501],[-0.334,1.838],[-2.951,1.504],[0.835,1.671],[-1.504,2.896],[1.671,0.835],[0.557,3.174],[1.949,-0.278],[2.45,2.283],[1.392,-1.281],[3.341,0.501],[0.334,-1.838],[2.951,-1.504],[-0.835,-1.671],[1.504,-2.896],[-1.726,-0.891],[-0.557,-3.174],[-1.949,0.278]],"v":[[4.316,-21.412],[-4.372,-21.412],[-9.551,-19.741],[-16.567,-14.841],[-19.797,-10.553],[-22.47,-2.59],[-22.47,2.701],[-19.797,10.664],[-16.623,14.897],[-9.606,19.797],[-4.372,21.412],[4.316,21.412],[9.551,19.797],[16.567,14.897],[19.797,10.609],[22.47,2.645],[22.47,-2.645],[19.797,-10.609],[16.567,-14.897],[9.551,-19.797]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.988235294819,0.78823530674,0.203921571374,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":1200,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":".green400","cl":"green400","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[97.335,135.554,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[10.748,5.402]],"o":[[0,0],[-0.891,-40.374],[0,0]],"v":[[16.706,59.315],[16.706,7.288],[-16.706,-59.315]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.35686275363,0.72549021244,0.454901963472,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3.824,"ix":5},"lc":2,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":1200,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":6,"ty":3,"nm":"▽ Right Flower","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[144.155,88.602,0],"ix":2,"l":2},"a":{"a":0,"k":[31.228,40.542,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"ip":0,"op":1200,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":".black","cl":"black","parent":6,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[45.33,17.598,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-2.184,0],[0,2.184],[2.184,0],[0,-2.184]],"o":[[2.184,0],[0,-2.184],[-2.184,0],[0,2.184]],"v":[[0,3.954],[3.954,0],[0,-3.954],[-3.954,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":1200,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":".red400","cl":"red400","parent":6,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[45.024,17.515,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.167,2.283],[4.678,-6.014],[2.283,-0.223],[-5.959,-4.733],[-0.167,-2.283],[-4.678,6.014],[-2.283,0.223],[5.959,4.733]],"o":[[-0.613,-7.574],[-1.448,1.782],[-7.629,0.668],[1.838,1.448],[0.613,7.574],[1.392,-1.838],[7.629,-0.668],[-1.838,-1.448]],"v":[[11.054,-9.829],[-3.87,-14.284],[-9.718,-11.11],[-14.228,3.926],[-11.054,9.829],[3.87,14.284],[9.718,11.11],[14.228,-3.926]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.933333337307,0.403921574354,0.360784322023,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":1200,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":".green400","cl":"green400","parent":6,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[22.485,51.377,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[9.244,-14.2],[-4.678,11.138],[7.407,2.729]],"o":[[7.741,4.121],[1.002,-2.951],[-5.457,-1.448]],"v":[[-14.689,4.256],[14.269,2.642],[7.586,-8.663]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.35686275363,0.72549021244,0.454901963472,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3.824,"ix":5},"lc":2,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":1200,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":".green400","cl":"green400","parent":6,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[16.651,52.32,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-10.414,5.68]],"o":[[1.726,-32.355],[0,0]],"v":[[-16.651,28.763],[16.651,-28.763]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.35686275363,0.72549021244,0.454901963472,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3.824,"ix":5},"lc":2,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":1200,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":".green400","cl":"green400","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[85.004,158.386,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,-17.306]],"o":[[34.304,21.05],[0,0]],"v":[[-23.31,-36.483],[23.31,36.483]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.35686275363,0.72549021244,0.454901963472,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3.824,"ix":5},"lc":2,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":1200,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":".green400","cl":"green400","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[55.116,132.289,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[5.847,-0.501],[1.281,-3.62],[-0.78,-2.172],[-3.341,-0.891],[-3.898,2.951],[-2.339,4.01],[1.114,0.501]],"o":[[-4.177,0.39],[-0.668,1.893],[1.169,3.341],[4.733,0.668],[3.731,-2.84],[-1.114,-0.501],[-5.29,-2.228]],"v":[[-5.506,-9.773],[-14.416,-3.09],[-14.361,3.147],[-7.065,9.607],[5.91,6.655],[14.931,-4.315],[11.59,-5.819]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.35686275363,0.72549021244,0.454901963472,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3.824,"ix":5},"lc":2,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":1200,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":".green400","cl":"green400","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[65.652,111.9,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[5.179,3.007],[0.724,0.167],[2.228,-1.392],[-0.446,-4.622],[-4.288,-3.341],[0,-0.056],[-0.724,4.901]],"o":[[-0.668,-0.39],[-2.562,-0.613],[-4.065,2.617],[0.557,5.513],[0.501,0.39],[2.172,-4.511],[0.78,-5.235]],"v":[[4.896,-14.778],[2.836,-15.613],[-4.849,-14.221],[-9.917,-1.97],[-1.731,11.284],[5.23,15.851],[9.685,1.483]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.35686275363,0.72549021244,0.454901963472,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3.824,"ix":5},"lc":2,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":1200,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":".green400","cl":"green400","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[133.059,138.554,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[3.731,-15.203]],"o":[[-27.844,11.695],[0,0]],"v":[[19.018,-18.878],[-19.018,18.878]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.35686275363,0.72549021244,0.454901963472,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3.824,"ix":5},"lc":2,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":1200,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":15,"ty":4,"nm":".green400","cl":"green400","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[164.078,125.618,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-6.404,-1.726],[-2.673,2.45],[-0.334,2.005],[0.446,1.392],[4.455,0.613],[1.671,-0.835],[0.223,-0.446],[-0.39,-0.501]],"o":[[3.397,0.891],[1.281,-1.169],[0.278,-1.448],[-1.392,-4.511],[-3.564,-0.501],[-0.446,0.223],[-0.223,0.501],[3.787,5.235]],"v":[[1.642,9.094],[11.777,7.256],[14.339,2.467],[14.061,-1.876],[4.705,-9.506],[-12.057,-5.942],[-14.452,-4.661],[-13.505,-2.879]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.35686275363,0.72549021244,0.454901963472,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":3.824,"ix":5},"lc":2,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Vector","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":1200,"st":0,"ct":1,"bm":0}]},{"id":"comp_3","nm":"Action Key","fr":60,"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"action icon","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[67.56,56.18,0],"ix":2,"l":2},"a":{"a":0,"k":[67.56,56.18,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,3.379],[3.379,0],[0,-3.379],[-3.379,0]],"o":[[0,-3.379],[-3.379,0],[0,3.379],[3.379,0]],"v":[[6.144,0],[0,-6.144],[-6.144,0],[0,6.144]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,6.789],[-6.789,0],[0,-6.789],[6.789,0]],"o":[[0,-6.789],[6.789,0],[0,6.789],[-6.789,0]],"v":[[-12.288,0],[0,-12.288],[12.288,0],[0,12.288]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"tr","p":{"a":0,"k":[-3.185,-3.229],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Vector","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[-1.101,1.239],[-1.26,-1.207],[0,0],[1.215,-1.215],[1.205,1.15],[0,0]],"o":[[1.159,-1.304],[0,0],[1.241,1.189],[-1.177,1.177],[0,0],[-1.199,-1.144]],"v":[[1.548,2.22],[5.978,2.043],[14.529,10.239],[14.575,14.619],[10.291,14.669],[1.723,6.491]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100.469,100.469],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Union","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[84.621,73.217],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"mag","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[24.577,24.577],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 2","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[81.029,35.842],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"top R","np":1,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[24.577,24.577],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 3","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[47.241,69.628],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"bottom L","np":1,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[24.577,24.577],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[47.241,35.841],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"top L","np":1,"cix":2,"bm":0,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.603921592236,0.627451002598,0.65098041296,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":1200,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Action (not dynamic)","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[53.25,53.25,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[106.5,106.5],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":32,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Action (not dynamic)","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":1200,"st":0,"ct":1,"bm":0}]}],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"matte","td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[174,109,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[348,218],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":16,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":431,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":2,"ty":0,"nm":"Omni_EDU_05","tt":1,"tp":1,"refId":"comp_0","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[174,109,0],"ix":2,"l":2},"a":{"a":0,"k":[174,109,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"w":348,"h":218,"ip":0,"op":431,"st":0,"ct":1,"bm":0}],"markers":[],"props":{}}
\ No newline at end of file
diff --git a/quickstep/res/values-af/strings.xml b/quickstep/res/values-af/strings.xml
index 48aec13..e1f52e7 100644
--- a/quickstep/res/values-af/strings.xml
+++ b/quickstep/res/values-af/strings.xml
@@ -21,6 +21,8 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Speld vas"</string>
     <string name="recent_task_option_freeform" msgid="48863056265284071">"Vormvry"</string>
+    <!-- no translation found for recent_task_option_desktop (8280879717125435668) -->
+    <skip />
     <string name="recents_empty_message" msgid="7040467240571714191">"Geen onlangse items nie"</string>
     <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Programgebruikinstellings"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Vee alles uit"</string>
@@ -93,7 +95,7 @@
     <string name="default_device_name" msgid="6660656727127422487">"toestel"</string>
     <string name="allset_navigation_settings" msgid="4713404605961476027"><annotation id="link">"Stelselnavigasie-instellings"</annotation></string>
     <string name="action_share" msgid="2648470652637092375">"Deel"</string>
-    <string name="action_screenshot" msgid="8171125848358142917">"Skermkiekie"</string>
+    <string name="action_screenshot" msgid="8171125848358142917">"Skermskoot"</string>
     <string name="action_split" msgid="2098009717623550676">"Verdeel"</string>
     <string name="action_save_app_pair" msgid="5974823919237645229">"Stoor app-paar"</string>
     <string name="toast_split_select_app" msgid="8464310533320556058">"Tik op ’n ander app om verdeelde skerm te gebruik"</string>
@@ -116,6 +118,8 @@
     <string name="taskbar_edu_features" msgid="3320337287472848162">"Doen meer met die Taakbalk"</string>
     <string name="taskbar_edu_pinning_title" msgid="210102174154211712">"Wys altyd die Taakbalk"</string>
     <string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"Raak en hou die verdeler in om altyd die Taakbalk onderaan jou skerm te wys"</string>
+    <string name="taskbar_edu_circle_to_search_title" msgid="4322780398403949508">"Raak en hou die aksiesleutel om te soek wat op jou skerm is"</string>
+    <string name="taskbar_edu_circle_to_search_disclosure" msgid="5841648785867787221">"Hierdie produk gebruik die deel van jou skerm wat gekies is om te soek. Google se <xliff:g id="BEGIN_PRIVACY_LINK">&lt;a href="%1$s"&gt;</xliff:g>privaatheidsbeleid<xliff:g id="END_PRIVACY_LINK">&lt;/a&gt;</xliff:g> en <xliff:g id="BEGIN_TOS_LINK">&lt;a href="%2$s"&gt;</xliff:g>diensbepalings<xliff:g id="END_TOS_LINK">&lt;/a&gt;</xliff:g> geld."</string>
     <string name="taskbar_edu_close" msgid="887022990168191073">"Maak toe"</string>
     <string name="taskbar_edu_done" msgid="6880178093977704569">"Klaar"</string>
     <string name="taskbar_button_home" msgid="2151398979630664652">"Tuis"</string>
diff --git a/quickstep/res/values-am/strings.xml b/quickstep/res/values-am/strings.xml
index 1942a74..959d06c 100644
--- a/quickstep/res/values-am/strings.xml
+++ b/quickstep/res/values-am/strings.xml
@@ -21,6 +21,8 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_pin" msgid="7929860679018978258">"ሰካ"</string>
     <string name="recent_task_option_freeform" msgid="48863056265284071">"ነፃ ቅጽ"</string>
+    <!-- no translation found for recent_task_option_desktop (8280879717125435668) -->
+    <skip />
     <string name="recents_empty_message" msgid="7040467240571714191">"ምንም የቅርብ ጊዜ ንጥሎች የሉም"</string>
     <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"የመተግበሪያ አጠቃቀም ቅንብሮች"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"ሁሉንም አጽዳ"</string>
@@ -116,6 +118,8 @@
     <string name="taskbar_edu_features" msgid="3320337287472848162">"በተግባር አሞሌው ተጨማሪ ነገር ያድርጉ"</string>
     <string name="taskbar_edu_pinning_title" msgid="210102174154211712">"የተግባር አሞሌውን ሁልጊዜ አሳይ"</string>
     <string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"በማያ ገጽዎ ግርጌ ላይ ያለውን የተግባር አሞሌ ሁልጊዜ ለማሳየት፣ መክፈያን ይንኩ እና ይያዙ"</string>
+    <string name="taskbar_edu_circle_to_search_title" msgid="4322780398403949508">"በማያ ገጽዎ ላይ ያለውን ነገር ለመፈለግ የተግባር ቁልፉን ነክተው ይያዙ"</string>
+    <string name="taskbar_edu_circle_to_search_disclosure" msgid="5841648785867787221">"ይህ ምርት የተመረጠውን የማያ ገጽዎን ክፍል ለመፈለግ ይጠቀማል። የGoogle <xliff:g id="BEGIN_PRIVACY_LINK">&lt;a href="%1$s"&gt;</xliff:g>የግላዊነት መመሪያ<xliff:g id="END_PRIVACY_LINK">&lt;/a&gt;</xliff:g> እና <xliff:g id="BEGIN_TOS_LINK">&lt;a href="%2$s"&gt;</xliff:g>የአገልግሎት ውል<xliff:g id="END_TOS_LINK">&lt;/a&gt;</xliff:g> ተፈጻሚ ናቸው።"</string>
     <string name="taskbar_edu_close" msgid="887022990168191073">"ዝጋ"</string>
     <string name="taskbar_edu_done" msgid="6880178093977704569">"ተጠናቅቋል"</string>
     <string name="taskbar_button_home" msgid="2151398979630664652">"መነሻ"</string>
diff --git a/quickstep/res/values-ar/strings.xml b/quickstep/res/values-ar/strings.xml
index 9b68f49..2eaea0c 100644
--- a/quickstep/res/values-ar/strings.xml
+++ b/quickstep/res/values-ar/strings.xml
@@ -21,7 +21,9 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_pin" msgid="7929860679018978258">"تثبيت"</string>
     <string name="recent_task_option_freeform" msgid="48863056265284071">"شكل مجاني"</string>
-    <string name="recents_empty_message" msgid="7040467240571714191">"ليست هناك عناصر تم استخدامها مؤخرًا"</string>
+    <!-- no translation found for recent_task_option_desktop (8280879717125435668) -->
+    <skip />
+    <string name="recents_empty_message" msgid="7040467240571714191">"ما مِن عناصر تم استخدامها مؤخرًا"</string>
     <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"إعدادات استخدام التطبيق"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"محو الكل"</string>
     <string name="accessibility_recent_apps" msgid="4058661986695117371">"التطبيقات المستخدمة مؤخرًا"</string>
@@ -95,12 +97,12 @@
     <string name="action_share" msgid="2648470652637092375">"مشاركة"</string>
     <string name="action_screenshot" msgid="8171125848358142917">"لقطة شاشة"</string>
     <string name="action_split" msgid="2098009717623550676">"تقسيم"</string>
-    <string name="action_save_app_pair" msgid="5974823919237645229">"حفظ إعدادات الميزة"</string>
+    <string name="action_save_app_pair" msgid="5974823919237645229">"حفظ استخدام التطبيقين معًا"</string>
     <string name="toast_split_select_app" msgid="8464310533320556058">"انقر على تطبيق آخر لاستخدام وضع تقسيم الشاشة."</string>
-    <string name="toast_contextual_split_select_app" msgid="433510957123687090">"اختَر تطبيقًا آخر لاستخدام \"وضع تقسيم الشاشة\"."</string>
+    <string name="toast_contextual_split_select_app" msgid="433510957123687090">"اختَر تطبيقًا آخر لاستخدام \"وضع تقسيم الشاشة\""</string>
     <string name="toast_split_select_app_cancel" msgid="1532690483356445639"><b>"إلغاء"</b></string>
     <string name="toast_split_select_cont_desc" msgid="2119685056059607602">"الخروج من وضع تقسيم الشاشة"</string>
-    <string name="toast_split_app_unsupported" msgid="2360229567007828914">"اختَر تطبيقًا آخر لاستخدام \"وضع تقسيم الشاشة\"."</string>
+    <string name="toast_split_app_unsupported" msgid="2360229567007828914">"اختَر تطبيقًا آخر لاستخدام \"وضع تقسيم الشاشة\""</string>
     <string name="blocked_by_policy" msgid="2071401072261365546">"لا يسمح التطبيق أو لا تسمح مؤسستك بهذا الإجراء."</string>
     <string name="split_widgets_not_supported" msgid="1355743038053053866">"التطبيقات المصغّرة غير متوفّرة حاليًا، يرجى اختيار تطبيق آخر."</string>
     <string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"هل تريد تخطي الدليل التوجيهي للتنقّل؟"</string>
@@ -116,6 +118,8 @@
     <string name="taskbar_edu_features" msgid="3320337287472848162">"إنجاز المزيد باستخدام شريط التطبيقات"</string>
     <string name="taskbar_edu_pinning_title" msgid="210102174154211712">"عرض \"شريط التطبيقات\" دائمًا"</string>
     <string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"انقر مع الاستمرار على أداة تقسيم الشاشة لعرض \"شريط التطبيقات\" دائمًا في أسفل الشاشة."</string>
+    <string name="taskbar_edu_circle_to_search_title" msgid="4322780398403949508">"انقر مع الاستمرار على مفتاح الإجراء للبحث عن المحتوى الذي يظهر على شاشتك"</string>
+    <string name="taskbar_edu_circle_to_search_disclosure" msgid="5841648785867787221">"‏يستخدم هذا المنتج الجزء المحدّد من الشاشة للبحث. تسري <xliff:g id="BEGIN_PRIVACY_LINK">&lt;a href="%1$s"&gt;</xliff:g>سياسة خصوصية<xliff:g id="END_PRIVACY_LINK">&lt;/a&gt;</xliff:g> Google و<xliff:g id="BEGIN_TOS_LINK">&lt;a href="%2$s"&gt;</xliff:g>بنود خدمتها<xliff:g id="END_TOS_LINK">&lt;/a&gt;</xliff:g>."</string>
     <string name="taskbar_edu_close" msgid="887022990168191073">"إغلاق"</string>
     <string name="taskbar_edu_done" msgid="6880178093977704569">"تم"</string>
     <string name="taskbar_button_home" msgid="2151398979630664652">"الرئيسية"</string>
diff --git a/quickstep/res/values-as/strings.xml b/quickstep/res/values-as/strings.xml
index 51068d9..72482ff 100644
--- a/quickstep/res/values-as/strings.xml
+++ b/quickstep/res/values-as/strings.xml
@@ -21,6 +21,8 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_pin" msgid="7929860679018978258">"পিন"</string>
     <string name="recent_task_option_freeform" msgid="48863056265284071">"Freeform"</string>
+    <!-- no translation found for recent_task_option_desktop (8280879717125435668) -->
+    <skip />
     <string name="recents_empty_message" msgid="7040467240571714191">"কোনো শেহতীয়া বস্তু নাই"</string>
     <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"এপে ব্যৱহাৰ কৰা ডেটাৰ ছেটিং"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"আটাইবোৰ মচক"</string>
@@ -116,6 +118,8 @@
     <string name="taskbar_edu_features" msgid="3320337287472848162">"টাস্কবাৰৰ জৰিয়তে অধিক কাৰ্য সম্পাদন কৰক"</string>
     <string name="taskbar_edu_pinning_title" msgid="210102174154211712">"টাস্কবাৰডাল সদায় দেখুৱাওক"</string>
     <string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"আপোনাৰ স্ক্ৰীনৰ তলত সদায় টাস্কবাৰডাল দেখুৱাবলৈ বিভাজকডাল স্পৰ্শ কৰি ধৰি ৰাখক"</string>
+    <string name="taskbar_edu_circle_to_search_title" msgid="4322780398403949508">"আপোনাৰ স্ক্ৰীনখনত থকা সমল সন্ধান কৰিবলৈ কাৰ্য কীটো স্পৰ্শ কৰি ধৰি ৰাখক"</string>
+    <string name="taskbar_edu_circle_to_search_disclosure" msgid="5841648785867787221">"এই প্ৰ’ডাক্টটোৱে সন্ধান কৰিবলৈ আপোনাৰ স্ক্ৰীনখনৰ বাছনি কৰা অংশ ব্যৱহাৰ কৰে। Googleৰ <xliff:g id="BEGIN_PRIVACY_LINK">&lt;a href="%1$s"&gt;</xliff:g>গোপনীয়তাৰ নীতি<xliff:g id="END_PRIVACY_LINK">&lt;/a&gt;</xliff:g> আৰু <xliff:g id="BEGIN_TOS_LINK">&lt;a href="%2$s"&gt;</xliff:g>সেৱাৰ চৰ্তাৱলী<xliff:g id="END_TOS_LINK">&lt;/a&gt;</xliff:g> প্ৰযোজ্য।"</string>
     <string name="taskbar_edu_close" msgid="887022990168191073">"বন্ধ কৰক"</string>
     <string name="taskbar_edu_done" msgid="6880178093977704569">"হ’ল"</string>
     <string name="taskbar_button_home" msgid="2151398979630664652">"গৃহপৃষ্ঠা"</string>
diff --git a/quickstep/res/values-az/strings.xml b/quickstep/res/values-az/strings.xml
index 4b52f0b..68fcb3c 100644
--- a/quickstep/res/values-az/strings.xml
+++ b/quickstep/res/values-az/strings.xml
@@ -21,6 +21,8 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Sancın"</string>
     <string name="recent_task_option_freeform" msgid="48863056265284071">"Sərbəst rejim"</string>
+    <!-- no translation found for recent_task_option_desktop (8280879717125435668) -->
+    <skip />
     <string name="recents_empty_message" msgid="7040467240571714191">"Son elementlər yoxdur"</string>
     <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Tətbiq istifadə ayarları"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Hamısını silin"</string>
@@ -116,6 +118,8 @@
     <string name="taskbar_edu_features" msgid="3320337287472848162">"Tapşırıq paneli ilə daha çox şey edin"</string>
     <string name="taskbar_edu_pinning_title" msgid="210102174154211712">"İşləmə panelini həmişə göstərin"</string>
     <string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"İşləmə panelini həmişə ekranın aşağısında göstərmək üçün ayırıcı üzərinə toxunun və saxlayın"</string>
+    <string name="taskbar_edu_circle_to_search_title" msgid="4322780398403949508">"Ekranda axtarış etmək üçün fəaliyyət açarına toxunub saxlayın"</string>
+    <string name="taskbar_edu_circle_to_search_disclosure" msgid="5841648785867787221">"Bu məhsul axtarış üçün ekranın seçilmiş hissəsindən istifadə edir. Google <xliff:g id="BEGIN_PRIVACY_LINK">&lt;a href="%1$s"&gt;</xliff:g>Məxfilik Siyasəti<xliff:g id="END_PRIVACY_LINK">&lt;/a&gt;</xliff:g> və <xliff:g id="BEGIN_TOS_LINK">&lt;a href="%2$s"&gt;</xliff:g>Xidmət Şərtləri<xliff:g id="END_TOS_LINK">&lt;/a&gt;</xliff:g> tətbiq edilir."</string>
     <string name="taskbar_edu_close" msgid="887022990168191073">"Bağlayın"</string>
     <string name="taskbar_edu_done" msgid="6880178093977704569">"Hazırdır"</string>
     <string name="taskbar_button_home" msgid="2151398979630664652">"Ev"</string>
diff --git a/quickstep/res/values-b+sr+Latn/strings.xml b/quickstep/res/values-b+sr+Latn/strings.xml
index 1afde8f..6fb8f01 100644
--- a/quickstep/res/values-b+sr+Latn/strings.xml
+++ b/quickstep/res/values-b+sr+Latn/strings.xml
@@ -21,6 +21,8 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Zakači"</string>
     <string name="recent_task_option_freeform" msgid="48863056265284071">"Slobodni oblik"</string>
+    <!-- no translation found for recent_task_option_desktop (8280879717125435668) -->
+    <skip />
     <string name="recents_empty_message" msgid="7040467240571714191">"Nema nedavnih stavki"</string>
     <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Podešavanja korišćenja aplikacije"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Obriši sve"</string>
@@ -112,10 +114,12 @@
     <string name="taskbar_edu_splitscreen" msgid="5605512479258053350">"Prevucite na stranu da biste koristili 2 aplikacije odjednom"</string>
     <string name="taskbar_edu_stashing" msgid="5645461372669217294">"Sporo prevucite nagore da biste videli traku zadataka"</string>
     <string name="taskbar_edu_suggestions" msgid="8215044496435527982">"Dobijajte predloge aplikacija na osnovu rutine"</string>
-    <string name="taskbar_edu_pinning" msgid="6708550858580071558">"Dugo pritiskajte razdelnik da biste zakačili traku zadataka"</string>
+    <string name="taskbar_edu_pinning" msgid="6708550858580071558">"Dugo pritisnite razdelnik da biste zakačili traku zadataka"</string>
     <string name="taskbar_edu_features" msgid="3320337287472848162">"Uradite više pomoću trake zadataka"</string>
     <string name="taskbar_edu_pinning_title" msgid="210102174154211712">"Uvek prikazuj traku zadataka"</string>
     <string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"Da bi traka zadataka uvek bila prikazana u dnu ekrana, dodirnite i zadržite razdelnik"</string>
+    <string name="taskbar_edu_circle_to_search_title" msgid="4322780398403949508">"Dodirnite i zadržite taster radnji da biste pretražili ono što je na ekranu"</string>
+    <string name="taskbar_edu_circle_to_search_disclosure" msgid="5841648785867787221">"Ovaj proizvod koristi izabrani deo ekrana za pretragu. Primenjuju se Google <xliff:g id="BEGIN_PRIVACY_LINK">&lt;a href="%1$s"&gt;</xliff:g>politika privatnosti<xliff:g id="END_PRIVACY_LINK">&lt;/a&gt;</xliff:g> i <xliff:g id="BEGIN_TOS_LINK">&lt;a href="%2$s"&gt;</xliff:g>uslovi korišćenja usluge<xliff:g id="END_TOS_LINK">&lt;/a&gt;</xliff:g>."</string>
     <string name="taskbar_edu_close" msgid="887022990168191073">"Zatvori"</string>
     <string name="taskbar_edu_done" msgid="6880178093977704569">"Gotovo"</string>
     <string name="taskbar_button_home" msgid="2151398979630664652">"Početna"</string>
diff --git a/quickstep/res/values-be/strings.xml b/quickstep/res/values-be/strings.xml
index 8d874fd..344a3e6 100644
--- a/quickstep/res/values-be/strings.xml
+++ b/quickstep/res/values-be/strings.xml
@@ -21,6 +21,8 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Замацаваць"</string>
     <string name="recent_task_option_freeform" msgid="48863056265284071">"Адвольная форма"</string>
+    <!-- no translation found for recent_task_option_desktop (8280879717125435668) -->
+    <skip />
     <string name="recents_empty_message" msgid="7040467240571714191">"Няма новых элементаў"</string>
     <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Налады выкарыстання праграмы"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Ачысціць усё"</string>
@@ -116,6 +118,10 @@
     <string name="taskbar_edu_features" msgid="3320337287472848162">"Выкарыстоўвайце магчымасці панэлі задач"</string>
     <string name="taskbar_edu_pinning_title" msgid="210102174154211712">"Замацуйце панэль задач унізе экрана"</string>
     <string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"Для гэтага націсніце на раздзяляльнік і ўтрымлівайце яго"</string>
+    <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
+    <skip />
+    <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
+    <skip />
     <string name="taskbar_edu_close" msgid="887022990168191073">"Закрыць"</string>
     <string name="taskbar_edu_done" msgid="6880178093977704569">"Гатова"</string>
     <string name="taskbar_button_home" msgid="2151398979630664652">"Галоўны экран"</string>
diff --git a/quickstep/res/values-bg/strings.xml b/quickstep/res/values-bg/strings.xml
index be66004..6ae8931 100644
--- a/quickstep/res/values-bg/strings.xml
+++ b/quickstep/res/values-bg/strings.xml
@@ -21,6 +21,8 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Фиксиране"</string>
     <string name="recent_task_option_freeform" msgid="48863056265284071">"Свободна форма"</string>
+    <!-- no translation found for recent_task_option_desktop (8280879717125435668) -->
+    <skip />
     <string name="recents_empty_message" msgid="7040467240571714191">"Няма скорошни елементи"</string>
     <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Настройки за използването на приложенията"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Изчистване на всички"</string>
@@ -95,7 +97,7 @@
     <string name="action_share" msgid="2648470652637092375">"Споделяне"</string>
     <string name="action_screenshot" msgid="8171125848358142917">"Екранна снимка"</string>
     <string name="action_split" msgid="2098009717623550676">"Разделяне на екрана"</string>
-    <string name="action_save_app_pair" msgid="5974823919237645229">"Двойка прил.: Запис"</string>
+    <string name="action_save_app_pair" msgid="5974823919237645229">"Запис на двойка приложения"</string>
     <string name="toast_split_select_app" msgid="8464310533320556058">"Докоснете друго прил., за да ползвате разд. екран"</string>
     <string name="toast_contextual_split_select_app" msgid="433510957123687090">"За разделен екран изберете още едно приложение"</string>
     <string name="toast_split_select_app_cancel" msgid="1532690483356445639"><b>"Отказ"</b></string>
@@ -116,6 +118,10 @@
     <string name="taskbar_edu_features" msgid="3320337287472848162">"Правете повече неща с лентата на задачите"</string>
     <string name="taskbar_edu_pinning_title" msgid="210102174154211712">"Лентата на задачите да се показва винаги"</string>
     <string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"За да фиксирате лентата на задачите най-долу на екрана, докоснете и задръжте разделителя"</string>
+    <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
+    <skip />
+    <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
+    <skip />
     <string name="taskbar_edu_close" msgid="887022990168191073">"Затваряне"</string>
     <string name="taskbar_edu_done" msgid="6880178093977704569">"Готово"</string>
     <string name="taskbar_button_home" msgid="2151398979630664652">"Начало"</string>
diff --git a/quickstep/res/values-bn/strings.xml b/quickstep/res/values-bn/strings.xml
index 7ffbb64..dec05ff 100644
--- a/quickstep/res/values-bn/strings.xml
+++ b/quickstep/res/values-bn/strings.xml
@@ -21,6 +21,8 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_pin" msgid="7929860679018978258">"পিন করুন"</string>
     <string name="recent_task_option_freeform" msgid="48863056265284071">"ফ্রি-ফর্ম"</string>
+    <!-- no translation found for recent_task_option_desktop (8280879717125435668) -->
+    <skip />
     <string name="recents_empty_message" msgid="7040467240571714191">"কোনও সাম্প্রতিক আইটেম নেই"</string>
     <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"অ্যাপ ব্যবহারের সেটিংস"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"সবকিছু খালি করুন"</string>
@@ -116,6 +118,10 @@
     <string name="taskbar_edu_features" msgid="3320337287472848162">"\'টাস্কবার\' ফিচারের সাহায্যে আরও অনেক কিছু করুন"</string>
     <string name="taskbar_edu_pinning_title" msgid="210102174154211712">"টাস্কবার সবসময় দেখানো"</string>
     <string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"স্ক্রিনের নিচে টাস্কবার সবসময় দেখাতে ডিভাইডার টাচ করে ধরে থাকুন"</string>
+    <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
+    <skip />
+    <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
+    <skip />
     <string name="taskbar_edu_close" msgid="887022990168191073">"বন্ধ করুন"</string>
     <string name="taskbar_edu_done" msgid="6880178093977704569">"হয়ে গেছে"</string>
     <string name="taskbar_button_home" msgid="2151398979630664652">"হোম"</string>
diff --git a/quickstep/res/values-bs/strings.xml b/quickstep/res/values-bs/strings.xml
index ccf6c36..83e4935 100644
--- a/quickstep/res/values-bs/strings.xml
+++ b/quickstep/res/values-bs/strings.xml
@@ -21,6 +21,8 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Zakači"</string>
     <string name="recent_task_option_freeform" msgid="48863056265284071">"Slobodan oblik"</string>
+    <!-- no translation found for recent_task_option_desktop (8280879717125435668) -->
+    <skip />
     <string name="recents_empty_message" msgid="7040467240571714191">"Nema nedavnih stavki"</string>
     <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Postavke korištenja aplikacije"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Obriši sve"</string>
@@ -116,6 +118,8 @@
     <string name="taskbar_edu_features" msgid="3320337287472848162">"Uradite više pomoću trake zadataka"</string>
     <string name="taskbar_edu_pinning_title" msgid="210102174154211712">"Stalni prikaz trake zadataka"</string>
     <string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"Da se traka zadataka uvijek prikazuje na dnu ekrana, dodirnite i zadržite razdjelnik"</string>
+    <string name="taskbar_edu_circle_to_search_title" msgid="4322780398403949508">"Dodirnite i zadržite tipku za radnju da biste pretražili što se nalazi na zaslonu"</string>
+    <string name="taskbar_edu_circle_to_search_disclosure" msgid="5841648785867787221">"Ovaj proizvod upotrebljava odabrani dio zaslona za pretraživanje. Primjenjuju se Googleova <xliff:g id="BEGIN_PRIVACY_LINK">&lt;a href="%1$s"&gt;</xliff:g>pravila o privatnosti<xliff:g id="END_PRIVACY_LINK">&lt;/a&gt;</xliff:g> i <xliff:g id="BEGIN_TOS_LINK">&lt;a href="%2$s"&gt;</xliff:g>uvjeti pružanja usluge<xliff:g id="END_TOS_LINK">&lt;/a&gt;</xliff:g>."</string>
     <string name="taskbar_edu_close" msgid="887022990168191073">"Zatvori"</string>
     <string name="taskbar_edu_done" msgid="6880178093977704569">"Gotovo"</string>
     <string name="taskbar_button_home" msgid="2151398979630664652">"Dom"</string>
diff --git a/quickstep/res/values-ca/strings.xml b/quickstep/res/values-ca/strings.xml
index 1cffbdf..d4c7d91 100644
--- a/quickstep/res/values-ca/strings.xml
+++ b/quickstep/res/values-ca/strings.xml
@@ -21,6 +21,8 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Fixa"</string>
     <string name="recent_task_option_freeform" msgid="48863056265284071">"Format lliure"</string>
+    <!-- no translation found for recent_task_option_desktop (8280879717125435668) -->
+    <skip />
     <string name="recents_empty_message" msgid="7040467240571714191">"No hi ha cap element recent"</string>
     <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Configuració d\'ús d\'aplicacions"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Esborra-ho tot"</string>
@@ -116,6 +118,10 @@
     <string name="taskbar_edu_features" msgid="3320337287472848162">"Treu més partit de la Barra de tasques"</string>
     <string name="taskbar_edu_pinning_title" msgid="210102174154211712">"Mostra sempre la Barra de tasques"</string>
     <string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"Perquè es mostri sempre la Barra de tasques a la part inferior de la pantalla, mantén premut el separador"</string>
+    <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
+    <skip />
+    <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
+    <skip />
     <string name="taskbar_edu_close" msgid="887022990168191073">"Tanca"</string>
     <string name="taskbar_edu_done" msgid="6880178093977704569">"Fet"</string>
     <string name="taskbar_button_home" msgid="2151398979630664652">"Inici"</string>
@@ -129,7 +135,7 @@
     <string name="taskbar_a11y_shown_title" msgid="6842833581088937713">"Es mostra la Barra de tasques"</string>
     <string name="taskbar_a11y_hidden_title" msgid="9154903639589659284">"S\'ha amagat la Barra de tasques"</string>
     <string name="taskbar_phone_a11y_title" msgid="4933360237131229395">"Barra de navegació"</string>
-    <string name="always_show_taskbar" msgid="3608801276107751229">"Mostra Barra de tasques"</string>
+    <string name="always_show_taskbar" msgid="3608801276107751229">"Barra de tasques sempre visible"</string>
     <string name="change_navigation_mode" msgid="9088393078736808968">"Canvia el mode de navegació"</string>
     <string name="taskbar_divider_a11y_title" msgid="6608690309720242080">"Separador de la Barra de tasques"</string>
     <string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Mou a la part superior o a l\'esquerra"</string>
diff --git a/quickstep/res/values-cs/strings.xml b/quickstep/res/values-cs/strings.xml
index f3f5777..743fc2b 100644
--- a/quickstep/res/values-cs/strings.xml
+++ b/quickstep/res/values-cs/strings.xml
@@ -21,7 +21,9 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Připnout"</string>
     <string name="recent_task_option_freeform" msgid="48863056265284071">"Neomezený režim"</string>
-    <string name="recents_empty_message" msgid="7040467240571714191">"Žádné nedávné položky"</string>
+    <!-- no translation found for recent_task_option_desktop (8280879717125435668) -->
+    <skip />
+    <string name="recents_empty_message" msgid="7040467240571714191">"Žádné položky z nedávné doby"</string>
     <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Nastavení využití aplikací"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Vymazat vše"</string>
     <string name="accessibility_recent_apps" msgid="4058661986695117371">"Poslední aplikace"</string>
@@ -112,10 +114,14 @@
     <string name="taskbar_edu_splitscreen" msgid="5605512479258053350">"Přetáhněte aplikaci na stranu a používejte tak dvě najednou"</string>
     <string name="taskbar_edu_stashing" msgid="5645461372669217294">"Panel aplikací zobrazíte pomalým přejetím prstem nahoru"</string>
     <string name="taskbar_edu_suggestions" msgid="8215044496435527982">"Dostávejte návrhy aplikací podle toho, jaké používáte"</string>
-    <string name="taskbar_edu_pinning" msgid="6708550858580071558">"Dlouhým stisknutím oddělovače připnete panel aplikací"</string>
+    <string name="taskbar_edu_pinning" msgid="6708550858580071558">"Dlouhým stisknutím oddělovače panel aplikací připnete"</string>
     <string name="taskbar_edu_features" msgid="3320337287472848162">"Více možností s panelem aplikací"</string>
     <string name="taskbar_edu_pinning_title" msgid="210102174154211712">"Stálé zobrazení panelu aplikací"</string>
     <string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"Pokud chcete, aby se panel aplikací vždy zobrazoval ve spodní části obrazovky, podržte oddělovač."</string>
+    <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
+    <skip />
+    <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
+    <skip />
     <string name="taskbar_edu_close" msgid="887022990168191073">"Zavřít"</string>
     <string name="taskbar_edu_done" msgid="6880178093977704569">"Hotovo"</string>
     <string name="taskbar_button_home" msgid="2151398979630664652">"Domů"</string>
diff --git a/quickstep/res/values-da/strings.xml b/quickstep/res/values-da/strings.xml
index 623a0b7..cfe55cf 100644
--- a/quickstep/res/values-da/strings.xml
+++ b/quickstep/res/values-da/strings.xml
@@ -21,6 +21,8 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Fastgør"</string>
     <string name="recent_task_option_freeform" msgid="48863056265284071">"Frit format"</string>
+    <!-- no translation found for recent_task_option_desktop (8280879717125435668) -->
+    <skip />
     <string name="recents_empty_message" msgid="7040467240571714191">"Ingen nye elementer"</string>
     <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Indstillinger for appforbrug"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Ryd alt"</string>
@@ -116,6 +118,10 @@
     <string name="taskbar_edu_features" msgid="3320337287472848162">"Få mere fra hånden med proceslinjen"</string>
     <string name="taskbar_edu_pinning_title" msgid="210102174154211712">"Vis altid proceslinjen"</string>
     <string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"Hvis du vil have, at proceslinjen altid vises nederst på din skærm, skal du holde fingeren på skillelinjen"</string>
+    <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
+    <skip />
+    <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
+    <skip />
     <string name="taskbar_edu_close" msgid="887022990168191073">"Luk"</string>
     <string name="taskbar_edu_done" msgid="6880178093977704569">"Luk"</string>
     <string name="taskbar_button_home" msgid="2151398979630664652">"Hjem"</string>
diff --git a/quickstep/res/values-de/strings.xml b/quickstep/res/values-de/strings.xml
index c4371ee..1d012bb 100644
--- a/quickstep/res/values-de/strings.xml
+++ b/quickstep/res/values-de/strings.xml
@@ -21,6 +21,8 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Fixieren"</string>
     <string name="recent_task_option_freeform" msgid="48863056265284071">"Freeform-Modus"</string>
+    <!-- no translation found for recent_task_option_desktop (8280879717125435668) -->
+    <skip />
     <string name="recents_empty_message" msgid="7040467240571714191">"Keine kürzlich verwendeten Elemente"</string>
     <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Einstellungen zur App-Nutzung"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Alle Apps schließen"</string>
@@ -116,6 +118,10 @@
     <string name="taskbar_edu_features" msgid="3320337287472848162">"Mehr Möglichkeiten mit der Taskleiste"</string>
     <string name="taskbar_edu_pinning_title" msgid="210102174154211712">"Taskleiste immer anzeigen"</string>
     <string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"Damit die Taskleiste immer unten angezeigt wird, halte den Teiler gedrückt"</string>
+    <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
+    <skip />
+    <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
+    <skip />
     <string name="taskbar_edu_close" msgid="887022990168191073">"Schließen"</string>
     <string name="taskbar_edu_done" msgid="6880178093977704569">"Fertig"</string>
     <string name="taskbar_button_home" msgid="2151398979630664652">"Startbildschirm"</string>
diff --git a/quickstep/res/values-el/strings.xml b/quickstep/res/values-el/strings.xml
index 69f1718..ae3bef8 100644
--- a/quickstep/res/values-el/strings.xml
+++ b/quickstep/res/values-el/strings.xml
@@ -21,6 +21,8 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Καρφίτσωμα"</string>
     <string name="recent_task_option_freeform" msgid="48863056265284071">"Ελεύθερη μορφή"</string>
+    <!-- no translation found for recent_task_option_desktop (8280879717125435668) -->
+    <skip />
     <string name="recents_empty_message" msgid="7040467240571714191">"Δεν υπάρχουν πρόσφατα στοιχεία"</string>
     <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Ρυθμίσεις χρήσης εφαρμογής"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Διαγραφή όλων"</string>
@@ -116,6 +118,10 @@
     <string name="taskbar_edu_features" msgid="3320337287472848162">"Κάντε περισσότερα με τη Γραμμή εργαλείων"</string>
     <string name="taskbar_edu_pinning_title" msgid="210102174154211712">"Να εμφανίζεται πάντα η Γραμμή εργαλείων"</string>
     <string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"Για να εμφανίζεται πάντα η Γραμμή εργαλείων στο κάτω μέρος της οθόνης, αγγίξτε παρατεταμένα το διαχωριστικό"</string>
+    <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
+    <skip />
+    <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
+    <skip />
     <string name="taskbar_edu_close" msgid="887022990168191073">"Κλείσιμο"</string>
     <string name="taskbar_edu_done" msgid="6880178093977704569">"Τέλος"</string>
     <string name="taskbar_button_home" msgid="2151398979630664652">"Αρχική σελίδα"</string>
diff --git a/quickstep/res/values-en-rAU/strings.xml b/quickstep/res/values-en-rAU/strings.xml
index aa119ed..fea224b 100644
--- a/quickstep/res/values-en-rAU/strings.xml
+++ b/quickstep/res/values-en-rAU/strings.xml
@@ -21,6 +21,8 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Pin"</string>
     <string name="recent_task_option_freeform" msgid="48863056265284071">"Freeform"</string>
+    <!-- no translation found for recent_task_option_desktop (8280879717125435668) -->
+    <skip />
     <string name="recents_empty_message" msgid="7040467240571714191">"No recent items"</string>
     <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"App usage settings"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Clear all"</string>
@@ -116,6 +118,10 @@
     <string name="taskbar_edu_features" msgid="3320337287472848162">"Do more with the Taskbar"</string>
     <string name="taskbar_edu_pinning_title" msgid="210102174154211712">"Always show the Taskbar"</string>
     <string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"To always show the Taskbar on the bottom of your screen, touch and hold the divider"</string>
+    <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
+    <skip />
+    <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
+    <skip />
     <string name="taskbar_edu_close" msgid="887022990168191073">"Close"</string>
     <string name="taskbar_edu_done" msgid="6880178093977704569">"Done"</string>
     <string name="taskbar_button_home" msgid="2151398979630664652">"Home"</string>
diff --git a/quickstep/res/values-en-rCA/strings.xml b/quickstep/res/values-en-rCA/strings.xml
index 8da2f2d..37f4bce 100644
--- a/quickstep/res/values-en-rCA/strings.xml
+++ b/quickstep/res/values-en-rCA/strings.xml
@@ -21,6 +21,8 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Pin"</string>
     <string name="recent_task_option_freeform" msgid="48863056265284071">"Freeform"</string>
+    <!-- no translation found for recent_task_option_desktop (8280879717125435668) -->
+    <skip />
     <string name="recents_empty_message" msgid="7040467240571714191">"No recent items"</string>
     <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"App usage settings"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Clear all"</string>
@@ -116,6 +118,8 @@
     <string name="taskbar_edu_features" msgid="3320337287472848162">"Do more with the Taskbar"</string>
     <string name="taskbar_edu_pinning_title" msgid="210102174154211712">"Always show the Taskbar"</string>
     <string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"To always show the Taskbar on the bottom of your screen, touch &amp; hold the divider"</string>
+    <string name="taskbar_edu_circle_to_search_title" msgid="4322780398403949508">"Touch &amp; hold the action key to search what\'s on your screen"</string>
+    <string name="taskbar_edu_circle_to_search_disclosure" msgid="5841648785867787221">"This product uses the selected part of your screen to search. Google\'s <xliff:g id="BEGIN_PRIVACY_LINK">&lt;a href="%1$s"&gt;</xliff:g>Privacy Policy<xliff:g id="END_PRIVACY_LINK">&lt;/a&gt;</xliff:g> and <xliff:g id="BEGIN_TOS_LINK">&lt;a href="%2$s"&gt;</xliff:g>Terms of Service<xliff:g id="END_TOS_LINK">&lt;/a&gt;</xliff:g> apply."</string>
     <string name="taskbar_edu_close" msgid="887022990168191073">"Close"</string>
     <string name="taskbar_edu_done" msgid="6880178093977704569">"Done"</string>
     <string name="taskbar_button_home" msgid="2151398979630664652">"Home"</string>
diff --git a/quickstep/res/values-en-rGB/strings.xml b/quickstep/res/values-en-rGB/strings.xml
index aa119ed..fea224b 100644
--- a/quickstep/res/values-en-rGB/strings.xml
+++ b/quickstep/res/values-en-rGB/strings.xml
@@ -21,6 +21,8 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Pin"</string>
     <string name="recent_task_option_freeform" msgid="48863056265284071">"Freeform"</string>
+    <!-- no translation found for recent_task_option_desktop (8280879717125435668) -->
+    <skip />
     <string name="recents_empty_message" msgid="7040467240571714191">"No recent items"</string>
     <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"App usage settings"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Clear all"</string>
@@ -116,6 +118,10 @@
     <string name="taskbar_edu_features" msgid="3320337287472848162">"Do more with the Taskbar"</string>
     <string name="taskbar_edu_pinning_title" msgid="210102174154211712">"Always show the Taskbar"</string>
     <string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"To always show the Taskbar on the bottom of your screen, touch and hold the divider"</string>
+    <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
+    <skip />
+    <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
+    <skip />
     <string name="taskbar_edu_close" msgid="887022990168191073">"Close"</string>
     <string name="taskbar_edu_done" msgid="6880178093977704569">"Done"</string>
     <string name="taskbar_button_home" msgid="2151398979630664652">"Home"</string>
diff --git a/quickstep/res/values-en-rIN/strings.xml b/quickstep/res/values-en-rIN/strings.xml
index aa119ed..fea224b 100644
--- a/quickstep/res/values-en-rIN/strings.xml
+++ b/quickstep/res/values-en-rIN/strings.xml
@@ -21,6 +21,8 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Pin"</string>
     <string name="recent_task_option_freeform" msgid="48863056265284071">"Freeform"</string>
+    <!-- no translation found for recent_task_option_desktop (8280879717125435668) -->
+    <skip />
     <string name="recents_empty_message" msgid="7040467240571714191">"No recent items"</string>
     <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"App usage settings"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Clear all"</string>
@@ -116,6 +118,10 @@
     <string name="taskbar_edu_features" msgid="3320337287472848162">"Do more with the Taskbar"</string>
     <string name="taskbar_edu_pinning_title" msgid="210102174154211712">"Always show the Taskbar"</string>
     <string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"To always show the Taskbar on the bottom of your screen, touch and hold the divider"</string>
+    <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
+    <skip />
+    <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
+    <skip />
     <string name="taskbar_edu_close" msgid="887022990168191073">"Close"</string>
     <string name="taskbar_edu_done" msgid="6880178093977704569">"Done"</string>
     <string name="taskbar_button_home" msgid="2151398979630664652">"Home"</string>
diff --git a/quickstep/res/values-en-rXC/strings.xml b/quickstep/res/values-en-rXC/strings.xml
index 42223fe..c64c495 100644
--- a/quickstep/res/values-en-rXC/strings.xml
+++ b/quickstep/res/values-en-rXC/strings.xml
@@ -21,6 +21,8 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_pin" msgid="7929860679018978258">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‏‎‏‏‏‎‎‎‎‎‏‏‎‎‏‎‎‎‎‏‏‎‎‏‎‎‎‏‎‏‏‏‏‏‏‎‏‏‎‏‎‎‎‎‏‏‏‎‎‏‏‎‏‏‏‏‎‏‎‎‏‎‎Pin‎‏‎‎‏‎"</string>
     <string name="recent_task_option_freeform" msgid="48863056265284071">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‎‎‎‏‎‏‎‏‏‎‏‏‎‎‏‏‎‎‎‏‎‏‏‎‎‎‎‏‏‎‏‎‏‏‏‎‏‎‏‎‏‎‏‎‎‎‎‏‎‎‏‏‏‏‎‎‏‏‏‎Freeform‎‏‎‎‏‎"</string>
+    <!-- no translation found for recent_task_option_desktop (8280879717125435668) -->
+    <skip />
     <string name="recents_empty_message" msgid="7040467240571714191">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‏‏‎‏‏‎‏‎‎‏‏‎‎‎‎‏‏‏‎‏‎‎‏‏‏‎‎‏‏‏‏‏‏‎‎‎‎‏‏‎‏‎‎‏‏‏‎‏‎‏‎‎‎‏‏‏‏‎No recent items‎‏‎‎‏‎"</string>
     <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‏‎‏‏‏‏‎‎‏‏‎‏‏‏‏‎‎‏‏‎‎‏‎‎‏‎‎‏‎‏‏‎‏‎‎‏‏‎‏‏‎‎‎‎‏‎‏‎‏‎‎‎‏‏‏‎‏‎‏‎‏‎App usage settings‎‏‎‎‏‎"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‎‏‎‎‏‏‏‏‏‎‎‎‏‎‏‏‏‏‏‎‎‏‎‎‏‎‎‎‎‎‏‎‏‏‏‎‏‎‎‎‏‎‏‏‎‎‏‎‏‏‏‎‎‎‏‏‏‏‏‏‏‎Clear all‎‏‎‎‏‎"</string>
@@ -116,6 +118,8 @@
     <string name="taskbar_edu_features" msgid="3320337287472848162">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‎‏‏‏‎‎‎‎‏‎‏‎‎‎‎‏‏‎‏‎‏‎‎‏‎‏‎‏‏‏‏‎‎‏‎‏‎‎‏‎‎‏‏‎‏‏‎‎‏‏‏‎‏‎‎‏‎‎‎‏‎‎Do more with the Taskbar‎‏‎‎‏‎"</string>
     <string name="taskbar_edu_pinning_title" msgid="210102174154211712">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‎‏‎‏‎‏‏‏‎‏‎‏‎‎‏‏‎‏‏‏‎‏‏‎‏‎‎‎‎‎‏‏‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‏‏‎‎‎‎‎‎‎‎Always show the Taskbar‎‏‎‎‏‎"</string>
     <string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‎‎‏‎‎‏‎‎‏‏‎‎‎‎‎‏‏‏‎‎‎‎‏‎‎‏‎‏‎‎‏‏‏‏‎‏‎‏‏‏‎‏‎‏‏‎‏‏‎‏‏‏‎‏‏‏‎‎‎‏‏‎To always show the Taskbar on the bottom of your screen, touch &amp; hold the divider‎‏‎‎‏‎"</string>
+    <string name="taskbar_edu_circle_to_search_title" msgid="4322780398403949508">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‏‏‎‏‏‏‏‏‏‏‏‎‏‏‎‎‏‏‎‎‏‏‏‎‏‏‏‏‎‏‎‎‎‏‎‎‎‏‏‏‎‎‎‏‏‏‎‎‏‎‎‏‏‏‏‎‎‎‏‎‎‎Touch &amp; hold the action key to search what\'s on your screen‎‏‎‎‏‎"</string>
+    <string name="taskbar_edu_circle_to_search_disclosure" msgid="5841648785867787221">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‏‎‎‎‏‎‎‎‏‎‎‎‏‏‎‏‏‎‏‎‎‏‎‎‏‏‏‏‎‏‏‎‏‎‎‎‎‎‎‏‏‏‏‎‏‏‏‎‎‏‎‏‏‏‏‎‏‎‏‎‏‎This product uses the selected part of your screen to search. Google\'s ‎‏‎‎‏‏‎<xliff:g id="BEGIN_PRIVACY_LINK">&lt;a href="%1$s"&gt;</xliff:g>‎‏‎‎‏‏‏‎Privacy Policy‎‏‎‎‏‏‎<xliff:g id="END_PRIVACY_LINK">&lt;/a&gt;</xliff:g>‎‏‎‎‏‏‏‎ and ‎‏‎‎‏‏‎<xliff:g id="BEGIN_TOS_LINK">&lt;a href="%2$s"&gt;</xliff:g>‎‏‎‎‏‏‏‎Terms of Service‎‏‎‎‏‏‎<xliff:g id="END_TOS_LINK">&lt;/a&gt;</xliff:g>‎‏‎‎‏‏‏‎ apply.‎‏‎‎‏‎"</string>
     <string name="taskbar_edu_close" msgid="887022990168191073">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‎‎‏‏‎‎‎‏‎‎‏‏‏‏‎‏‎‏‎‏‏‎‏‎‏‏‎‏‎‏‏‎‏‏‏‏‎‎‏‎‎‏‎‏‎‎‎‏‏‏‎‎‎‎‎‏‏‎‎‎‎‏‎Close‎‏‎‎‏‎"</string>
     <string name="taskbar_edu_done" msgid="6880178093977704569">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‏‏‏‏‏‎‏‏‏‏‎‏‏‎‏‎‎‏‏‎‏‏‎‎‎‎‏‏‎‎‎‎‏‎‎‏‎‏‏‏‏‎‏‏‏‎‎‎‏‏‎‎‎‎‏‏‏‏‎‎‏‎Done‎‏‎‎‏‎"</string>
     <string name="taskbar_button_home" msgid="2151398979630664652">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‎‏‏‏‏‎‏‏‏‎‏‏‎‏‏‎‏‎‎‏‏‎‏‏‏‏‏‏‎‎‏‎‎‏‎‏‏‏‏‎‎‎‎‎‏‏‎‎‎‎‎‏‎‏‏‏‏‎‎‏‏‎‎‎Home‎‏‎‎‏‎"</string>
diff --git a/quickstep/res/values-es-rUS/strings.xml b/quickstep/res/values-es-rUS/strings.xml
index 580a8df..244c23f 100644
--- a/quickstep/res/values-es-rUS/strings.xml
+++ b/quickstep/res/values-es-rUS/strings.xml
@@ -21,6 +21,8 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Fijar"</string>
     <string name="recent_task_option_freeform" msgid="48863056265284071">"Formato libre"</string>
+    <!-- no translation found for recent_task_option_desktop (8280879717125435668) -->
+    <skip />
     <string name="recents_empty_message" msgid="7040467240571714191">"No hay elementos recientes"</string>
     <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Configuración de uso de la app"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Cerrar todo"</string>
@@ -116,6 +118,10 @@
     <string name="taskbar_edu_features" msgid="3320337287472848162">"Aprovecha mejor la Barra de tareas"</string>
     <string name="taskbar_edu_pinning_title" msgid="210102174154211712">"Mostrar siempre la Barra de tareas"</string>
     <string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"Mantén presionado el divisor para mostrar siempre la Barra de tareas en la parte inferior de la pantalla"</string>
+    <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
+    <skip />
+    <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
+    <skip />
     <string name="taskbar_edu_close" msgid="887022990168191073">"Cerrar"</string>
     <string name="taskbar_edu_done" msgid="6880178093977704569">"Listo"</string>
     <string name="taskbar_button_home" msgid="2151398979630664652">"Botón de inicio"</string>
@@ -129,7 +135,7 @@
     <string name="taskbar_a11y_shown_title" msgid="6842833581088937713">"Barra de tareas visible"</string>
     <string name="taskbar_a11y_hidden_title" msgid="9154903639589659284">"Barra de tareas oculta"</string>
     <string name="taskbar_phone_a11y_title" msgid="4933360237131229395">"Barra de navegación"</string>
-    <string name="always_show_taskbar" msgid="3608801276107751229">"Ver siempre Barra de tareas"</string>
+    <string name="always_show_taskbar" msgid="3608801276107751229">"Barra de tareas visible"</string>
     <string name="change_navigation_mode" msgid="9088393078736808968">"Cambiar el modo de navegación"</string>
     <string name="taskbar_divider_a11y_title" msgid="6608690309720242080">"Divisor de la Barra de tareas"</string>
     <string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Mover a la parte superior o izquierda"</string>
diff --git a/quickstep/res/values-es/strings.xml b/quickstep/res/values-es/strings.xml
index 0900f78..1bab3ac 100644
--- a/quickstep/res/values-es/strings.xml
+++ b/quickstep/res/values-es/strings.xml
@@ -21,6 +21,8 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Fijar"</string>
     <string name="recent_task_option_freeform" msgid="48863056265284071">"Formato libre"</string>
+    <!-- no translation found for recent_task_option_desktop (8280879717125435668) -->
+    <skip />
     <string name="recents_empty_message" msgid="7040467240571714191">"No hay nada reciente"</string>
     <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Ajustes de uso de la aplicación"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Borrar todo"</string>
@@ -116,6 +118,10 @@
     <string name="taskbar_edu_features" msgid="3320337287472848162">"Sácale más partido a la barra de tareas"</string>
     <string name="taskbar_edu_pinning_title" msgid="210102174154211712">"Mostrar siempre la barra de tareas"</string>
     <string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"Para mostrar siempre la barra de tareas en la parte inferior, mantén pulsada la línea divisoria"</string>
+    <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
+    <skip />
+    <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
+    <skip />
     <string name="taskbar_edu_close" msgid="887022990168191073">"Cerrar"</string>
     <string name="taskbar_edu_done" msgid="6880178093977704569">"Hecho"</string>
     <string name="taskbar_button_home" msgid="2151398979630664652">"Inicio"</string>
@@ -129,7 +135,7 @@
     <string name="taskbar_a11y_shown_title" msgid="6842833581088937713">"Barra de tareas visible"</string>
     <string name="taskbar_a11y_hidden_title" msgid="9154903639589659284">"Barra de tareas oculta"</string>
     <string name="taskbar_phone_a11y_title" msgid="4933360237131229395">"Barra de navegación"</string>
-    <string name="always_show_taskbar" msgid="3608801276107751229">"Barra de Tareas visible"</string>
+    <string name="always_show_taskbar" msgid="3608801276107751229">"Barra de tareas visible"</string>
     <string name="change_navigation_mode" msgid="9088393078736808968">"Cambiar el modo de navegación"</string>
     <string name="taskbar_divider_a11y_title" msgid="6608690309720242080">"Divisor de Barra de Tareas"</string>
     <string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Mover arriba/a la izquierda"</string>
diff --git a/quickstep/res/values-et/strings.xml b/quickstep/res/values-et/strings.xml
index 65f02eb..0a587d1 100644
--- a/quickstep/res/values-et/strings.xml
+++ b/quickstep/res/values-et/strings.xml
@@ -21,6 +21,8 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Kinnita"</string>
     <string name="recent_task_option_freeform" msgid="48863056265284071">"Vabavorm"</string>
+    <!-- no translation found for recent_task_option_desktop (8280879717125435668) -->
+    <skip />
     <string name="recents_empty_message" msgid="7040467240571714191">"Hiljutisi üksusi pole"</string>
     <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Rakenduse kasutuse seaded"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Sule kõik"</string>
@@ -116,6 +118,10 @@
     <string name="taskbar_edu_features" msgid="3320337287472848162">"Tehke tegumiriba abil enamat"</string>
     <string name="taskbar_edu_pinning_title" msgid="210102174154211712">"Alati kuvatud tegumiriba"</string>
     <string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"Puudutage pikalt jaoturit, et tegumiriba oleks ekraani allosas alati kuvatud"</string>
+    <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
+    <skip />
+    <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
+    <skip />
     <string name="taskbar_edu_close" msgid="887022990168191073">"Sule"</string>
     <string name="taskbar_edu_done" msgid="6880178093977704569">"Valmis"</string>
     <string name="taskbar_button_home" msgid="2151398979630664652">"Avaleht"</string>
diff --git a/quickstep/res/values-eu/strings.xml b/quickstep/res/values-eu/strings.xml
index 3247785..e10a085 100644
--- a/quickstep/res/values-eu/strings.xml
+++ b/quickstep/res/values-eu/strings.xml
@@ -21,6 +21,8 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Ainguratu"</string>
     <string name="recent_task_option_freeform" msgid="48863056265284071">"Modu librea"</string>
+    <!-- no translation found for recent_task_option_desktop (8280879717125435668) -->
+    <skip />
     <string name="recents_empty_message" msgid="7040467240571714191">"Ez dago azkenaldi honetako ezer"</string>
     <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Aplikazioen erabileraren ezarpenak"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Garbitu guztiak"</string>
@@ -110,12 +112,16 @@
     <string name="accessibility_rotate_button" msgid="4771825231336502943">"Biratu pantaila"</string>
     <string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"Zereginen barra erabiltzeko argibideak"</string>
     <string name="taskbar_edu_splitscreen" msgid="5605512479258053350">"Bi aplikazio batera erabiltzeko, arrastatu bat albo batera"</string>
-    <string name="taskbar_edu_stashing" msgid="5645461372669217294">"Zereginen barra ikusteko, pasatu hatza gora poliki"</string>
+    <string name="taskbar_edu_stashing" msgid="5645461372669217294">"Zereginen barra ikusteko, pasatu hatza gora mantso"</string>
     <string name="taskbar_edu_suggestions" msgid="8215044496435527982">"Jaso aplikazioen iradokizunak erabileran oinarrituta"</string>
     <string name="taskbar_edu_pinning" msgid="6708550858580071558">"Zereginen barra ainguratzeko, sakatu zatitzailea luze"</string>
     <string name="taskbar_edu_features" msgid="3320337287472848162">"Egin gauza gehiago zereginen barrarekin"</string>
     <string name="taskbar_edu_pinning_title" msgid="210102174154211712">"Erakutsi beti zereginen barra"</string>
     <string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"Pantailaren behealdeko zereginen barra beti erakusteko, eduki sakatuta zatitzailea"</string>
+    <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
+    <skip />
+    <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
+    <skip />
     <string name="taskbar_edu_close" msgid="887022990168191073">"Itxi"</string>
     <string name="taskbar_edu_done" msgid="6880178093977704569">"Eginda"</string>
     <string name="taskbar_button_home" msgid="2151398979630664652">"Hasiera"</string>
diff --git a/quickstep/res/values-fa/strings.xml b/quickstep/res/values-fa/strings.xml
index e8d0a00..958eecc 100644
--- a/quickstep/res/values-fa/strings.xml
+++ b/quickstep/res/values-fa/strings.xml
@@ -21,6 +21,8 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_pin" msgid="7929860679018978258">"پین"</string>
     <string name="recent_task_option_freeform" msgid="48863056265284071">"Freeform"</string>
+    <!-- no translation found for recent_task_option_desktop (8280879717125435668) -->
+    <skip />
     <string name="recents_empty_message" msgid="7040467240571714191">"چیز جدیدی اینجا نیست"</string>
     <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"تنظیمات استفاده از برنامه"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"پاک کردن همه"</string>
@@ -116,6 +118,8 @@
     <string name="taskbar_edu_features" msgid="3320337287472848162">"با «نوار وظیفه» می‌توانید کارهای بیشتر انجام دهید"</string>
     <string name="taskbar_edu_pinning_title" msgid="210102174154211712">"همیشه نشان داده شدن «نوار وظیفه»"</string>
     <string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"برای اینکه «نوار وظیفه» همیشه در پایین صفحه نشان داده شود، تقسیم‌کننده را لمس کنید و نگه دارید"</string>
+    <string name="taskbar_edu_circle_to_search_title" msgid="4322780398403949508">"برای جستجوی محتوای صفحه‌نمایش، دکمه کنش را لمس کنید و نگه دارید"</string>
+    <string name="taskbar_edu_circle_to_search_disclosure" msgid="5841648785867787221">"‏این محصول از قسمت انتخاب‌شده صفحه‌نمایش شما برای جستجو استفاده می‌کند. <xliff:g id="BEGIN_PRIVACY_LINK">&lt;a href="%1$s"&gt;</xliff:g>خط‌مشی رازداری<xliff:g id="END_PRIVACY_LINK">&lt;/a&gt;</xliff:g> و <xliff:g id="BEGIN_TOS_LINK">&lt;a href="%2$s"&gt;</xliff:g>شرایط خدمات<xliff:g id="END_TOS_LINK">&lt;/a&gt;</xliff:g> Google اعمال می‌شود."</string>
     <string name="taskbar_edu_close" msgid="887022990168191073">"بستن"</string>
     <string name="taskbar_edu_done" msgid="6880178093977704569">"تمام"</string>
     <string name="taskbar_button_home" msgid="2151398979630664652">"صفحه اصلی"</string>
diff --git a/quickstep/res/values-fi/strings.xml b/quickstep/res/values-fi/strings.xml
index e913f85..d4a0d83 100644
--- a/quickstep/res/values-fi/strings.xml
+++ b/quickstep/res/values-fi/strings.xml
@@ -21,6 +21,8 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Kiinnitä"</string>
     <string name="recent_task_option_freeform" msgid="48863056265284071">"Vapaamuotoinen"</string>
+    <!-- no translation found for recent_task_option_desktop (8280879717125435668) -->
+    <skip />
     <string name="recents_empty_message" msgid="7040467240571714191">"Ei viimeaikaisia kohteita"</string>
     <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Sovelluksen käyttöasetukset"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Poista kaikki"</string>
@@ -109,13 +111,17 @@
     <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Ohita"</string>
     <string name="accessibility_rotate_button" msgid="4771825231336502943">"Käännä näyttö"</string>
     <string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"Tehtäväpalkin ohje"</string>
-    <string name="taskbar_edu_splitscreen" msgid="5605512479258053350">"Vedä sovellus sivuun, ja voit käyttää kahta sovellusta"</string>
+    <string name="taskbar_edu_splitscreen" msgid="5605512479258053350">"Vedä sovellus sivuun ja käytä kahta sovellusta"</string>
     <string name="taskbar_edu_stashing" msgid="5645461372669217294">"Näytä tehtäväpalkki pyyhkäisemällä ylös hitaasti"</string>
-    <string name="taskbar_edu_suggestions" msgid="8215044496435527982">"Sovellussuosituksia käytön perusteella"</string>
+    <string name="taskbar_edu_suggestions" msgid="8215044496435527982">"Vastaanota sovellussuosituksia käytön perusteella"</string>
     <string name="taskbar_edu_pinning" msgid="6708550858580071558">"Kiinnitä tehtäväpalkki painamalla jakajaa pitkään"</string>
     <string name="taskbar_edu_features" msgid="3320337287472848162">"Vinkkejä tehtäväpalkin tehokkaampaan käyttöön"</string>
     <string name="taskbar_edu_pinning_title" msgid="210102174154211712">"Näytä tehtäväpalkki aina"</string>
     <string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"Jos haluat tehtäväpalkin näkyvän aina näytön alaosassa, kosketa jakajaa pitkään"</string>
+    <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
+    <skip />
+    <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
+    <skip />
     <string name="taskbar_edu_close" msgid="887022990168191073">"Sulje"</string>
     <string name="taskbar_edu_done" msgid="6880178093977704569">"Valmis"</string>
     <string name="taskbar_button_home" msgid="2151398979630664652">"Etusivu"</string>
diff --git a/quickstep/res/values-fr-rCA/strings.xml b/quickstep/res/values-fr-rCA/strings.xml
index 6173bee..444bb83 100644
--- a/quickstep/res/values-fr-rCA/strings.xml
+++ b/quickstep/res/values-fr-rCA/strings.xml
@@ -21,6 +21,8 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Épingler"</string>
     <string name="recent_task_option_freeform" msgid="48863056265284071">"Forme libre"</string>
+    <!-- no translation found for recent_task_option_desktop (8280879717125435668) -->
+    <skip />
     <string name="recents_empty_message" msgid="7040467240571714191">"Aucun élément récent"</string>
     <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Paramètres d\'utilisation de l\'application"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Tout effacer"</string>
@@ -116,6 +118,10 @@
     <string name="taskbar_edu_features" msgid="3320337287472848162">"Faites-en plus avec la barre des tâches"</string>
     <string name="taskbar_edu_pinning_title" msgid="210102174154211712">"Toujours afficher la Barre des tâches"</string>
     <string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"Pour toujours afficher la Barre des tâches en bas de l\'écran, maintenez le doigt sur le séparateur"</string>
+    <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
+    <skip />
+    <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
+    <skip />
     <string name="taskbar_edu_close" msgid="887022990168191073">"Fermer"</string>
     <string name="taskbar_edu_done" msgid="6880178093977704569">"OK"</string>
     <string name="taskbar_button_home" msgid="2151398979630664652">"Accueil"</string>
diff --git a/quickstep/res/values-fr/strings.xml b/quickstep/res/values-fr/strings.xml
index a74e7b6..0d70416 100644
--- a/quickstep/res/values-fr/strings.xml
+++ b/quickstep/res/values-fr/strings.xml
@@ -21,6 +21,8 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Épingler"</string>
     <string name="recent_task_option_freeform" msgid="48863056265284071">"Format libre"</string>
+    <!-- no translation found for recent_task_option_desktop (8280879717125435668) -->
+    <skip />
     <string name="recents_empty_message" msgid="7040467240571714191">"Aucun élément récent"</string>
     <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Paramètres de consommation de l\'application"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Tout effacer"</string>
@@ -110,12 +112,16 @@
     <string name="accessibility_rotate_button" msgid="4771825231336502943">"Faire pivoter l\'écran"</string>
     <string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"Fonctionnement de la barre des tâches"</string>
     <string name="taskbar_edu_splitscreen" msgid="5605512479258053350">"Faites glisser une appli sur le côté pour en utiliser 2 à la fois"</string>
-    <string name="taskbar_edu_stashing" msgid="5645461372669217294">"Balayez lentement vers haut pour afficher barre des tâches"</string>
+    <string name="taskbar_edu_stashing" msgid="5645461372669217294">"Balayez lentement vers le haut pour voir la barre des tâches"</string>
     <string name="taskbar_edu_suggestions" msgid="8215044496435527982">"Obtenez des suggestions d\'applis basées sur vos habitudes"</string>
     <string name="taskbar_edu_pinning" msgid="6708550858580071558">"Appui prolongé sur le séparateur pour épingler la barre des tâches"</string>
     <string name="taskbar_edu_features" msgid="3320337287472848162">"Faites-en plus avec la barre des tâches"</string>
     <string name="taskbar_edu_pinning_title" msgid="210102174154211712">"Toujours afficher la barre des tâches"</string>
     <string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"Pour toujours afficher la barre des tâches en bas de votre écran, appuyez sur le séparateur de manière prolongée."</string>
+    <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
+    <skip />
+    <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
+    <skip />
     <string name="taskbar_edu_close" msgid="887022990168191073">"Fermer"</string>
     <string name="taskbar_edu_done" msgid="6880178093977704569">"OK"</string>
     <string name="taskbar_button_home" msgid="2151398979630664652">"Accueil"</string>
@@ -134,7 +140,7 @@
     <string name="taskbar_divider_a11y_title" msgid="6608690309720242080">"Séparateur de barre des tâches"</string>
     <string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Déplacer en haut ou à gauche"</string>
     <string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"Déplacer en bas ou à droite"</string>
-    <string name="quick_switch_overflow" msgid="6935266023013283353">"{count,plural, =1{Afficher # autre appli.}one{Afficher # autre appli.}other{Afficher # autre applis.}}"</string>
+    <string name="quick_switch_overflow" msgid="6935266023013283353">"{count,plural, =1{Afficher # autre appli}one{Afficher # autre appli}other{Afficher # autre applis}}"</string>
     <string name="quick_switch_split_task" msgid="5598194724255333896">"<xliff:g id="APP_NAME_1">%1$s</xliff:g> et <xliff:g id="APP_NAME_2">%2$s</xliff:g>"</string>
     <string name="desktop_select_app_toast" msgid="2306057322833956910">"Ajout de l\'appli au bureau"</string>
     <string name="desktop_button_close_app_toast" msgid="5283096349579408560">"Annuler"</string>
diff --git a/quickstep/res/values-gl/strings.xml b/quickstep/res/values-gl/strings.xml
index 9875823..eadd73d 100644
--- a/quickstep/res/values-gl/strings.xml
+++ b/quickstep/res/values-gl/strings.xml
@@ -21,6 +21,8 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Fixar"</string>
     <string name="recent_task_option_freeform" msgid="48863056265284071">"Forma libre"</string>
+    <!-- no translation found for recent_task_option_desktop (8280879717125435668) -->
+    <skip />
     <string name="recents_empty_message" msgid="7040467240571714191">"Non hai elementos recentes"</string>
     <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Configuración do uso de aplicacións"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Borrar todo"</string>
@@ -112,10 +114,14 @@
     <string name="taskbar_edu_splitscreen" msgid="5605512479258053350">"Arrastra unha aplicación cara a un lado para usar dúas á vez"</string>
     <string name="taskbar_edu_stashing" msgid="5645461372669217294">"Pasa o dedo amodo cara arriba para ver a barra de tarefas"</string>
     <string name="taskbar_edu_suggestions" msgid="8215044496435527982">"Obtén suxestións de aplicacións en función da túa rutina"</string>
-    <string name="taskbar_edu_pinning" msgid="6708550858580071558">"Mantén premida a liña divisoria para fixar a Barra de tarefas"</string>
+    <string name="taskbar_edu_pinning" msgid="6708550858580071558">"Mantén premida a liña divisoria para fixar a barra de tarefas"</string>
     <string name="taskbar_edu_features" msgid="3320337287472848162">"Tira máis proveito da barra de tarefas"</string>
     <string name="taskbar_edu_pinning_title" msgid="210102174154211712">"Mostrar sempre a barra de tarefas"</string>
     <string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"Para fixar a barra de tarefas na parte inferior, mantén premida a liña divisoria"</string>
+    <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
+    <skip />
+    <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
+    <skip />
     <string name="taskbar_edu_close" msgid="887022990168191073">"Pechar"</string>
     <string name="taskbar_edu_done" msgid="6880178093977704569">"Listo"</string>
     <string name="taskbar_button_home" msgid="2151398979630664652">"Inicio"</string>
diff --git a/quickstep/res/values-gu/strings.xml b/quickstep/res/values-gu/strings.xml
index 0e6f237..644240a 100644
--- a/quickstep/res/values-gu/strings.xml
+++ b/quickstep/res/values-gu/strings.xml
@@ -21,6 +21,8 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_pin" msgid="7929860679018978258">"પિન કરો"</string>
     <string name="recent_task_option_freeform" msgid="48863056265284071">"ફ્રિફોર્મ"</string>
+    <!-- no translation found for recent_task_option_desktop (8280879717125435668) -->
+    <skip />
     <string name="recents_empty_message" msgid="7040467240571714191">"તાજેતરની કોઈ આઇટમ નથી"</string>
     <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"ઍપ વપરાશનું સેટિંગ"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"બધું સાફ કરો"</string>
@@ -116,6 +118,8 @@
     <string name="taskbar_edu_features" msgid="3320337287472848162">"ટાસ્કબાર વડે બીજું ઘણું કરો"</string>
     <string name="taskbar_edu_pinning_title" msgid="210102174154211712">"ટાસ્કબાર હંમેશાં બતાવો"</string>
     <string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"ટાસ્કબાર હંમેશાં તમારી સ્ક્રીનમાં સૌથી નીચે દેખાય તે માટે વિભાજકને ટચ કરીને થોડીવાર દબાવી રાખો"</string>
+    <string name="taskbar_edu_circle_to_search_title" msgid="4322780398403949508">"તમારી સ્ક્રીન પર જે હોય તે શોધવા માટે, ઍક્શન કી ટચ કરીને દબાવી રાખો"</string>
+    <string name="taskbar_edu_circle_to_search_disclosure" msgid="5841648785867787221">"શોધવા માટે, આ પ્રોડક્ટ તમારી સ્ક્રીનના પસંદ કરેલા ભાગનો ઉપયોગ કરે છે. Googleની <xliff:g id="BEGIN_PRIVACY_LINK">&lt;a href="%1$s"&gt;</xliff:g>પ્રાઇવસી પૉલિસી<xliff:g id="END_PRIVACY_LINK">&lt;/a&gt;</xliff:g> અને <xliff:g id="BEGIN_TOS_LINK">&lt;a href="%2$s"&gt;</xliff:g>સેવાની શરતો<xliff:g id="END_TOS_LINK">&lt;/a&gt;</xliff:g> લાગુ થાય છે."</string>
     <string name="taskbar_edu_close" msgid="887022990168191073">"બંધ કરો"</string>
     <string name="taskbar_edu_done" msgid="6880178093977704569">"થઈ ગયું"</string>
     <string name="taskbar_button_home" msgid="2151398979630664652">"હોમ"</string>
diff --git a/quickstep/res/values-hi/strings.xml b/quickstep/res/values-hi/strings.xml
index 368cc0a..b2da5db 100644
--- a/quickstep/res/values-hi/strings.xml
+++ b/quickstep/res/values-hi/strings.xml
@@ -21,9 +21,11 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_pin" msgid="7929860679018978258">"पिन करें"</string>
     <string name="recent_task_option_freeform" msgid="48863056265284071">"फ़्रीफ़ॉर्म"</string>
-    <string name="recents_empty_message" msgid="7040467240571714191">"हाल ही में इस्तेमाल किया गया कोई ऐप्लिकेशन नहीं है"</string>
+    <!-- no translation found for recent_task_option_desktop (8280879717125435668) -->
+    <skip />
+    <string name="recents_empty_message" msgid="7040467240571714191">"हाल ही का कोई आइटम नहीं है"</string>
     <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"ऐप्लिकेशन इस्तेमाल की सेटिंग"</string>
-    <string name="recents_clear_all" msgid="5328176793634888831">"सभी ऐप्लिकेशन बंद करें"</string>
+    <string name="recents_clear_all" msgid="5328176793634888831">"सभी हटाएं"</string>
     <string name="accessibility_recent_apps" msgid="4058661986695117371">"हाल ही में इस्तेमाल किए गए ऐप्लिकेशन"</string>
     <string name="task_view_closed" msgid="9170038230110856166">"टास्क बंद किया गया"</string>
     <string name="task_contents_description_with_remaining_time" msgid="4479688746574672685">"<xliff:g id="TASK_DESCRIPTION">%1$s</xliff:g>, <xliff:g id="REMAINING_TIME">%2$s</xliff:g>"</string>
@@ -110,12 +112,14 @@
     <string name="accessibility_rotate_button" msgid="4771825231336502943">"स्क्रीन घुमाएं"</string>
     <string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"टास्कबार का ट्यूटोरियल"</string>
     <string name="taskbar_edu_splitscreen" msgid="5605512479258053350">"किसी ऐप को किनारे की ओर ड्रैग करके 2 ऐप एक साथ इस्तेमाल करें"</string>
-    <string name="taskbar_edu_stashing" msgid="5645461372669217294">"टास्कबार दिखाने के लिए, ऊपर की ओर धीरे से स्वाइप करें"</string>
-    <string name="taskbar_edu_suggestions" msgid="8215044496435527982">"डिवाइस के इस्तेमाल के आधार पर ऐप्लिकेशन के सुझाव पाएं"</string>
+    <string name="taskbar_edu_stashing" msgid="5645461372669217294">"टास्कबार देखने के लिए, ऊपर की ओर धीरे से स्वाइप करें"</string>
+    <string name="taskbar_edu_suggestions" msgid="8215044496435527982">"इस्तेमाल के आधार पर ऐप्लिकेशन के सुझाव पाएं"</string>
     <string name="taskbar_edu_pinning" msgid="6708550858580071558">"टास्कबार को पिन करने के लिए डिवाइडर को दबाकर रखें"</string>
-    <string name="taskbar_edu_features" msgid="3320337287472848162">"टास्कबार की मदद से कई और काम करें"</string>
+    <string name="taskbar_edu_features" msgid="3320337287472848162">"टास्कबार के साथ कई और काम करें"</string>
     <string name="taskbar_edu_pinning_title" msgid="210102174154211712">"टास्कबार को हमेशा दिखाएं"</string>
     <string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"टास्कबार को हमेशा अपनी स्क्रीन के नीचे दिखाने के लिए, डिवाइडर दबाकर रखें"</string>
+    <string name="taskbar_edu_circle_to_search_title" msgid="4322780398403949508">"स्क्रीन में दिख रहे कॉन्टेंट को खोजने के लिए, ऐक्शन बटन को दबाकर रखें"</string>
+    <string name="taskbar_edu_circle_to_search_disclosure" msgid="5841648785867787221">"यह प्रॉडक्ट, कॉन्टेंट खोजने के लिए स्क्रीन पर चुनिंदा हिस्से का इस्तेमाल करता है. Google की <xliff:g id="BEGIN_PRIVACY_LINK">&lt;a href="%1$s"&gt;</xliff:g>निजता नीति<xliff:g id="END_PRIVACY_LINK">&lt;/a&gt;</xliff:g> और <xliff:g id="BEGIN_TOS_LINK">&lt;a href="%2$s"&gt;</xliff:g>सेवा की शर्तें<xliff:g id="END_TOS_LINK">&lt;/a&gt;</xliff:g> लागू होती हैं."</string>
     <string name="taskbar_edu_close" msgid="887022990168191073">"बंद करें"</string>
     <string name="taskbar_edu_done" msgid="6880178093977704569">"हो गया"</string>
     <string name="taskbar_button_home" msgid="2151398979630664652">"होम"</string>
diff --git a/quickstep/res/values-hr/strings.xml b/quickstep/res/values-hr/strings.xml
index 34030dd..b68d961 100644
--- a/quickstep/res/values-hr/strings.xml
+++ b/quickstep/res/values-hr/strings.xml
@@ -21,6 +21,8 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Prikvači"</string>
     <string name="recent_task_option_freeform" msgid="48863056265284071">"Slobodni oblik"</string>
+    <!-- no translation found for recent_task_option_desktop (8280879717125435668) -->
+    <skip />
     <string name="recents_empty_message" msgid="7040467240571714191">"Nema nedavnih stavki"</string>
     <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Postavke upotrebe aplikacija"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Izbriši sve"</string>
@@ -116,6 +118,8 @@
     <string name="taskbar_edu_features" msgid="3320337287472848162">"Učinite više pomoću trake sa zadacima"</string>
     <string name="taskbar_edu_pinning_title" msgid="210102174154211712">"Uvijek prikazuj traku sa zadacima"</string>
     <string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"Da bi se traka prikazivala, dodirnite i držite razdjelnik"</string>
+    <string name="taskbar_edu_circle_to_search_title" msgid="4322780398403949508">"Dodirnite i zadržite tipku za radnju da biste pretražili što se nalazi na zaslonu"</string>
+    <string name="taskbar_edu_circle_to_search_disclosure" msgid="5841648785867787221">"Ovaj proizvod upotrebljava odabrani dio zaslona za pretraživanje. Primjenjuju se Googleova <xliff:g id="BEGIN_PRIVACY_LINK">&lt;a href="%1$s"&gt;</xliff:g>pravila o privatnosti<xliff:g id="END_PRIVACY_LINK">&lt;/a&gt;</xliff:g> i <xliff:g id="BEGIN_TOS_LINK">&lt;a href="%2$s"&gt;</xliff:g>uvjeti pružanja usluge<xliff:g id="END_TOS_LINK">&lt;/a&gt;</xliff:g>."</string>
     <string name="taskbar_edu_close" msgid="887022990168191073">"Zatvori"</string>
     <string name="taskbar_edu_done" msgid="6880178093977704569">"Gotovo"</string>
     <string name="taskbar_button_home" msgid="2151398979630664652">"Početna"</string>
diff --git a/quickstep/res/values-hu/strings.xml b/quickstep/res/values-hu/strings.xml
index 017c5f6..e69bc53 100644
--- a/quickstep/res/values-hu/strings.xml
+++ b/quickstep/res/values-hu/strings.xml
@@ -21,6 +21,8 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Kitűzés"</string>
     <string name="recent_task_option_freeform" msgid="48863056265284071">"Szabad forma"</string>
+    <!-- no translation found for recent_task_option_desktop (8280879717125435668) -->
+    <skip />
     <string name="recents_empty_message" msgid="7040467240571714191">"Nincsenek mostanában használt elemek"</string>
     <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Alkalmazáshasználati beállítások"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Összes törlése"</string>
@@ -116,6 +118,10 @@
     <string name="taskbar_edu_features" msgid="3320337287472848162">"Jobban kihasználhatja a Feladatsávot"</string>
     <string name="taskbar_edu_pinning_title" msgid="210102174154211712">"Mindig jelenjen meg a Feladatsáv"</string>
     <string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"Ahhoz, hogy a Feladatsáv mindig megjelenjen a képernyő alján, érintse meg és tartsa lenyomva az elválasztót"</string>
+    <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
+    <skip />
+    <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
+    <skip />
     <string name="taskbar_edu_close" msgid="887022990168191073">"Bezárás"</string>
     <string name="taskbar_edu_done" msgid="6880178093977704569">"Kész"</string>
     <string name="taskbar_button_home" msgid="2151398979630664652">"Kezdőlap"</string>
@@ -129,7 +135,7 @@
     <string name="taskbar_a11y_shown_title" msgid="6842833581088937713">"Feladatsáv megjelenítve"</string>
     <string name="taskbar_a11y_hidden_title" msgid="9154903639589659284">"Feladatsáv elrejtve"</string>
     <string name="taskbar_phone_a11y_title" msgid="4933360237131229395">"Navigációs sáv"</string>
-    <string name="always_show_taskbar" msgid="3608801276107751229">"Mindig megjelenő feladatsáv"</string>
+    <string name="always_show_taskbar" msgid="3608801276107751229">"Mindig megjelenő Feladatsáv"</string>
     <string name="change_navigation_mode" msgid="9088393078736808968">"Navigációs mód módosítása"</string>
     <string name="taskbar_divider_a11y_title" msgid="6608690309720242080">"Feladatsáv-elválasztó"</string>
     <string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Mozgatás felülre vagy a bal oldalra"</string>
diff --git a/quickstep/res/values-hy/strings.xml b/quickstep/res/values-hy/strings.xml
index c09ceba..1889a4e 100644
--- a/quickstep/res/values-hy/strings.xml
+++ b/quickstep/res/values-hy/strings.xml
@@ -21,6 +21,8 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Ամրացնել"</string>
     <string name="recent_task_option_freeform" msgid="48863056265284071">"Կամայական ձև"</string>
+    <!-- no translation found for recent_task_option_desktop (8280879717125435668) -->
+    <skip />
     <string name="recents_empty_message" msgid="7040467240571714191">"Այստեղ դեռ ոչինչ չկա"</string>
     <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Հավելվածի օգտագործման կարգավորումներ"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Փակել բոլորը"</string>
@@ -97,10 +99,10 @@
     <string name="action_split" msgid="2098009717623550676">"Տրոհել"</string>
     <string name="action_save_app_pair" msgid="5974823919237645229">"Պահել հավելվ․ զույգը"</string>
     <string name="toast_split_select_app" msgid="8464310533320556058">"Հպեք այլ հավելվածի՝ տրոհված էկրանից օգտվելու համար"</string>
-    <string name="toast_contextual_split_select_app" msgid="433510957123687090">"Ընտրեք այլ հավելված՝ կիսված էկրանից օգտվելու համար"</string>
+    <string name="toast_contextual_split_select_app" msgid="433510957123687090">"Ընտրեք այլ հավելված՝ տրոհված էկրանից օգտվելու համար"</string>
     <string name="toast_split_select_app_cancel" msgid="1532690483356445639"><b>"Չեղարկել"</b></string>
     <string name="toast_split_select_cont_desc" msgid="2119685056059607602">"Դուրս գալ տրոհված էկրանի ռեժիմից"</string>
-    <string name="toast_split_app_unsupported" msgid="2360229567007828914">"Ընտրեք այլ հավելված՝ կիսված էկրանից օգտվելու համար"</string>
+    <string name="toast_split_app_unsupported" msgid="2360229567007828914">"Ընտրեք այլ հավելված՝ տրոհված էկրանից օգտվելու համար"</string>
     <string name="blocked_by_policy" msgid="2071401072261365546">"Այս գործողությունն արգելված է հավելվածի կամ ձեր կազմակերպության կողմից"</string>
     <string name="split_widgets_not_supported" msgid="1355743038053053866">"Վիջեթները ներկայումս չեն աջակցվում. ընտրեք այլ հավելված"</string>
     <string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Բաց թողնե՞լ նավիգացիայի ուղեցույցը"</string>
@@ -116,6 +118,10 @@
     <string name="taskbar_edu_features" msgid="3320337287472848162">"Օգտվեք հավելվածների վահանակի բոլոր հնարավորություններից"</string>
     <string name="taskbar_edu_pinning_title" msgid="210102174154211712">"Ամրացրեք հավելվածների վահանակը"</string>
     <string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"Հավելվածների վահանակն էկրանի ներքևում ամրացնելու համար հպեք և պահեք բաժանիչը"</string>
+    <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
+    <skip />
+    <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
+    <skip />
     <string name="taskbar_edu_close" msgid="887022990168191073">"Փակել"</string>
     <string name="taskbar_edu_done" msgid="6880178093977704569">"Պատրաստ է"</string>
     <string name="taskbar_button_home" msgid="2151398979630664652">"Սկիզբ"</string>
diff --git a/quickstep/res/values-in/strings.xml b/quickstep/res/values-in/strings.xml
index 7fefe9c..eec7e10 100644
--- a/quickstep/res/values-in/strings.xml
+++ b/quickstep/res/values-in/strings.xml
@@ -21,6 +21,8 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Sematkan"</string>
     <string name="recent_task_option_freeform" msgid="48863056265284071">"Format bebas"</string>
+    <!-- no translation found for recent_task_option_desktop (8280879717125435668) -->
+    <skip />
     <string name="recents_empty_message" msgid="7040467240571714191">"Tidak ada item yang baru dibuka"</string>
     <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Setelan penggunaan aplikasi"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Hapus semua"</string>
@@ -97,10 +99,10 @@
     <string name="action_split" msgid="2098009717623550676">"Pisahkan"</string>
     <string name="action_save_app_pair" msgid="5974823919237645229">"Simpan pasangan apl"</string>
     <string name="toast_split_select_app" msgid="8464310533320556058">"Ketuk aplikasi lain untuk memakai layar terpisah"</string>
-    <string name="toast_contextual_split_select_app" msgid="433510957123687090">"Pilih aplikasi lain untuk menggunakan layar terpisah"</string>
+    <string name="toast_contextual_split_select_app" msgid="433510957123687090">"Pilih aplikasi lain untuk dibuka di layar terpisah"</string>
     <string name="toast_split_select_app_cancel" msgid="1532690483356445639"><b>"Batal"</b></string>
     <string name="toast_split_select_cont_desc" msgid="2119685056059607602">"Keluar dari pemilihan layar terpisah"</string>
-    <string name="toast_split_app_unsupported" msgid="2360229567007828914">"Pilih aplikasi lain untuk memakai layar terpisah"</string>
+    <string name="toast_split_app_unsupported" msgid="2360229567007828914">"Pilih aplikasi lain untuk dibuka di layar terpisah"</string>
     <string name="blocked_by_policy" msgid="2071401072261365546">"Tindakan ini tidak diizinkan oleh aplikasi atau organisasi Anda"</string>
     <string name="split_widgets_not_supported" msgid="1355743038053053866">"Widget saat ini tidak didukung, pilih aplikasi lain"</string>
     <string name="skip_tutorial_dialog_title" msgid="2725643161260038458">"Lewati tutorial gestur?"</string>
@@ -113,9 +115,11 @@
     <string name="taskbar_edu_stashing" msgid="5645461372669217294">"Geser perlahan ke atas untuk menampilkan Taskbar"</string>
     <string name="taskbar_edu_suggestions" msgid="8215044496435527982">"Dapatkan saran aplikasi berdasarkan rutinitas Anda"</string>
     <string name="taskbar_edu_pinning" msgid="6708550858580071558">"Tekan lama pemisah untuk menyematkan Taskbar"</string>
-    <string name="taskbar_edu_features" msgid="3320337287472848162">"Lakukan lebih banyak dengan Taskbar"</string>
+    <string name="taskbar_edu_features" msgid="3320337287472848162">"Lakukan lebih banyak hal dengan Taskbar"</string>
     <string name="taskbar_edu_pinning_title" msgid="210102174154211712">"Selalu tampilkan Taskbar"</string>
     <string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"Untuk selalu menampilkan Taskbar di bagian bawah layar Anda, sentuh &amp; tahan pembatasnya"</string>
+    <string name="taskbar_edu_circle_to_search_title" msgid="4322780398403949508">"Sentuh &amp; tahan tombol tindakan untuk mencari konten di layar Anda"</string>
+    <string name="taskbar_edu_circle_to_search_disclosure" msgid="5841648785867787221">"Produk ini menggunakan bagian layar terpilih untuk menelusuri. <xliff:g id="BEGIN_PRIVACY_LINK">&lt;a href="%1$s"&gt;</xliff:g>Kebijakan Privasi<xliff:g id="END_PRIVACY_LINK">&lt;/a&gt;</xliff:g> dan <xliff:g id="BEGIN_TOS_LINK">&lt;a href="%2$s"&gt;</xliff:g>Persyaratan Layanan<xliff:g id="END_TOS_LINK">&lt;/a&gt;</xliff:g> Google berlaku."</string>
     <string name="taskbar_edu_close" msgid="887022990168191073">"Tutup"</string>
     <string name="taskbar_edu_done" msgid="6880178093977704569">"Selesai"</string>
     <string name="taskbar_button_home" msgid="2151398979630664652">"Layar utama"</string>
diff --git a/quickstep/res/values-is/strings.xml b/quickstep/res/values-is/strings.xml
index 47cf293..e023124 100644
--- a/quickstep/res/values-is/strings.xml
+++ b/quickstep/res/values-is/strings.xml
@@ -21,6 +21,8 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Festa"</string>
     <string name="recent_task_option_freeform" msgid="48863056265284071">"Frjálst snið"</string>
+    <!-- no translation found for recent_task_option_desktop (8280879717125435668) -->
+    <skip />
     <string name="recents_empty_message" msgid="7040467240571714191">"Engin nýleg atriði"</string>
     <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Notkunarstillingar forrits"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Hreinsa allt"</string>
@@ -116,6 +118,8 @@
     <string name="taskbar_edu_features" msgid="3320337287472848162">"Nýttu forritastikuna betur"</string>
     <string name="taskbar_edu_pinning_title" msgid="210102174154211712">"Halda forritastikunni sýnilegri"</string>
     <string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"Haltu skjáskiptingunni neðst á skjánum inni til að halda forritastikunni sýnilegri"</string>
+    <string name="taskbar_edu_circle_to_search_title" msgid="4322780398403949508">"Haltu aðgerðalyklinum inni til að leita að því sem er á skjánum"</string>
+    <string name="taskbar_edu_circle_to_search_disclosure" msgid="5841648785867787221">"Þessi vara notar valinn hluta skjásins til að leita. <xliff:g id="BEGIN_PRIVACY_LINK">&lt;a href="%1$s"&gt;</xliff:g>Persónuverndarstefna<xliff:g id="END_PRIVACY_LINK">&lt;/a&gt;</xliff:g> og <xliff:g id="BEGIN_TOS_LINK">&lt;a href="%2$s"&gt;</xliff:g>þjónustuskilmálar<xliff:g id="END_TOS_LINK">&lt;/a&gt;</xliff:g> Google gilda."</string>
     <string name="taskbar_edu_close" msgid="887022990168191073">"Loka"</string>
     <string name="taskbar_edu_done" msgid="6880178093977704569">"Lokið"</string>
     <string name="taskbar_button_home" msgid="2151398979630664652">"Heim"</string>
diff --git a/quickstep/res/values-it/strings.xml b/quickstep/res/values-it/strings.xml
index fc07b94..aeeb6a2 100644
--- a/quickstep/res/values-it/strings.xml
+++ b/quickstep/res/values-it/strings.xml
@@ -21,6 +21,8 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Blocca su schermo"</string>
     <string name="recent_task_option_freeform" msgid="48863056265284071">"Forma libera"</string>
+    <!-- no translation found for recent_task_option_desktop (8280879717125435668) -->
+    <skip />
     <string name="recents_empty_message" msgid="7040467240571714191">"Nessun elemento recente"</string>
     <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Impostazioni di utilizzo delle app"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Cancella tutto"</string>
@@ -116,6 +118,10 @@
     <string name="taskbar_edu_features" msgid="3320337287472848162">"Fai di più con la barra delle app"</string>
     <string name="taskbar_edu_pinning_title" msgid="210102174154211712">"Mostra sempre la barra delle app"</string>
     <string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"Per mostrare sempre la barra delle app in basso, tocca e tieni premuto il divisore"</string>
+    <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
+    <skip />
+    <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
+    <skip />
     <string name="taskbar_edu_close" msgid="887022990168191073">"Chiudi"</string>
     <string name="taskbar_edu_done" msgid="6880178093977704569">"Fine"</string>
     <string name="taskbar_button_home" msgid="2151398979630664652">"Home"</string>
diff --git a/quickstep/res/values-iw/strings.xml b/quickstep/res/values-iw/strings.xml
index 1a8311f..3899f67 100644
--- a/quickstep/res/values-iw/strings.xml
+++ b/quickstep/res/values-iw/strings.xml
@@ -21,6 +21,8 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_pin" msgid="7929860679018978258">"הצמדה"</string>
     <string name="recent_task_option_freeform" msgid="48863056265284071">"מצב חופשי"</string>
+    <!-- no translation found for recent_task_option_desktop (8280879717125435668) -->
+    <skip />
     <string name="recents_empty_message" msgid="7040467240571714191">"אין פריטים אחרונים"</string>
     <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"הגדרות שימוש באפליקציה"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"ניקוי הכול"</string>
@@ -111,11 +113,15 @@
     <string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"הסבר על סרגל האפליקציות"</string>
     <string name="taskbar_edu_splitscreen" msgid="5605512479258053350">"כדי להשתמש בשתי אפליקציות בו-זמנית, צריך לגרור אפליקציה לצד"</string>
     <string name="taskbar_edu_stashing" msgid="5645461372669217294">"צריך להחליק לאט למעלה כדי להציג את סרגל האפליקציות"</string>
-    <string name="taskbar_edu_suggestions" msgid="8215044496435527982">"קבלת הצעות לאפליקציות על סמך השימוש השגרתי שלך"</string>
+    <string name="taskbar_edu_suggestions" msgid="8215044496435527982">"אפשר לקבל הצעות לאפליקציות על סמך השימוש השגרתי שלך"</string>
     <string name="taskbar_edu_pinning" msgid="6708550858580071558">"כדי להצמיד את סרגל האפליקציות, לוחצים לחיצה ארוכה על המחיצה"</string>
     <string name="taskbar_edu_features" msgid="3320337287472848162">"פעולות נוספות שאפשר לעשות עם סרגל האפליקציות"</string>
     <string name="taskbar_edu_pinning_title" msgid="210102174154211712">"תמיד להציג את סרגל האפליקציות"</string>
     <string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"כדי להציג תמיד את סרגל האפליקציות בתחתית המסך, יש ללחוץ לחיצה ארוכה על המחיצה"</string>
+    <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
+    <skip />
+    <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
+    <skip />
     <string name="taskbar_edu_close" msgid="887022990168191073">"סגירה"</string>
     <string name="taskbar_edu_done" msgid="6880178093977704569">"סיום"</string>
     <string name="taskbar_button_home" msgid="2151398979630664652">"בית"</string>
diff --git a/quickstep/res/values-ja/strings.xml b/quickstep/res/values-ja/strings.xml
index 1d82852..8125ea4 100644
--- a/quickstep/res/values-ja/strings.xml
+++ b/quickstep/res/values-ja/strings.xml
@@ -21,6 +21,8 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_pin" msgid="7929860679018978258">"固定"</string>
     <string name="recent_task_option_freeform" msgid="48863056265284071">"フリーフォーム"</string>
+    <!-- no translation found for recent_task_option_desktop (8280879717125435668) -->
+    <skip />
     <string name="recents_empty_message" msgid="7040467240571714191">"最近のアイテムはありません"</string>
     <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"アプリの使用状況の設定"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"すべてクリア"</string>
@@ -116,6 +118,10 @@
     <string name="taskbar_edu_features" msgid="3320337287472848162">"タスクバーの各種機能"</string>
     <string name="taskbar_edu_pinning_title" msgid="210102174154211712">"タスクバーを常に表示"</string>
     <string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"タスクバーを画面下部に常に表示するには分割線を長押しします"</string>
+    <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
+    <skip />
+    <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
+    <skip />
     <string name="taskbar_edu_close" msgid="887022990168191073">"閉じる"</string>
     <string name="taskbar_edu_done" msgid="6880178093977704569">"完了"</string>
     <string name="taskbar_button_home" msgid="2151398979630664652">"ホーム"</string>
diff --git a/quickstep/res/values-ka/strings.xml b/quickstep/res/values-ka/strings.xml
index f682e8d..14c0773 100644
--- a/quickstep/res/values-ka/strings.xml
+++ b/quickstep/res/values-ka/strings.xml
@@ -21,6 +21,8 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_pin" msgid="7929860679018978258">"ჩამაგრება"</string>
     <string name="recent_task_option_freeform" msgid="48863056265284071">"თავისუფალი ფორმა"</string>
+    <!-- no translation found for recent_task_option_desktop (8280879717125435668) -->
+    <skip />
     <string name="recents_empty_message" msgid="7040467240571714191">"ბოლოს გამოყენებული ერთეულები არ არის"</string>
     <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"აპების გამოყენების პარამეტრები"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"ყველას გასუფთავება"</string>
@@ -116,6 +118,10 @@
     <string name="taskbar_edu_features" msgid="3320337287472848162">"გააკეთეთ მეტი ამოცანათა ზოლის მეშვეობით"</string>
     <string name="taskbar_edu_pinning_title" msgid="210102174154211712">"ამოცანათა ზოლის მუდმივად ჩვენება"</string>
     <string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"თქვენი ეკრანის ქვედა ნაწილში ამოცანათა ზოლის მუდმივად საჩვენებლად, ხანგრძლივად შეეხეთ გამყოფს"</string>
+    <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
+    <skip />
+    <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
+    <skip />
     <string name="taskbar_edu_close" msgid="887022990168191073">"დახურვა"</string>
     <string name="taskbar_edu_done" msgid="6880178093977704569">"მზადაა"</string>
     <string name="taskbar_button_home" msgid="2151398979630664652">"მთავარი"</string>
diff --git a/quickstep/res/values-kk/strings.xml b/quickstep/res/values-kk/strings.xml
index 8cdf151..9964105 100644
--- a/quickstep/res/values-kk/strings.xml
+++ b/quickstep/res/values-kk/strings.xml
@@ -21,6 +21,8 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Бекіту"</string>
     <string name="recent_task_option_freeform" msgid="48863056265284071">"Еркін форма"</string>
+    <!-- no translation found for recent_task_option_desktop (8280879717125435668) -->
+    <skip />
     <string name="recents_empty_message" msgid="7040467240571714191">"Соңғы элементтер жоқ"</string>
     <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Қолданбаны пайдалану параметрлері"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Барлығын өшіру"</string>
@@ -116,6 +118,10 @@
     <string name="taskbar_edu_features" msgid="3320337287472848162">"Тапсырмалар жолағында мүмкіндік көп"</string>
     <string name="taskbar_edu_pinning_title" msgid="210102174154211712">"Тапсырмалар жолағын әрдайым көрсету"</string>
     <string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"Экранның төменгі жағында тапсырмалар жолағы әрдайым көрсетілуі үшін, бөлгішті басып тұрыңыз."</string>
+    <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
+    <skip />
+    <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
+    <skip />
     <string name="taskbar_edu_close" msgid="887022990168191073">"Жабу"</string>
     <string name="taskbar_edu_done" msgid="6880178093977704569">"Дайын"</string>
     <string name="taskbar_button_home" msgid="2151398979630664652">"Негізгі экран"</string>
diff --git a/quickstep/res/values-km/strings.xml b/quickstep/res/values-km/strings.xml
index c599ccf..3b7180c 100644
--- a/quickstep/res/values-km/strings.xml
+++ b/quickstep/res/values-km/strings.xml
@@ -21,6 +21,8 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_pin" msgid="7929860679018978258">"ខ្ទាស់"</string>
     <string name="recent_task_option_freeform" msgid="48863056265284071">"មុខងារទម្រង់សេរី"</string>
+    <!-- no translation found for recent_task_option_desktop (8280879717125435668) -->
+    <skip />
     <string name="recents_empty_message" msgid="7040467240571714191">"មិនមានធាតុថ្មីៗទេ"</string>
     <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"ការកំណត់​ការប្រើប្រាស់​កម្មវិធី"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"សម្អាត​ទាំងអស់"</string>
@@ -116,6 +118,8 @@
     <string name="taskbar_edu_features" msgid="3320337287472848162">"ធ្វើបានកាន់តែច្រើនដោយប្រើរបារកិច្ចការ"</string>
     <string name="taskbar_edu_pinning_title" msgid="210102174154211712">"បង្ហាញរបារកិច្ចការជានិច្ច"</string>
     <string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"ដើម្បីបង្ហាញរបារកិច្ចការនៅផ្នែកខាងក្រោមនៃអេក្រង់របស់អ្នកជានិច្ច សូមចុចបន្ទាត់ខណ្ឌចែកឱ្យជាប់"</string>
+    <string name="taskbar_edu_circle_to_search_title" msgid="4322780398403949508">"ចុចគ្រាប់ចុចសកម្មភាពឱ្យជាប់ ដើម្បីស្វែងរកអ្វីដែលមាននៅលើអេក្រង់របស់អ្នក"</string>
+    <string name="taskbar_edu_circle_to_search_disclosure" msgid="5841648785867787221">"ផលិតផលនេះប្រើប្រាស់ផ្នែកដែលបានជ្រើសរើសនៃអេក្រង់របស់អ្នក ដើម្បីស្វែងរក។ <xliff:g id="BEGIN_PRIVACY_LINK">&lt;a href="%1$s"&gt;</xliff:g>គោលការណ៍​ឯកជនភាព<xliff:g id="END_PRIVACY_LINK">&lt;/a&gt;</xliff:g> និង<xliff:g id="BEGIN_TOS_LINK">&lt;a href="%2$s"&gt;</xliff:g>លក្ខខណ្ឌ​ប្រើប្រាស់<xliff:g id="END_TOS_LINK">&lt;/a&gt;</xliff:g>របស់ Google ត្រូវបានអនុវត្ត។"</string>
     <string name="taskbar_edu_close" msgid="887022990168191073">"បិទ"</string>
     <string name="taskbar_edu_done" msgid="6880178093977704569">"រួចរាល់"</string>
     <string name="taskbar_button_home" msgid="2151398979630664652">"ទំព័រដើម"</string>
diff --git a/quickstep/res/values-kn/strings.xml b/quickstep/res/values-kn/strings.xml
index 903534a..688098c 100644
--- a/quickstep/res/values-kn/strings.xml
+++ b/quickstep/res/values-kn/strings.xml
@@ -21,6 +21,8 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_pin" msgid="7929860679018978258">"ಪಿನ್ ಮಾಡಿ"</string>
     <string name="recent_task_option_freeform" msgid="48863056265284071">"ಮುಕ್ತಸ್ವರೂಪ"</string>
+    <!-- no translation found for recent_task_option_desktop (8280879717125435668) -->
+    <skip />
     <string name="recents_empty_message" msgid="7040467240571714191">"ಯಾವುದೇ ಇತ್ತೀಚಿನ ಐಟಂಗಳಿಲ್ಲ"</string>
     <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"ಆ್ಯಪ್‌ ಬಳಕೆಯ ಸೆಟ್ಟಿಂಗ್‌ಗಳು"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"ಎಲ್ಲವನ್ನೂ ತೆರವುಗೊಳಿಸಿ"</string>
@@ -112,10 +114,14 @@
     <string name="taskbar_edu_splitscreen" msgid="5605512479258053350">"ಒಂದೇ ಬಾರಿಗೆ 2 ಆ್ಯಪ್‌ಗಳನ್ನು ಬಳಸಲು ಆ್ಯಪ್ ಅನ್ನು ಬದಿಗೆ ಎಳೆಯಿರಿ"</string>
     <string name="taskbar_edu_stashing" msgid="5645461372669217294">"ಟಾಸ್ಕ್‌ಬಾರ್ ಕಾಣುವಂತೆ ಮಾಡಲು ನಿಧಾನವಾಗಿ ಮೇಲಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡಿ"</string>
     <string name="taskbar_edu_suggestions" msgid="8215044496435527982">"ನಿಮ್ಮ ದಿನಚರಿಯ ಆಧಾರದ ಮೇಲೆ ಆ್ಯಪ್ ಸಲಹೆಗಳನ್ನು ಪಡೆಯಿರಿ"</string>
-    <string name="taskbar_edu_pinning" msgid="6708550858580071558">"ಟಾಸ್ಕ್ ಬಾರ್ ಅನ್ನು ಪಿನ್ ಮಾಡಲು ಡಿವೈಡರ್ ಮೇಲೆ ದೀರ್ಘಕಾಲ ಒತ್ತಿರಿ"</string>
+    <string name="taskbar_edu_pinning" msgid="6708550858580071558">"ಟಾಸ್ಕ್‌‌ಬಾರ್ ಅನ್ನು ಪಿನ್ ಮಾಡಲು ಡಿವೈಡರ್ ಮೇಲೆ ದೀರ್ಘಕಾಲ ಒತ್ತಿರಿ"</string>
     <string name="taskbar_edu_features" msgid="3320337287472848162">"ಟಾಸ್ಕ್‌ಬಾರ್ ಮೂಲಕ ಹೆಚ್ಚಿನದನ್ನು ಮಾಡಿ"</string>
     <string name="taskbar_edu_pinning_title" msgid="210102174154211712">"ಯಾವಾಗಲೂ ಟಾಸ್ಕ್‌ಬಾರ್ ಅನ್ನು ತೋರಿಸಿ"</string>
     <string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"ಯಾವಾಗಲೂ ನಿಮ್ಮ ಸ್ಕ್ರೀನ್‌ನ ಕೆಳಭಾಗದಲ್ಲಿ ಟಾಸ್ಕ್ ಬಾರ್ ಅನ್ನು ತೋರಿಸಲು, ಡಿವೈಡರ್ ಅನ್ನು ಸ್ಪರ್ಶಿಸಿ ಹಿಡಿದಿಟ್ಟುಕೊಳ್ಳಿ"</string>
+    <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
+    <skip />
+    <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
+    <skip />
     <string name="taskbar_edu_close" msgid="887022990168191073">"ಮುಚ್ಚಿರಿ"</string>
     <string name="taskbar_edu_done" msgid="6880178093977704569">"ಆಯಿತು"</string>
     <string name="taskbar_button_home" msgid="2151398979630664652">"ಮುಖಪುಟ"</string>
diff --git a/quickstep/res/values-ko/strings.xml b/quickstep/res/values-ko/strings.xml
index 9a885c1..b8a131a 100644
--- a/quickstep/res/values-ko/strings.xml
+++ b/quickstep/res/values-ko/strings.xml
@@ -21,6 +21,8 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_pin" msgid="7929860679018978258">"고정"</string>
     <string name="recent_task_option_freeform" msgid="48863056265284071">"자유 형식"</string>
+    <!-- no translation found for recent_task_option_desktop (8280879717125435668) -->
+    <skip />
     <string name="recents_empty_message" msgid="7040467240571714191">"최근 항목이 없습니다."</string>
     <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"앱 사용 설정"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"모두 삭제"</string>
@@ -116,6 +118,10 @@
     <string name="taskbar_edu_features" msgid="3320337287472848162">"태스크 바 최대한 활용하기"</string>
     <string name="taskbar_edu_pinning_title" msgid="210102174154211712">"태스크 바 항상 표시"</string>
     <string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"화면 하단에 태스크 바를 항상 표시하려면 구분선을 길게 터치하세요."</string>
+    <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
+    <skip />
+    <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
+    <skip />
     <string name="taskbar_edu_close" msgid="887022990168191073">"닫기"</string>
     <string name="taskbar_edu_done" msgid="6880178093977704569">"완료"</string>
     <string name="taskbar_button_home" msgid="2151398979630664652">"홈"</string>
diff --git a/quickstep/res/values-ky/strings.xml b/quickstep/res/values-ky/strings.xml
index 5fa61fb..061952c 100644
--- a/quickstep/res/values-ky/strings.xml
+++ b/quickstep/res/values-ky/strings.xml
@@ -21,6 +21,8 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Кадап коюу"</string>
     <string name="recent_task_option_freeform" msgid="48863056265284071">"Эркин форма режими"</string>
+    <!-- no translation found for recent_task_option_desktop (8280879717125435668) -->
+    <skip />
     <string name="recents_empty_message" msgid="7040467240571714191">"Акыркы колдонмолор жок"</string>
     <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Колдонмону пайдалануу параметрлери"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Баарын тазалоо"</string>
@@ -109,13 +111,15 @@
     <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Өткрп жиберүү"</string>
     <string name="accessibility_rotate_button" msgid="4771825231336502943">"Экранды буруу"</string>
     <string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"Тапшырмалар тактасы жөнүндө маалымат"</string>
-    <string name="taskbar_edu_splitscreen" msgid="5605512479258053350">"2 колдонмону бир убакта пайдалануу үчүн капталга сүйрөңүз"</string>
+    <string name="taskbar_edu_splitscreen" msgid="5605512479258053350">"2 колдонмону бир убакта пайдалануу үчүн капталга сүйрөйсүз"</string>
     <string name="taskbar_edu_stashing" msgid="5645461372669217294">"Тапшырмалар тактасын көрүү үчүн экранды жай өйдө сүрүңүз"</string>
-    <string name="taskbar_edu_suggestions" msgid="8215044496435527982">"Программаңыздын негизинде сунушталган колдонмолорду алуу"</string>
-    <string name="taskbar_edu_pinning" msgid="6708550858580071558">"Тапшырмалар панелин кадап коюу үчүн бөлгүчтү коё бербей басып туруңуз"</string>
-    <string name="taskbar_edu_features" msgid="3320337287472848162">"Тапшырмалар тактасы менен көбүрөөк нерселерди аткарыңыз"</string>
+    <string name="taskbar_edu_suggestions" msgid="8215044496435527982">"Аракеттериңизге негизделген сунуштарды алып турасыз"</string>
+    <string name="taskbar_edu_pinning" msgid="6708550858580071558">"Тапшырмалар тактасын кадап коюу үчүн бөлгүчтү коё бербей басып турасыз"</string>
+    <string name="taskbar_edu_features" msgid="3320337287472848162">"Тапшырмалар тактасы менен көбүрөөк иш бүтүрөсүз"</string>
     <string name="taskbar_edu_pinning_title" msgid="210102174154211712">"Тапшырмалар панелин ар дайым көрсөтүү"</string>
     <string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"Тапшырмалар панелин экрандын ылдый жагында ар дайым көрсөтүү үчүн бөлгүчтү коё бербей басыңыз"</string>
+    <string name="taskbar_edu_circle_to_search_title" msgid="4322780398403949508">"Экрандагы нерсени издөө үчүн аракет баскычын коё бербей кармап туруңуз"</string>
+    <string name="taskbar_edu_circle_to_search_disclosure" msgid="5841648785867787221">"Бул кызмат издөө үчүн экранда тандалган бөлүктү колдонот. Google\'дун <xliff:g id="BEGIN_PRIVACY_LINK">&lt;a href="%1$s"&gt;</xliff:g>Купуялык эрежелери<xliff:g id="END_PRIVACY_LINK">&lt;/a&gt;</xliff:g> жана <xliff:g id="BEGIN_TOS_LINK">&lt;a href="%2$s"&gt;</xliff:g>Тейлөө шарттары<xliff:g id="END_TOS_LINK">&lt;/a&gt;</xliff:g> колдонулат."</string>
     <string name="taskbar_edu_close" msgid="887022990168191073">"Жабуу"</string>
     <string name="taskbar_edu_done" msgid="6880178093977704569">"Бүттү"</string>
     <string name="taskbar_button_home" msgid="2151398979630664652">"Башкы бет"</string>
@@ -129,7 +133,7 @@
     <string name="taskbar_a11y_shown_title" msgid="6842833581088937713">"Тапшырмалар панели көрсөтүлдү"</string>
     <string name="taskbar_a11y_hidden_title" msgid="9154903639589659284">"Тапшырмалар панели жашырылды"</string>
     <string name="taskbar_phone_a11y_title" msgid="4933360237131229395">"Чабыттоо тилкеси"</string>
-    <string name="always_show_taskbar" msgid="3608801276107751229">"Тапшырмалар панелин ар дайым көрсөтүү"</string>
+    <string name="always_show_taskbar" msgid="3608801276107751229">"Такта ар дайым көрүнсүн"</string>
     <string name="change_navigation_mode" msgid="9088393078736808968">"Өтүү режимин өзгөртүү"</string>
     <string name="taskbar_divider_a11y_title" msgid="6608690309720242080">"Тапшырмалар панелин бөлгүч"</string>
     <string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Жогорку/сол бурчка жылдыруу"</string>
diff --git a/quickstep/res/values-lo/strings.xml b/quickstep/res/values-lo/strings.xml
index 0940368..211e9ed 100644
--- a/quickstep/res/values-lo/strings.xml
+++ b/quickstep/res/values-lo/strings.xml
@@ -21,6 +21,8 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_pin" msgid="7929860679018978258">"ປັກໝຸດ"</string>
     <string name="recent_task_option_freeform" msgid="48863056265284071">"ຮູບແບບອິດສະຫລະ"</string>
+    <!-- no translation found for recent_task_option_desktop (8280879717125435668) -->
+    <skip />
     <string name="recents_empty_message" msgid="7040467240571714191">"ບໍ່ມີລາຍການຫຼ້າສຸດ"</string>
     <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"ການຕັ້ງຄ່າການນຳໃຊ້ແອັບ"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"ລຶບລ້າງທັງໝົດ"</string>
@@ -116,6 +118,8 @@
     <string name="taskbar_edu_features" msgid="3320337287472848162">"ເຮັດສິ່ງຕ່າງໆໄດ້ຫຼາຍຂຶ້ນດ້ວຍແຖບໜ້າວຽກ"</string>
     <string name="taskbar_edu_pinning_title" msgid="210102174154211712">"ສະແດງແຖບໜ້າວຽກສະເໝີ"</string>
     <string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"ເພື່ອໃຫ້ແຖບໜ້າວຽກສະແດງຢູ່ລຸ່ມໜ້າຈໍຂອງທ່ານຢູ່ສະເໝີ, ໃຫ້ແຕະຕົວແບ່ງຄ້າງໄວ້"</string>
+    <string name="taskbar_edu_circle_to_search_title" msgid="4322780398403949508">"ແຕະປຸ່ມຄຳສັ່ງຄ້າງໄວ້ເພື່ອຊອກຫາສິ່ງທີ່ຢູ່ເທິງໜ້າຈໍຂອງທ່ານ"</string>
+    <string name="taskbar_edu_circle_to_search_disclosure" msgid="5841648785867787221">"ສິນຄ້ານີ້ໃຊ້ສ່ວນທີ່ເລືອກຂອງໜ້າຈໍຂອງທ່ານເພື່ອຊອກຫາ. ເປັນໄປຕາມ <xliff:g id="BEGIN_PRIVACY_LINK">&lt;a href="%1$s"&gt;</xliff:g>ນະໂຍບາຍຄວາມເປັນສ່ວນຕົວ<xliff:g id="END_PRIVACY_LINK">&lt;/a&gt;</xliff:g> ແລະ <xliff:g id="BEGIN_TOS_LINK">&lt;a href="%2$s"&gt;</xliff:g>ຂໍ້ກຳນົດບໍລິການ<xliff:g id="END_TOS_LINK">&lt;/a&gt;</xliff:g> ຂອງ Google."</string>
     <string name="taskbar_edu_close" msgid="887022990168191073">"ປິດ"</string>
     <string name="taskbar_edu_done" msgid="6880178093977704569">"ແລ້ວໆ"</string>
     <string name="taskbar_button_home" msgid="2151398979630664652">"ໜ້າຫຼັກ"</string>
diff --git a/quickstep/res/values-lt/strings.xml b/quickstep/res/values-lt/strings.xml
index 8a276da..e2f1af9 100644
--- a/quickstep/res/values-lt/strings.xml
+++ b/quickstep/res/values-lt/strings.xml
@@ -21,6 +21,8 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Prisegti"</string>
     <string name="recent_task_option_freeform" msgid="48863056265284071">"Laisva forma"</string>
+    <!-- no translation found for recent_task_option_desktop (8280879717125435668) -->
+    <skip />
     <string name="recents_empty_message" msgid="7040467240571714191">"Nėra jokių naujausių elementų"</string>
     <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Programos naudojimo nustatymai"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Išvalyti viską"</string>
@@ -116,6 +118,10 @@
     <string name="taskbar_edu_features" msgid="3320337287472848162">"Atlikite daugiau naudodami Užduočių juostą"</string>
     <string name="taskbar_edu_pinning_title" msgid="210102174154211712">"Visada rodyti užduočių juostą"</string>
     <string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"Jei norite, kad užduočių juosta visada būtų rodoma ekrano apačioje, palieskite ir palaikykite daliklį"</string>
+    <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
+    <skip />
+    <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
+    <skip />
     <string name="taskbar_edu_close" msgid="887022990168191073">"Uždaryti"</string>
     <string name="taskbar_edu_done" msgid="6880178093977704569">"Atlikta"</string>
     <string name="taskbar_button_home" msgid="2151398979630664652">"Pagrindinis"</string>
diff --git a/quickstep/res/values-lv/strings.xml b/quickstep/res/values-lv/strings.xml
index cb211c0..6881a09 100644
--- a/quickstep/res/values-lv/strings.xml
+++ b/quickstep/res/values-lv/strings.xml
@@ -21,6 +21,8 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Piespraust"</string>
     <string name="recent_task_option_freeform" msgid="48863056265284071">"Brīva forma"</string>
+    <!-- no translation found for recent_task_option_desktop (8280879717125435668) -->
+    <skip />
     <string name="recents_empty_message" msgid="7040467240571714191">"Nav nesenu vienumu."</string>
     <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Lietotņu izmantošanas iestatījumi"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Notīrīt visu"</string>
@@ -116,6 +118,10 @@
     <string name="taskbar_edu_features" msgid="3320337287472848162">"Plašākas iespējas, izmantojot uzdevumu joslu"</string>
     <string name="taskbar_edu_pinning_title" msgid="210102174154211712">"Vienmēr rādīt uzdevumu joslu"</string>
     <string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"Lai uzdevumu joslu rādītu apakšdaļā, pieskarieties atdalītājam un turiet"</string>
+    <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
+    <skip />
+    <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
+    <skip />
     <string name="taskbar_edu_close" msgid="887022990168191073">"Aizvērt"</string>
     <string name="taskbar_edu_done" msgid="6880178093977704569">"Gatavs"</string>
     <string name="taskbar_button_home" msgid="2151398979630664652">"Sākums"</string>
diff --git a/quickstep/res/values-mk/strings.xml b/quickstep/res/values-mk/strings.xml
index b4c9569..6408a4d 100644
--- a/quickstep/res/values-mk/strings.xml
+++ b/quickstep/res/values-mk/strings.xml
@@ -21,6 +21,8 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Закачи"</string>
     <string name="recent_task_option_freeform" msgid="48863056265284071">"Freeform"</string>
+    <!-- no translation found for recent_task_option_desktop (8280879717125435668) -->
+    <skip />
     <string name="recents_empty_message" msgid="7040467240571714191">"Нема неодамнешни ставки"</string>
     <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Поставки за користење на апликациите"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Избриши ги сите"</string>
@@ -95,7 +97,7 @@
     <string name="action_share" msgid="2648470652637092375">"Сподели"</string>
     <string name="action_screenshot" msgid="8171125848358142917">"Слика од екранот"</string>
     <string name="action_split" msgid="2098009717623550676">"Раздели"</string>
-    <string name="action_save_app_pair" msgid="5974823919237645229">"Зачувај пар аплик."</string>
+    <string name="action_save_app_pair" msgid="5974823919237645229">"Зачувај го паров"</string>
     <string name="toast_split_select_app" msgid="8464310533320556058">"Допрете друга аплик. за да користите поделен екран"</string>
     <string name="toast_contextual_split_select_app" msgid="433510957123687090">"Изберете друга апликација за да користите поделен екран"</string>
     <string name="toast_split_select_app_cancel" msgid="1532690483356445639"><b>"Откажи"</b></string>
@@ -109,13 +111,17 @@
     <string name="gesture_tutorial_action_button_label_skip" msgid="394452764989751960">"Прескокни"</string>
     <string name="accessibility_rotate_button" msgid="4771825231336502943">"Ротирајте го екранот"</string>
     <string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"Обука за лентата со задачи"</string>
-    <string name="taskbar_edu_splitscreen" msgid="5605512479258053350">"Повлечете апликација настрана за да користите 2 апликации"</string>
-    <string name="taskbar_edu_stashing" msgid="5645461372669217294">"Полека повлечете нагоре за да се прикаже лентата со задачи"</string>
+    <string name="taskbar_edu_splitscreen" msgid="5605512479258053350">"Повлечете апликација настрана за да користите 2 апликации одеднаш"</string>
+    <string name="taskbar_edu_stashing" msgid="5645461372669217294">"Полека повлечете нагоре за да се прикаже „Лентата со задачи“"</string>
     <string name="taskbar_edu_suggestions" msgid="8215044496435527982">"Добивајте предлози за апликации според вашата рутина"</string>
     <string name="taskbar_edu_pinning" msgid="6708550858580071558">"Притиснете долго на разделникот за да ја закачите „Лентата со задачи“"</string>
     <string name="taskbar_edu_features" msgid="3320337287472848162">"Правете сешто со „Лентата со задачи“"</string>
     <string name="taskbar_edu_pinning_title" msgid="210102174154211712">"Како секогаш да се прикажува „Лентата со задачи“"</string>
     <string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"Допрете и задржете го разделникот за да може „Лентата со задачи“ секогаш да се прикажува на дното на екранот"</string>
+    <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
+    <skip />
+    <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
+    <skip />
     <string name="taskbar_edu_close" msgid="887022990168191073">"Затвори"</string>
     <string name="taskbar_edu_done" msgid="6880178093977704569">"Готово"</string>
     <string name="taskbar_button_home" msgid="2151398979630664652">"Дома"</string>
diff --git a/quickstep/res/values-ml/strings.xml b/quickstep/res/values-ml/strings.xml
index be61137..17380a0 100644
--- a/quickstep/res/values-ml/strings.xml
+++ b/quickstep/res/values-ml/strings.xml
@@ -21,6 +21,8 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_pin" msgid="7929860679018978258">"പിൻ ചെയ്യുക"</string>
     <string name="recent_task_option_freeform" msgid="48863056265284071">"ഫ്രീഫോം"</string>
+    <!-- no translation found for recent_task_option_desktop (8280879717125435668) -->
+    <skip />
     <string name="recents_empty_message" msgid="7040467240571714191">"സമീപകാല ഇനങ്ങൾ ഒന്നുമില്ല"</string>
     <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"ആപ്പ് ഉപയോഗ ക്രമീകരണം"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"എല്ലാം മായ്‌ക്കുക"</string>
@@ -116,6 +118,8 @@
     <string name="taskbar_edu_features" msgid="3320337287472848162">"ടാസ്‌ക്‌ബാർ ഉപയോഗിച്ച് കൂടുതൽ ചെയ്യുക"</string>
     <string name="taskbar_edu_pinning_title" msgid="210102174154211712">"എല്ലായ്‌പ്പോഴും ടാസ്‌ക്‌ബാർ കാണിക്കുക"</string>
     <string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"ടാസ്‌ക്ബാർ എല്ലായ്‌പ്പോഴും നിങ്ങളുടെ സ്‌ക്രീനിന്റെ ചുവടെ കാണിക്കുന്നതിന് ഡിവൈഡറിൽ സ്‌പർശിച്ച് പിടിക്കുക"</string>
+    <string name="taskbar_edu_circle_to_search_title" msgid="4322780398403949508">"നിങ്ങളുടെ സ്‌ക്രീനിൽ എന്താണ് ഉള്ളതെന്ന് തിരയാൻ ആക്ഷൻ കീ സ്‌പർശിച്ച് പിടിക്കുക"</string>
+    <string name="taskbar_edu_circle_to_search_disclosure" msgid="5841648785867787221">"തിരയുന്നതിന് ഈ ഉൽപ്പന്നം സ്‌ക്രീനിലെ തിരഞ്ഞെടുത്ത ഭാഗം ഉപയോഗിക്കുന്നു. Google-ന്റെ <xliff:g id="BEGIN_PRIVACY_LINK">&lt;a href="%1$s"&gt;</xliff:g>സ്വകാര്യതാ നയവും<xliff:g id="END_PRIVACY_LINK">&lt;/a&gt;</xliff:g> <xliff:g id="BEGIN_TOS_LINK">&lt;a href="%2$s"&gt;</xliff:g>സേവന നിബന്ധനകളും<xliff:g id="END_TOS_LINK">&lt;/a&gt;</xliff:g> ബാധകമാണ്."</string>
     <string name="taskbar_edu_close" msgid="887022990168191073">"അടയ്ക്കുക"</string>
     <string name="taskbar_edu_done" msgid="6880178093977704569">"പൂർത്തിയായി"</string>
     <string name="taskbar_button_home" msgid="2151398979630664652">"ഹോം"</string>
diff --git a/quickstep/res/values-mn/strings.xml b/quickstep/res/values-mn/strings.xml
index d4f7537..bc6a43b 100644
--- a/quickstep/res/values-mn/strings.xml
+++ b/quickstep/res/values-mn/strings.xml
@@ -21,6 +21,8 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Бэхлэх"</string>
     <string name="recent_task_option_freeform" msgid="48863056265284071">"Чөлөөтэй хувьсах"</string>
+    <!-- no translation found for recent_task_option_desktop (8280879717125435668) -->
+    <skip />
     <string name="recents_empty_message" msgid="7040467240571714191">"Сүүлийн үеийн зүйл алга"</string>
     <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Апп ашиглалтын тохиргоо"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Бүгдийг арилгах"</string>
@@ -116,6 +118,10 @@
     <string name="taskbar_edu_features" msgid="3320337287472848162">"Ажлын хэсгийн тусламжтай илүү ихийг хийгээрэй"</string>
     <string name="taskbar_edu_pinning_title" msgid="210102174154211712">"Ажлын хэсгийг үргэлж харуулах"</string>
     <string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"Дэлгэцийнхээ доод талд Ажлын хэсгийг үргэлж харуулахын тулд хуваагч дээр хүрээд удаан дарна уу"</string>
+    <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
+    <skip />
+    <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
+    <skip />
     <string name="taskbar_edu_close" msgid="887022990168191073">"Хаах"</string>
     <string name="taskbar_edu_done" msgid="6880178093977704569">"Дууссан"</string>
     <string name="taskbar_button_home" msgid="2151398979630664652">"Гэр"</string>
diff --git a/quickstep/res/values-mr/strings.xml b/quickstep/res/values-mr/strings.xml
index c8f147a..b0c6aca 100644
--- a/quickstep/res/values-mr/strings.xml
+++ b/quickstep/res/values-mr/strings.xml
@@ -21,6 +21,8 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_pin" msgid="7929860679018978258">"पिन करा"</string>
     <string name="recent_task_option_freeform" msgid="48863056265284071">"फ्रीफॉर्म"</string>
+    <!-- no translation found for recent_task_option_desktop (8280879717125435668) -->
+    <skip />
     <string name="recents_empty_message" msgid="7040467240571714191">"कोणतेही अलीकडील आयटम नाहीत"</string>
     <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"अ‍ॅप वापर सेटिंग्ज"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"सर्व साफ करा"</string>
@@ -116,6 +118,10 @@
     <string name="taskbar_edu_features" msgid="3320337287472848162">"टास्कबार चा पुरेपूर वापर करा"</string>
     <string name="taskbar_edu_pinning_title" msgid="210102174154211712">"टास्कबार नेहमी दाखवा"</string>
     <string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"टास्कबार नेहमी तुमच्या स्क्रीनच्या तळाशी दाखवण्यासाठी, विभाजकाला स्पर्श करून धरून ठेवा"</string>
+    <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
+    <skip />
+    <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
+    <skip />
     <string name="taskbar_edu_close" msgid="887022990168191073">"बंद करा"</string>
     <string name="taskbar_edu_done" msgid="6880178093977704569">"पूर्ण झाले"</string>
     <string name="taskbar_button_home" msgid="2151398979630664652">"होम"</string>
diff --git a/quickstep/res/values-ms/strings.xml b/quickstep/res/values-ms/strings.xml
index 575ce64..87c6e24 100644
--- a/quickstep/res/values-ms/strings.xml
+++ b/quickstep/res/values-ms/strings.xml
@@ -21,6 +21,8 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Semat"</string>
     <string name="recent_task_option_freeform" msgid="48863056265284071">"Bentuk bebas"</string>
+    <!-- no translation found for recent_task_option_desktop (8280879717125435668) -->
+    <skip />
     <string name="recents_empty_message" msgid="7040467240571714191">"Tiada item terbaharu"</string>
     <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Tetapan penggunaan apl"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Kosongkan semua"</string>
@@ -116,6 +118,8 @@
     <string name="taskbar_edu_features" msgid="3320337287472848162">"Lakukan lebih banyak perkara dengan Bar Tugas"</string>
     <string name="taskbar_edu_pinning_title" msgid="210102174154211712">"Sentiasa paparkan Bar Tugas"</string>
     <string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"Untuk sentiasa memaparkan Bar Tugas pada bahagian bawah skrin, sentuh &amp; tahan pembahagi"</string>
+    <string name="taskbar_edu_circle_to_search_title" msgid="4322780398403949508">"Sentuh &amp; tahan kekunci tindakan untuk mencari kandungan yang dipaparkan pada skrin anda"</string>
+    <string name="taskbar_edu_circle_to_search_disclosure" msgid="5841648785867787221">"Produk ini menggunakan bahagian yang dipilih pada skrin untuk membuat carian. <xliff:g id="BEGIN_PRIVACY_LINK">&lt;a href="%1$s"&gt;</xliff:g>Dasar Privasi<xliff:g id="END_PRIVACY_LINK">&lt;/a&gt;</xliff:g> dan <xliff:g id="BEGIN_TOS_LINK">&lt;a href="%2$s"&gt;</xliff:g>Syarat Perkhidmatan<xliff:g id="END_TOS_LINK">&lt;/a&gt;</xliff:g> Google digunakan."</string>
     <string name="taskbar_edu_close" msgid="887022990168191073">"Tutup"</string>
     <string name="taskbar_edu_done" msgid="6880178093977704569">"Selesai"</string>
     <string name="taskbar_button_home" msgid="2151398979630664652">"Laman Utama"</string>
diff --git a/quickstep/res/values-my/strings.xml b/quickstep/res/values-my/strings.xml
index 762f669..d7c98d3 100644
--- a/quickstep/res/values-my/strings.xml
+++ b/quickstep/res/values-my/strings.xml
@@ -21,6 +21,8 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_pin" msgid="7929860679018978258">"ပင်ထိုးရန်"</string>
     <string name="recent_task_option_freeform" msgid="48863056265284071">"အလွတ်ပုံစံ"</string>
+    <!-- no translation found for recent_task_option_desktop (8280879717125435668) -->
+    <skip />
     <string name="recents_empty_message" msgid="7040467240571714191">"မကြာမီကဖွင့်ထားသည်များ မရှိပါ"</string>
     <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"အက်ပ်အသုံးပြုမှု ဆက်တင်များ"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"အားလုံးရှင်းရန်"</string>
@@ -116,6 +118,10 @@
     <string name="taskbar_edu_features" msgid="3320337287472848162">"Taskbar ဖြင့် ပိုမိုလုပ်ဆောင်နိုင်ခြင်း"</string>
     <string name="taskbar_edu_pinning_title" msgid="210102174154211712">"Taskbar ကို အမြဲပြပါ"</string>
     <string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"Taskbar ကို စခရင်အောက်ခြေတွင် အမြဲပြရန် ခွဲခြားမျဉ်းကို တို့ထိ၍ ဖိထားပါ"</string>
+    <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
+    <skip />
+    <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
+    <skip />
     <string name="taskbar_edu_close" msgid="887022990168191073">"ပိတ်ရန်"</string>
     <string name="taskbar_edu_done" msgid="6880178093977704569">"ပြီးပြီ"</string>
     <string name="taskbar_button_home" msgid="2151398979630664652">"ပင်မစာမျက်နှာ"</string>
@@ -129,7 +135,7 @@
     <string name="taskbar_a11y_shown_title" msgid="6842833581088937713">"Taskbar ပြထားသည်"</string>
     <string name="taskbar_a11y_hidden_title" msgid="9154903639589659284">"Taskbar ဖျောက်ထားသည်"</string>
     <string name="taskbar_phone_a11y_title" msgid="4933360237131229395">"လမ်းညွှန်ဘား"</string>
-    <string name="always_show_taskbar" msgid="3608801276107751229">"Taskbar အမြဲပြပါ"</string>
+    <string name="always_show_taskbar" msgid="3608801276107751229">"Taskbar အမြဲပြရန်"</string>
     <string name="change_navigation_mode" msgid="9088393078736808968">"ရွှေ့ကြည့်သည့်မုဒ် ပြောင်းရန်"</string>
     <string name="taskbar_divider_a11y_title" msgid="6608690309720242080">"လုပ်ဆောင်စရာဘား ပိုင်းခြားစနစ်"</string>
     <string name="move_drop_target_top_or_left" msgid="2988702185049595807">"အပေါ်/ဘယ်ဘက်သို့ ရွှေ့ရန်"</string>
diff --git a/quickstep/res/values-nb/strings.xml b/quickstep/res/values-nb/strings.xml
index 2383000..550bacc 100644
--- a/quickstep/res/values-nb/strings.xml
+++ b/quickstep/res/values-nb/strings.xml
@@ -21,6 +21,8 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Fest"</string>
     <string name="recent_task_option_freeform" msgid="48863056265284071">"Fritt format"</string>
+    <!-- no translation found for recent_task_option_desktop (8280879717125435668) -->
+    <skip />
     <string name="recents_empty_message" msgid="7040467240571714191">"Ingen nylige elementer"</string>
     <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Innstillinger for appbruk"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Fjern alt"</string>
@@ -116,6 +118,10 @@
     <string name="taskbar_edu_features" msgid="3320337287472848162">"Gjør mer med oppgavelinjen"</string>
     <string name="taskbar_edu_pinning_title" msgid="210102174154211712">"Vis alltid oppgavelinjen"</string>
     <string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"For å alltid vise oppgavelinjen nederst på skjermen, trykk og hold på skillelinjen"</string>
+    <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
+    <skip />
+    <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
+    <skip />
     <string name="taskbar_edu_close" msgid="887022990168191073">"Lukk"</string>
     <string name="taskbar_edu_done" msgid="6880178093977704569">"Ferdig"</string>
     <string name="taskbar_button_home" msgid="2151398979630664652">"Hjem"</string>
diff --git a/quickstep/res/values-ne/strings.xml b/quickstep/res/values-ne/strings.xml
index fb5ebb3..acfa2ce 100644
--- a/quickstep/res/values-ne/strings.xml
+++ b/quickstep/res/values-ne/strings.xml
@@ -21,6 +21,8 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_pin" msgid="7929860679018978258">"पिन गर्नुहोस्"</string>
     <string name="recent_task_option_freeform" msgid="48863056265284071">"फ्रिफर्म"</string>
+    <!-- no translation found for recent_task_option_desktop (8280879717125435668) -->
+    <skip />
     <string name="recents_empty_message" msgid="7040467240571714191">"हालसालैको कुनै पनि वस्तु छैन"</string>
     <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"एपको उपयोगका सेटिङहरू"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"सबै मेटाउनुहोस्"</string>
@@ -114,8 +116,10 @@
     <string name="taskbar_edu_suggestions" msgid="8215044496435527982">"आफ्नो रुटिनका आधारमा एपसम्बन्धी सुझावहरू प्राप्त गर्नुहोस्"</string>
     <string name="taskbar_edu_pinning" msgid="6708550858580071558">"टास्कबार पिन गर्न डिभाइडरमा केही बेरसम्म थिच्नुहोस्"</string>
     <string name="taskbar_edu_features" msgid="3320337287472848162">"टास्कबार प्रयोग गरेर अझ धेरै कार्य गर्नुहोस्"</string>
-    <string name="taskbar_edu_pinning_title" msgid="210102174154211712">"टास्कबार सधैँ देखाइयोस्"</string>
+    <string name="taskbar_edu_pinning_title" msgid="210102174154211712">"टास्कबार सधैँ देखाउनुहोस्"</string>
     <string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"आफ्नो स्क्रिनको पुछारमा टास्कबार सधैँ देखाइराख्न डिभाइडर टच एन्ड होल्ड गर्नुहोस्"</string>
+    <string name="taskbar_edu_circle_to_search_title" msgid="4322780398403949508">"आफ्नो स्क्रिनमा भएका कुराहरू खोज्न एक्सन कीमा टच एण्ड होल्ड गर्नुहोस्"</string>
+    <string name="taskbar_edu_circle_to_search_disclosure" msgid="5841648785867787221">"यो उत्पादनले तपाईंले चयन गर्नुभएको स्क्रिनको भाग प्रयोग गरेर खोजी गर्छ। Google को <xliff:g id="BEGIN_PRIVACY_LINK">&lt;a href="%1$s"&gt;</xliff:g>गोपनीयता नीति<xliff:g id="END_PRIVACY_LINK">&lt;/a&gt;</xliff:g> र <xliff:g id="BEGIN_TOS_LINK">&lt;a href="%2$s"&gt;</xliff:g>सेवाका सर्तहरू<xliff:g id="END_TOS_LINK">&lt;/a&gt;</xliff:g> लागू हुन्छन्।"</string>
     <string name="taskbar_edu_close" msgid="887022990168191073">"बन्द गर्नुहोस्"</string>
     <string name="taskbar_edu_done" msgid="6880178093977704569">"सम्पन्न भयो"</string>
     <string name="taskbar_button_home" msgid="2151398979630664652">"होम"</string>
@@ -129,12 +133,12 @@
     <string name="taskbar_a11y_shown_title" msgid="6842833581088937713">"टास्कबार देखाइएको छ"</string>
     <string name="taskbar_a11y_hidden_title" msgid="9154903639589659284">"टास्कबार लुकाइएको छ"</string>
     <string name="taskbar_phone_a11y_title" msgid="4933360237131229395">"नेभिगेसन बार"</string>
-    <string name="always_show_taskbar" msgid="3608801276107751229">"टास्कबार सधैँ देखाइयोस्"</string>
+    <string name="always_show_taskbar" msgid="3608801276107751229">"टास्कबार सधैँ देखाउनुहोस्"</string>
     <string name="change_navigation_mode" msgid="9088393078736808968">"नेभिगेसन मोड बदल्नुहोस्"</string>
     <string name="taskbar_divider_a11y_title" msgid="6608690309720242080">"टास्कबार डिभाइडर"</string>
     <string name="move_drop_target_top_or_left" msgid="2988702185049595807">"सिरान/बायाँतिर सार्नुहोस्"</string>
     <string name="move_drop_target_bottom_or_right" msgid="5431393418797620162">"फेद/दायाँतिर सार्नुहोस्"</string>
-    <string name="quick_switch_overflow" msgid="6935266023013283353">"{count,plural, =1{थप # एप देखाइयोस्।}other{थप # वटा एप देखाइयोस्।}}"</string>
+    <string name="quick_switch_overflow" msgid="6935266023013283353">"{count,plural, =1{थप # एप देखाउनुहोस्।}other{थप # वटा एप देखाउनुहोस्।}}"</string>
     <string name="quick_switch_split_task" msgid="5598194724255333896">"<xliff:g id="APP_NAME_1">%1$s</xliff:g> र <xliff:g id="APP_NAME_2">%2$s</xliff:g>"</string>
     <string name="desktop_select_app_toast" msgid="2306057322833956910">"डेस्कटपमा एप हालिँदै छ"</string>
     <string name="desktop_button_close_app_toast" msgid="5283096349579408560">"रद्द गर्नुहोस्"</string>
diff --git a/quickstep/res/values-nl/strings.xml b/quickstep/res/values-nl/strings.xml
index 999da4e..3032ade 100644
--- a/quickstep/res/values-nl/strings.xml
+++ b/quickstep/res/values-nl/strings.xml
@@ -21,6 +21,8 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Vastzetten"</string>
     <string name="recent_task_option_freeform" msgid="48863056265284071">"Vrije vorm"</string>
+    <!-- no translation found for recent_task_option_desktop (8280879717125435668) -->
+    <skip />
     <string name="recents_empty_message" msgid="7040467240571714191">"Geen recente items"</string>
     <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Instellingen voor app-gebruik"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Alles wissen"</string>
@@ -97,7 +99,7 @@
     <string name="action_split" msgid="2098009717623550676">"Splitsen"</string>
     <string name="action_save_app_pair" msgid="5974823919237645229">"App-paar opslaan"</string>
     <string name="toast_split_select_app" msgid="8464310533320556058">"Tik op nog een app om je scherm te splitsen"</string>
-    <string name="toast_contextual_split_select_app" msgid="433510957123687090">"Kies andere app om gesplitst scherm te gebruiken"</string>
+    <string name="toast_contextual_split_select_app" msgid="433510957123687090">"Kies een andere app om gesplitst scherm te gebruiken"</string>
     <string name="toast_split_select_app_cancel" msgid="1532690483356445639"><b>"Annuleren"</b></string>
     <string name="toast_split_select_cont_desc" msgid="2119685056059607602">"Sluit de selectie voor gesplitst scherm"</string>
     <string name="toast_split_app_unsupported" msgid="2360229567007828914">"Kies andere app om gesplitst scherm te gebruiken"</string>
@@ -116,6 +118,10 @@
     <string name="taskbar_edu_features" msgid="3320337287472848162">"Doe meer met de taakbalk"</string>
     <string name="taskbar_edu_pinning_title" msgid="210102174154211712">"De taakbalk altijd tonen"</string>
     <string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"Houd de scheidingslijn ingedrukt als je de taakbalk altijd onderaan je scherm wilt tonen"</string>
+    <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
+    <skip />
+    <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
+    <skip />
     <string name="taskbar_edu_close" msgid="887022990168191073">"Sluiten"</string>
     <string name="taskbar_edu_done" msgid="6880178093977704569">"Klaar"</string>
     <string name="taskbar_button_home" msgid="2151398979630664652">"Home"</string>
diff --git a/quickstep/res/values-or/strings.xml b/quickstep/res/values-or/strings.xml
index 1ddcdf2..a67cff9 100644
--- a/quickstep/res/values-or/strings.xml
+++ b/quickstep/res/values-or/strings.xml
@@ -21,6 +21,8 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_pin" msgid="7929860679018978258">"ପିନ୍‍"</string>
     <string name="recent_task_option_freeform" msgid="48863056265284071">"ଫ୍ରିଫର୍ମ"</string>
+    <!-- no translation found for recent_task_option_desktop (8280879717125435668) -->
+    <skip />
     <string name="recents_empty_message" msgid="7040467240571714191">"ବର୍ତ୍ତମାନର କୌଣସି ଆଇଟମ ନାହିଁ"</string>
     <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"ଆପ ବ୍ୟବହାର ସେଟିଂସ"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"ସବୁ ଖାଲି କରନ୍ତୁ"</string>
@@ -116,6 +118,8 @@
     <string name="taskbar_edu_features" msgid="3320337287472848162">"ଟାସ୍କବାର ମାଧ୍ୟମରେ ଆହୁରି ଅନେକ କିଛି କରନ୍ତୁ"</string>
     <string name="taskbar_edu_pinning_title" msgid="210102174154211712">"ସର୍ବଦା ଟାସ୍କବାର ଦେଖାନ୍ତୁ"</string>
     <string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"ଆପଣଙ୍କ ସ୍କ୍ରିନର ନିମ୍ନରେ ସର୍ବଦା ଟାସ୍କବାର ଦେଖାଇବା ପାଇଁ ଡିଭାଇଡରକୁ ସ୍ପର୍ଶ କରି ଧରି ରଖନ୍ତୁ"</string>
+    <string name="taskbar_edu_circle_to_search_title" msgid="4322780398403949508">"ଆପଣଙ୍କ ସ୍କ୍ରିନରେ କଣ ଅଛି ତାହା ସର୍ଚ୍ଚ କରିବା ପାଇଁ ଆକ୍ସନ କୀ\'କୁ ସ୍ପର୍ଶ କରି ଧରି ରଖନ୍ତୁ"</string>
+    <string name="taskbar_edu_circle_to_search_disclosure" msgid="5841648785867787221">"ସର୍ଚ୍ଚ କରିବା ପାଇଁ ଏହି ପ୍ରଡକ୍ଟ ଆପଣଙ୍କ ସ୍କ୍ରିନର ଚୟନିତ ଅଂଶକୁ ବ୍ୟବହାର କରେ। Googleର <xliff:g id="BEGIN_PRIVACY_LINK">&lt;a href="%1$s"&gt;</xliff:g>ଗୋପନୀୟତା ନୀତି<xliff:g id="END_PRIVACY_LINK">&lt;/a&gt;</xliff:g> ଏବଂ <xliff:g id="BEGIN_TOS_LINK">&lt;a href="%2$s"&gt;</xliff:g>ସେବାର ସର୍ତ୍ତାବଳୀ<xliff:g id="END_TOS_LINK">&lt;/a&gt;</xliff:g> ଲାଗୁ ହୁଏ।"</string>
     <string name="taskbar_edu_close" msgid="887022990168191073">"ବନ୍ଦ କରନ୍ତୁ"</string>
     <string name="taskbar_edu_done" msgid="6880178093977704569">"ହୋଇଗଲା"</string>
     <string name="taskbar_button_home" msgid="2151398979630664652">"ହୋମ"</string>
diff --git a/quickstep/res/values-pa/strings.xml b/quickstep/res/values-pa/strings.xml
index 4b80a2e..38d2dac 100644
--- a/quickstep/res/values-pa/strings.xml
+++ b/quickstep/res/values-pa/strings.xml
@@ -21,7 +21,9 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_pin" msgid="7929860679018978258">"ਪਿੰਨ ਕਰੋ"</string>
     <string name="recent_task_option_freeform" msgid="48863056265284071">"ਫ੍ਰੀਫਾਰਮ"</string>
-    <string name="recents_empty_message" msgid="7040467240571714191">"ਕੋਈ ਹਾਲੀਆ ਆਈਟਮਾਂ ਨਹੀਂ"</string>
+    <!-- no translation found for recent_task_option_desktop (8280879717125435668) -->
+    <skip />
+    <string name="recents_empty_message" msgid="7040467240571714191">"ਕੋਈ ਹਾਲੀਆ ਆਈਟਮ ਨਹੀਂ"</string>
     <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"ਐਪ ਵਰਤੋਂ ਦੀਆਂ ਸੈਟਿੰਗਾਂ"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"ਸਭ ਕਲੀਅਰ ਕਰੋ"</string>
     <string name="accessibility_recent_apps" msgid="4058661986695117371">"ਹਾਲੀਆ ਐਪਾਂ"</string>
@@ -116,6 +118,10 @@
     <string name="taskbar_edu_features" msgid="3320337287472848162">"ਟਾਸਕਬਾਰ ਦਾ ਹੋਰ ਲਾਹਾ ਲਓ"</string>
     <string name="taskbar_edu_pinning_title" msgid="210102174154211712">"ਹਮੇਸ਼ਾਂ ਟਾਸਕਬਾਰ ਦਿਖਾਉਣਾ"</string>
     <string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"ਆਪਣੀ ਸਕ੍ਰੀਨ ਦੇ ਹੇਠਾਂ ਹਮੇਸ਼ਾਂ ਟਾਸਕਬਾਰ ਦਿਖਾਉਣ ਲਈ, ਵਿਭਾਜਕ ਨੂੰ ਸਪਰਸ਼ ਕਰ ਕੇ ਰੱਖੋ"</string>
+    <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
+    <skip />
+    <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
+    <skip />
     <string name="taskbar_edu_close" msgid="887022990168191073">"ਬੰਦ ਕਰੋ"</string>
     <string name="taskbar_edu_done" msgid="6880178093977704569">"ਸਮਝ ਲਿਆ"</string>
     <string name="taskbar_button_home" msgid="2151398979630664652">"ਘਰ"</string>
diff --git a/quickstep/res/values-pl/strings.xml b/quickstep/res/values-pl/strings.xml
index bf816fe..9a55b94 100644
--- a/quickstep/res/values-pl/strings.xml
+++ b/quickstep/res/values-pl/strings.xml
@@ -21,6 +21,8 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Przypnij"</string>
     <string name="recent_task_option_freeform" msgid="48863056265284071">"Tryb dowolny"</string>
+    <!-- no translation found for recent_task_option_desktop (8280879717125435668) -->
+    <skip />
     <string name="recents_empty_message" msgid="7040467240571714191">"Brak ostatnich elementów"</string>
     <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Ustawienia użycia aplikacji"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Wyczyść wszystko"</string>
@@ -116,6 +118,8 @@
     <string name="taskbar_edu_features" msgid="3320337287472848162">"Wykorzystaj potencjał paska aplikacji"</string>
     <string name="taskbar_edu_pinning_title" msgid="210102174154211712">"Zawsze wyświetlaj pasek aplikacji"</string>
     <string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"Aby zawsze wyświetlać pasek aplikacji u dołu ekranu, naciśnij i przytrzymaj linię dzielenia ekranu"</string>
+    <string name="taskbar_edu_circle_to_search_title" msgid="4322780398403949508">"Aby rozpocząć wyszukiwanie na podstawie zawartości ekranu, naciśnij i przytrzymaj klawisz działania"</string>
+    <string name="taskbar_edu_circle_to_search_disclosure" msgid="5841648785867787221">"Usługa przy wyszukiwaniu używa zaznaczonego fragmentu ekranu. Obowiązują zapisy <xliff:g id="BEGIN_PRIVACY_LINK">&lt;a href="%1$s"&gt;</xliff:g>Polityki prywatności<xliff:g id="END_PRIVACY_LINK">&lt;/a&gt;</xliff:g> i <xliff:g id="BEGIN_TOS_LINK">&lt;a href="%2$s"&gt;</xliff:g>Warunków korzystania z usług<xliff:g id="END_TOS_LINK">&lt;/a&gt;</xliff:g> Google."</string>
     <string name="taskbar_edu_close" msgid="887022990168191073">"Zamknij"</string>
     <string name="taskbar_edu_done" msgid="6880178093977704569">"Gotowe"</string>
     <string name="taskbar_button_home" msgid="2151398979630664652">"Ekran główny"</string>
diff --git a/quickstep/res/values-pt-rPT/strings.xml b/quickstep/res/values-pt-rPT/strings.xml
index ce13890..202813b 100644
--- a/quickstep/res/values-pt-rPT/strings.xml
+++ b/quickstep/res/values-pt-rPT/strings.xml
@@ -21,6 +21,8 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Fixar"</string>
     <string name="recent_task_option_freeform" msgid="48863056265284071">"Forma livre"</string>
+    <!-- no translation found for recent_task_option_desktop (8280879717125435668) -->
+    <skip />
     <string name="recents_empty_message" msgid="7040467240571714191">"Nenhum item recente"</string>
     <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Definições de utilização de aplicações"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Limpar tudo"</string>
@@ -110,12 +112,14 @@
     <string name="accessibility_rotate_button" msgid="4771825231336502943">"Rodar ecrã"</string>
     <string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"Educação da Barra de tarefas"</string>
     <string name="taskbar_edu_splitscreen" msgid="5605512479258053350">"Arraste uma app para o lado para usar 2 apps em simultâneo"</string>
-    <string name="taskbar_edu_stashing" msgid="5645461372669217294">"Deslize lentamente para cima para mostrar a Barra de tarefas"</string>
+    <string name="taskbar_edu_stashing" msgid="5645461372669217294">"Deslize lentamente para cima para ver a Barra de tarefas"</string>
     <string name="taskbar_edu_suggestions" msgid="8215044496435527982">"Receba sugestões de apps baseadas na sua rotina"</string>
     <string name="taskbar_edu_pinning" msgid="6708550858580071558">"Mantenha o divisor premido para fixar a Barra de tarefas"</string>
     <string name="taskbar_edu_features" msgid="3320337287472848162">"Faça mais com a Barra de tarefas"</string>
     <string name="taskbar_edu_pinning_title" msgid="210102174154211712">"Mostre sempre a Barra de tarefas"</string>
     <string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"Para mostrar sempre a Barra de tarefas no fundo do ecrã, toque sem soltar no divisor"</string>
+    <string name="taskbar_edu_circle_to_search_title" msgid="4322780398403949508">"Toque sem soltar na tecla de ação para pesquisar o que está no ecrã"</string>
+    <string name="taskbar_edu_circle_to_search_disclosure" msgid="5841648785867787221">"Este produto usa a parte selecionada do ecrã para pesquisar. Aplicam-se a <xliff:g id="BEGIN_PRIVACY_LINK">&lt;a href="%1$s"&gt;</xliff:g>Política de Privacidade<xliff:g id="END_PRIVACY_LINK">&lt;/a&gt;</xliff:g> e os <xliff:g id="BEGIN_TOS_LINK">&lt;a href="%2$s"&gt;</xliff:g>Termos de Utilização<xliff:g id="END_TOS_LINK">&lt;/a&gt;</xliff:g> da Google."</string>
     <string name="taskbar_edu_close" msgid="887022990168191073">"Fechar"</string>
     <string name="taskbar_edu_done" msgid="6880178093977704569">"Concluir"</string>
     <string name="taskbar_button_home" msgid="2151398979630664652">"Início"</string>
diff --git a/quickstep/res/values-pt/strings.xml b/quickstep/res/values-pt/strings.xml
index 80f461a..532a598 100644
--- a/quickstep/res/values-pt/strings.xml
+++ b/quickstep/res/values-pt/strings.xml
@@ -21,6 +21,8 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Fixar"</string>
     <string name="recent_task_option_freeform" msgid="48863056265284071">"Forma livre"</string>
+    <!-- no translation found for recent_task_option_desktop (8280879717125435668) -->
+    <skip />
     <string name="recents_empty_message" msgid="7040467240571714191">"Nenhum item recente"</string>
     <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Configurações de uso do app"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Remover tudo"</string>
@@ -116,6 +118,10 @@
     <string name="taskbar_edu_features" msgid="3320337287472848162">"Aproveite ainda mais a Barra de tarefas"</string>
     <string name="taskbar_edu_pinning_title" msgid="210102174154211712">"Sempre mostrar a Barra de tarefas"</string>
     <string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"Toque e pressione o divisor para sempre mostrar a Barra de tarefas na parte de baixo da tela"</string>
+    <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
+    <skip />
+    <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
+    <skip />
     <string name="taskbar_edu_close" msgid="887022990168191073">"Fechar"</string>
     <string name="taskbar_edu_done" msgid="6880178093977704569">"Concluído"</string>
     <string name="taskbar_button_home" msgid="2151398979630664652">"Início"</string>
diff --git a/quickstep/res/values-ro/strings.xml b/quickstep/res/values-ro/strings.xml
index 25307b0..ed7dfd8 100644
--- a/quickstep/res/values-ro/strings.xml
+++ b/quickstep/res/values-ro/strings.xml
@@ -21,6 +21,8 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Fixează"</string>
     <string name="recent_task_option_freeform" msgid="48863056265284071">"Formă liberă"</string>
+    <!-- no translation found for recent_task_option_desktop (8280879717125435668) -->
+    <skip />
     <string name="recents_empty_message" msgid="7040467240571714191">"Niciun element recent"</string>
     <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Setări de utilizare a aplicației"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Șterge tot"</string>
@@ -116,6 +118,10 @@
     <string name="taskbar_edu_features" msgid="3320337287472848162">"Fă mai multe din Bara de activități"</string>
     <string name="taskbar_edu_pinning_title" msgid="210102174154211712">"Afișează întotdeauna Bara de activități"</string>
     <string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"Pentru a afișa mereu Bara de activități în partea de jos a ecranului, atinge lung separatorul"</string>
+    <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
+    <skip />
+    <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
+    <skip />
     <string name="taskbar_edu_close" msgid="887022990168191073">"Închide"</string>
     <string name="taskbar_edu_done" msgid="6880178093977704569">"Gata"</string>
     <string name="taskbar_button_home" msgid="2151398979630664652">"Ecran de pornire"</string>
diff --git a/quickstep/res/values-ru/strings.xml b/quickstep/res/values-ru/strings.xml
index 4e1a213..6f1d9e7 100644
--- a/quickstep/res/values-ru/strings.xml
+++ b/quickstep/res/values-ru/strings.xml
@@ -21,6 +21,8 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Закрепить"</string>
     <string name="recent_task_option_freeform" msgid="48863056265284071">"Произвольная форма"</string>
+    <!-- no translation found for recent_task_option_desktop (8280879717125435668) -->
+    <skip />
     <string name="recents_empty_message" msgid="7040467240571714191">"Здесь пока ничего нет."</string>
     <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Настройки использования приложения"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Очистить все"</string>
@@ -116,6 +118,8 @@
     <string name="taskbar_edu_features" msgid="3320337287472848162">"Используйте все возможности панели задач"</string>
     <string name="taskbar_edu_pinning_title" msgid="210102174154211712">"Закрепите панель задач внизу экрана"</string>
     <string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"Для этого нажмите на разделитель и удерживайте его."</string>
+    <string name="taskbar_edu_circle_to_search_title" msgid="4322780398403949508">"Чтобы найти информацию об объекте на экране, нажмите и удерживайте клавишу действия"</string>
+    <string name="taskbar_edu_circle_to_search_disclosure" msgid="5841648785867787221">"Этот продукт использует выделенную часть экрана для поиска. При этом действуют <xliff:g id="BEGIN_PRIVACY_LINK">&lt;a href="%1$s"&gt;</xliff:g>Политика конфиденциальности<xliff:g id="END_PRIVACY_LINK">&lt;/a&gt;</xliff:g> и <xliff:g id="BEGIN_TOS_LINK">&lt;a href="%2$s"&gt;</xliff:g>Условия использования<xliff:g id="END_TOS_LINK">&lt;/a&gt;</xliff:g> Google."</string>
     <string name="taskbar_edu_close" msgid="887022990168191073">"Закрыть"</string>
     <string name="taskbar_edu_done" msgid="6880178093977704569">"Готово"</string>
     <string name="taskbar_button_home" msgid="2151398979630664652">"Главный экран"</string>
diff --git a/quickstep/res/values-si/strings.xml b/quickstep/res/values-si/strings.xml
index 2e2151d..1335e0e 100644
--- a/quickstep/res/values-si/strings.xml
+++ b/quickstep/res/values-si/strings.xml
@@ -21,6 +21,8 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_pin" msgid="7929860679018978258">"අමුණන්න"</string>
     <string name="recent_task_option_freeform" msgid="48863056265284071">"Freeform"</string>
+    <!-- no translation found for recent_task_option_desktop (8280879717125435668) -->
+    <skip />
     <string name="recents_empty_message" msgid="7040467240571714191">"මෑත අයිතම නැත"</string>
     <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"යෙදුම් භාවිත සැකසීම්"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"සියල්ල හිස් කරන්න"</string>
@@ -116,6 +118,10 @@
     <string name="taskbar_edu_features" msgid="3320337287472848162">"කාර්ය තීරුව සමග තවත් කරන්න"</string>
     <string name="taskbar_edu_pinning_title" msgid="210102174154211712">"සෑම විටම කාර්ය තීරුව පෙන්වන්න"</string>
     <string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"සෑම විටම ඔබේ තිරයේ පතුලේ ඇති කාර්ය තීරුව පෙන්වීමට, බෙදුම්කරු ස්පර්ශ කර අල්ලාගෙන සිටින්න"</string>
+    <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
+    <skip />
+    <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
+    <skip />
     <string name="taskbar_edu_close" msgid="887022990168191073">"වසන්න"</string>
     <string name="taskbar_edu_done" msgid="6880178093977704569">"නිමයි"</string>
     <string name="taskbar_button_home" msgid="2151398979630664652">"මුල් පිටුව"</string>
diff --git a/quickstep/res/values-sk/strings.xml b/quickstep/res/values-sk/strings.xml
index 1865043..48f7a9c 100644
--- a/quickstep/res/values-sk/strings.xml
+++ b/quickstep/res/values-sk/strings.xml
@@ -21,6 +21,8 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Pripnúť"</string>
     <string name="recent_task_option_freeform" msgid="48863056265284071">"Voľný režim"</string>
+    <!-- no translation found for recent_task_option_desktop (8280879717125435668) -->
+    <skip />
     <string name="recents_empty_message" msgid="7040467240571714191">"Žiadne nedávne položky"</string>
     <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Nastavenia využívania aplikácie"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Vymazať všetko"</string>
@@ -97,7 +99,7 @@
     <string name="action_split" msgid="2098009717623550676">"Rozdeliť"</string>
     <string name="action_save_app_pair" msgid="5974823919237645229">"Uložiť pár aplikácií"</string>
     <string name="toast_split_select_app" msgid="8464310533320556058">"Obrazovku rozdelíte klepnutím na inú aplikáciu"</string>
-    <string name="toast_contextual_split_select_app" msgid="433510957123687090">"Na použitie rozdelenej obrazovky vyberte inú aplikáciu"</string>
+    <string name="toast_contextual_split_select_app" msgid="433510957123687090">"Na použitie rozdelenej obrazovky vyberte ďalšiu aplikáciu"</string>
     <string name="toast_split_select_app_cancel" msgid="1532690483356445639"><b>"Zrušiť"</b></string>
     <string name="toast_split_select_cont_desc" msgid="2119685056059607602">"Ukončite výber rozdelenej obrazovky"</string>
     <string name="toast_split_app_unsupported" msgid="2360229567007828914">"Na použitie rozd. obrazovky vyberte inú aplikáciu"</string>
@@ -116,6 +118,8 @@
     <string name="taskbar_edu_features" msgid="3320337287472848162">"Panel aplikácií vám ponúka ďalšie možnosti"</string>
     <string name="taskbar_edu_pinning_title" msgid="210102174154211712">"Vždy zobrazovať panel aplikácií"</string>
     <string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"Ak chcete, aby sa panel aplikácií vždy zobrazoval v dolnej časti obrazovky, pridržte rozdeľovač"</string>
+    <string name="taskbar_edu_circle_to_search_title" msgid="4322780398403949508">"Ak chcete vyhľadávať, čo je na obrazovke, pridržte akčný kláves."</string>
+    <string name="taskbar_edu_circle_to_search_disclosure" msgid="5841648785867787221">"Táto služba používa na účely vyhľadávania vybranú časť obrazovky. Uplatňujú sa <xliff:g id="BEGIN_PRIVACY_LINK">&lt;a href="%1$s"&gt;</xliff:g>pravidlá ochrany súkromia<xliff:g id="END_PRIVACY_LINK">&lt;/a&gt;</xliff:g> a <xliff:g id="BEGIN_TOS_LINK">&lt;a href="%2$s"&gt;</xliff:g>zmluvné podmienky<xliff:g id="END_TOS_LINK">&lt;/a&gt;</xliff:g> spoločnosti Google."</string>
     <string name="taskbar_edu_close" msgid="887022990168191073">"Zavrieť"</string>
     <string name="taskbar_edu_done" msgid="6880178093977704569">"Hotovo"</string>
     <string name="taskbar_button_home" msgid="2151398979630664652">"Plocha"</string>
diff --git a/quickstep/res/values-sl/strings.xml b/quickstep/res/values-sl/strings.xml
index 4fa37df..58e34f2 100644
--- a/quickstep/res/values-sl/strings.xml
+++ b/quickstep/res/values-sl/strings.xml
@@ -21,6 +21,8 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Pripni"</string>
     <string name="recent_task_option_freeform" msgid="48863056265284071">"Prosta oblika"</string>
+    <!-- no translation found for recent_task_option_desktop (8280879717125435668) -->
+    <skip />
     <string name="recents_empty_message" msgid="7040467240571714191">"Ni nedavnih elementov"</string>
     <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Nastavitve uporabe aplikacij"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Počisti vse"</string>
@@ -116,6 +118,8 @@
     <string name="taskbar_edu_features" msgid="3320337287472848162">"Naredite več z opravilno vrstico"</string>
     <string name="taskbar_edu_pinning_title" msgid="210102174154211712">"Stalni prikaz opravilne vrstice"</string>
     <string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"Če želite, da je opravilna vrstica vedno prikazana na dnu zaslona, pridržite razdelilno črto."</string>
+    <string name="taskbar_edu_circle_to_search_title" msgid="4322780398403949508">"Za iskanje po zaslonu se dotaknite in pridržite tipko za dejanja"</string>
+    <string name="taskbar_edu_circle_to_search_disclosure" msgid="5841648785867787221">"Ta izdelek za iskanje uporablja izbrani del zaslona. Veljajo Googlov <xliff:g id="BEGIN_PRIVACY_LINK">&lt;a href="%1$s"&gt;</xliff:g>pravilnik o zasebnosti<xliff:g id="END_PRIVACY_LINK">&lt;/a&gt;</xliff:g> in <xliff:g id="BEGIN_TOS_LINK">&lt;a href="%2$s"&gt;</xliff:g>pogoji storitve<xliff:g id="END_TOS_LINK">&lt;/a&gt;</xliff:g>."</string>
     <string name="taskbar_edu_close" msgid="887022990168191073">"Zapri"</string>
     <string name="taskbar_edu_done" msgid="6880178093977704569">"Končano"</string>
     <string name="taskbar_button_home" msgid="2151398979630664652">"Začetni zaslon"</string>
@@ -129,7 +133,7 @@
     <string name="taskbar_a11y_shown_title" msgid="6842833581088937713">"Opravilna vrstica je prikazana"</string>
     <string name="taskbar_a11y_hidden_title" msgid="9154903639589659284">"Opravilna vrstica je skrita"</string>
     <string name="taskbar_phone_a11y_title" msgid="4933360237131229395">"Vrstica za krmarjenje"</string>
-    <string name="always_show_taskbar" msgid="3608801276107751229">"Stalen prikaz opravilne vrstice"</string>
+    <string name="always_show_taskbar" msgid="3608801276107751229">"Stalen prikaz oprav. vrstice"</string>
     <string name="change_navigation_mode" msgid="9088393078736808968">"Spreminjanje načina navigacije"</string>
     <string name="taskbar_divider_a11y_title" msgid="6608690309720242080">"Razdelilnik opravilne vrstice"</string>
     <string name="move_drop_target_top_or_left" msgid="2988702185049595807">"Premakni na vrh/levo"</string>
diff --git a/quickstep/res/values-sq/strings.xml b/quickstep/res/values-sq/strings.xml
index 94e5c53..1cc11d2 100644
--- a/quickstep/res/values-sq/strings.xml
+++ b/quickstep/res/values-sq/strings.xml
@@ -21,6 +21,8 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Gozhdo"</string>
     <string name="recent_task_option_freeform" msgid="48863056265284071">"Formë e lirë"</string>
+    <!-- no translation found for recent_task_option_desktop (8280879717125435668) -->
+    <skip />
     <string name="recents_empty_message" msgid="7040467240571714191">"Nuk ka asnjë artikull të fundit"</string>
     <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Cilësimet e përdorimit të aplikacionit"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Pastroji të gjitha"</string>
@@ -116,6 +118,10 @@
     <string name="taskbar_edu_features" msgid="3320337287472848162">"Bëj më shumë me \"Shiritin e detyrave\""</string>
     <string name="taskbar_edu_pinning_title" msgid="210102174154211712">"Shfaq gjithmonë \"Shiritin e detyrave\""</string>
     <string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"Prek e mbaj ndarësin dhe shfaq gjithmonë \"Shiritin e detyrave\" në fund të ekranit"</string>
+    <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
+    <skip />
+    <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
+    <skip />
     <string name="taskbar_edu_close" msgid="887022990168191073">"Mbyll"</string>
     <string name="taskbar_edu_done" msgid="6880178093977704569">"U krye"</string>
     <string name="taskbar_button_home" msgid="2151398979630664652">"Faqja kryesore"</string>
diff --git a/quickstep/res/values-sr/strings.xml b/quickstep/res/values-sr/strings.xml
index 822d25c..0164d67 100644
--- a/quickstep/res/values-sr/strings.xml
+++ b/quickstep/res/values-sr/strings.xml
@@ -21,6 +21,8 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Закачи"</string>
     <string name="recent_task_option_freeform" msgid="48863056265284071">"Слободни облик"</string>
+    <!-- no translation found for recent_task_option_desktop (8280879717125435668) -->
+    <skip />
     <string name="recents_empty_message" msgid="7040467240571714191">"Нема недавних ставки"</string>
     <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Подешавања коришћења апликације"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Обриши све"</string>
@@ -112,10 +114,12 @@
     <string name="taskbar_edu_splitscreen" msgid="5605512479258053350">"Превуците на страну да бисте користили 2 апликације одједном"</string>
     <string name="taskbar_edu_stashing" msgid="5645461372669217294">"Споро превуците нагоре да бисте видели траку задатака"</string>
     <string name="taskbar_edu_suggestions" msgid="8215044496435527982">"Добијајте предлоге апликација на основу рутине"</string>
-    <string name="taskbar_edu_pinning" msgid="6708550858580071558">"Дуго притискајте разделник да бисте закачили траку задатака"</string>
+    <string name="taskbar_edu_pinning" msgid="6708550858580071558">"Дуго притисните разделник да бисте закачили траку задатака"</string>
     <string name="taskbar_edu_features" msgid="3320337287472848162">"Урадите више помоћу траке задатака"</string>
     <string name="taskbar_edu_pinning_title" msgid="210102174154211712">"Увек приказуј траку задатака"</string>
     <string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"Да би трака задатака увек била приказана у дну екрана, додирните и задржите разделник"</string>
+    <string name="taskbar_edu_circle_to_search_title" msgid="4322780398403949508">"Додирните и задржите тастер радњи да бисте претражили оно што је на екрану"</string>
+    <string name="taskbar_edu_circle_to_search_disclosure" msgid="5841648785867787221">"Овај производ користи изабрани део екрана за претрагу. Примењују се Google <xliff:g id="BEGIN_PRIVACY_LINK">&lt;a href="%1$s"&gt;</xliff:g>политика приватности<xliff:g id="END_PRIVACY_LINK">&lt;/a&gt;</xliff:g> и <xliff:g id="BEGIN_TOS_LINK">&lt;a href="%2$s"&gt;</xliff:g>услови коришћења услуге<xliff:g id="END_TOS_LINK">&lt;/a&gt;</xliff:g>."</string>
     <string name="taskbar_edu_close" msgid="887022990168191073">"Затвори"</string>
     <string name="taskbar_edu_done" msgid="6880178093977704569">"Готово"</string>
     <string name="taskbar_button_home" msgid="2151398979630664652">"Почетна"</string>
diff --git a/quickstep/res/values-sv/strings.xml b/quickstep/res/values-sv/strings.xml
index 0464246..d994ef5 100644
--- a/quickstep/res/values-sv/strings.xml
+++ b/quickstep/res/values-sv/strings.xml
@@ -21,6 +21,8 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Fäst"</string>
     <string name="recent_task_option_freeform" msgid="48863056265284071">"Fritt format"</string>
+    <!-- no translation found for recent_task_option_desktop (8280879717125435668) -->
+    <skip />
     <string name="recents_empty_message" msgid="7040467240571714191">"Listan är tom"</string>
     <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Inställningar för appanvändning"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Rensa alla"</string>
@@ -116,6 +118,10 @@
     <string name="taskbar_edu_features" msgid="3320337287472848162">"Gör mer med aktivitetsfältet"</string>
     <string name="taskbar_edu_pinning_title" msgid="210102174154211712">"Visa alltid aktivitetsfältet"</string>
     <string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"Tryck länge på avgränsaren för att alltid visa aktivitetsfältet längst ned på skärmen"</string>
+    <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
+    <skip />
+    <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
+    <skip />
     <string name="taskbar_edu_close" msgid="887022990168191073">"Stäng"</string>
     <string name="taskbar_edu_done" msgid="6880178093977704569">"Klar"</string>
     <string name="taskbar_button_home" msgid="2151398979630664652">"Startsida"</string>
diff --git a/quickstep/res/values-sw/strings.xml b/quickstep/res/values-sw/strings.xml
index 9af3db5..9d925a5 100644
--- a/quickstep/res/values-sw/strings.xml
+++ b/quickstep/res/values-sw/strings.xml
@@ -21,6 +21,8 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Bandika"</string>
     <string name="recent_task_option_freeform" msgid="48863056265284071">"Muundo huru"</string>
+    <!-- no translation found for recent_task_option_desktop (8280879717125435668) -->
+    <skip />
     <string name="recents_empty_message" msgid="7040467240571714191">"Hakuna vipengee vya hivi karibuni"</string>
     <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Mipangilio ya matumizi ya programu"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Ondoa zote"</string>
@@ -116,6 +118,8 @@
     <string name="taskbar_edu_features" msgid="3320337287472848162">"Kamilisha mengi kwa kutumia Upauzana huu"</string>
     <string name="taskbar_edu_pinning_title" msgid="210102174154211712">"Onyesha Upauzana kila wakati"</string>
     <string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"Ili uonyeshe Upauzana kila wakati chini ya skrini yako, gusa na ushikilie kitenganishi"</string>
+    <string name="taskbar_edu_circle_to_search_title" msgid="4322780398403949508">"Gusa na ushikilie kitufe cha vitendo ili utafute kilicho kwenye skrini yako"</string>
+    <string name="taskbar_edu_circle_to_search_disclosure" msgid="5841648785867787221">"Bidhaa hii hutumia sehemu uliyochagua kwenye skrini yako kutafuta. <xliff:g id="BEGIN_PRIVACY_LINK">&lt;a href="%1$s"&gt;</xliff:g>Sera ya Faragha<xliff:g id="END_PRIVACY_LINK">&lt;/a&gt;</xliff:g> na <xliff:g id="BEGIN_TOS_LINK">&lt;a href="%2$s"&gt;</xliff:g>Sheria na Masharti<xliff:g id="END_TOS_LINK">&lt;/a&gt;</xliff:g> ya Google yatatumika."</string>
     <string name="taskbar_edu_close" msgid="887022990168191073">"Funga"</string>
     <string name="taskbar_edu_done" msgid="6880178093977704569">"Imemaliza"</string>
     <string name="taskbar_button_home" msgid="2151398979630664652">"Mwanzo"</string>
diff --git a/quickstep/res/values-ta/strings.xml b/quickstep/res/values-ta/strings.xml
index 279e9f9..2f458f4 100644
--- a/quickstep/res/values-ta/strings.xml
+++ b/quickstep/res/values-ta/strings.xml
@@ -21,6 +21,8 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_pin" msgid="7929860679018978258">"பின் செய்தல்"</string>
     <string name="recent_task_option_freeform" msgid="48863056265284071">"குறிப்பிட்ட வடிவமில்லாத பயன்முறை"</string>
+    <!-- no translation found for recent_task_option_desktop (8280879717125435668) -->
+    <skip />
     <string name="recents_empty_message" msgid="7040467240571714191">"சமீபத்தியவை எதுவுமில்லை"</string>
     <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"ஆப்ஸ் உபயோக அமைப்புகள்"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"எல்லாம் அழி"</string>
@@ -116,6 +118,10 @@
     <string name="taskbar_edu_features" msgid="3320337287472848162">"செயல் பட்டி மூலம் மேலும் பலவற்றைச் செய்யுங்கள்"</string>
     <string name="taskbar_edu_pinning_title" msgid="210102174154211712">"செயல் பட்டியை எப்போதும் காட்டுதல்"</string>
     <string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"திரையின் கீழ்ப்பகுதியில் செயல் பட்டியை எப்போதும் காட்டுவதற்கு, பிரிப்பானைத் தொட்டுப் பிடித்திருக்கவும்"</string>
+    <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
+    <skip />
+    <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
+    <skip />
     <string name="taskbar_edu_close" msgid="887022990168191073">"மூடுக"</string>
     <string name="taskbar_edu_done" msgid="6880178093977704569">"முடிந்தது"</string>
     <string name="taskbar_button_home" msgid="2151398979630664652">"முகப்பு"</string>
diff --git a/quickstep/res/values-te/strings.xml b/quickstep/res/values-te/strings.xml
index 9461d48..5f1feff 100644
--- a/quickstep/res/values-te/strings.xml
+++ b/quickstep/res/values-te/strings.xml
@@ -21,6 +21,8 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_pin" msgid="7929860679018978258">"పిన్ చేయండి"</string>
     <string name="recent_task_option_freeform" msgid="48863056265284071">"సంప్రదాయేతర"</string>
+    <!-- no translation found for recent_task_option_desktop (8280879717125435668) -->
+    <skip />
     <string name="recents_empty_message" msgid="7040467240571714191">"ఇటీవలి ఐటెమ్‌లు ఏవీ లేవు"</string>
     <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"యాప్ వినియోగ సెట్టింగ్‌లు"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"అన్నీ తీసివేయండి"</string>
@@ -116,6 +118,8 @@
     <string name="taskbar_edu_features" msgid="3320337287472848162">"టాస్క్‌బార్‌తో మరిన్ని చేయండి"</string>
     <string name="taskbar_edu_pinning_title" msgid="210102174154211712">"టాస్క్‌బార్‌ను నిరంతరం చూపండి"</string>
     <string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"మీ స్క్రీన్ దిగువున టాస్క్‌బార్‌ను నిరంతరం చూపడానికి, డివైడర్‌ను తాకి, నొక్కి ఉంచండి"</string>
+    <string name="taskbar_edu_circle_to_search_title" msgid="4322780398403949508">"మీ స్క్రీన్‌లో ఏం ఉందో సెర్చ్ చేయడానికి యాక్షన్ కీని తాకి ఉంచండి"</string>
+    <string name="taskbar_edu_circle_to_search_disclosure" msgid="5841648785867787221">"ఈ ప్రోడక్ట్, సెర్చ్ చేయడానికి మీ స్క్రీన్‌లో ఎంచుకున్న భాగాన్ని ఉపయోగిస్తుంది. Google <xliff:g id="BEGIN_PRIVACY_LINK">&lt;a href="%1$s"&gt;</xliff:g>గోప్యతా పాలసీ<xliff:g id="END_PRIVACY_LINK">&lt;/a&gt;</xliff:g>, <xliff:g id="BEGIN_TOS_LINK">&lt;a href="%2$s"&gt;</xliff:g>సర్వీస్ నియమాలు<xliff:g id="END_TOS_LINK">&lt;/a&gt;</xliff:g> వర్తిస్తాయి."</string>
     <string name="taskbar_edu_close" msgid="887022990168191073">"మూసివేయండి"</string>
     <string name="taskbar_edu_done" msgid="6880178093977704569">"పూర్తయింది"</string>
     <string name="taskbar_button_home" msgid="2151398979630664652">"మొదటి ట్యాబ్"</string>
diff --git a/quickstep/res/values-th/strings.xml b/quickstep/res/values-th/strings.xml
index 6eff112..ea6a285 100644
--- a/quickstep/res/values-th/strings.xml
+++ b/quickstep/res/values-th/strings.xml
@@ -21,6 +21,8 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_pin" msgid="7929860679018978258">"ปักหมุด"</string>
     <string name="recent_task_option_freeform" msgid="48863056265284071">"รูปแบบอิสระ"</string>
+    <!-- no translation found for recent_task_option_desktop (8280879717125435668) -->
+    <skip />
     <string name="recents_empty_message" msgid="7040467240571714191">"ไม่มีรายการล่าสุด"</string>
     <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"การตั้งค่าการใช้แอป"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"ล้างทั้งหมด"</string>
@@ -116,6 +118,8 @@
     <string name="taskbar_edu_features" msgid="3320337287472848162">"ทำสิ่งต่างๆ ได้มากขึ้นด้วยแถบงาน"</string>
     <string name="taskbar_edu_pinning_title" msgid="210102174154211712">"แสดงแถบงานเสมอ"</string>
     <string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"หากต้องการให้แถบงานแสดงที่ด้านล่างหน้าจออยู่เสมอ ให้แตะตัวแบ่งค้างไว้"</string>
+    <string name="taskbar_edu_circle_to_search_title" msgid="4322780398403949508">"แตะปุ่มดำเนินการค้างไว้เพื่อค้นหาสิ่งที่อยู่บนหน้าจอ"</string>
+    <string name="taskbar_edu_circle_to_search_disclosure" msgid="5841648785867787221">"ผลิตภัณฑ์นี้ใช้ส่วนที่เลือกของหน้าจอเพื่อค้นหา เป็นไปตาม<xliff:g id="BEGIN_PRIVACY_LINK">&lt;a href="%1$s"&gt;</xliff:g>นโยบายความเป็นส่วนตัว<xliff:g id="END_PRIVACY_LINK">&lt;/a&gt;</xliff:g>และ<xliff:g id="BEGIN_TOS_LINK">&lt;a href="%2$s"&gt;</xliff:g>ข้อกําหนดในการให้บริการ<xliff:g id="END_TOS_LINK">&lt;/a&gt;</xliff:g>ของ Google"</string>
     <string name="taskbar_edu_close" msgid="887022990168191073">"ปิด"</string>
     <string name="taskbar_edu_done" msgid="6880178093977704569">"เสร็จ"</string>
     <string name="taskbar_button_home" msgid="2151398979630664652">"หน้าแรก"</string>
diff --git a/quickstep/res/values-tl/strings.xml b/quickstep/res/values-tl/strings.xml
index a6106c8..5fbc57b 100644
--- a/quickstep/res/values-tl/strings.xml
+++ b/quickstep/res/values-tl/strings.xml
@@ -21,6 +21,8 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_pin" msgid="7929860679018978258">"I-pin"</string>
     <string name="recent_task_option_freeform" msgid="48863056265284071">"Freeform"</string>
+    <!-- no translation found for recent_task_option_desktop (8280879717125435668) -->
+    <skip />
     <string name="recents_empty_message" msgid="7040467240571714191">"Walang kamakailang item"</string>
     <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Mga setting ng paggamit ng app"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"I-clear lahat"</string>
@@ -116,6 +118,8 @@
     <string name="taskbar_edu_features" msgid="3320337287472848162">"Mas maraming magawa gamit ang Taskbar"</string>
     <string name="taskbar_edu_pinning_title" msgid="210102174154211712">"Palaging ipakita ang Taskbar"</string>
     <string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"Para palaging ipakita ang Taskbar sa ibaba ng iyong screen, pindutin nang matagal ang divider"</string>
+    <string name="taskbar_edu_circle_to_search_title" msgid="4322780398403949508">"Pindutin nang matagal ang action key para hanapin kung ano ang nasa iyong screen"</string>
+    <string name="taskbar_edu_circle_to_search_disclosure" msgid="5841648785867787221">"Ginagamit ng produktong ito ang piniling bahagi ng iyong screen para maghanap. Nalalapat ang <xliff:g id="BEGIN_PRIVACY_LINK">&lt;a href="%1$s"&gt;</xliff:g>Patakaran sa Privacy<xliff:g id="END_PRIVACY_LINK">&lt;/a&gt;</xliff:g> at <xliff:g id="BEGIN_TOS_LINK">&lt;a href="%2$s"&gt;</xliff:g>Mga Tuntunin ng Serbisyo<xliff:g id="END_TOS_LINK">&lt;/a&gt;</xliff:g> ng Google."</string>
     <string name="taskbar_edu_close" msgid="887022990168191073">"Isara"</string>
     <string name="taskbar_edu_done" msgid="6880178093977704569">"Tapos na"</string>
     <string name="taskbar_button_home" msgid="2151398979630664652">"Home"</string>
diff --git a/quickstep/res/values-tr/strings.xml b/quickstep/res/values-tr/strings.xml
index f562feb..a10d0e3 100644
--- a/quickstep/res/values-tr/strings.xml
+++ b/quickstep/res/values-tr/strings.xml
@@ -21,6 +21,8 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Sabitle"</string>
     <string name="recent_task_option_freeform" msgid="48863056265284071">"Serbest çalışma"</string>
+    <!-- no translation found for recent_task_option_desktop (8280879717125435668) -->
+    <skip />
     <string name="recents_empty_message" msgid="7040467240571714191">"Yeni öğe yok"</string>
     <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Uygulama kullanım ayarları"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Tümünü temizle"</string>
@@ -116,6 +118,10 @@
     <string name="taskbar_edu_features" msgid="3320337287472848162">"Görev çubuğuyla daha fazla şey yapın"</string>
     <string name="taskbar_edu_pinning_title" msgid="210102174154211712">"Görev çubuğunu sabitleyin"</string>
     <string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"Ayırıcıya dokunup basılı tuttuğunuzda görev çubuğu ekranın alt kısmına sabitlenir"</string>
+    <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
+    <skip />
+    <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
+    <skip />
     <string name="taskbar_edu_close" msgid="887022990168191073">"Kapat"</string>
     <string name="taskbar_edu_done" msgid="6880178093977704569">"Bitti"</string>
     <string name="taskbar_button_home" msgid="2151398979630664652">"Ana ekran"</string>
diff --git a/quickstep/res/values-uk/strings.xml b/quickstep/res/values-uk/strings.xml
index 4df24d7..5e19342 100644
--- a/quickstep/res/values-uk/strings.xml
+++ b/quickstep/res/values-uk/strings.xml
@@ -21,6 +21,8 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Закріпити"</string>
     <string name="recent_task_option_freeform" msgid="48863056265284071">"Довільна форма"</string>
+    <!-- no translation found for recent_task_option_desktop (8280879717125435668) -->
+    <skip />
     <string name="recents_empty_message" msgid="7040467240571714191">"Немає нещодавніх додатків"</string>
     <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Налаштування використання додатка"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Очистити все"</string>
@@ -116,6 +118,10 @@
     <string name="taskbar_edu_features" msgid="3320337287472848162">"Більше можливостей завдяки панелі завдань"</string>
     <string name="taskbar_edu_pinning_title" msgid="210102174154211712">"Завжди показувати панель завдань"</string>
     <string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"Щоб завжди показувати панель завдань унизу екрана, натисніть і втримуйте роздільник"</string>
+    <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
+    <skip />
+    <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
+    <skip />
     <string name="taskbar_edu_close" msgid="887022990168191073">"Закрити"</string>
     <string name="taskbar_edu_done" msgid="6880178093977704569">"Готово"</string>
     <string name="taskbar_button_home" msgid="2151398979630664652">"Головний екран"</string>
diff --git a/quickstep/res/values-ur/strings.xml b/quickstep/res/values-ur/strings.xml
index 3c5d22d..7b14045 100644
--- a/quickstep/res/values-ur/strings.xml
+++ b/quickstep/res/values-ur/strings.xml
@@ -21,6 +21,8 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_pin" msgid="7929860679018978258">"پن کریں"</string>
     <string name="recent_task_option_freeform" msgid="48863056265284071">"فری فارم"</string>
+    <!-- no translation found for recent_task_option_desktop (8280879717125435668) -->
+    <skip />
     <string name="recents_empty_message" msgid="7040467240571714191">"کوئی حالیہ آئٹم نہیں"</string>
     <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"ایپ کے استعمال کی ترتیبات"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"سبھی کو صاف کریں"</string>
@@ -116,6 +118,8 @@
     <string name="taskbar_edu_features" msgid="3320337287472848162">"ٹاسک بار سے بہت کچھ کریں"</string>
     <string name="taskbar_edu_pinning_title" msgid="210102174154211712">"ہمیشہ ٹاسک بار دکھائیں"</string>
     <string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"ٹاسک بار کو ہمیشہ اپنی اسکرین کے نیچے دکھانے کے لیے، ڈیوائیڈر کو ٹچ کریں اور دبائے رکھیں"</string>
+    <string name="taskbar_edu_circle_to_search_title" msgid="4322780398403949508">"آپ کی اسکرین پر جو کچھ ہے اسے تلاش کرنے کے لیے ایکشن کلید کو ٹچ کریں اور دبائے رکھیں"</string>
+    <string name="taskbar_edu_circle_to_search_disclosure" msgid="5841648785867787221">"‏یہ پروڈکٹ تلاش کرنے کے لیے آپ کی اسکرین کا منتخب حصہ استعمال کرتا ہے۔ Google کی <xliff:g id="BEGIN_PRIVACY_LINK">&lt;a href="%1$s"&gt;</xliff:g>رازداری کی پالیسی<xliff:g id="END_PRIVACY_LINK">&lt;/a&gt;</xliff:g> اور <xliff:g id="BEGIN_TOS_LINK">&lt;a href="%2$s"&gt;</xliff:g>سروس کی شرائط<xliff:g id="END_TOS_LINK">&lt;/a&gt;</xliff:g> لاگو ہوتی ہیں۔"</string>
     <string name="taskbar_edu_close" msgid="887022990168191073">"بند کریں"</string>
     <string name="taskbar_edu_done" msgid="6880178093977704569">"ہو گیا"</string>
     <string name="taskbar_button_home" msgid="2151398979630664652">"ہوم"</string>
diff --git a/quickstep/res/values-uz/strings.xml b/quickstep/res/values-uz/strings.xml
index 1540ed5..efbb6a3 100644
--- a/quickstep/res/values-uz/strings.xml
+++ b/quickstep/res/values-uz/strings.xml
@@ -21,6 +21,8 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Qadash"</string>
     <string name="recent_task_option_freeform" msgid="48863056265284071">"Erkin shakl"</string>
+    <!-- no translation found for recent_task_option_desktop (8280879717125435668) -->
+    <skip />
     <string name="recents_empty_message" msgid="7040467240571714191">"Yaqinda ishlatilgan ilovalar yo‘q"</string>
     <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Ilovadan foydalanish sozlamalari"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Hammasini tozalash"</string>
@@ -116,6 +118,10 @@
     <string name="taskbar_edu_features" msgid="3320337287472848162">"Vazifalar panelidan maksimal darajada foydalaning"</string>
     <string name="taskbar_edu_pinning_title" msgid="210102174154211712">"Vazifalar paneli doim chiqarilsin"</string>
     <string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"Vazifalar panelini ekranning pastki qismida doim chiqib turishi uchun ajratkichni bosib turing"</string>
+    <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
+    <skip />
+    <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
+    <skip />
     <string name="taskbar_edu_close" msgid="887022990168191073">"Yopish"</string>
     <string name="taskbar_edu_done" msgid="6880178093977704569">"Tayyor"</string>
     <string name="taskbar_button_home" msgid="2151398979630664652">"Bosh ekran"</string>
diff --git a/quickstep/res/values-vi/strings.xml b/quickstep/res/values-vi/strings.xml
index fb28736..8d35279 100644
--- a/quickstep/res/values-vi/strings.xml
+++ b/quickstep/res/values-vi/strings.xml
@@ -21,6 +21,8 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Ghim"</string>
     <string name="recent_task_option_freeform" msgid="48863056265284071">"Dạng tự do"</string>
+    <!-- no translation found for recent_task_option_desktop (8280879717125435668) -->
+    <skip />
     <string name="recents_empty_message" msgid="7040467240571714191">"Không có mục gần đây nào"</string>
     <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Cài đặt mức sử dụng ứng dụng"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Xóa tất cả"</string>
@@ -116,6 +118,10 @@
     <string name="taskbar_edu_features" msgid="3320337287472848162">"Làm nhiều việc hơn qua Thanh tác vụ"</string>
     <string name="taskbar_edu_pinning_title" msgid="210102174154211712">"Luôn hiện Taskbar"</string>
     <string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"Để luôn hiện Taskbar ở cuối màn hình, hãy nhấn và giữ đường phân chia"</string>
+    <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
+    <skip />
+    <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
+    <skip />
     <string name="taskbar_edu_close" msgid="887022990168191073">"Đóng"</string>
     <string name="taskbar_edu_done" msgid="6880178093977704569">"Xong"</string>
     <string name="taskbar_button_home" msgid="2151398979630664652">"Màn hình chính"</string>
diff --git a/quickstep/res/values-zh-rCN/strings.xml b/quickstep/res/values-zh-rCN/strings.xml
index 3f6cc2c..b567c66 100644
--- a/quickstep/res/values-zh-rCN/strings.xml
+++ b/quickstep/res/values-zh-rCN/strings.xml
@@ -21,6 +21,8 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_pin" msgid="7929860679018978258">"固定"</string>
     <string name="recent_task_option_freeform" msgid="48863056265284071">"自由窗口"</string>
+    <!-- no translation found for recent_task_option_desktop (8280879717125435668) -->
+    <skip />
     <string name="recents_empty_message" msgid="7040467240571714191">"近期没有任何内容"</string>
     <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"应用使用设置"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"全部清除"</string>
@@ -95,7 +97,7 @@
     <string name="action_share" msgid="2648470652637092375">"分享"</string>
     <string name="action_screenshot" msgid="8171125848358142917">"屏幕截图"</string>
     <string name="action_split" msgid="2098009717623550676">"拆分"</string>
-    <string name="action_save_app_pair" msgid="5974823919237645229">"保存应用对"</string>
+    <string name="action_save_app_pair" msgid="5974823919237645229">"保存应用组合"</string>
     <string name="toast_split_select_app" msgid="8464310533320556058">"点按另一个应用即可使用分屏"</string>
     <string name="toast_contextual_split_select_app" msgid="433510957123687090">"另外选择一个应用才可使用分屏模式"</string>
     <string name="toast_split_select_app_cancel" msgid="1532690483356445639"><b>"取消"</b></string>
@@ -110,12 +112,16 @@
     <string name="accessibility_rotate_button" msgid="4771825231336502943">"旋转屏幕"</string>
     <string name="taskbar_edu_a11y_title" msgid="5417986057866415355">"任务栏教程"</string>
     <string name="taskbar_edu_splitscreen" msgid="5605512479258053350">"将一个应用拖到一侧,即可同时使用两个应用"</string>
-    <string name="taskbar_edu_stashing" msgid="5645461372669217294">"缓慢向上滑动即可显示任务栏"</string>
+    <string name="taskbar_edu_stashing" msgid="5645461372669217294">"缓慢上滑即可显示任务栏"</string>
     <string name="taskbar_edu_suggestions" msgid="8215044496435527982">"根据您的日常使用习惯获得应用建议"</string>
     <string name="taskbar_edu_pinning" msgid="6708550858580071558">"长按分隔线即可固定任务栏"</string>
     <string name="taskbar_edu_features" msgid="3320337287472848162">"体验任务栏的更多功能"</string>
     <string name="taskbar_edu_pinning_title" msgid="210102174154211712">"始终显示任务栏"</string>
     <string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"若要始终在屏幕底部显示任务栏,请轻触并按住分隔线"</string>
+    <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
+    <skip />
+    <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
+    <skip />
     <string name="taskbar_edu_close" msgid="887022990168191073">"关闭"</string>
     <string name="taskbar_edu_done" msgid="6880178093977704569">"完成"</string>
     <string name="taskbar_button_home" msgid="2151398979630664652">"主屏幕"</string>
diff --git a/quickstep/res/values-zh-rHK/strings.xml b/quickstep/res/values-zh-rHK/strings.xml
index 050c47c..b314def 100644
--- a/quickstep/res/values-zh-rHK/strings.xml
+++ b/quickstep/res/values-zh-rHK/strings.xml
@@ -21,6 +21,8 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_pin" msgid="7929860679018978258">"固定"</string>
     <string name="recent_task_option_freeform" msgid="48863056265284071">"自由形式"</string>
+    <!-- no translation found for recent_task_option_desktop (8280879717125435668) -->
+    <skip />
     <string name="recents_empty_message" msgid="7040467240571714191">"最近沒有任何項目"</string>
     <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"應用程式使用情況設定"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"全部清除"</string>
@@ -95,7 +97,7 @@
     <string name="action_share" msgid="2648470652637092375">"分享"</string>
     <string name="action_screenshot" msgid="8171125848358142917">"螢幕截圖"</string>
     <string name="action_split" msgid="2098009717623550676">"分割"</string>
-    <string name="action_save_app_pair" msgid="5974823919237645229">"儲存應用程式配對"</string>
+    <string name="action_save_app_pair" msgid="5974823919237645229">"儲存應用程式組合"</string>
     <string name="toast_split_select_app" msgid="8464310533320556058">"輕按其他應用程式以使用分割螢幕"</string>
     <string name="toast_contextual_split_select_app" msgid="433510957123687090">"選擇其他應用程式才能使用分割螢幕"</string>
     <string name="toast_split_select_app_cancel" msgid="1532690483356445639"><b>"取消"</b></string>
@@ -116,6 +118,10 @@
     <string name="taskbar_edu_features" msgid="3320337287472848162">"工作列助你事半功倍"</string>
     <string name="taskbar_edu_pinning_title" msgid="210102174154211712">"一律顯示工作列"</string>
     <string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"如要持續在畫面底部顯示工作列,請按住分隔線"</string>
+    <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
+    <skip />
+    <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
+    <skip />
     <string name="taskbar_edu_close" msgid="887022990168191073">"關閉"</string>
     <string name="taskbar_edu_done" msgid="6880178093977704569">"完成"</string>
     <string name="taskbar_button_home" msgid="2151398979630664652">"住宅"</string>
diff --git a/quickstep/res/values-zh-rTW/strings.xml b/quickstep/res/values-zh-rTW/strings.xml
index 2e89466..0864c55 100644
--- a/quickstep/res/values-zh-rTW/strings.xml
+++ b/quickstep/res/values-zh-rTW/strings.xml
@@ -21,6 +21,8 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_pin" msgid="7929860679018978258">"固定"</string>
     <string name="recent_task_option_freeform" msgid="48863056265284071">"自由形式"</string>
+    <!-- no translation found for recent_task_option_desktop (8280879717125435668) -->
+    <skip />
     <string name="recents_empty_message" msgid="7040467240571714191">"最近沒有任何項目"</string>
     <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"應用程式使用情況設定"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"全部清除"</string>
@@ -116,6 +118,10 @@
     <string name="taskbar_edu_features" msgid="3320337287472848162">"充分發揮工作列的功用"</string>
     <string name="taskbar_edu_pinning_title" msgid="210102174154211712">"一律顯示工作列"</string>
     <string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"如要一律在畫面底部顯示工作列,請按住分隔線"</string>
+    <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
+    <skip />
+    <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
+    <skip />
     <string name="taskbar_edu_close" msgid="887022990168191073">"關閉"</string>
     <string name="taskbar_edu_done" msgid="6880178093977704569">"完成"</string>
     <string name="taskbar_button_home" msgid="2151398979630664652">"主畫面"</string>
diff --git a/quickstep/res/values-zu/strings.xml b/quickstep/res/values-zu/strings.xml
index 0688082..e1c1f3a 100644
--- a/quickstep/res/values-zu/strings.xml
+++ b/quickstep/res/values-zu/strings.xml
@@ -21,6 +21,8 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Phina"</string>
     <string name="recent_task_option_freeform" msgid="48863056265284071">"I-Freeform"</string>
+    <!-- no translation found for recent_task_option_desktop (8280879717125435668) -->
+    <skip />
     <string name="recents_empty_message" msgid="7040467240571714191">"Azikho izinto zakamuva"</string>
     <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Izilungiselelo zokusetshenziswa kohlelo lokusebenza"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Sula konke"</string>
@@ -116,6 +118,10 @@
     <string name="taskbar_edu_features" msgid="3320337287472848162">"Yenza okwengeziwe nge-Taskbar"</string>
     <string name="taskbar_edu_pinning_title" msgid="210102174154211712">"Bonisa njalo i-Taskbar"</string>
     <string name="taskbar_edu_pinning_standalone" msgid="2636919474366410467">"Ukuze ubonise njalo i-Taskbar phansi kwesikrini sakho, thinta bese ubamba isihlukanisi"</string>
+    <!-- no translation found for taskbar_edu_circle_to_search_title (4322780398403949508) -->
+    <skip />
+    <!-- no translation found for taskbar_edu_circle_to_search_disclosure (5841648785867787221) -->
+    <skip />
     <string name="taskbar_edu_close" msgid="887022990168191073">"Vala"</string>
     <string name="taskbar_edu_done" msgid="6880178093977704569">"Kwenziwe"</string>
     <string name="taskbar_button_home" msgid="2151398979630664652">"Ikhaya"</string>
diff --git a/quickstep/res/values/attrs.xml b/quickstep/res/values/attrs.xml
index 7288774..ccc7f18 100644
--- a/quickstep/res/values/attrs.xml
+++ b/quickstep/res/values/attrs.xml
@@ -30,6 +30,11 @@
         <attr name="hoverBorderColor" format="color" />
     </declare-styleable>
 
+    <declare-styleable name="ClearAllButton">
+        <!-- focus border color for overview clear all button views -->
+        <attr name="focusBorderColor" />
+    </declare-styleable>
+
     <!--
          Gesture nav edu specific attributes. These attributes are used to customize Gesture nav edu
          view lottie animation colors in XML files.
diff --git a/quickstep/res/values/config.xml b/quickstep/res/values/config.xml
index e45d9fd..c4ee11a 100644
--- a/quickstep/res/values/config.xml
+++ b/quickstep/res/values/config.xml
@@ -26,6 +26,19 @@
     <string name="test_information_handler_class" translatable="false">com.android.quickstep.QuickstepTestInformationHandler</string>
     <string name="window_manager_proxy_class" translatable="false">com.android.quickstep.util.SystemWindowManagerProxy</string>
     <string name="widget_holder_factory_class" translatable="false">com.android.launcher3.uioverrides.QuickstepWidgetHolder$QuickstepHolderFactory</string>
+    <string name="instant_app_resolver_class" translatable="false">com.android.quickstep.InstantAppResolverImpl</string>
+    <string name="app_launch_tracker_class" translatable="false">com.android.launcher3.appprediction.PredictionAppTracker</string>
+    <string name="main_process_initializer_class" translatable="false">com.android.quickstep.QuickstepProcessInitializer</string>
+    <string name="model_delegate_class" translatable="false">com.android.launcher3.model.QuickstepModelDelegate</string>
+    <string name="secondary_display_predictions_class" translatable="false">com.android.launcher3.secondarydisplay.SecondaryDisplayPredictionsImpl</string>
+    <string name="taskbar_model_callbacks_factory_class" translatable="false">com.android.launcher3.taskbar.TaskbarModelCallbacksFactory</string>
+    <string name="taskbar_view_callbacks_factory_class" translatable="false">com.android.launcher3.taskbar.TaskbarViewCallbacksFactory</string>
+    <string name="launcher_restore_event_logger_class" translatable="false">com.android.quickstep.LauncherRestoreEventLoggerImpl</string>
+
+    <string name="nav_handle_long_press_handler_class" translatable="false"></string>
+    <string name="assist_utils_class" translatable="false"></string>
+    <string name="assist_state_manager_class" translatable="false"></string>
+    <string name="api_wrapper_class" translatable="false">com.android.launcher3.uioverrides.SystemApiWrapper</string>
 
     <!-- The number of thumbnails and icons to keep in the cache. The thumbnail cache size also
          determines how many thumbnails will be fetched in the background. -->
diff --git a/quickstep/res/values/dimens.xml b/quickstep/res/values/dimens.xml
index b757a2f..69e07f2 100644
--- a/quickstep/res/values/dimens.xml
+++ b/quickstep/res/values/dimens.xml
@@ -98,6 +98,8 @@
     <dimen name="default_task_dismiss_drag_velocity_grid_focus_task">5dp</dimen>
 
     <dimen name="recents_clear_all_deadzone_vertical_margin">70dp</dimen>
+    <dimen name="recents_clear_all_outline_radius">24dp</dimen>
+    <dimen name="recents_clear_all_outline_padding">2dp</dimen>
 
     <!-- The speed in dp/s at which the user needs to be scrolling in recents such that we start
              loading full resolution screenshots. -->
@@ -401,6 +403,7 @@
     <dimen name="taskbar_edu_features_tooltip_width_with_one_feature">412dp</dimen>
     <dimen name="taskbar_edu_features_tooltip_width_with_two_features">428dp</dimen>
     <dimen name="taskbar_edu_features_tooltip_width_with_three_features">624dp</dimen>
+    <dimen name="taskbar_edu_circle_to_search_subtitle_text_size">12sp</dimen>
 
     <!--- Taskbar Pinning -->
     <dimen name="taskbar_pinning_popup_menu_width">300dp</dimen>
diff --git a/quickstep/res/values/override.xml b/quickstep/res/values/override.xml
deleted file mode 100644
index cba1f5b..0000000
--- a/quickstep/res/values/override.xml
+++ /dev/null
@@ -1,42 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-
-<!-- Class overrides for launcher with quickstep. -->
-
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-  <string name="instant_app_resolver_class" translatable="false">com.android.quickstep.InstantAppResolverImpl</string>
-
-  <string name="app_launch_tracker_class" translatable="false">com.android.launcher3.appprediction.PredictionAppTracker</string>
-
-  <string name="main_process_initializer_class" translatable="false">com.android.quickstep.QuickstepProcessInitializer</string>
-
-  <string name="model_delegate_class" translatable="false">com.android.launcher3.model.QuickstepModelDelegate</string>
-
-  <string name="nav_handle_long_press_handler_class" translatable="false"></string>
-
-  <string name="assist_utils_class" translatable="false"></string>
-
-  <string name="secondary_display_predictions_class" translatable="false">com.android.launcher3.secondarydisplay.SecondaryDisplayPredictionsImpl</string>
-
-  <string name="taskbar_model_callbacks_factory_class" translatable="false">com.android.launcher3.taskbar.TaskbarModelCallbacksFactory</string>
-
-  <string name="taskbar_view_callbacks_factory_class" translatable="false">com.android.launcher3.taskbar.TaskbarViewCallbacksFactory</string>
-
-  <string name="assist_state_manager_class" translatable="false"></string>
-
-  <string name="launcher_restore_event_logger_class" translatable="false">com.android.quickstep.LauncherRestoreEventLoggerImpl</string>
-
-</resources>
diff --git a/quickstep/res/values/strings.xml b/quickstep/res/values/strings.xml
index 75a4fc8..71855eb 100644
--- a/quickstep/res/values/strings.xml
+++ b/quickstep/res/values/strings.xml
@@ -26,6 +26,8 @@
     <string name="recent_task_option_pin">Pin</string>
     <!-- Title for an option to enter freeform mode for a given app -->
     <string name="recent_task_option_freeform">Freeform</string>
+    <!-- Title for an option to enter desktop windowing mode for a given app -->
+    <string name="recent_task_option_desktop">Desktop</string>
 
     <!-- Recents: The empty recents string. [CHAR LIMIT=NONE] -->
     <string name="recents_empty_message">No recent items</string>
@@ -273,6 +275,10 @@
     <string name="taskbar_edu_pinning_title">Always show the Taskbar</string>
     <!-- Text in dialog that shows a user how to pin the Taskbar. [CHAR_LIMIT 150] -->
     <string name="taskbar_edu_pinning_standalone">To always show the Taskbar on the bottom of your screen, touch &amp; hold the divider</string>
+    <!-- Title in dialog that shows a user how to invoke the Circle to Search feature. [CHAR_LIMIT 150] -->
+    <string name="taskbar_edu_circle_to_search_title">Touch &amp; hold the action key to search what\'s on your screen</string>
+    <!-- Message showed to user to disclose privacy information they need to accept in order to access the app. [CHAR LIMIT=200]-->
+    <string name="taskbar_edu_circle_to_search_disclosure">This product uses the selected part of your screen to search. Google\'s <xliff:g example="https://policies.google.com/privacy/embedded" id="begin_privacy_link">&lt;a href=\"%1$s\"&gt;</xliff:g>Privacy Policy<xliff:g id="end_privacy_link">&lt;/a&gt;</xliff:g> and <xliff:g example="https://policies.google.com/terms" id="begin_tos_link">&lt;a href=\"%2$s\"&gt;</xliff:g>Terms of Service<xliff:g id="end_tos_link">&lt;/a&gt;</xliff:g> apply.</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] -->
diff --git a/quickstep/src/com/android/launcher3/HomeTransitionController.java b/quickstep/src/com/android/launcher3/HomeTransitionController.java
deleted file mode 100644
index c4a2e9e..0000000
--- a/quickstep/src/com/android/launcher3/HomeTransitionController.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2023 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;
-
-import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
-
-import androidx.annotation.Nullable;
-
-import com.android.launcher3.uioverrides.QuickstepLauncher;
-import com.android.quickstep.SystemUiProxy;
-import com.android.wm.shell.shared.IHomeTransitionListener;
-
-/**
- * Controls launcher response to home activity visibility changing.
- */
-public class HomeTransitionController {
-
-    @Nullable private QuickstepLauncher mLauncher;
-    @Nullable private IHomeTransitionListener mHomeTransitionListener;
-
-    public void registerHomeTransitionListener(QuickstepLauncher launcher) {
-        mLauncher = launcher;
-        mHomeTransitionListener = new IHomeTransitionListener.Stub() {
-            @Override
-            public void onHomeVisibilityChanged(boolean isVisible) {
-                MAIN_EXECUTOR.execute(() -> {
-                    if (mLauncher != null && mLauncher.getTaskbarUIController() != null) {
-                        mLauncher.getTaskbarUIController().onLauncherVisibilityChanged(isVisible);
-                    }
-                });
-            }
-        };
-
-        SystemUiProxy.INSTANCE.get(mLauncher).setHomeTransitionListener(mHomeTransitionListener);
-    }
-
-    public void unregisterHomeTransitionListener() {
-        SystemUiProxy.INSTANCE.get(mLauncher).setHomeTransitionListener(null);
-        mHomeTransitionListener = null;
-        mLauncher = null;
-    }
-}
diff --git a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
index be532b4..0697f47 100644
--- a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
+++ b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
@@ -173,6 +173,7 @@
 import java.util.ArrayList;
 import java.util.LinkedHashMap;
 import java.util.List;
+import java.util.Map.Entry;
 
 /**
  * Manages the opening and closing app transitions from Launcher
diff --git a/quickstep/src/com/android/launcher3/WidgetPickerActivity.java b/quickstep/src/com/android/launcher3/WidgetPickerActivity.java
index 8c4db4a..23cb8e9 100644
--- a/quickstep/src/com/android/launcher3/WidgetPickerActivity.java
+++ b/quickstep/src/com/android/launcher3/WidgetPickerActivity.java
@@ -35,23 +35,31 @@
 import android.view.WindowManager;
 
 import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
 
 import com.android.launcher3.dragndrop.SimpleDragLayer;
 import com.android.launcher3.model.WidgetItem;
+import com.android.launcher3.model.WidgetPredictionsRequester;
 import com.android.launcher3.model.WidgetsModel;
+import com.android.launcher3.model.data.ItemInfo;
 import com.android.launcher3.popup.PopupDataProvider;
+import com.android.launcher3.util.PackageUserKey;
 import com.android.launcher3.widget.BaseWidgetSheet;
 import com.android.launcher3.widget.WidgetCell;
 import com.android.launcher3.widget.model.WidgetsListBaseEntry;
+import com.android.launcher3.widget.model.WidgetsListHeaderEntry;
 import com.android.launcher3.widget.picker.WidgetsFullSheet;
 
 import java.util.ArrayList;
+import java.util.List;
 import java.util.Locale;
+import java.util.Map;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
 
 /** An Activity that can host Launcher's widget picker. */
 public class WidgetPickerActivity extends BaseActivity {
     private static final String TAG = "WidgetPickerActivity";
-
     /**
      * Name of the extra that indicates that a widget being dragged.
      *
@@ -64,14 +72,33 @@
     // the intent, then widgets will not be filtered for size.
     private static final String EXTRA_DESIRED_WIDGET_WIDTH = "desired_widget_width";
     private static final String EXTRA_DESIRED_WIDGET_HEIGHT = "desired_widget_height";
-
+    /**
+     * Widgets currently added by the user in the UI surface.
+     * <p>This allows widget picker to exclude existing widgets from suggestions.</p>
+     */
+    private static final String EXTRA_ADDED_APP_WIDGETS = "added_app_widgets";
+    /**
+     * A unique identifier of the surface hosting the widgets;
+     * <p>"widgets" is reserved for home screen surface.</p>
+     * <p>"widgets_hub" is reserved for glanceable hub surface.</p>
+     */
+    private static final String EXTRA_UI_SURFACE = "ui_surface";
+    private static final Pattern UI_SURFACE_PATTERN =
+            Pattern.compile("^(widgets|widgets_hub)$");
     private SimpleDragLayer<WidgetPickerActivity> mDragLayer;
     private WidgetsModel mModel;
+    private LauncherAppState mApp;
+    private WidgetPredictionsRequester mWidgetPredictionsRequester;
     private final PopupDataProvider mPopupDataProvider = new PopupDataProvider(i -> {});
 
     private int mDesiredWidgetWidth;
     private int mDesiredWidgetHeight;
     private int mWidgetCategoryFilter;
+    @Nullable
+    private String mUiSurface;
+    // Widgets existing on the host surface.
+    @NonNull
+    private List<AppWidgetProviderInfo> mAddedWidgets = new ArrayList<>();
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
@@ -80,9 +107,8 @@
         getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
         getWindow().clearFlags(WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER);
 
-        LauncherAppState app = LauncherAppState.getInstance(this);
-        InvariantDeviceProfile idp = app.getInvariantDeviceProfile();
-
+        mApp = LauncherAppState.getInstance(this);
+        InvariantDeviceProfile idp = mApp.getInvariantDeviceProfile();
         mDeviceProfile = idp.getDeviceProfile(this);
         mModel = new WidgetsModel();
 
@@ -97,6 +123,11 @@
         widgetSheet.disableNavBarScrim(true);
         widgetSheet.addOnCloseListener(this::finish);
 
+        parseIntentExtras();
+        refreshAndBindWidgets();
+    }
+
+    private void parseIntentExtras() {
         // A value of 0 for either size means that no filtering will occur in that dimension. If
         // both values are 0, then no size filtering will occur.
         mDesiredWidgetWidth =
@@ -108,7 +139,15 @@
         mWidgetCategoryFilter =
                 getIntent().getIntExtra(AppWidgetManager.EXTRA_CATEGORY_FILTER, 0);
 
-        refreshAndBindWidgets();
+        String uiSurfaceParam = getIntent().getStringExtra(EXTRA_UI_SURFACE);
+        if (uiSurfaceParam != null && UI_SURFACE_PATTERN.matcher(uiSurfaceParam).matches()) {
+            mUiSurface = uiSurfaceParam;
+        }
+        ArrayList<AppWidgetProviderInfo> addedWidgets = getIntent().getParcelableArrayListExtra(
+                EXTRA_ADDED_APP_WIDGETS, AppWidgetProviderInfo.class);
+        if (addedWidgets != null) {
+            mAddedWidgets = addedWidgets;
+        }
     }
 
     @NonNull
@@ -179,11 +218,12 @@
         };
     }
 
+    /** Updates the model with widgets and provides them after applying the provided filter. */
     private void refreshAndBindWidgets() {
         MODEL_EXECUTOR.execute(() -> {
             LauncherAppState app = LauncherAppState.getInstance(this);
             mModel.update(app, null);
-            final ArrayList<WidgetsListBaseEntry> widgets =
+            final List<WidgetsListBaseEntry> allWidgets =
                     mModel.getFilteredWidgetsListForPicker(
                             app.getContext(),
                             /*widgetItemFilter=*/ widget -> {
@@ -193,10 +233,37 @@
                                 return verdict.isAcceptable;
                             }
                     );
-            MAIN_EXECUTOR.execute(() -> mPopupDataProvider.setAllWidgets(widgets));
+            bindWidgets(allWidgets);
+            if (mUiSurface != null) {
+                Map<PackageUserKey, List<WidgetItem>> allWidgetsMap = allWidgets.stream()
+                        .filter(WidgetsListHeaderEntry.class::isInstance)
+                        .collect(Collectors.toMap(
+                                entry -> PackageUserKey.fromPackageItemInfo(entry.mPkgItem),
+                                entry -> entry.mWidgets)
+                        );
+                mWidgetPredictionsRequester = new WidgetPredictionsRequester(app.getContext(),
+                        mUiSurface, allWidgetsMap);
+                mWidgetPredictionsRequester.request(mAddedWidgets, this::bindRecommendedWidgets);
+            }
         });
     }
 
+    private void bindWidgets(List<WidgetsListBaseEntry> widgets) {
+        MAIN_EXECUTOR.execute(() -> mPopupDataProvider.setAllWidgets(widgets));
+    }
+
+    private void bindRecommendedWidgets(List<ItemInfo> recommendedWidgets) {
+        MAIN_EXECUTOR.execute(() -> mPopupDataProvider.setRecommendedWidgets(recommendedWidgets));
+    }
+
+    @Override
+    protected void onDestroy() {
+        super.onDestroy();
+        if (mWidgetPredictionsRequester != null) {
+            mWidgetPredictionsRequester.clear();
+        }
+    }
+
     private WidgetAcceptabilityVerdict isWidgetAcceptable(WidgetItem widget) {
         final AppWidgetProviderInfo info = widget.widgetInfo;
         if (info == null) {
diff --git a/quickstep/src/com/android/launcher3/appprediction/PredictionRowView.java b/quickstep/src/com/android/launcher3/appprediction/PredictionRowView.java
index b36fd66..70e01f5 100644
--- a/quickstep/src/com/android/launcher3/appprediction/PredictionRowView.java
+++ b/quickstep/src/com/android/launcher3/appprediction/PredictionRowView.java
@@ -37,7 +37,6 @@
 import com.android.launcher3.allapps.FloatingHeaderRow;
 import com.android.launcher3.allapps.FloatingHeaderView;
 import com.android.launcher3.anim.AlphaUpdateListener;
-import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.keyboard.FocusIndicatorHelper;
 import com.android.launcher3.keyboard.FocusIndicatorHelper.SimpleFocusIndicatorHelper;
 import com.android.launcher3.model.data.ItemInfo;
@@ -45,6 +44,7 @@
 import com.android.launcher3.model.data.WorkspaceItemInfo;
 import com.android.launcher3.views.ActivityContext;
 
+import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.stream.Collectors;
@@ -240,7 +240,11 @@
             icon.reset();
             if (predictionCount > i) {
                 icon.setVisibility(View.VISIBLE);
-                icon.applyFromWorkspaceItem(mPredictedApps.get(i));
+                WorkspaceItemInfo predictedItem = mPredictedApps.get(i);
+                predictedItem.rank = i;
+                predictedItem.cellX = i;
+                predictedItem.cellY = 0;
+                icon.applyFromWorkspaceItem(predictedItem);
             } else {
                 icon.setVisibility(predictionCount == 0 ? GONE : INVISIBLE);
             }
@@ -281,4 +285,11 @@
         return getChildAt(0);
     }
 
+    public void dump(String prefix, PrintWriter writer) {
+        writer.println(prefix + this.getClass().getSimpleName());
+        writer.println(prefix + "\tmPredictionsEnabled: " + mPredictionsEnabled);
+        writer.println(prefix + "\tmPredictionUiUpdatePaused: " + mPredictionUiUpdatePaused);
+        writer.println(prefix + "\tmNumPredictedAppsPerRow: " + mNumPredictedAppsPerRow);
+        writer.println(prefix + "\tmPredictedApps: " + mPredictedApps);
+    }
 }
diff --git a/quickstep/src/com/android/launcher3/desktop/DesktopRecentsTransitionController.kt b/quickstep/src/com/android/launcher3/desktop/DesktopRecentsTransitionController.kt
index 10733fb..3ef8e54 100644
--- a/quickstep/src/com/android/launcher3/desktop/DesktopRecentsTransitionController.kt
+++ b/quickstep/src/com/android/launcher3/desktop/DesktopRecentsTransitionController.kt
@@ -20,9 +20,9 @@
 import android.os.RemoteException
 import android.util.Log
 import android.view.SurfaceControl
-import android.window.IRemoteTransition
 import android.window.IRemoteTransitionFinishedCallback
 import android.window.RemoteTransition
+import android.window.RemoteTransitionStub
 import android.window.TransitionInfo
 import com.android.launcher3.statehandlers.DepthController
 import com.android.launcher3.statemanager.StateManager
@@ -56,12 +56,17 @@
         systemUiProxy.showDesktopApps(desktopTaskView.display.displayId, transition)
     }
 
+    /** Launch desktop tasks from recents view */
+    fun moveToDesktop(taskId: Int) {
+        systemUiProxy.moveToDesktop(taskId)
+    }
+
     private class RemoteDesktopLaunchTransitionRunner(
         private val desktopTaskView: DesktopTaskView,
         private val stateManager: StateManager<*>,
         private val depthController: DepthController?,
         private val successCallback: Consumer<Boolean>?
-    ) : IRemoteTransition.Stub() {
+    ) : RemoteTransitionStub() {
 
         override fun startAnimation(
             token: IBinder,
@@ -90,17 +95,6 @@
                 }
             }
         }
-
-        override fun mergeAnimation(
-            transition: IBinder,
-            info: TransitionInfo,
-            t: SurfaceControl.Transaction,
-            mergeTarget: IBinder,
-            finishCallback: IRemoteTransitionFinishedCallback
-        ) {}
-
-        override fun onTransitionConsumed(transition: IBinder?, aborted: Boolean) {
-        }
     }
 
     companion object {
diff --git a/quickstep/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java b/quickstep/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java
index 672bd1d..1c5a75d 100644
--- a/quickstep/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java
+++ b/quickstep/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java
@@ -499,7 +499,7 @@
 
         @Override
         public void onClick(View view) {
-            dismissTaskMenuView(mTarget);
+            dismissTaskMenuView();
             pinPrediction(mItemInfo);
         }
     }
diff --git a/quickstep/src/com/android/launcher3/model/QuickstepModelDelegate.java b/quickstep/src/com/android/launcher3/model/QuickstepModelDelegate.java
index c0e0587..bc35125 100644
--- a/quickstep/src/com/android/launcher3/model/QuickstepModelDelegate.java
+++ b/quickstep/src/com/android/launcher3/model/QuickstepModelDelegate.java
@@ -111,12 +111,11 @@
     private final InvariantDeviceProfile mIDP;
     private final AppEventProducer mAppEventProducer;
     private final StatsManager mStatsManager;
-    private final Context mContext;
 
     protected boolean mActive = false;
 
     public QuickstepModelDelegate(Context context) {
-        mContext = context;
+        super(context);
         mAppEventProducer = new AppEventProducer(context, this::onAppTargetEvent);
 
         mIDP = InvariantDeviceProfile.INSTANCE.get(context);
diff --git a/quickstep/src/com/android/launcher3/model/WellbeingModel.java b/quickstep/src/com/android/launcher3/model/WellbeingModel.java
index 3d04cb6..c345d6e 100644
--- a/quickstep/src/com/android/launcher3/model/WellbeingModel.java
+++ b/quickstep/src/com/android/launcher3/model/WellbeingModel.java
@@ -44,7 +44,6 @@
 import androidx.annotation.Nullable;
 import androidx.annotation.WorkerThread;
 
-import com.android.launcher3.BaseDraggingActivity;
 import com.android.launcher3.R;
 import com.android.launcher3.model.data.ItemInfo;
 import com.android.launcher3.popup.RemoteActionShortcut;
@@ -53,6 +52,7 @@
 import com.android.launcher3.util.MainThreadInitializedObject;
 import com.android.launcher3.util.Preconditions;
 import com.android.launcher3.util.SimpleBroadcastReceiver;
+import com.android.launcher3.views.ActivityContext;
 
 import java.util.Arrays;
 import java.util.HashMap;
@@ -147,7 +147,7 @@
 
     @MainThread
     private SystemShortcut getShortcutForApp(String packageName, int userId,
-            BaseDraggingActivity activity, ItemInfo info, View originalView) {
+            Context context, ItemInfo info, View originalView) {
         Preconditions.assertUIThread();
         // Work profile apps are not recognized by digital wellbeing.
         if (userId != UserHandle.myUserId()) {
@@ -171,7 +171,7 @@
                         "getShortcutForApp [" + packageName + "]: action: '" + action.getTitle()
                                 + "'");
             }
-            return new RemoteActionShortcut(action, activity, info, originalView);
+            return new RemoteActionShortcut(action, context, info, originalView);
         }
     }
 
@@ -305,9 +305,11 @@
     /**
      * Shortcut factory for generating wellbeing action
      */
-    public static final SystemShortcut.Factory<BaseDraggingActivity> SHORTCUT_FACTORY =
-            (activity, info, originalView) -> (info.getTargetComponent() == null) ? null
-                    : INSTANCE.get(activity).getShortcutForApp(
-                            info.getTargetComponent().getPackageName(), info.user.getIdentifier(),
-                            activity, info, originalView);
+    public static final SystemShortcut.Factory<ActivityContext> SHORTCUT_FACTORY =
+            (context, info, originalView) ->
+                    (info.getTargetComponent() == null) ? null
+                            : INSTANCE.get(originalView.getContext()).getShortcutForApp(
+                                    info.getTargetComponent().getPackageName(), info.user.getIdentifier(),
+                                    ActivityContext.lookupContext(originalView.getContext()),
+                                    info, originalView);
 }
diff --git a/quickstep/src/com/android/launcher3/model/WidgetPredictionsRequester.java b/quickstep/src/com/android/launcher3/model/WidgetPredictionsRequester.java
new file mode 100644
index 0000000..8431396
--- /dev/null
+++ b/quickstep/src/com/android/launcher3/model/WidgetPredictionsRequester.java
@@ -0,0 +1,233 @@
+/*
+ * Copyright (C) 2024 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.Flags.enableCategorizedWidgetSuggestions;
+import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_WIDGETS_PREDICTION;
+import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
+import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
+
+import android.app.prediction.AppPredictionContext;
+import android.app.prediction.AppPredictionManager;
+import android.app.prediction.AppPredictor;
+import android.app.prediction.AppTarget;
+import android.app.prediction.AppTargetEvent;
+import android.app.prediction.AppTargetId;
+import android.appwidget.AppWidgetProviderInfo;
+import android.content.ComponentName;
+import android.content.Context;
+import android.os.Bundle;
+import android.text.TextUtils;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.VisibleForTesting;
+import androidx.annotation.WorkerThread;
+
+import com.android.launcher3.model.data.ItemInfo;
+import com.android.launcher3.util.ComponentKey;
+import com.android.launcher3.util.PackageUserKey;
+import com.android.launcher3.widget.PendingAddWidgetInfo;
+import com.android.launcher3.widget.picker.WidgetRecommendationCategoryProvider;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.function.Consumer;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+
+/**
+ * Works with app predictor to fetch and process widget predictions displayed in a standalone
+ * widget picker activity for a UI surface.
+ */
+public class WidgetPredictionsRequester {
+    private static final int NUM_OF_RECOMMENDED_WIDGETS_PREDICATION = 20;
+    private static final String BUNDLE_KEY_ADDED_APP_WIDGETS = "added_app_widgets";
+
+    @Nullable
+    private AppPredictor mAppPredictor;
+    private final Context mContext;
+    @NonNull
+    private final String mUiSurface;
+    @NonNull
+    private final Map<PackageUserKey, List<WidgetItem>> mAllWidgets;
+
+    public WidgetPredictionsRequester(Context context, @NonNull String uiSurface,
+            @NonNull Map<PackageUserKey, List<WidgetItem>> allWidgets) {
+        mContext = context;
+        mUiSurface = uiSurface;
+        mAllWidgets = Collections.unmodifiableMap(allWidgets);
+    }
+
+    /**
+     * Requests predictions from the app predictions manager and registers the provided callback to
+     * receive updates when predictions are available.
+     *
+     * @param existingWidgets widgets that are currently added to the surface;
+     * @param callback        consumer of prediction results to be called when predictions are
+     *                        available
+     */
+    public void request(List<AppWidgetProviderInfo> existingWidgets,
+            Consumer<List<ItemInfo>> callback) {
+        Bundle bundle = buildBundleForPredictionSession(existingWidgets, mUiSurface);
+        Predicate<WidgetItem> filter = notOnUiSurfaceFilter(existingWidgets);
+
+        MODEL_EXECUTOR.execute(() -> {
+            clear();
+            AppPredictionManager apm = mContext.getSystemService(AppPredictionManager.class);
+            if (apm == null) {
+                return;
+            }
+
+            mAppPredictor = apm.createAppPredictionSession(
+                    new AppPredictionContext.Builder(mContext)
+                            .setUiSurface(mUiSurface)
+                            .setExtras(bundle)
+                            .setPredictedTargetCount(NUM_OF_RECOMMENDED_WIDGETS_PREDICATION)
+                            .build());
+            mAppPredictor.registerPredictionUpdates(MODEL_EXECUTOR,
+                    targets -> bindPredictions(targets, filter, callback));
+            mAppPredictor.requestPredictionUpdate();
+        });
+    }
+
+    /**
+     * Returns a bundle that can be passed in a prediction session
+     *
+     * @param addedWidgets widgets that are already added by the user in the ui surface
+     * @param uiSurface    a unique identifier of the surface hosting widgets; format
+     *                     "widgets_xx"; note - "widgets" is reserved for home screen surface.
+     */
+    @VisibleForTesting
+    static Bundle buildBundleForPredictionSession(List<AppWidgetProviderInfo> addedWidgets,
+            String uiSurface) {
+        Bundle bundle = new Bundle();
+        ArrayList<AppTargetEvent> addedAppTargetEvents = new ArrayList<>();
+        for (AppWidgetProviderInfo info : addedWidgets) {
+            ComponentName componentName = info.provider;
+            AppTargetEvent appTargetEvent = buildAppTargetEvent(uiSurface, info, componentName);
+            addedAppTargetEvents.add(appTargetEvent);
+        }
+        bundle.putParcelableArrayList(BUNDLE_KEY_ADDED_APP_WIDGETS, addedAppTargetEvents);
+        return bundle;
+    }
+
+    /**
+     * Builds the AppTargetEvent for added widgets in a form that can be passed to the widget
+     * predictor.
+     * Also see {@link PredictionHelper}
+     */
+    private static AppTargetEvent buildAppTargetEvent(String uiSurface, AppWidgetProviderInfo info,
+            ComponentName componentName) {
+        AppTargetId appTargetId = new AppTargetId("widget:" + componentName.getPackageName());
+        AppTarget appTarget = new AppTarget.Builder(appTargetId, componentName.getPackageName(),
+                /*user=*/ info.getProfile()).setClassName(componentName.getClassName()).build();
+        return new AppTargetEvent.Builder(appTarget, AppTargetEvent.ACTION_PIN)
+                .setLaunchLocation(uiSurface).build();
+    }
+
+    /**
+     * Returns a filter to match {@link WidgetItem}s that don't exist on the UI surface.
+     */
+    @NonNull
+    @VisibleForTesting
+    static Predicate<WidgetItem> notOnUiSurfaceFilter(
+            List<AppWidgetProviderInfo> existingWidgets) {
+        Set<ComponentKey> existingComponentKeys = existingWidgets.stream().map(
+                widget -> new ComponentKey(widget.provider, widget.getProfile())).collect(
+                Collectors.toSet());
+        return widgetItem -> !existingComponentKeys.contains(widgetItem);
+    }
+
+    /** Provides the predictions returned by the predictor to the registered callback. */
+    @WorkerThread
+    private void bindPredictions(List<AppTarget> targets, Predicate<WidgetItem> filter,
+            Consumer<List<ItemInfo>> callback) {
+        List<WidgetItem> filteredPredictions = filterPredictions(targets, mAllWidgets, filter);
+        List<ItemInfo> mappedPredictions = mapWidgetItemsToItemInfo(filteredPredictions);
+
+        MAIN_EXECUTOR.execute(() -> callback.accept(mappedPredictions));
+    }
+
+    /**
+     * Applies the provided filter (e.g. widgets not on workspace) on the predictions returned by
+     * the predictor.
+     */
+    @VisibleForTesting
+    static List<WidgetItem> filterPredictions(List<AppTarget> predictions,
+            Map<PackageUserKey, List<WidgetItem>> allWidgets, Predicate<WidgetItem> filter) {
+        List<WidgetItem> servicePredictedItems = new ArrayList<>();
+        List<WidgetItem> localFilteredWidgets = new ArrayList<>();
+
+        for (AppTarget prediction : predictions) {
+            List<WidgetItem> widgetsInPackage = allWidgets.get(
+                    new PackageUserKey(prediction.getPackageName(), prediction.getUser()));
+            if (widgetsInPackage == null || widgetsInPackage.isEmpty()) {
+                continue;
+            }
+            String className = prediction.getClassName();
+            if (!TextUtils.isEmpty(className)) {
+                WidgetItem item = widgetsInPackage.stream()
+                        .filter(w -> className.equals(w.componentName.getClassName()))
+                        .filter(filter)
+                        .findFirst().orElse(null);
+                if (item != null) {
+                    servicePredictedItems.add(item);
+                    continue;
+                }
+            }
+            // No widget was added by the service, try local filtering
+            widgetsInPackage.stream().filter(filter).findFirst()
+                    .ifPresent(localFilteredWidgets::add);
+        }
+        if (servicePredictedItems.isEmpty()) {
+            servicePredictedItems.addAll(localFilteredWidgets);
+        }
+
+        return servicePredictedItems;
+    }
+
+    /**
+     * Converts the list of {@link WidgetItem}s to the list of {@link ItemInfo}s.
+     */
+    private List<ItemInfo> mapWidgetItemsToItemInfo(List<WidgetItem> widgetItems) {
+        List<ItemInfo> items;
+        if (enableCategorizedWidgetSuggestions()) {
+            WidgetRecommendationCategoryProvider categoryProvider =
+                    WidgetRecommendationCategoryProvider.newInstance(mContext);
+            items = widgetItems.stream()
+                    .map(it -> new PendingAddWidgetInfo(it.widgetInfo, CONTAINER_WIDGETS_PREDICTION,
+                            categoryProvider.getWidgetRecommendationCategory(mContext, it)))
+                    .collect(Collectors.toList());
+        } else {
+            items = widgetItems.stream().map(it -> new PendingAddWidgetInfo(it.widgetInfo,
+                    CONTAINER_WIDGETS_PREDICTION)).collect(Collectors.toList());
+        }
+        return items;
+    }
+
+    /** Cleans up any open prediction sessions. */
+    public void clear() {
+        if (mAppPredictor != null) {
+            mAppPredictor.destroy();
+            mAppPredictor = null;
+        }
+    }
+}
diff --git a/quickstep/src/com/android/launcher3/statehandlers/DesktopVisibilityController.java b/quickstep/src/com/android/launcher3/statehandlers/DesktopVisibilityController.java
index f9a8c99..c0dacf1 100644
--- a/quickstep/src/com/android/launcher3/statehandlers/DesktopVisibilityController.java
+++ b/quickstep/src/com/android/launcher3/statehandlers/DesktopVisibilityController.java
@@ -19,7 +19,6 @@
 
 import static com.android.launcher3.LauncherState.BACKGROUND_APP;
 import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
-import static com.android.window.flags.Flags.enableDesktopWindowingMode;
 
 import android.os.Debug;
 import android.os.SystemProperties;
@@ -49,7 +48,7 @@
             "persist.wm.debug.desktop_stashing", false);
     private final Launcher mLauncher;
 
-    private int mVisibleFreeformTasksCount;
+    private int mVisibleDesktopTasksCount;
     private boolean mInOverviewState;
     private boolean mBackgroundStateEnabled;
     private boolean mGestureInProgress;
@@ -74,7 +73,7 @@
                         if (DEBUG) {
                             Log.d(TAG, "desktop visible tasks count changed=" + visibleTasksCount);
                         }
-                        setVisibleFreeformTasksCount(visibleTasksCount);
+                        setVisibleDesktopTasksCount(visibleTasksCount);
                     }
                 });
             }
@@ -109,54 +108,51 @@
     }
 
     /**
-     * Whether freeform windows are visible in desktop mode.
+     * Whether desktop tasks are visible in desktop mode.
      */
-    public boolean areFreeformTasksVisible() {
-        boolean freeformTasksVisible = mVisibleFreeformTasksCount > 0;
+    public boolean areDesktopTasksVisible() {
+        boolean desktopTasksVisible = mVisibleDesktopTasksCount > 0;
         if (DEBUG) {
-            Log.d(TAG, "areFreeformTasksVisible: freeformVisible=" + freeformTasksVisible
+            Log.d(TAG, "areDesktopTasksVisible: desktopVisible=" + desktopTasksVisible
                     + " overview=" + mInOverviewState);
         }
-        return freeformTasksVisible && !mInOverviewState;
+        return desktopTasksVisible && !mInOverviewState;
     }
 
     /**
-     * Number of visible freeform windows in desktop mode.
+     * Number of visible desktop windows in desktop mode.
      */
-    public int getVisibleFreeformTasksCount() {
-        return mVisibleFreeformTasksCount;
+    public int getVisibleDesktopTasksCount() {
+        return mVisibleDesktopTasksCount;
     }
 
     /**
-     * Sets the number of freeform windows that are visible and updates launcher visibility based on
+     * Sets the number of desktop windows that are visible and updates launcher visibility based on
      * it.
      */
-    public void setVisibleFreeformTasksCount(int visibleTasksCount) {
+    public void setVisibleDesktopTasksCount(int visibleTasksCount) {
         if (DEBUG) {
-            Log.d(TAG, "setVisibleFreeformTasksCount: visibleTasksCount=" + visibleTasksCount
-                    + " currentValue=" + mVisibleFreeformTasksCount);
-        }
-        if (!enableDesktopWindowingMode()) {
-            return;
+            Log.d(TAG, "setVisibleDesktopTasksCount: visibleTasksCount=" + visibleTasksCount
+                    + " currentValue=" + mVisibleDesktopTasksCount);
         }
 
-        if (visibleTasksCount != mVisibleFreeformTasksCount) {
-            final boolean wasVisible = mVisibleFreeformTasksCount > 0;
+        if (visibleTasksCount != mVisibleDesktopTasksCount) {
+            final boolean wasVisible = mVisibleDesktopTasksCount > 0;
             final boolean isVisible = visibleTasksCount > 0;
-            mVisibleFreeformTasksCount = visibleTasksCount;
+            mVisibleDesktopTasksCount = visibleTasksCount;
 
             if (wasVisible != isVisible) {
-                if (mVisibleFreeformTasksCount > 0) {
+                if (mVisibleDesktopTasksCount > 0) {
                     setLauncherViewsVisibility(View.INVISIBLE);
                     if (!mInOverviewState) {
-                        // When freeform is visible & we're not in overview, we want launcher to
-                        // appear paused, this ensures that taskbar displays.
+                        // When desktop tasks are visible & we're not in overview, we want launcher
+                        // to appear paused, this ensures that taskbar displays.
                         markLauncherPaused();
                     }
                 } else {
                     setLauncherViewsVisibility(View.VISIBLE);
-                    // If freeform isn't visible ensure that launcher appears resumed to behave
-                    // normally.
+                    // If desktop tasks aren't visible, ensure that launcher appears resumed to
+                    // behave normally.
                     markLauncherResumed();
                 }
             }
@@ -180,17 +176,14 @@
             Log.d(TAG, "setOverviewStateEnabled: enabled=" + overviewStateEnabled
                     + " currentValue=" + mInOverviewState);
         }
-        if (!enableDesktopWindowingMode()) {
-            return;
-        }
         if (overviewStateEnabled != mInOverviewState) {
             mInOverviewState = overviewStateEnabled;
             if (mInOverviewState) {
                 setLauncherViewsVisibility(View.VISIBLE);
                 markLauncherResumed();
-            } else if (areFreeformTasksVisible() && !mGestureInProgress) {
+            } else if (areDesktopTasksVisible() && !mGestureInProgress) {
                 // Switching out of overview state and gesture finished.
-                // If freeform tasks are still visible, hide launcher again.
+                // If desktop tasks are still visible, hide launcher again.
                 setLauncherViewsVisibility(View.INVISIBLE);
                 markLauncherPaused();
             }
@@ -202,16 +195,13 @@
             Log.d(TAG, "setBackgroundStateEnabled: enabled=" + backgroundStateEnabled
                     + " currentValue=" + mBackgroundStateEnabled);
         }
-        if (!enableDesktopWindowingMode()) {
-            return;
-        }
         if (backgroundStateEnabled != mBackgroundStateEnabled) {
             mBackgroundStateEnabled = backgroundStateEnabled;
             if (mBackgroundStateEnabled) {
                 setLauncherViewsVisibility(View.VISIBLE);
                 markLauncherResumed();
-            } else if (areFreeformTasksVisible() && !mGestureInProgress) {
-                // Switching out of background state. If freeform tasks are visible, pause launcher.
+            } else if (areDesktopTasksVisible() && !mGestureInProgress) {
+                // Switching out of background state. If desktop tasks are visible, pause launcher.
                 setLauncherViewsVisibility(View.INVISIBLE);
                 markLauncherPaused();
             }
@@ -229,9 +219,6 @@
      * Notify controller that recents gesture has started.
      */
     public void setRecentsGestureStart() {
-        if (!enableDesktopWindowingMode()) {
-            return;
-        }
         if (DEBUG) {
             Log.d(TAG, "setRecentsGestureStart");
         }
@@ -243,9 +230,6 @@
      * {@link com.android.quickstep.GestureState.GestureEndTarget}
      */
     public void setRecentsGestureEnd(@Nullable GestureState.GestureEndTarget endTarget) {
-        if (!enableDesktopWindowingMode()) {
-            return;
-        }
         if (DEBUG) {
             Log.d(TAG, "setRecentsGestureEnd: endTarget=" + endTarget);
         }
@@ -267,7 +251,7 @@
      * Handle launcher moving to home due to home gesture or home button press.
      */
     public void onHomeActionTriggered() {
-        if (IS_STASHING_ENABLED && areFreeformTasksVisible()) {
+        if (IS_STASHING_ENABLED && areDesktopTasksVisible()) {
             SystemUiProxy.INSTANCE.get(mLauncher).stashDesktopApps(mLauncher.getDisplayId());
         }
     }
@@ -286,7 +270,7 @@
             dragLayer.setVisibility(visibility);
         }
         if (mLauncher instanceof QuickstepLauncher ql && ql.getTaskbarUIController() != null
-                && mVisibleFreeformTasksCount != 0) {
+                && mVisibleDesktopTasksCount != 0) {
             ql.getTaskbarUIController().onLauncherVisibilityChanged(visibility == VISIBLE);
         }
     }
diff --git a/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchController.java b/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchController.java
index bed85d7..584106b 100644
--- a/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchController.java
@@ -15,8 +15,6 @@
  */
 package com.android.launcher3.taskbar;
 
-import static com.android.window.flags.Flags.enableDesktopWindowingMode;
-
 import android.content.ComponentName;
 import android.content.pm.ActivityInfo;
 
@@ -117,9 +115,7 @@
         DesktopVisibilityController desktopController =
                 LauncherActivityInterface.INSTANCE.getDesktopVisibilityController();
         final boolean onDesktop =
-                enableDesktopWindowingMode()
-                        && desktopController != null
-                        && desktopController.areFreeformTasksVisible();
+                desktopController != null && desktopController.areDesktopTasksVisible();
 
         if (mModel.isTaskListValid(mTaskListChangeId)) {
             // When we are opening the KQS with no focus override, check if the first task is
@@ -158,14 +154,12 @@
 
         // Hide all desktop tasks and show them on the hidden tile
         int hiddenDesktopTasks = 0;
-        if (enableDesktopWindowingMode()) {
-            DesktopTask desktopTask = findDesktopTask(tasks);
-            if (desktopTask != null) {
-                hiddenDesktopTasks = desktopTask.tasks.size();
-                tasks = tasks.stream()
-                        .filter(t -> !(t instanceof DesktopTask))
-                        .collect(Collectors.toCollection(ArrayList<GroupTask>::new));
-            }
+        DesktopTask desktopTask = findDesktopTask(tasks);
+        if (desktopTask != null) {
+            hiddenDesktopTasks = desktopTask.tasks.size();
+            tasks = tasks.stream()
+                    .filter(t -> !(t instanceof DesktopTask))
+                    .collect(Collectors.toCollection(ArrayList<GroupTask>::new));
         }
         mTasks = tasks.stream()
                 .limit(MAX_TASKS)
diff --git a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
index a59aead..81f2c0f 100644
--- a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
@@ -21,7 +21,6 @@
 import static com.android.launcher3.taskbar.TaskbarEduTooltipControllerKt.TOOLTIP_STEP_FEATURES;
 import static com.android.launcher3.taskbar.TaskbarLauncherStateController.FLAG_VISIBLE;
 import static com.android.quickstep.TaskAnimationManager.ENABLE_SHELL_TRANSITIONS;
-import static com.android.window.flags.Flags.enableDesktopWindowingMode;
 
 import android.animation.Animator;
 import android.animation.AnimatorSet;
@@ -35,6 +34,7 @@
 import androidx.annotation.Nullable;
 
 import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.Flags;
 import com.android.launcher3.LauncherState;
 import com.android.launcher3.QuickstepTransitionManager;
 import com.android.launcher3.R;
@@ -49,8 +49,10 @@
 import com.android.launcher3.util.DisplayController;
 import com.android.launcher3.util.MultiPropertyFactory;
 import com.android.launcher3.util.OnboardingPrefs;
+import com.android.quickstep.HomeVisibilityState;
 import com.android.quickstep.LauncherActivityInterface;
 import com.android.quickstep.RecentsAnimationCallbacks;
+import com.android.quickstep.SystemUiProxy;
 import com.android.quickstep.util.GroupTask;
 import com.android.quickstep.util.TISBindHelper;
 import com.android.quickstep.views.RecentsView;
@@ -79,6 +81,7 @@
                     AnimatedFloat.VALUE, DISPLAY_PROGRESS_COUNT, Float::max);
 
     private final QuickstepLauncher mLauncher;
+    private final HomeVisibilityState mHomeState;
 
     private final DeviceProfile.OnDeviceProfileChangeListener mOnDeviceProfileChangeListener =
             dp -> {
@@ -87,6 +90,8 @@
                     mControllers.taskbarViewController.onRotationChanged(dp);
                 }
             };
+    private final HomeVisibilityState.VisibilityChangeListener  mVisibilityChangeListener =
+            this::onLauncherVisibilityChanged;
 
     // Initialized in init.
     private final TaskbarLauncherStateController
@@ -94,6 +99,7 @@
 
     public LauncherTaskbarUIController(QuickstepLauncher launcher) {
         mLauncher = launcher;
+        mHomeState =  SystemUiProxy.INSTANCE.get(mLauncher).getHomeVisibilityState();
     }
 
     @Override
@@ -104,8 +110,11 @@
                 mControllers.getSharedState().sysuiStateFlags);
 
         mLauncher.setTaskbarUIController(this);
-
-        onLauncherVisibilityChanged(mLauncher.hasBeenResumed(), true /* fromInit */);
+        mHomeState.addListener(mVisibilityChangeListener);
+        onLauncherVisibilityChanged(
+                Flags.useActivityOverlay()
+                        ? mHomeState.isHomeVisible() : mLauncher.hasBeenResumed(),
+                true /* fromInit */);
 
         onStashedInAppChanged(mLauncher.getDeviceProfile());
         mLauncher.addOnDeviceProfileChangeListener(mOnDeviceProfileChangeListener);
@@ -129,6 +138,7 @@
 
         mLauncher.setTaskbarUIController(null);
         mLauncher.removeOnDeviceProfileChangeListener(mOnDeviceProfileChangeListener);
+        mHomeState.removeListener(mVisibilityChangeListener);
         updateTaskTransitionSpec(true);
     }
 
@@ -209,19 +219,13 @@
         DesktopVisibilityController desktopController =
                 LauncherActivityInterface.INSTANCE.getDesktopVisibilityController();
         final boolean onDesktop =
-                enableDesktopWindowingMode()
-                        && desktopController != null
-                        && desktopController.areFreeformTasksVisible();
+                desktopController != null && desktopController.areDesktopTasksVisible();
         if (onDesktop) {
             isVisible = false;
         }
 
         mTaskbarLauncherStateController.updateStateForFlag(FLAG_VISIBLE, isVisible);
-        // TODO(b/308851855): Skip animation for launching split from home, will refine later
-        boolean skipAnimForSplit = enableSplitContextually() &&
-                mLauncher.areBothSplitAppsConfirmed() &&
-                mLauncher.getStateManager().getState() == LauncherState.NORMAL;
-        if (skipAnimForSplit || fromInit) {
+        if (fromInit) {
             duration = 0;
         }
         return mTaskbarLauncherStateController.applyState(duration, startAnimation);
@@ -234,7 +238,8 @@
 
     @Override
     public void refreshResumedState() {
-        onLauncherVisibilityChanged(mLauncher.hasBeenResumed());
+        onLauncherVisibilityChanged(Flags.useActivityOverlay()
+                ? mHomeState.isHomeVisible() : mLauncher.hasBeenResumed());
     }
 
     @Override
@@ -299,6 +304,8 @@
      */
     public void showEduOnAppLaunch() {
         if (!shouldShowEduOnAppLaunch()) {
+            // Called in case the edu finishes and circle to search edu is still pending
+            mControllers.taskbarEduTooltipController.maybeShowCircleToSearchEdu();
             return;
         }
 
@@ -312,6 +319,11 @@
         mControllers.taskbarEduTooltipController.maybeShowSwipeEdu();
     }
 
+    /** Will make the next onRecentsAnimationFinished() animation a no-op. */
+    public void setSkipNextRecentsAnimEnd() {
+        mTaskbarLauncherStateController.setSkipNextRecentsAnimEnd();
+    }
+
     /**
      * Returns {@code true} if a Taskbar education should be shown on application launch.
      */
@@ -409,15 +421,15 @@
     }
 
     @Override
-    protected boolean isInOverview() {
-        return mTaskbarLauncherStateController.isInOverview();
+    protected boolean isInOverviewUi() {
+        return mTaskbarLauncherStateController.isInOverviewUi();
     }
 
     @Override
     protected boolean canToggleHomeAllApps() {
         return mLauncher.isResumed()
-                && !mTaskbarLauncherStateController.isInOverview()
-                && !mLauncher.areFreeformTasksVisible();
+                && !mTaskbarLauncherStateController.isInOverviewUi()
+                && !mLauncher.areDesktopTasksVisible();
     }
 
     @Override
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
index 8769f11..49d4afe 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
@@ -113,8 +113,8 @@
 import com.android.launcher3.testing.shared.TestProtocol;
 import com.android.launcher3.touch.ItemClickHandler;
 import com.android.launcher3.touch.ItemClickHandler.ItemClickProxy;
-import com.android.launcher3.uioverrides.ApiWrapper;
 import com.android.launcher3.util.ActivityOptionsWrapper;
+import com.android.launcher3.util.ApiWrapper;
 import com.android.launcher3.util.ComponentKey;
 import com.android.launcher3.util.DisplayController;
 import com.android.launcher3.util.Executors;
@@ -665,7 +665,7 @@
 
         LauncherAtom.TaskBarContainer.Builder taskbarBuilder =
                 LauncherAtom.TaskBarContainer.newBuilder();
-        if (mControllers.uiController.isInOverview()) {
+        if (mControllers.uiController.isInOverviewUi()) {
             taskbarBuilder.setTaskSwitcherContainer(
                     LauncherAtom.TaskSwitcherContainer.newBuilder());
         }
@@ -1120,7 +1120,7 @@
                         } else if (info.isPromise()) {
                             TestLogging.recordEvent(
                                     TestProtocol.SEQUENCE_MAIN, "start: taskbarPromiseIcon");
-                            intent = ApiWrapper.getAppMarketActivityIntent(this,
+                            intent = ApiWrapper.INSTANCE.get(this).getAppMarketActivityIntent(
                                     info.getTargetPackage(), Process.myUserHandle());
                             startActivity(intent);
 
@@ -1233,13 +1233,13 @@
             return;
         }
 
-        boolean findExactPairMatch = itemInfos.size() == 2;
+        boolean isLaunchingAppPair = itemInfos.size() == 2;
         // Convert the list of ItemInfo instances to a list of ComponentKeys
         List<ComponentKey> componentKeys =
                 itemInfos.stream().map(ItemInfo::getComponentKey).toList();
         recents.getSplitSelectController().findLastActiveTasksAndRunCallback(
                 componentKeys,
-                findExactPairMatch,
+                isLaunchingAppPair,
                 foundTasks -> {
                     @Nullable Task foundTask = foundTasks[0];
                     if (foundTask != null) {
@@ -1253,10 +1253,18 @@
                         }
                     }
 
-                    if (findExactPairMatch) {
-                        // We did not find the app pair we were looking for, so launch one.
-                        recents.getSplitSelectController().getAppPairsController().launchAppPair(
-                                (AppPairIcon) launchingIconView, -1 /*cuj*/);
+                    if (isLaunchingAppPair) {
+                        // Finish recents animation if it's running before launching to ensure
+                        // we get both leashes for the animation
+                        mControllers.uiController.setSkipNextRecentsAnimEnd();
+                        recents.switchToScreenshot(() ->
+                                recents.finishRecentsAnimation(true /*toRecents*/,
+                                        false /*shouldPip*/,
+                                        () -> recents
+                                                .getSplitSelectController()
+                                                .getAppPairsController()
+                                                .launchAppPair((AppPairIcon) launchingIconView,
+                                                        -1 /*cuj*/)));
                     } else {
                         startItemInfoActivity(itemInfos.get(0), foundTask);
                     }
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarEduTooltipController.kt b/quickstep/src/com/android/launcher3/taskbar/TaskbarEduTooltipController.kt
index 7eed955..e53f627 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarEduTooltipController.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarEduTooltipController.kt
@@ -15,7 +15,12 @@
  */
 package com.android.launcher3.taskbar
 
+import android.content.Intent
+import android.net.Uri
 import android.os.Bundle
+import android.text.SpannableString
+import android.text.method.LinkMovementMethod
+import android.text.style.URLSpan
 import android.view.Gravity
 import android.view.View
 import android.view.View.GONE
@@ -24,16 +29,20 @@
 import android.view.ViewGroup.MarginLayoutParams
 import android.view.accessibility.AccessibilityEvent
 import android.view.accessibility.AccessibilityNodeInfo
+import android.widget.TextView
 import androidx.annotation.IntDef
 import androidx.annotation.LayoutRes
+import androidx.core.text.HtmlCompat
 import androidx.core.view.updateLayoutParams
 import com.airbnb.lottie.LottieAnimationView
+import com.android.launcher3.LauncherPrefs
 import com.android.launcher3.R
 import com.android.launcher3.Utilities
 import com.android.launcher3.config.FeatureFlags.enableTaskbarPinning
 import com.android.launcher3.taskbar.TaskbarAutohideSuspendController.FLAG_AUTOHIDE_SUSPEND_EDU_OPEN
 import com.android.launcher3.taskbar.TaskbarControllers.LoggableTaskbarController
 import com.android.launcher3.util.DisplayController
+import com.android.launcher3.util.OnboardingPrefs.TASKBAR_CIRCLE_TO_SEARCH_EDU_SEEN
 import com.android.launcher3.util.OnboardingPrefs.TASKBAR_EDU_TOOLTIP_STEP
 import com.android.launcher3.views.BaseDragLayer
 import com.android.quickstep.util.LottieAnimationColorUtils
@@ -52,6 +61,10 @@
  * This value should match the maximum count for [TASKBAR_EDU_TOOLTIP_STEP].
  */
 const val TOOLTIP_STEP_NONE = 3
+/** The base URL for the Privacy Policy that will later be localized. */
+private const val PRIVACY_POLICY_BASE_URL = "https://policies.google.com/privacy/embedded?hl="
+/** The base URL for the Terms of Service that will later be localized. */
+private const val TOS_BASE_URL = "https://policies.google.com/terms?hl="
 
 /** Current step in the tooltip EDU flow. */
 @Retention(AnnotationRetention.SOURCE)
@@ -70,6 +83,15 @@
         get() = isTooltipEnabled && tooltipStep <= TOOLTIP_STEP_FEATURES
     private lateinit var controllers: TaskbarControllers
 
+    // Keep track of whether the user has seen the Circle to Search Edu
+    private var userHasSeenCircleToSearchEdu: Boolean
+        get() {
+            return TASKBAR_CIRCLE_TO_SEARCH_EDU_SEEN.get(activityContext)
+        }
+        private set(seen) {
+            LauncherPrefs.get(activityContext).put(TASKBAR_CIRCLE_TO_SEARCH_EDU_SEEN, seen)
+        }
+
     @TaskbarEduTooltipStep
     var tooltipStep: Int
         get() {
@@ -83,6 +105,8 @@
 
     fun init(controllers: TaskbarControllers) {
         this.controllers = controllers
+        // We want to show the Circle To Search Edu right after pinning, so we post it here
+        activityContext.dragLayer.post { maybeShowCircleToSearchEdu() }
     }
 
     /** Shows swipe EDU tooltip if it is the current [tooltipStep]. */
@@ -112,6 +136,7 @@
     fun maybeShowFeaturesEdu() {
         if (!isTooltipEnabled || tooltipStep > TOOLTIP_STEP_FEATURES) {
             maybeShowPinningEdu()
+            maybeShowCircleToSearchEdu()
             return
         }
 
@@ -207,6 +232,96 @@
         }
     }
 
+    /**
+     * Shows standalone Circle To Search EDU tooltip if this EDU has not been seen.
+     *
+     * We show this standalone edu for users to learn to how to trigger Circle To Search from the
+     * pinned taskbar
+     */
+    fun maybeShowCircleToSearchEdu() {
+        if (
+            !enableTaskbarPinning() ||
+                !DisplayController.isPinnedTaskbar(activityContext) ||
+                !isTooltipEnabled ||
+                userHasSeenCircleToSearchEdu
+        ) {
+            return
+        }
+        userHasSeenCircleToSearchEdu = true
+        inflateTooltip(R.layout.taskbar_edu_circle_to_search)
+        tooltip?.run {
+            requireViewById<LottieAnimationView>(R.id.circle_to_search_animation)
+                .supportLightTheme()
+            val eduSubtitle: TextView = requireViewById(R.id.circle_to_search_text)
+            showDisclosureText(eduSubtitle)
+            updateLayoutParams<BaseDragLayer.LayoutParams> {
+                if (DisplayController.isTransientTaskbar(activityContext)) {
+                    bottomMargin += activityContext.deviceProfile.taskbarHeight
+                }
+                // Unlike other tooltips, we want to align with the all apps button rather than
+                // center.
+                gravity = Gravity.BOTTOM
+                marginStart = 0
+                width =
+                    resources.getDimensionPixelSize(
+                        R.dimen.taskbar_edu_features_tooltip_width_with_one_feature
+                    )
+            }
+
+            // Calculate the amount the tooltip must be shifted by to align with the action key
+            val allAppsButtonView = controllers.taskbarViewController.allAppsButtonView
+            if (allAppsButtonView != null) {
+                val allAppsIconLocation = allAppsButtonView.x + allAppsButtonView.width / 2
+                x = allAppsIconLocation - layoutParams.width / 2
+            }
+
+            show()
+        }
+    }
+
+    /**
+     * Set up the provided TextView to display legal disclosures. The method takes locale into
+     * account to show the appropriate links to regional disclosures.
+     */
+    private fun TaskbarEduTooltip.showDisclosureText(
+        textView: TextView,
+        stringId: Int = R.string.taskbar_edu_circle_to_search_disclosure,
+    ) {
+        val locale = resources.configuration.locales[0]
+        val text =
+            SpannableString(
+                HtmlCompat.fromHtml(
+                    resources.getString(
+                        stringId,
+                        PRIVACY_POLICY_BASE_URL + locale.language,
+                        TOS_BASE_URL + locale.language,
+                    ),
+                    HtmlCompat.FROM_HTML_MODE_COMPACT,
+                )
+            )
+        // Directly process URLSpan clicks
+        text.getSpans(0, text.length, URLSpan::class.java).forEach { urlSpan ->
+            val url: URLSpan =
+                object : URLSpan(urlSpan.url) {
+                    override fun onClick(widget: View) {
+                        val uri = Uri.parse(urlSpan.url)
+                        val context = widget.context
+                        val intent =
+                            Intent(Intent.ACTION_VIEW, uri).setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+                        context.startActivity(intent)
+                    }
+                }
+
+            val spanStart = text.getSpanStart(urlSpan)
+            val spanEnd = text.getSpanEnd(urlSpan)
+            val spanFlags = text.getSpanFlags(urlSpan)
+            text.removeSpan(urlSpan)
+            text.setSpan(url, spanStart, spanEnd, spanFlags)
+        }
+        textView.text = text
+        textView.movementMethod = LinkMovementMethod.getInstance()
+    }
+
     /** Closes the current [tooltip]. */
     fun hide() = tooltip?.close(true)
 
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarInsetsController.kt b/quickstep/src/com/android/launcher3/taskbar/TaskbarInsetsController.kt
index 7cad57b..6163dad 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarInsetsController.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarInsetsController.kt
@@ -163,6 +163,10 @@
                 setProviderInsets(provider, layoutParams.gravity, rotation)
             }
         }
+        // Also set the parent providers (i.e. not in paramsForRotation).
+        for (provider in windowLayoutParams.providedInsets) {
+            setProviderInsets(provider, windowLayoutParams.gravity, context.display.rotation)
+        }
         context.notifyUpdateLayoutParams()
     }
 
@@ -371,7 +375,7 @@
         ) {
             // Taskbar has some touchable elements, take over the full taskbar area
             if (
-                controllers.uiController.isInOverview &&
+                controllers.uiController.isInOverviewUi &&
                     DisplayController.isTransientTaskbar(context)
             ) {
                 val region =
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java
index 8d48154..17dcace 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java
@@ -148,6 +148,7 @@
     private Integer mPrevState;
     private int mState;
     private LauncherState mLauncherState = LauncherState.NORMAL;
+    private boolean mSkipNextRecentsAnimEnd;
 
     // Time when FLAG_TASKBAR_HIDDEN was last cleared, SystemClock.elapsedRealtime (milliseconds).
     private long mLastUnlockTimeMs = 0;
@@ -292,12 +293,12 @@
 
         if (mTaskBarRecentsAnimationListener != null) {
             mTaskBarRecentsAnimationListener.endGestureStateOverride(
-                    !mLauncher.isInState(LauncherState.OVERVIEW));
+                    !mLauncher.isInState(LauncherState.OVERVIEW), false /*canceled*/);
         }
         mTaskBarRecentsAnimationListener = new TaskBarRecentsAnimationListener(callbacks);
         callbacks.addListener(mTaskBarRecentsAnimationListener);
         ((RecentsView) mLauncher.getOverviewPanel()).setTaskLaunchListener(() ->
-                mTaskBarRecentsAnimationListener.endGestureStateOverride(true));
+                mTaskBarRecentsAnimationListener.endGestureStateOverride(true, false /*canceled*/));
 
         ((RecentsView) mLauncher.getOverviewPanel()).setTaskLaunchCancelledRunnable(() -> {
             updateStateForUserFinishedToApp(false /* finishedToApp */);
@@ -318,6 +319,11 @@
         mShouldDelayLauncherStateAnim = shouldDelayLauncherStateAnim;
     }
 
+    /** Will make the next onRecentsAnimationFinished() a no-op. */
+    public void setSkipNextRecentsAnimEnd() {
+        mSkipNextRecentsAnimEnd = true;
+    }
+
     /** SysUI flags updated, see QuickStepContract.SYSUI_STATE_* values. */
     public void updateStateForSysuiFlags(int systemUiStateFlags) {
         updateStateForSysuiFlags(systemUiStateFlags, /* applyState */ true);
@@ -656,11 +662,12 @@
      * Returns if the current Launcher state has hotseat on top of other elemnets.
      */
     public boolean isInHotseatOnTopStates() {
-        return mLauncherState != LauncherState.ALL_APPS;
+        return mLauncherState != LauncherState.ALL_APPS
+                && !mLauncher.getWorkspace().isOverlayShown();
     }
 
-    boolean isInOverview() {
-        return mLauncherState == LauncherState.OVERVIEW;
+    boolean isInOverviewUi() {
+        return mLauncherState.overviewUi;
     }
 
     private void playStateTransitionAnim(AnimatorSet animatorSet, long duration,
@@ -770,19 +777,33 @@
         @Override
         public void onRecentsAnimationCanceled(HashMap<Integer, ThumbnailData> thumbnailDatas) {
             boolean isInOverview = mLauncher.isInState(LauncherState.OVERVIEW);
-            endGestureStateOverride(!isInOverview);
+            endGestureStateOverride(!isInOverview, true /*canceled*/);
         }
 
         @Override
         public void onRecentsAnimationFinished(RecentsAnimationController controller) {
-            endGestureStateOverride(!controller.getFinishTargetIsLauncher());
+            endGestureStateOverride(!controller.getFinishTargetIsLauncher(), false /*canceled*/);
         }
 
-        private void endGestureStateOverride(boolean finishedToApp) {
+        /**
+         * Handles whatever cleanup is needed after the recents animation is completed.
+         * NOTE: If {@link #mSkipNextRecentsAnimEnd} is set and we're coming from a non-cancelled
+         * path, this will not call {@link #updateStateForUserFinishedToApp(boolean)}
+         *
+         * @param finishedToApp {@code true} if the recents animation finished to showing an app and
+         *                      not workspace or overview
+         * @param canceled {@code true} if the recents animation was canceled instead of finishing
+         *                 to completion
+         */
+        private void endGestureStateOverride(boolean finishedToApp, boolean canceled) {
             mCallbacks.removeListener(this);
             mTaskBarRecentsAnimationListener = null;
             ((RecentsView) mLauncher.getOverviewPanel()).setTaskLaunchListener(null);
 
+            if (mSkipNextRecentsAnimEnd && !canceled) {
+                mSkipNextRecentsAnimEnd = false;
+                return;
+            }
             updateStateForUserFinishedToApp(finishedToApp);
         }
     }
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java
index e4f9ba5..e47640b 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java
@@ -58,6 +58,7 @@
 import androidx.annotation.VisibleForTesting;
 
 import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.Launcher;
 import com.android.launcher3.LauncherAppState;
 import com.android.launcher3.anim.AnimatorPlaybackController;
 import com.android.launcher3.statemanager.StatefulActivity;
@@ -339,12 +340,12 @@
 
     /**
      * Toggles All Apps for Taskbar or Launcher depending on the current state.
-     *
-     * @param homeAllAppsIntent Intent used if Taskbar is not enabled or Launcher is resumed.
      */
-    public void toggleAllApps(Intent homeAllAppsIntent) {
+    public void toggleAllApps() {
         if (mTaskbarActivityContext == null || mTaskbarActivityContext.canToggleHomeAllApps()) {
-            mContext.startActivity(homeAllAppsIntent);
+            // Home All Apps should be toggled from this class, because the controllers are not
+            // initialized when Taskbar is disabled (i.e. TaskbarActivityContext is null).
+            if (mActivity instanceof Launcher l) l.toggleAllAppsSearch();
         } else {
             mTaskbarActivityContext.toggleAllAppsSearch();
         }
@@ -443,7 +444,8 @@
                 LauncherAppState.getIDP(mContext).getDeviceProfile(mContext) : null;
 
             // All Apps action is unrelated to navbar unification, so we only need to check DP.
-            mAllAppsActionManager.setTaskbarPresent(dp != null && dp.isTaskbarPresent);
+            final boolean isLargeScreenTaskbar = dp != null && dp.isTaskbarPresent;
+            mAllAppsActionManager.setTaskbarPresent(isLargeScreenTaskbar);
 
             destroyExistingTaskbar();
 
@@ -467,6 +469,7 @@
             }
             mSharedState.startTaskbarVariantIsTransient =
                     DisplayController.isTransientTaskbar(mTaskbarActivityContext);
+            mSharedState.allAppsVisible = mSharedState.allAppsVisible && isLargeScreenTaskbar;
             mTaskbarActivityContext.init(mSharedState);
 
             if (mActivity != null) {
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarNavButtonController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarNavButtonController.java
index e293ad4..03f55ca 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarNavButtonController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarNavButtonController.java
@@ -27,7 +27,6 @@
 import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASKBAR_IME_SWITCHER_BUTTON_TAP;
 import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASKBAR_OVERVIEW_BUTTON_LONGPRESS;
 import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASKBAR_OVERVIEW_BUTTON_TAP;
-import static com.android.window.flags.Flags.enableDesktopWindowingMode;
 import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_HOME_KEY;
 import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_RECENTS;
 import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_SCREEN_PINNING;
@@ -281,12 +280,10 @@
     private void navigateHome() {
         TaskUtils.closeSystemWindowsAsync(CLOSE_SYSTEM_WINDOWS_REASON_HOME_KEY);
 
-        if (enableDesktopWindowingMode()) {
-            DesktopVisibilityController desktopVisibilityController =
-                    LauncherActivityInterface.INSTANCE.getDesktopVisibilityController();
-            if (desktopVisibilityController != null) {
-                desktopVisibilityController.onHomeActionTriggered();
-            }
+        DesktopVisibilityController desktopVisibilityController =
+                LauncherActivityInterface.INSTANCE.getDesktopVisibilityController();
+        if (desktopVisibilityController != null) {
+            desktopVisibilityController.onHomeActionTriggered();
         }
 
         mService.getOverviewCommandHelper().addCommand(OverviewCommandHelper.TYPE_HOME);
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarPopupController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarPopupController.java
index 4462f20..2730be1 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarPopupController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarPopupController.java
@@ -118,7 +118,7 @@
                 FolderInfo fi = (FolderInfo) info;
                 if (fi.anyMatch(matcher)) {
                     FolderDotInfo folderDotInfo = new FolderDotInfo();
-                    for (WorkspaceItemInfo si : fi.getContents()) {
+                    for (ItemInfo si : fi.getContents()) {
                         folderDotInfo.addDotInfo(mPopupDataProvider.getDotInfoForItem(si));
                     }
                     ((FolderIcon) v).setDotInfo(folderDotInfo);
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
index 3d58464..15be8e7 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
@@ -598,7 +598,8 @@
                             ? stashTranslation : 0)
                     .setDuration(duration));
             mAnimator.play(mTaskbarImeBgAlpha.animateToValue(
-                    hasAnyFlag(FLAG_STASHED_IN_APP_IME) ? 0 : 1).setDuration(duration));
+                    (hasAnyFlag(FLAG_STASHED_IN_APP_IME) && isStashed) ? 0 : 1).setDuration(
+                    duration));
             mAnimator.addListener(AnimatorListeners.forEndCallback(() -> {
                 mAnimator = null;
                 mIsStashed = isStashed;
@@ -890,17 +891,11 @@
     }
 
     /**
-     * Should be called when a system gesture starts and settles, so we can defer updating
-     * FLAG_STASHED_IN_APP_IME until after the gesture transition completes.
+     * Should be called when a system gesture starts and settles, so we can remove
+     * FLAG_STASHED_IN_APP_IME while the gesture is in progress.
      */
     public void setSystemGestureInProgress(boolean inProgress) {
         mIsSystemGestureInProgress = inProgress;
-        if (mIsSystemGestureInProgress) {
-            return;
-        }
-
-        // Only update the following flags when system gesture is not in progress.
-        updateStateForFlag(FLAG_STASHED_IN_TASKBAR_ALL_APPS, false);
         setStashedImeState();
     }
 
@@ -952,12 +947,9 @@
                 && !hasAnyFlag(systemUiStateFlags, SYSUI_STATE_STATUS_BAR_KEYGUARD_GOING_AWAY);
         updateStateForFlag(FLAG_STASHED_DEVICE_LOCKED, isLocked);
 
-        // Only update FLAG_STASHED_IN_APP_IME when system gesture is not in progress.
         mIsImeShowing = hasAnyFlag(systemUiStateFlags, SYSUI_STATE_IME_SHOWING);
         mIsImeSwitcherShowing = hasAnyFlag(systemUiStateFlags, SYSUI_STATE_IME_SWITCHER_SHOWING);
-
-        if (!mIsSystemGestureInProgress) {
-            updateStateForFlag(FLAG_STASHED_IN_APP_IME, shouldStashForIme());
+        if (updateStateForFlag(FLAG_STASHED_IN_APP_IME, shouldStashForIme())) {
             animDuration = TASKBAR_STASH_DURATION_FOR_IME;
             startDelay = getTaskbarStashStartDelayForIme();
         }
@@ -970,7 +962,8 @@
      *
      * <p>Do not stash if in small screen, with 3 button nav, and in landscape (or seascape).
      * <p>Do not stash if taskbar is transient.
-     * <p>Do not stash if hardware keyboard is attached and taskbar is pinned and IME is docked
+     * <p>Do not stash if hardware keyboard is attached and taskbar is pinned and IME is docked.
+     * <p>Do not stash if a system gesture is started.
      */
     private boolean shouldStashForIme() {
         if (DisplayController.isTransientTaskbar(mActivity)) {
@@ -992,7 +985,12 @@
         DesktopVisibilityController visibilityController =
                 LauncherActivityInterface.INSTANCE.getDesktopVisibilityController();
         if (visibilityController != null && mActivity.isHardwareKeyboard()
-                && mActivity.isThreeButtonNav() && visibilityController.areFreeformTasksVisible()) {
+                && mActivity.isThreeButtonNav() && visibilityController.areDesktopTasksVisible()) {
+            return false;
+        }
+
+        // Do not stash if a gesture started.
+        if (mIsSystemGestureInProgress) {
             return false;
         }
 
@@ -1007,13 +1005,16 @@
      * @param flag    The flag to update.
      * @param enabled Whether to enable the flag: True will cause the task bar to be stashed /
      *                unstashed.
+     * @return Whether the flag state changed.
      */
-    public void updateStateForFlag(int flag, boolean enabled) {
+    public boolean updateStateForFlag(int flag, boolean enabled) {
+        int oldState = mState;
         if (enabled) {
             mState |= flag;
         } else {
             mState &= ~flag;
         }
+        return mState != oldState;
     }
 
     /**
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java
index 109400e..2e78489 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java
@@ -193,7 +193,7 @@
     }
 
     /** Returns {@code true} if Taskbar is currently within overview. */
-    protected boolean isInOverview() {
+    protected boolean isInOverviewUi() {
         return false;
     }
 
@@ -399,4 +399,12 @@
         mControllers.taskbarStashController.updateStateForFlag(FLAG_IN_APP, !isVisible);
         mControllers.taskbarStashController.applyState();
     }
+
+    /**
+     * Request for UI controller to ignore animations for the next callback for the end of recents
+     * animation
+     */
+    public void setSkipNextRecentsAnimEnd() {
+        // Overridden
+    }
 }
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java
index dc2684e..effef3c 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java
@@ -32,6 +32,7 @@
 import android.graphics.Rect;
 import android.os.Bundle;
 import android.util.AttributeSet;
+import android.view.DisplayCutout;
 import android.view.InputDevice;
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
@@ -134,7 +135,7 @@
 
         int actualMargin = resources.getDimensionPixelSize(R.dimen.taskbar_icon_spacing);
         int actualIconSize = mActivityContext.getDeviceProfile().taskbarIconSize;
-        if (enableTaskbarPinning()) {
+        if (enableTaskbarPinning() && !mActivityContext.isThreeButtonNav()) {
             DeviceProfile deviceProfile = mActivityContext.getTransientTaskbarDeviceProfile();
             actualIconSize = deviceProfile.taskbarIconSize;
         }
@@ -472,6 +473,29 @@
             iconEnd = centerAlignIconEnd + offset;
         }
 
+        // Currently, we support only one device with display cutout and we only are concern about
+        // it when the bottom rect is present and non empty
+        DisplayCutout displayCutout = getDisplay().getCutout();
+        if (displayCutout != null && !displayCutout.getBoundingRectBottom().isEmpty()) {
+            Rect cutoutBottomRect = displayCutout.getBoundingRectBottom();
+            // when cutout present at the bottom of screen align taskbar icons to cutout offset
+            // if taskbar icon overlaps with cutout
+            int taskbarIconLeftBound = iconEnd - spaceNeeded;
+            int taskbarIconRightBound = iconEnd;
+
+            boolean doesTaskbarIconsOverlapWithCutout =
+                    taskbarIconLeftBound <= cutoutBottomRect.centerX()
+                            && cutoutBottomRect.centerX() <= taskbarIconRightBound;
+
+            if (doesTaskbarIconsOverlapWithCutout) {
+                if (!layoutRtl) {
+                    iconEnd = spaceNeeded + cutoutBottomRect.width();
+                } else {
+                    iconEnd = right - cutoutBottomRect.width();
+                }
+            }
+        }
+
         sTmpRect.set(mIconLayoutBounds);
 
         // Layout the children
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java
index 1f7f0a7..5d0eac3 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java
@@ -337,11 +337,6 @@
     private void updateTaskbarIconTranslationXForPinning() {
         View[] iconViews = mTaskbarView.getIconViews();
         float scale = mTaskbarIconTranslationXForPinning.value;
-        float taskbarCenterX =
-                mTaskbarView.getLeft() + (mTaskbarView.getRight() - mTaskbarView.getLeft()) / 2.0f;
-
-        float finalMarginScale = mapRange(scale, 0f, mTransientIconSize - mPersistentIconSize);
-
         float transientTaskbarAllAppsOffset = mActivity.getResources().getDimension(
                 mTaskbarView.getAllAppsButtonTranslationXOffset(true));
         float persistentTaskbarAllAppsOffset = mActivity.getResources().getDimension(
@@ -354,6 +349,17 @@
             allAppIconTranslateRange *= -1;
         }
 
+        if (mActivity.isThreeButtonNav()) {
+            ((IconButtonView) mTaskbarView.getAllAppsButtonView())
+                    .setTranslationXForTaskbarAllAppsIcon(allAppIconTranslateRange);
+            return;
+        }
+
+        float taskbarCenterX =
+                mTaskbarView.getLeft() + (mTaskbarView.getRight() - mTaskbarView.getLeft()) / 2.0f;
+
+        float finalMarginScale = mapRange(scale, 0f, mTransientIconSize - mPersistentIconSize);
+
         float halfIconCount = iconViews.length / 2.0f;
         for (int iconIndex = 0; iconIndex < iconViews.length; iconIndex++) {
             View iconView = iconViews[iconIndex];
diff --git a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsSlideInView.java b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsSlideInView.java
index 3b04602..6ceec3e 100644
--- a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsSlideInView.java
+++ b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsSlideInView.java
@@ -96,7 +96,7 @@
         mAllAppsCallbacks.onAllAppsTransitionStart(true);
         if (!animate) {
             mAllAppsCallbacks.onAllAppsTransitionEnd(true);
-            mTranslationShift = TRANSLATION_SHIFT_OPENED;
+            setTranslationShift(TRANSLATION_SHIFT_OPENED);
             return;
         }
 
@@ -207,10 +207,10 @@
     }
 
     @Override
-    protected void onScaleProgressChanged() {
-        super.onScaleProgressChanged();
-        mAppsView.setClipChildren(!mIsBackProgressing);
-        mAppsView.getAppsRecyclerViewContainer().setClipChildren(!mIsBackProgressing);
+    protected void onUserSwipeToDismissProgressChanged() {
+        super.onUserSwipeToDismissProgressChanged();
+        mAppsView.setClipChildren(!mIsDismissInProgress);
+        mAppsView.getAppsRecyclerViewContainer().setClipChildren(!mIsDismissInProgress);
     }
 
     @Override
@@ -264,7 +264,7 @@
         if (mAllAppsCallbacks.handleSearchBackInvoked()) {
             // We need to scale back taskbar all apps if we navigate back within search inside all
             // apps
-            animateSlideInViewToNoScale();
+            animateSwipeToDismissProgressToStart();
         } else {
             super.onBackInvoked();
         }
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarController.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarController.java
index 1f3c483..a2c1b07 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarController.java
@@ -151,6 +151,9 @@
     private BubbleStashController mBubbleStashController;
     private BubbleStashedHandleViewController mBubbleStashedHandleViewController;
 
+    // Keep track of bubble bar bounds sent to shell to avoid sending duplicate updates
+    private final Rect mLastSentBubbleBarBounds = new Rect();
+
     /**
      * Similar to {@link BubbleBarUpdate} but rather than {@link BubbleInfo}s it uses
      * {@link BubbleBarBubble}s so that it can be used to update the views.
@@ -220,7 +223,8 @@
             mBubbleStashedHandleViewController.setHiddenForBubbles(
                     !sBubbleBarEnabled || mBubbles.isEmpty());
             mBubbleBarViewController.setUpdateSelectedBubbleAfterCollapse(
-                    key -> setSelectedBubble(mBubbles.get(key)));
+                    key -> setSelectedBubbleInternal(mBubbles.get(key)));
+            mBubbleBarViewController.setBoundsChangeListener(this::onBubbleBarBoundsChanged);
         });
     }
 
@@ -237,7 +241,8 @@
                 // we're on the main executor now, so check that the overflow hasn't been created
                 // again to avoid races.
                 if (mOverflowBubble == null) {
-                    mBubbleBarViewController.addBubble(overflow);
+                    mBubbleBarViewController.addBubble(
+                            overflow, /* isExpanding= */ false, /* suppressAnimation= */ true);
                     mOverflowBubble = overflow;
                 }
             });
@@ -306,6 +311,10 @@
     private void applyViewChanges(BubbleBarViewUpdate update) {
         final boolean isCollapsed = (update.expandedChanged && !update.expanded)
                 || (!update.expandedChanged && !mBubbleBarViewController.isExpanded());
+        final boolean isExpanding = update.expandedChanged && update.expanded;
+        // don't animate bubbles if this is the initial state because we may be unfolding or
+        // enabling gesture nav
+        final boolean suppressAnimation = update.initialState;
         BubbleBarItem previouslySelectedBubble = mSelectedBubble;
         BubbleBarBubble bubbleToSelect = null;
         if (!update.removedBubbles.isEmpty()) {
@@ -322,7 +331,7 @@
         }
         if (update.addedBubble != null) {
             mBubbles.put(update.addedBubble.getKey(), update.addedBubble);
-            mBubbleBarViewController.addBubble(update.addedBubble);
+            mBubbleBarViewController.addBubble(update.addedBubble, isExpanding, suppressAnimation);
             if (isCollapsed) {
                 // If we're collapsed, the most recently added bubble will be selected.
                 bubbleToSelect = update.addedBubble;
@@ -335,7 +344,7 @@
                 BubbleBarBubble bubble = update.currentBubbles.get(i);
                 if (bubble != null) {
                     mBubbles.put(bubble.getKey(), bubble);
-                    mBubbleBarViewController.addBubble(bubble);
+                    mBubbleBarViewController.addBubble(bubble, isExpanding, suppressAnimation);
                     if (isCollapsed) {
                         // If we're collapsed, the most recently added bubble will be selected.
                         bubbleToSelect = bubble;
@@ -390,7 +399,7 @@
             }
         }
         if (bubbleToSelect != null) {
-            setSelectedBubble(bubbleToSelect);
+            setSelectedBubbleInternal(bubbleToSelect);
             if (previouslySelectedBubble == null) {
                 mBubbleStashController.animateToInitialState(update.expanded);
             }
@@ -409,8 +418,7 @@
             if (update.bubbleBarLocation != mBubbleBarViewController.getBubbleBarLocation()) {
                 // Animate when receiving updates. Skip it if we received the initial state.
                 boolean animate = !update.initialState;
-                mBubbleBarViewController.setBubbleBarLocation(update.bubbleBarLocation, animate);
-                mBubbleStashController.setBubbleBarLocation(update.bubbleBarLocation);
+                updateBubbleBarLocationInternal(update.bubbleBarLocation, animate);
             }
         }
     }
@@ -427,7 +435,9 @@
                         info.getFlags() | Notification.BubbleMetadata.FLAG_SUPPRESS_NOTIFICATION);
                 mSelectedBubble.getView().updateDotVisibility(true /* animate */);
             }
-            mSystemUiProxy.showBubble(getSelectedBubbleKey(), getExpandedBubbleBarDisplayBounds());
+            Rect bounds = getExpandedBubbleBarDisplayBounds();
+            mLastSentBubbleBarBounds.set(bounds);
+            mSystemUiProxy.showBubble(getSelectedBubbleKey(), bounds);
         } else {
             Log.w(TAG, "Trying to show the selected bubble but it's null");
         }
@@ -436,7 +446,7 @@
     /** Updates the currently selected bubble for launcher views and tells WMShell to show it. */
     public void showAndSelectBubble(BubbleBarItem b) {
         if (DEBUG) Log.w(TAG, "showingSelectedBubble: " + b.getKey());
-        setSelectedBubble(b);
+        setSelectedBubbleInternal(b);
         showSelectedBubble();
     }
 
@@ -445,7 +455,7 @@
      * WMShell that the selection has changed, that should go through either
      * {@link #showSelectedBubble()} or {@link #showAndSelectBubble(BubbleBarItem)}.
      */
-    private void setSelectedBubble(BubbleBarItem b) {
+    private void setSelectedBubbleInternal(BubbleBarItem b) {
         if (!Objects.equals(b, mSelectedBubble)) {
             if (DEBUG) Log.w(TAG, "selectingBubble: " + b.getKey());
             mSelectedBubble = b;
@@ -464,6 +474,21 @@
         return null;
     }
 
+    /**
+     * Set a new bubble bar location.
+     * <p>
+     * Updates the value locally in Launcher and in WMShell.
+     */
+    public void updateBubbleBarLocation(BubbleBarLocation location) {
+        updateBubbleBarLocationInternal(location, false /* animate */);
+        mSystemUiProxy.setBubbleBarLocation(location);
+    }
+
+    private void updateBubbleBarLocationInternal(BubbleBarLocation location, boolean animate) {
+        mBubbleBarViewController.setBubbleBarLocation(location, animate);
+        mBubbleStashController.setBubbleBarLocation(location);
+    }
+
     //
     // Loading data for the bubbles
     //
@@ -595,27 +620,39 @@
         return mIconFactory.createBadgedIconBitmap(drawable).icon;
     }
 
+    private void onBubbleBarBoundsChanged(Rect newBounds) {
+        Rect displayBounds = convertToDisplayBounds(newBounds);
+        // Only send bounds over if they changed
+        if (!displayBounds.equals(mLastSentBubbleBarBounds)) {
+            mLastSentBubbleBarBounds.set(displayBounds);
+            mSystemUiProxy.setBubbleBarBounds(displayBounds);
+        }
+    }
+
     /**
      * Get bounds of the bubble bar as if it would be expanded.
      * Calculates the bounds instead of retrieving current view location as the view may be
      * animating.
      */
     private Rect getExpandedBubbleBarDisplayBounds() {
+        return convertToDisplayBounds(mBarView.getBubbleBarBounds());
+    }
+
+    private Rect convertToDisplayBounds(Rect currentBarBounds) {
         Point displaySize = DisplayController.INSTANCE.get(mContext).getInfo().currentSize;
-        Rect currentBarBounds = mBarView.getBubbleBarBounds();
-        Rect location = new Rect();
+        Rect displayBounds = new Rect();
         // currentBarBounds is only useful for distance from left or right edge.
         // It contains the current bounds, calculate the expanded bounds.
         if (mBarView.getBubbleBarLocation().isOnLeft(mBarView.isLayoutRtl())) {
-            location.left = currentBarBounds.left;
-            location.right = (int) (currentBarBounds.left + mBarView.expandedWidth());
+            displayBounds.left = currentBarBounds.left;
+            displayBounds.right = (int) (currentBarBounds.left + mBarView.expandedWidth());
         } else {
-            location.left = (int) (currentBarBounds.right - mBarView.expandedWidth());
-            location.right = currentBarBounds.right;
+            displayBounds.left = (int) (currentBarBounds.right - mBarView.expandedWidth());
+            displayBounds.right = currentBarBounds.right;
         }
         final int translation = (int) abs(mBubbleStashController.getBubbleBarTranslationY());
-        location.top = displaySize.y - currentBarBounds.height() - translation;
-        location.bottom = displaySize.y - translation;
-        return location;
+        displayBounds.top = displaySize.y - currentBarBounds.height() - translation;
+        displayBounds.bottom = displaySize.y - translation;
+        return displayBounds;
     }
 }
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarView.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarView.java
index 4ca7c89..711ba62 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarView.java
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarView.java
@@ -24,7 +24,9 @@
 import android.animation.ObjectAnimator;
 import android.animation.ValueAnimator;
 import android.annotation.Nullable;
+import android.annotation.SuppressLint;
 import android.content.Context;
+import android.graphics.PointF;
 import android.graphics.Rect;
 import android.util.AttributeSet;
 import android.util.LayoutDirection;
@@ -94,6 +96,8 @@
 
     private final BubbleBarBackground mBubbleBarBackground;
 
+    private boolean mIsAnimatingNewBubble = false;
+
     /**
      * The current bounds of all the bubble bar. Note that these bounds may not account for
      * translation. The bounds should be retrieved using {@link #getBubbleBarBounds()} which
@@ -108,6 +112,7 @@
     private final float mIconSize;
     // The elevation of the bubbles within the bar
     private final float mBubbleElevation;
+    private final float mDragElevation;
     private final int mPointerSize;
 
     // Whether the bar is expanded (i.e. the bubble activity is being displayed).
@@ -138,11 +143,15 @@
     @Nullable
     private Consumer<String> mUpdateSelectedBubbleAfterCollapse;
 
+    private boolean mDragging;
+
     @Nullable
     private BubbleView mDraggedBubbleView;
 
     private int mPreviousLayoutDirection = LayoutDirection.UNDEFINED;
 
+    private boolean mLocationChangePending;
+
     public BubbleBarView(Context context) {
         this(context, null);
     }
@@ -163,6 +172,7 @@
         mIconSpacing = getResources().getDimensionPixelSize(R.dimen.bubblebar_icon_spacing);
         mIconSize = getResources().getDimensionPixelSize(R.dimen.bubblebar_icon_size);
         mBubbleElevation = getResources().getDimensionPixelSize(R.dimen.bubblebar_icon_elevation);
+        mDragElevation = getResources().getDimensionPixelSize(R.dimen.bubblebar_drag_elevation);
         mPointerSize = getResources().getDimensionPixelSize(R.dimen.bubblebar_pointer_size);
 
         setClipToPadding(false);
@@ -237,12 +247,13 @@
         }
     }
 
+    @SuppressLint("RtlHardcoded")
     private void onBubbleBarLocationChanged() {
+        mLocationChangePending = false;
         final boolean onLeft = mBubbleBarLocation.isOnLeft(isLayoutRtl());
         mBubbleBarBackground.setAnchorLeft(onLeft);
         mRelativePivotX = onLeft ? 0f : 1f;
-        ViewGroup.LayoutParams layoutParams = getLayoutParams();
-        if (layoutParams instanceof LayoutParams lp) {
+        if (getLayoutParams() instanceof LayoutParams lp) {
             lp.gravity = Gravity.BOTTOM | (onLeft ? Gravity.LEFT : Gravity.RIGHT);
             setLayoutParams(lp);
         }
@@ -267,11 +278,82 @@
         }
     }
 
+    /**
+     * Set whether this view is being currently being dragged
+     */
+    public void setIsDragging(boolean dragging) {
+        if (mDragging == dragging) {
+            return;
+        }
+        mDragging = dragging;
+        setElevation(dragging ? mDragElevation : mBubbleElevation);
+        if (!dragging && mLocationChangePending) {
+            // During drag finish animation we may update the translation x value to shift the
+            // bubble to the new drop target. Clear the translation here.
+            setTranslationX(0f);
+            onBubbleBarLocationChanged();
+        }
+    }
+
+    /**
+     * Adjust resting position for the bubble bar while it is being dragged.
+     * <p>
+     * Bubble bar is laid out on left or right side of the screen. When it is being dragged to
+     * the opposite side, the resting position should be on that side. Calculate any additional
+     * translation that may be required to move the bubble bar to the new side.
+     *
+     * @param restingPosition relative resting position of the bubble bar from the laid out position
+     */
+    @SuppressLint("RtlHardcoded")
+    void adjustRelativeRestingPosition(PointF restingPosition) {
+        final boolean locationOnLeft = mBubbleBarLocation.isOnLeft(isLayoutRtl());
+        // Bubble bar is placed left or right with gravity. Check where it is currently.
+        final int absoluteGravity = Gravity.getAbsoluteGravity(
+                ((LayoutParams) getLayoutParams()).gravity, getLayoutDirection());
+        final boolean gravityOnLeft =
+                (absoluteGravity & Gravity.HORIZONTAL_GRAVITY_MASK) == Gravity.LEFT;
+
+        // Bubble bar is pinned to the same side per gravity and the desired location.
+        // Resting translation does not need to be adjusted.
+        if (locationOnLeft == gravityOnLeft) {
+            return;
+        }
+
+        // Bubble bar is laid out on left or right side of the screen. And the desired new
+        // location is on the other side. Calculate x translation value required to shift the
+        // bubble bar from one side to the other.
+        float x = getDistanceFromOtherSide();
+        if (locationOnLeft) {
+            // New location is on the left, shift left
+            // before -> |......ooo.| after -> |.ooo......|
+            restingPosition.x = -x;
+        } else {
+            // New location is on the right, shift right
+            // before -> |.ooo......| after -> |......ooo.|
+            restingPosition.x = x;
+        }
+    }
+
+    private float getDistanceFromOtherSide() {
+        // Calculate the shift needed to position the bubble bar on the other side
+        int displayWidth = getResources().getDisplayMetrics().widthPixels;
+        int margin = 0;
+        if (getLayoutParams() instanceof MarginLayoutParams lp) {
+            margin += lp.leftMargin;
+            margin += lp.rightMargin;
+        }
+        return (float) (displayWidth - getWidth() - margin);
+    }
+
     private void setBubbleBarLocationInternal(BubbleBarLocation bubbleBarLocation) {
         if (bubbleBarLocation != mBubbleBarLocation) {
             mBubbleBarLocation = bubbleBarLocation;
-            onBubbleBarLocationChanged();
-            invalidate();
+            if (mDragging) {
+                mLocationChangePending = true;
+            } else {
+                onBubbleBarLocationChanged();
+                invalidate();
+            }
         }
     }
 
@@ -377,6 +459,7 @@
 
     /** Prepares for animating a bubble while being stashed. */
     public void prepareForAnimatingBubbleWhileStashed(String bubbleKey) {
+        mIsAnimatingNewBubble = true;
         // we're about to animate the new bubble in. the new bubble has already been added to this
         // view, but we're currently stashed, so before we can start the animation we need make
         // everything else in the bubble bar invisible, except for the bubble that's being animated.
@@ -397,6 +480,9 @@
 
     /** Resets the state after the bubble animation completed. */
     public void onAnimatingBubbleCompleted() {
+        mIsAnimatingNewBubble = false;
+        // setting the background triggers relayout so no need to explicitly invalidate after the
+        // animation
         setBackground(mBubbleBarBackground);
         for (int i = 0; i < getChildCount(); i++) {
             final BubbleView view = (BubbleView) getChildAt(i);
@@ -441,6 +527,12 @@
      * on the expanded state.
      */
     private void updateChildrenRenderNodeProperties() {
+        if (mIsAnimatingNewBubble) {
+            // don't update bubbles if a new bubble animation is playing.
+            // the bubble bar will redraw itself via onLayout after the animation.
+            return;
+        }
+
         final float widthState = (float) mWidthAnimator.getAnimatedValue();
         final float currentWidth = getWidth();
         final float expandedWidth = expandedWidth();
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java
index 96d91ea..aa1b4df 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java
@@ -27,6 +27,7 @@
 import android.widget.FrameLayout;
 
 import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
 
 import com.android.launcher3.R;
 import com.android.launcher3.anim.AnimatedFloat;
@@ -84,6 +85,11 @@
 
     private BubbleBarViewAnimator mBubbleBarViewAnimator;
 
+    @Nullable
+    private BubbleBarBoundsChangeListener mBoundsChangeListener;
+
+    private final Rect mPreviousBubbleBarBounds = new Rect();
+
     public BubbleBarViewController(TaskbarActivityContext activity, BubbleBarView barView) {
         mActivity = activity;
         mBarView = barView;
@@ -113,9 +119,17 @@
         mBubbleBarClickListener = v -> onBubbleBarClicked();
         mBubbleDragController.setupBubbleBarView(mBarView);
         mBarView.setOnClickListener(mBubbleBarClickListener);
-        mBarView.addOnLayoutChangeListener((view, i, i1, i2, i3, i4, i5, i6, i7) ->
-                mTaskbarInsetsController.onTaskbarOrBubblebarWindowHeightOrInsetsChanged()
-        );
+        mBarView.addOnLayoutChangeListener(
+                (v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) -> {
+                    mTaskbarInsetsController.onTaskbarOrBubblebarWindowHeightOrInsetsChanged();
+                    Rect bubbleBarBounds = mBarView.getBubbleBarBounds();
+                    if (!bubbleBarBounds.equals(mPreviousBubbleBarBounds)) {
+                        mPreviousBubbleBarBounds.set(bubbleBarBounds);
+                        if (mBoundsChangeListener != null) {
+                            mBoundsChangeListener.onBoundsChanged(bubbleBarBounds);
+                        }
+                    }
+                });
 
         mBubbleBarViewAnimator = new BubbleBarViewAnimator(mBarView, mBubbleStashController);
     }
@@ -315,16 +329,21 @@
     /**
      * Adds the provided bubble to the bubble bar.
      */
-    public void addBubble(BubbleBarItem b) {
+    public void addBubble(BubbleBarItem b, boolean isExpanding, boolean suppressAnimation) {
         if (b != null) {
             mBarView.addView(b.getView(), 0,
                     new FrameLayout.LayoutParams(mIconSize, mIconSize, Gravity.LEFT));
             b.getView().setOnClickListener(mBubbleClickListener);
             mBubbleDragController.setupBubbleView(b.getView());
 
+            if (suppressAnimation) {
+                return;
+            }
+
             boolean isStashedOrGone =
                     mBubbleStashController.isStashed() || mBarView.getVisibility() != VISIBLE;
-            if (b instanceof BubbleBarBubble && isStashedOrGone) {
+            // don't animate the new bubble if we're auto expanding from stashed
+            if (b instanceof BubbleBarBubble && isStashedOrGone && !isExpanding) {
                 mBubbleBarViewAnimator.animateBubbleInForStashed((BubbleBarBubble) b);
             }
         } else {
@@ -426,4 +445,19 @@
     public void onDismissAllBubblesWhileDragging() {
         mSystemUiProxy.removeAllBubbles();
     }
+
+    /**
+     * Set listener to be notified when bubble bar bounds have changed
+     */
+    public void setBoundsChangeListener(@Nullable BubbleBarBoundsChangeListener listener) {
+        mBoundsChangeListener = listener;
+    }
+
+    /**
+     * Listener to receive updates about bubble bar bounds changing
+     */
+    public interface BubbleBarBoundsChangeListener {
+        /** Called when bounds have changed */
+        void onBoundsChanged(Rect newBounds);
+    }
 }
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleDragAnimator.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleDragAnimator.java
index 39440ba..8b811d9 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleDragAnimator.java
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleDragAnimator.java
@@ -18,7 +18,6 @@
 
 import static androidx.dynamicanimation.animation.SpringForce.DAMPING_RATIO_LOW_BOUNCY;
 import static androidx.dynamicanimation.animation.SpringForce.STIFFNESS_LOW;
-import static androidx.dynamicanimation.animation.SpringForce.STIFFNESS_MEDIUM;
 
 import android.content.res.Resources;
 import android.graphics.PointF;
@@ -42,11 +41,14 @@
     private static final float SCALE_BUBBLE_FOCUSED = 1.2f;
     private static final float SCALE_BUBBLE_CAPTURED = 0.9f;
     private static final float SCALE_BUBBLE_BAR_FOCUSED = 1.1f;
+    // 400f matches to MEDIUM_LOW spring stiffness
+    private static final float TRANSLATION_SPRING_STIFFNESS = 400f;
 
     private final PhysicsAnimator.SpringConfig mDefaultConfig =
             new PhysicsAnimator.SpringConfig(STIFFNESS_LOW, DAMPING_RATIO_LOW_BOUNCY);
     private final PhysicsAnimator.SpringConfig mTranslationConfig =
-            new PhysicsAnimator.SpringConfig(STIFFNESS_MEDIUM, DAMPING_RATIO_LOW_BOUNCY);
+            new PhysicsAnimator.SpringConfig(TRANSLATION_SPRING_STIFFNESS,
+                    DAMPING_RATIO_LOW_BOUNCY);
     @NonNull
     private final View mView;
     @NonNull
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleDragController.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleDragController.java
index dab7d9d..5ffc6d8 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleDragController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleDragController.java
@@ -25,7 +25,6 @@
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 
-import com.android.launcher3.R;
 import com.android.launcher3.taskbar.TaskbarActivityContext;
 
 /**
@@ -55,9 +54,8 @@
         mBubbleBarViewController = bubbleControllers.bubbleBarViewController;
         mBubbleDismissController = bubbleControllers.bubbleDismissController;
         mBubbleBarPinController = bubbleControllers.bubbleBarPinController;
-        mBubbleBarPinController.setListener(location -> {
-            // TODO(b/330585397): update bubble bar location in shell
-        });
+        mBubbleBarPinController.setListener(
+                bubbleControllers.bubbleBarController::updateBubbleBarLocation);
         mBubbleDismissController.setListener(
                 stuck -> mBubbleBarPinController.setDropTargetHidden(stuck));
     }
@@ -96,11 +94,8 @@
     @SuppressLint("ClickableViewAccessibility")
     public void setupBubbleBarView(@NonNull BubbleBarView bubbleBarView) {
         PointF initialRelativePivot = new PointF();
-        final int restingElevation = bubbleBarView.getResources().getDimensionPixelSize(
-                R.dimen.bubblebar_elevation);
-        final int dragElevation = bubbleBarView.getResources().getDimensionPixelSize(
-                R.dimen.bubblebar_drag_elevation);
         bubbleBarView.setOnTouchListener(new BubbleTouchListener() {
+
             @Override
             protected boolean onTouchDown(@NonNull View view, @NonNull MotionEvent event) {
                 if (bubbleBarView.isExpanded()) return false;
@@ -114,7 +109,7 @@
                 // By default the bubble bar view pivot is in bottom right corner, while dragging
                 // it should be centered in order to align it with the dismiss target view
                 bubbleBarView.setRelativePivot(/* x = */ 0.5f, /* y = */ 0.5f);
-                bubbleBarView.setElevation(dragElevation);
+                bubbleBarView.setIsDragging(true);
                 mBubbleBarPinController.onDragStart(
                         bubbleBarView.getBubbleBarLocation().isOnLeft(bubbleBarView.isLayoutRtl()));
             }
@@ -138,7 +133,14 @@
             void onDragEnd() {
                 // Restoring the initial pivot for the bubble bar view
                 bubbleBarView.setRelativePivot(initialRelativePivot.x, initialRelativePivot.y);
-                bubbleBarView.setElevation(restingElevation);
+                bubbleBarView.setIsDragging(false);
+            }
+
+            @Override
+            protected PointF getRestingPosition() {
+                PointF restingPosition = super.getRestingPosition();
+                bubbleBarView.adjustRelativeRestingPosition(restingPosition);
+                return restingPosition;
             }
         });
     }
@@ -226,6 +228,13 @@
         protected void onDragDismiss() {
         }
 
+        /**
+         * Get the resting position of the view when drag is released
+         */
+        protected PointF getRestingPosition() {
+            return mViewInitialPosition;
+        }
+
         @Override
         @SuppressLint("ClickableViewAccessibility")
         public boolean onTouch(@NonNull View view, @NonNull MotionEvent event) {
@@ -353,7 +362,7 @@
                 mAnimator.animateDismiss(mViewInitialPosition, onComplete);
             } else {
                 onDragRelease();
-                mAnimator.animateToInitialState(mViewInitialPosition, getCurrentVelocity(),
+                mAnimator.animateToInitialState(getRestingPosition(), getCurrentVelocity(),
                         onComplete);
             }
             mBubbleDismissController.hideDismissView();
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleStashController.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleStashController.java
index e25e586..61a2e22 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleStashController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleStashController.java
@@ -51,6 +51,15 @@
      */
     private static final float STASHED_BAR_SCALE = 0.5f;
 
+    /** The duration of hiding and showing the stashed handle as part of a new bubble animation. */
+    private static final long NEW_BUBBLE_HANDLE_ANIMATION_DURATION_MS = 200;
+
+    /** The translation Y value the handle animates to when hiding it for a new bubble. */
+    private static final int NEW_BUBBLE_HIDE_HANDLE_ANIMATION_TRANSLATION_Y = -20;
+
+    /** The alpha value the handle animates to when hiding it for a new bubble. */
+    public static final float NEW_BUBBLE_HIDE_HANDLE_ANIMATION_ALPHA = 0.5f;
+
     protected final TaskbarActivityContext mActivity;
 
     // Initialized in init.
@@ -64,6 +73,7 @@
     private AnimatedFloat mIconScaleForStash;
     private AnimatedFloat mIconTranslationYForStash;
     private MultiPropertyFactory.MultiProperty mBubbleStashedHandleAlpha;
+    private AnimatedFloat mBubbleStashedHandleTranslationY;
 
     private boolean mRequestedStashState;
     private boolean mRequestedExpandedState;
@@ -95,6 +105,7 @@
 
         mBubbleStashedHandleAlpha = mHandleViewController.getStashedHandleAlpha().get(
                 StashedHandleViewController.ALPHA_INDEX_STASHED);
+        mBubbleStashedHandleTranslationY = mHandleViewController.getStashedHandleTranslationY();
 
         mStashedHeight = mHandleViewController.getStashedHeight();
         mUnstashedHeight = mHandleViewController.getUnstashedHeight();
@@ -362,4 +373,35 @@
     public void setBubbleBarLocation(BubbleBarLocation bubbleBarLocation) {
         mHandleViewController.setBubbleBarLocation(bubbleBarLocation);
     }
+
+    /** Returns the x position of the center of the stashed handle. */
+    public float getStashedHandleCenterX() {
+        return mHandleViewController.getStashedHandleCenterX();
+    }
+
+    /** Returns the animation for hiding the handle before a new bubble animates in. */
+    public AnimatorSet buildHideHandleAnimationForNewBubble() {
+        AnimatorSet animatorSet = new AnimatorSet();
+        animatorSet.playTogether(
+                mBubbleStashedHandleTranslationY.animateToValue(
+                        NEW_BUBBLE_HIDE_HANDLE_ANIMATION_TRANSLATION_Y),
+                mBubbleStashedHandleAlpha.animateToValue(NEW_BUBBLE_HIDE_HANDLE_ANIMATION_ALPHA));
+        animatorSet.setDuration(NEW_BUBBLE_HANDLE_ANIMATION_DURATION_MS);
+        return animatorSet;
+    }
+
+    /** Sets the alpha value of the stashed handle. */
+    public void setStashAlpha(float alpha) {
+        mBubbleStashedHandleAlpha.setValue(alpha);
+    }
+
+    /** Returns the animation for showing the handle after a new bubble animated in. */
+    public AnimatorSet buildShowHandleAnimationForNewBubble() {
+        AnimatorSet animatorSet = new AnimatorSet();
+        animatorSet.playTogether(
+                mBubbleStashedHandleTranslationY.animateToValue(0),
+                mBubbleStashedHandleAlpha.animateToValue(1));
+        animatorSet.setDuration(NEW_BUBBLE_HANDLE_ANIMATION_DURATION_MS);
+        return animatorSet;
+    }
 }
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleStashedHandleViewController.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleStashedHandleViewController.java
index f64517a..2a5912a 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleStashedHandleViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleStashedHandleViewController.java
@@ -29,6 +29,7 @@
 import android.view.ViewOutlineProvider;
 
 import com.android.launcher3.R;
+import com.android.launcher3.anim.AnimatedFloat;
 import com.android.launcher3.anim.RevealOutlineAnimation;
 import com.android.launcher3.anim.RoundedRectRevealOutlineProvider;
 import com.android.launcher3.taskbar.StashedHandleView;
@@ -47,7 +48,7 @@
 
     private final TaskbarActivityContext mActivity;
     private final StashedHandleView mStashedHandleView;
-    private final MultiValueAlpha mTaskbarStashedHandleAlpha;
+    private final MultiValueAlpha mStashedHandleAlpha;
 
     // Initialized in init.
     private BubbleBarViewController mBarViewController;
@@ -58,6 +59,12 @@
     private int mStashedHandleWidth;
     private int mStashedHandleHeight;
 
+    private final AnimatedFloat mStashedHandleTranslationY =
+            new AnimatedFloat(this::updateTranslationY);
+
+    // Modified when swipe up is happening on the stashed handle or task bar.
+    private float mSwipeUpTranslationY;
+
     // The bounds we want to clip to in the settled state when showing the stashed handle.
     private final Rect mStashedHandleBounds = new Rect();
 
@@ -75,7 +82,7 @@
             StashedHandleView stashedHandleView) {
         mActivity = activity;
         mStashedHandleView = stashedHandleView;
-        mTaskbarStashedHandleAlpha = new MultiValueAlpha(mStashedHandleView, 1);
+        mStashedHandleAlpha = new MultiValueAlpha(mStashedHandleView, 1);
     }
 
     public void init(TaskbarControllers controllers, BubbleControllers bubbleControllers) {
@@ -93,7 +100,7 @@
                 R.dimen.transient_taskbar_bottom_margin);
         mStashedHandleView.getLayoutParams().height = mBarSize + bottomMargin;
 
-        mTaskbarStashedHandleAlpha.get(0).setValue(0);
+        mStashedHandleAlpha.get(0).setValue(0);
 
         mStashedTaskbarHeight = resources.getDimensionPixelSize(
                 R.dimen.bubblebar_stashed_size);
@@ -231,18 +238,33 @@
         }
     }
 
+    /** Returns an animator for translation Y. */
+    public AnimatedFloat getStashedHandleTranslationY() {
+        return mStashedHandleTranslationY;
+    }
+
     /**
      * Sets the translation of the stashed handle during the swipe up gesture.
      */
     public void setTranslationYForSwipe(float transY) {
-        mStashedHandleView.setTranslationY(transY);
+        mSwipeUpTranslationY = transY;
+        updateTranslationY();
+    }
+
+    private void updateTranslationY() {
+        mStashedHandleView.setTranslationY(mStashedHandleTranslationY.value + mSwipeUpTranslationY);
     }
 
     /**
      * Used by {@link BubbleStashController} to animate the handle when stashing or un stashing.
      */
     public MultiPropertyFactory<View> getStashedHandleAlpha() {
-        return mTaskbarStashedHandleAlpha;
+        return mStashedHandleAlpha;
+    }
+
+    /** Returns the x position of the center of the stashed handle. */
+    public float getStashedHandleCenterX() {
+        return mStashedHandleBounds.exactCenterX();
     }
 
     /**
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/animation/BubbleBarViewAnimator.kt b/quickstep/src/com/android/launcher3/taskbar/bubbles/animation/BubbleBarViewAnimator.kt
index bcb9f4d..1db5103 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/animation/BubbleBarViewAnimator.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/animation/BubbleBarViewAnimator.kt
@@ -18,12 +18,16 @@
 
 import android.view.View
 import android.view.View.VISIBLE
+import androidx.core.animation.AnimatorSet
+import androidx.core.animation.ObjectAnimator
+import androidx.core.animation.doOnEnd
 import androidx.dynamicanimation.animation.DynamicAnimation
 import androidx.dynamicanimation.animation.SpringForce
 import com.android.launcher3.taskbar.bubbles.BubbleBarBubble
 import com.android.launcher3.taskbar.bubbles.BubbleBarView
 import com.android.launcher3.taskbar.bubbles.BubbleStashController
 import com.android.launcher3.taskbar.bubbles.BubbleView
+import com.android.systemui.util.doOnEnd
 import com.android.wm.shell.shared.animation.PhysicsAnimator
 
 /** Handles animations for bubble bar bubbles. */
@@ -39,7 +43,17 @@
         /** The time to show the flyout. */
         const val FLYOUT_DELAY_MS: Long = 2500
         /** The translation Y the new bubble will animate to. */
-        const val BUBBLE_ANIMATION_TRANSLATION_Y = -50f
+        const val BUBBLE_ANIMATION_FINAL_TRANSLATION_Y = -50f
+        /** The initial translation Y value the new bubble is set to before the animation starts. */
+        // TODO(liranb): get rid of this and calculate this based on the y-distance between the
+        // bubble and the stash handle.
+        const val BUBBLE_ANIMATION_INITIAL_TRANSLATION_Y = 50f
+        /** The initial scale Y value that the new bubble is set to before the animation starts. */
+        const val BUBBLE_ANIMATION_INITIAL_SCALE_Y = 0.3f
+        /** The initial alpha value that the new bubble is set to before the animation starts. */
+        const val BUBBLE_ANIMATION_INITIAL_ALPHA = 0.5f
+        /** The duration of the hide bubble animation. */
+        const val HIDE_BUBBLE_ANIMATION_DURATION_MS = 250L
     }
 
     /** An interface for scheduling jobs. */
@@ -78,41 +92,94 @@
         // the animation of a new bubble is divided into 2 parts. The first part shows the bubble
         // and the second part hides it after a delay.
         val showAnimation = buildShowAnimation(bubbleView, b.key, animator)
-        val hideAnimation = buildHideAnimation(animator)
+        val hideAnimation = buildHideAnimation(bubbleView)
         scheduler.post(showAnimation)
         scheduler.postDelayed(FLYOUT_DELAY_MS, hideAnimation)
     }
 
-    /** Returns a lambda that starts the animation that shows the new bubble. */
+    /**
+     * Returns a lambda that starts the animation that shows the new bubble.
+     *
+     * The animation is divided into 2 parts. First the stash handle starts animating up and fades
+     * out. When it ends the bubble starts fading in. The bubble and stashed handle are aligned to
+     * give the impression of the stash handle morphing into the bubble.
+     */
     private fun buildShowAnimation(
         bubbleView: BubbleView,
         key: String,
-        animator: PhysicsAnimator<BubbleView>
+        bubbleAnimator: PhysicsAnimator<BubbleView>
     ): () -> Unit = {
+        // calculate the initial translation x the bubble should have in order to align it with the
+        // stash handle.
+        val initialTranslationX =
+            bubbleStashController.stashedHandleCenterX - bubbleView.centerXOnScreen
         bubbleBarView.prepareForAnimatingBubbleWhileStashed(key)
-        animator.setDefaultSpringConfig(springConfig)
-        animator
+        bubbleAnimator.setDefaultSpringConfig(springConfig)
+        bubbleAnimator
             .spring(DynamicAnimation.ALPHA, 1f)
-            .spring(DynamicAnimation.TRANSLATION_Y, BUBBLE_ANIMATION_TRANSLATION_Y)
+            .spring(DynamicAnimation.TRANSLATION_Y, BUBBLE_ANIMATION_FINAL_TRANSLATION_Y)
+            .spring(DynamicAnimation.SCALE_Y, 1f)
+        // prepare the bubble for the animation
         bubbleView.alpha = 0f
+        bubbleView.translationX = initialTranslationX
+        bubbleView.translationY = BUBBLE_ANIMATION_INITIAL_TRANSLATION_Y
+        bubbleView.scaleY = BUBBLE_ANIMATION_INITIAL_SCALE_Y
         bubbleView.visibility = VISIBLE
-        animator.start()
+        // start the stashed handle animation. when it ends, start the bubble animation.
+        val stashedHandleAnimation = bubbleStashController.buildHideHandleAnimationForNewBubble()
+        stashedHandleAnimation.doOnEnd {
+            bubbleView.alpha = BUBBLE_ANIMATION_INITIAL_ALPHA
+            bubbleAnimator.start()
+            bubbleStashController.setStashAlpha(0f)
+        }
+        stashedHandleAnimation.start()
     }
 
-    /** Returns a lambda that starts the animation that hides the new bubble. */
-    private fun buildHideAnimation(animator: PhysicsAnimator<BubbleView>): () -> Unit = {
-        animator.setDefaultSpringConfig(springConfig)
-        animator
-            .spring(DynamicAnimation.ALPHA, 0f)
-            .spring(DynamicAnimation.TRANSLATION_Y, 0f)
-            .addEndListener { _, _, _, canceled, _, _, allRelevantPropertyAnimsEnded ->
-                if (!canceled && allRelevantPropertyAnimsEnded) {
-                    if (bubbleStashController.isStashed) {
-                        bubbleBarView.alpha = 0f
-                    }
-                    bubbleBarView.onAnimatingBubbleCompleted()
-                }
+    /**
+     * Returns a lambda that starts the animation that hides the new bubble.
+     *
+     * Similarly to the show animation, this is divided into 2 parts. We first animate the bubble
+     * out, and then animate the stash handle in. At the end of the animation we reset the values of
+     * the bubble.
+     */
+    private fun buildHideAnimation(bubbleView: BubbleView): () -> Unit = {
+        val stashAnimation = bubbleStashController.buildShowHandleAnimationForNewBubble()
+        val alphaAnimator =
+            ObjectAnimator.ofFloat(bubbleView, View.ALPHA, BUBBLE_ANIMATION_INITIAL_ALPHA)
+        val translationYAnimator =
+            ObjectAnimator.ofFloat(
+                bubbleView,
+                View.TRANSLATION_Y,
+                BUBBLE_ANIMATION_INITIAL_TRANSLATION_Y
+            )
+        val scaleYAnimator =
+            ObjectAnimator.ofFloat(bubbleView, View.SCALE_Y, BUBBLE_ANIMATION_INITIAL_SCALE_Y)
+        val hideBubbleAnimation = AnimatorSet()
+        hideBubbleAnimation.playTogether(alphaAnimator, translationYAnimator, scaleYAnimator)
+        hideBubbleAnimation.duration = HIDE_BUBBLE_ANIMATION_DURATION_MS
+        hideBubbleAnimation.doOnEnd {
+            // the bubble is now hidden, start the stash handle animation and reset bubble
+            // properties
+            bubbleStashController.setStashAlpha(
+                BubbleStashController.NEW_BUBBLE_HIDE_HANDLE_ANIMATION_ALPHA
+            )
+            bubbleView.alpha = 0f
+            stashAnimation.start()
+            bubbleView.translationY = 0f
+            bubbleView.scaleY = 1f
+            if (bubbleStashController.isStashed) {
+                bubbleBarView.alpha = 0f
             }
-        animator.start()
+            bubbleBarView.onAnimatingBubbleCompleted()
+        }
+        hideBubbleAnimation.start()
     }
 }
+
+/** The X position in screen coordinates of the center of the bubble. */
+private val BubbleView.centerXOnScreen: Float
+    get() {
+        val screenCoordinates = IntArray(2)
+        getLocationOnScreen(screenCoordinates)
+        return screenCoordinates[0] + width / 2f
+    }
diff --git a/quickstep/src/com/android/launcher3/taskbar/navbutton/TaskbarNavLayoutter.kt b/quickstep/src/com/android/launcher3/taskbar/navbutton/TaskbarNavLayoutter.kt
index 9840791..34d3fad 100644
--- a/quickstep/src/com/android/launcher3/taskbar/navbutton/TaskbarNavLayoutter.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/navbutton/TaskbarNavLayoutter.kt
@@ -28,35 +28,39 @@
 import com.android.launcher3.taskbar.TaskbarActivityContext
 import com.android.systemui.shared.rotation.RotationButton
 
-/**
- * Layoutter for rendering task bar in large screen, both in 3-button and gesture nav mode.
- */
+/** Layoutter for rendering task bar in large screen, both in 3-button and gesture nav mode. */
 class TaskbarNavLayoutter(
-        resources: Resources,
-        navBarContainer: LinearLayout,
-        endContextualContainer: ViewGroup,
-        startContextualContainer: ViewGroup,
-        imeSwitcher: ImageView?,
-        rotationButton: RotationButton?,
-        a11yButton: ImageView?,
-        space: Space?
+    resources: Resources,
+    navBarContainer: LinearLayout,
+    endContextualContainer: ViewGroup,
+    startContextualContainer: ViewGroup,
+    imeSwitcher: ImageView?,
+    rotationButton: RotationButton?,
+    a11yButton: ImageView?,
+    space: Space?
 ) :
     AbstractNavButtonLayoutter(
-            resources,
-            navBarContainer,
-            endContextualContainer,
-            startContextualContainer,
-            imeSwitcher,
-            rotationButton,
-            a11yButton,
-            space
+        resources,
+        navBarContainer,
+        endContextualContainer,
+        startContextualContainer,
+        imeSwitcher,
+        rotationButton,
+        a11yButton,
+        space
     ) {
 
     override fun layoutButtons(context: TaskbarActivityContext, isA11yButtonPersistent: Boolean) {
         // Add spacing after the end of the last nav button
-        var navMarginEnd = resources
-                .getDimension(context.deviceProfile.inv.inlineNavButtonsEndSpacing)
-                .toInt()
+        var navMarginEnd =
+            resources.getDimension(context.deviceProfile.inv.inlineNavButtonsEndSpacing).toInt()
+
+        val cutout = context.display.cutout
+        val bottomRect = cutout?.boundingRectBottom
+        if (bottomRect != null && !bottomRect.isEmpty) {
+            navMarginEnd = bottomRect.width()
+        }
+
         val contextualWidth = endContextualContainer.width
         // If contextual buttons are showing, we check if the end margin is enough for the
         // contextual button to be showing - if not, move the nav buttons over a smidge
@@ -65,8 +69,11 @@
             navMarginEnd += resources.getDimensionPixelSize(R.dimen.taskbar_hotseat_nav_spacing) / 2
         }
 
-        val navButtonParams = FrameLayout.LayoutParams(
-                FrameLayout.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.MATCH_PARENT)
+        val navButtonParams =
+            FrameLayout.LayoutParams(
+                FrameLayout.LayoutParams.WRAP_CONTENT,
+                ViewGroup.LayoutParams.MATCH_PARENT
+            )
         navButtonParams.apply {
             gravity = Gravity.END or Gravity.CENTER_VERTICAL
             marginEnd = navMarginEnd
@@ -98,18 +105,28 @@
         startContextualContainer.removeAllViews()
 
         if (!context.deviceProfile.isGestureMode) {
-            val contextualMargin = resources.getDimensionPixelSize(
-                    R.dimen.taskbar_contextual_button_padding)
+            val contextualMargin =
+                resources.getDimensionPixelSize(R.dimen.taskbar_contextual_button_padding)
             repositionContextualContainer(endContextualContainer, WRAP_CONTENT, 0, 0, Gravity.END)
-            repositionContextualContainer(startContextualContainer, WRAP_CONTENT, contextualMargin,
-                    contextualMargin, Gravity.START)
+            repositionContextualContainer(
+                startContextualContainer,
+                WRAP_CONTENT,
+                contextualMargin,
+                contextualMargin,
+                Gravity.START
+            )
 
             if (imeSwitcher != null) {
-                val imeStartMargin = resources.getDimensionPixelSize(
-                        R.dimen.taskbar_ime_switcher_button_margin_start)
+                val imeStartMargin =
+                    resources.getDimensionPixelSize(
+                        R.dimen.taskbar_ime_switcher_button_margin_start
+                    )
                 startContextualContainer.addView(imeSwitcher)
-                val imeSwitcherButtonParams = FrameLayout.LayoutParams(
-                        FrameLayout.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)
+                val imeSwitcherButtonParams =
+                    FrameLayout.LayoutParams(
+                        FrameLayout.LayoutParams.MATCH_PARENT,
+                        ViewGroup.LayoutParams.MATCH_PARENT
+                    )
                 imeSwitcherButtonParams.apply {
                     marginStart = imeStartMargin
                     gravity = Gravity.CENTER_VERTICAL
diff --git a/quickstep/src/com/android/launcher3/uioverrides/ApiWrapper.java b/quickstep/src/com/android/launcher3/uioverrides/ApiWrapper.java
deleted file mode 100644
index 873dea8..0000000
--- a/quickstep/src/com/android/launcher3/uioverrides/ApiWrapper.java
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- * Copyright (C) 2017 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.uioverrides;
-
-import android.app.ActivityOptions;
-import android.app.PendingIntent;
-import android.app.Person;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentSender;
-import android.content.pm.ActivityInfo;
-import android.content.pm.LauncherActivityInfo;
-import android.content.pm.LauncherApps;
-import android.content.pm.LauncherUserInfo;
-import android.content.pm.ShortcutInfo;
-import android.graphics.drawable.ColorDrawable;
-import android.net.Uri;
-import android.os.UserHandle;
-import android.os.UserManager;
-import android.util.ArrayMap;
-import android.window.RemoteTransition;
-
-import com.android.launcher3.Flags;
-import com.android.launcher3.Utilities;
-import com.android.launcher3.proxy.ProxyActivityStarter;
-import com.android.launcher3.util.StartActivityParams;
-import com.android.launcher3.util.UserIconInfo;
-import com.android.quickstep.util.FadeOutRemoteTransition;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
-/**
- * A wrapper for the hidden API calls
- */
-public class ApiWrapper {
-
-    public static final boolean TASKBAR_DRAWN_IN_PROCESS = true;
-
-    public static Person[] getPersons(ShortcutInfo si) {
-        Person[] persons = si.getPersons();
-        return persons == null ? Utilities.EMPTY_PERSON_ARRAY : persons;
-    }
-
-    public static Map<String, LauncherActivityInfo> getActivityOverrides(Context context) {
-        return context.getSystemService(LauncherApps.class).getActivityOverrides();
-    }
-
-    /**
-     * Creates an ActivityOptions to play fade-out animation on closing targets
-     */
-    public static ActivityOptions createFadeOutAnimOptions(Context context) {
-        ActivityOptions options = ActivityOptions.makeBasic();
-        options.setRemoteTransition(new RemoteTransition(new FadeOutRemoteTransition()));
-        return options;
-    }
-
-    /**
-     * Returns a map of all users on the device to their corresponding UI properties
-     */
-    public static Map<UserHandle, UserIconInfo> queryAllUsers(Context context) {
-        UserManager um = context.getSystemService(UserManager.class);
-        Map<UserHandle, UserIconInfo> users = new ArrayMap<>();
-        List<UserHandle> usersActual = um.getUserProfiles();
-        if (usersActual != null) {
-            for (UserHandle user : usersActual) {
-                if (android.os.Flags.allowPrivateProfile() && Flags.enablePrivateSpace()) {
-                    LauncherApps launcherApps = context.getSystemService(LauncherApps.class);
-                    LauncherUserInfo launcherUserInfo = launcherApps.getLauncherUserInfo(user);
-                    if (launcherUserInfo == null) {
-                        continue;
-                    }
-                    // UserTypes not supported in Launcher are deemed to be the current
-                    // Foreground User.
-                    int userType = switch (launcherUserInfo.getUserType()) {
-                        case UserManager.USER_TYPE_PROFILE_MANAGED -> UserIconInfo.TYPE_WORK;
-                        case UserManager.USER_TYPE_PROFILE_CLONE -> UserIconInfo.TYPE_CLONED;
-                        case UserManager.USER_TYPE_PROFILE_PRIVATE -> UserIconInfo.TYPE_PRIVATE;
-                        default -> UserIconInfo.TYPE_MAIN;
-                    };
-                    long serial = launcherUserInfo.getUserSerialNumber();
-                    users.put(user, new UserIconInfo(user, userType, serial));
-                } else {
-                    long serial = um.getSerialNumberForUser(user);
-
-                    // Simple check to check if the provided user is work profile
-                    // TODO: Migrate to a better platform API
-                    NoopDrawable d = new NoopDrawable();
-                    boolean isWork = (d != context.getPackageManager().getUserBadgedIcon(d, user));
-                    UserIconInfo info = new UserIconInfo(
-                            user,
-                            isWork ? UserIconInfo.TYPE_WORK : UserIconInfo.TYPE_MAIN,
-                            serial);
-                    users.put(user, info);
-                }
-            }
-        }
-        return users;
-    }
-
-    /**
-     * Returns the list of the system packages that are installed at user creation.
-     * An empty list denotes that all system packages are installed for that user at creation.
-     */
-    public static List<String> getPreInstalledSystemPackages(Context context, UserHandle user) {
-        LauncherApps launcherApps = context.getSystemService(LauncherApps.class);
-        if (android.os.Flags.allowPrivateProfile() && Flags.enablePrivateSpace()
-                && Flags.privateSpaceSysAppsSeparation()) {
-            return launcherApps.getPreInstalledSystemPackages(user);
-        } else {
-            return new ArrayList<>();
-        }
-    }
-
-    /**
-     * Returns an intent which can be used to start the App Market activity (Installer
-     * Activity).
-     */
-    public static Intent getAppMarketActivityIntent(Context context, String packageName,
-            UserHandle user) {
-        LauncherApps launcherApps = context.getSystemService(LauncherApps.class);
-        if (android.os.Flags.allowPrivateProfile()
-                && Flags.enablePrivateSpace()
-                && (Flags.privateSpaceAppInstallerButton()
-                        || Flags.enablePrivateSpaceInstallShortcut())) {
-            StartActivityParams params = new StartActivityParams((PendingIntent) null, 0);
-            params.intentSender = launcherApps.getAppMarketActivityIntent(packageName, user);
-            ActivityOptions options = ActivityOptions.makeBasic()
-                    .setPendingIntentBackgroundActivityStartMode(ActivityOptions
-                            .MODE_BACKGROUND_ACTIVITY_START_ALLOWED);
-            params.options = options.toBundle();
-            params.requireActivityResult = false;
-            return ProxyActivityStarter.getLaunchIntent(context, params);
-        } else {
-            return new Intent(Intent.ACTION_VIEW)
-                    .setData(new Uri.Builder()
-                            .scheme("market")
-                            .authority("details")
-                            .appendQueryParameter("id", packageName)
-                            .build())
-                    .putExtra(Intent.EXTRA_REFERRER, new Uri.Builder().scheme("android-app")
-                            .authority(context.getPackageName()).build());
-        }
-    }
-
-    /**
-     * Returns an intent which can be used to open Private Space Settings.
-     */
-    public static Intent getPrivateSpaceSettingsIntent(Context context) {
-        if (android.os.Flags.allowPrivateProfile() && Flags.enablePrivateSpace()) {
-            LauncherApps launcherApps = context.getSystemService(LauncherApps.class);
-            IntentSender intentSender = launcherApps.getPrivateSpaceSettingsIntent();
-            if (intentSender == null) {
-                return null;
-            }
-            StartActivityParams params = new StartActivityParams((PendingIntent) null, 0);
-            params.intentSender = intentSender;
-            ActivityOptions options = ActivityOptions.makeBasic()
-                    .setPendingIntentBackgroundActivityStartMode(ActivityOptions
-                            .MODE_BACKGROUND_ACTIVITY_START_ALLOWED);
-            params.options = options.toBundle();
-            params.requireActivityResult = false;
-            return ProxyActivityStarter.getLaunchIntent(context, params);
-        }
-        return null;
-    }
-
-    /**
-     * Checks if an activity is flagged as non-resizeable.
-     */
-    public static boolean isNonResizeableActivity(LauncherActivityInfo lai) {
-        return lai.getActivityInfo().resizeMode == ActivityInfo.RESIZE_MODE_UNRESIZEABLE;
-    }
-
-    private static class NoopDrawable extends ColorDrawable {
-        @Override
-        public int getIntrinsicHeight() {
-            return 1;
-        }
-
-        @Override
-        public int getIntrinsicWidth() {
-            return 1;
-        }
-    }
-}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
index b49c752..6c05bfe 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
@@ -62,8 +62,8 @@
 import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
 import static com.android.quickstep.util.AnimUtils.completeRunnableListCallback;
 import static com.android.quickstep.util.SplitAnimationTimings.TABLET_HOME_TO_SPLIT;
-import static com.android.window.flags.Flags.enableDesktopWindowingMode;
 import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_HOME_KEY;
+import static com.android.window.flags.Flags.enableDesktopWindowingMode;
 import static com.android.wm.shell.common.split.SplitScreenConstants.SNAP_TO_50_50;
 
 import android.animation.Animator;
@@ -105,7 +105,6 @@
 import com.android.launcher3.AbstractFloatingView;
 import com.android.launcher3.DeviceProfile;
 import com.android.launcher3.Flags;
-import com.android.launcher3.HomeTransitionController;
 import com.android.launcher3.InvariantDeviceProfile;
 import com.android.launcher3.Launcher;
 import com.android.launcher3.LauncherSettings.Favorites;
@@ -182,6 +181,7 @@
 import com.android.quickstep.views.FloatingTaskView;
 import com.android.quickstep.views.OverviewActionsView;
 import com.android.quickstep.views.RecentsView;
+import com.android.quickstep.views.RecentsViewContainer;
 import com.android.quickstep.views.TaskView;
 import com.android.systemui.shared.recents.model.Task;
 import com.android.systemui.shared.system.ActivityManagerWrapper;
@@ -205,7 +205,7 @@
 import java.util.function.Predicate;
 import java.util.stream.Stream;
 
-public class QuickstepLauncher extends Launcher {
+public class QuickstepLauncher extends Launcher implements RecentsViewContainer {
     private static final boolean TRACE_LAYOUTS =
             SystemProperties.getBoolean("persist.debug.trace_layouts", false);
     private static final String TRACE_RELAYOUT_CLASS =
@@ -217,9 +217,10 @@
     private FixedContainerItems mAllAppsPredictions;
     private HotseatPredictionController mHotseatPredictionController;
     private DepthController mDepthController;
-    private DesktopVisibilityController mDesktopVisibilityController;
+    private @Nullable DesktopVisibilityController mDesktopVisibilityController;
     private QuickstepTransitionManager mAppTransitionManager;
-    private OverviewActionsView mActionsView;
+
+    private OverviewActionsView<?> mActionsView;
     private TISBindHelper mTISBindHelper;
     private @Nullable LauncherTaskbarUIController mTaskbarUIController;
     // Will be updated when dragging from taskbar.
@@ -245,14 +246,16 @@
 
     private boolean mIsPredictiveBackToHomeInProgress;
 
-    private HomeTransitionController mHomeTransitionController;
+    public static QuickstepLauncher getLauncher(Context context) {
+        return fromContext(context);
+    }
 
     @Override
     protected void setupViews() {
         super.setupViews();
 
         mActionsView = findViewById(R.id.overview_actions_view);
-        RecentsView overviewPanel = getOverviewPanel();
+        RecentsView<?,?> overviewPanel = getOverviewPanel();
         SystemUiProxy systemUiProxy = SystemUiProxy.INSTANCE.get(this);
         mSplitSelectStateController =
                 new SplitSelectStateController(this, mHandler, getStateManager(),
@@ -277,15 +280,10 @@
         mAppTransitionManager.registerRemoteAnimations();
         mAppTransitionManager.registerRemoteTransitions();
 
-        if (FeatureFlags.enableHomeTransitionListener()) {
-            mHomeTransitionController = new HomeTransitionController();
-            mHomeTransitionController.registerHomeTransitionListener(this);
-        }
-
         mTISBindHelper = new TISBindHelper(this, this::onTISConnected);
         mDepthController = new DepthController(this);
-        mDesktopVisibilityController = new DesktopVisibilityController(this);
         if (enableDesktopWindowingMode()) {
+            mDesktopVisibilityController = new DesktopVisibilityController(this);
             mDesktopVisibilityController.registerSystemUiListener();
             mSplitSelectStateController.initSplitFromDesktopController(this);
         }
@@ -523,10 +521,6 @@
             mLauncherUnfoldAnimationController.onDestroy();
         }
 
-        if (mHomeTransitionController != null) {
-            mHomeTransitionController.unregisterHomeTransitionListener();
-        }
-
         if (mDesktopVisibilityController != null) {
             mDesktopVisibilityController.unregisterSystemUiListener();
         }
@@ -948,15 +942,13 @@
 
     @Override
     public void setResumed() {
-        if (enableDesktopWindowingMode()) {
-            DesktopVisibilityController controller = mDesktopVisibilityController;
-            if (controller != null && controller.areFreeformTasksVisible()
-                    && !controller.isRecentsGestureInProgress()) {
-                // Return early to skip setting activity to appear as resumed
-                // TODO(b/255649902): shouldn't be needed when we have a separate launcher state
-                //  for desktop that we can use to control other parts of launcher
-                return;
-            }
+        if (mDesktopVisibilityController != null
+                && mDesktopVisibilityController.areDesktopTasksVisible()
+                && !mDesktopVisibilityController.isRecentsGestureInProgress()) {
+            // Return early to skip setting activity to appear as resumed
+            // TODO(b/255649902): shouldn't be needed when we have a separate launcher state
+            //  for desktop that we can use to control other parts of launcher
+            return;
         }
         super.setResumed();
     }
@@ -1069,8 +1061,9 @@
                 .playPlaceholderDismissAnim(this, splitDismissEvent);
     }
 
-    public <T extends OverviewActionsView> T getActionsView() {
-        return (T) mActionsView;
+    @Override
+    public OverviewActionsView<?> getActionsView() {
+        return mActionsView;
     }
 
     @Override
@@ -1090,6 +1083,7 @@
         return mDepthController;
     }
 
+    @Nullable
     public DesktopVisibilityController getDesktopVisibilityController() {
         return mDesktopVisibilityController;
     }
@@ -1297,9 +1291,9 @@
     }
 
     @Override
-    public boolean areFreeformTasksVisible() {
+    public boolean areDesktopTasksVisible() {
         if (mDesktopVisibilityController != null) {
-            return mDesktopVisibilityController.areFreeformTasksVisible();
+            return mDesktopVisibilityController.areDesktopTasksVisible();
         }
         return false;
     }
@@ -1382,25 +1376,25 @@
     }
 
     private static final class LauncherTaskViewController extends
-            TaskViewTouchController<Launcher> {
+            TaskViewTouchController<QuickstepLauncher> {
 
-        LauncherTaskViewController(Launcher activity) {
+        LauncherTaskViewController(QuickstepLauncher activity) {
             super(activity);
         }
 
         @Override
         protected boolean isRecentsInteractive() {
-            return mActivity.isInState(OVERVIEW) || mActivity.isInState(OVERVIEW_MODAL_TASK);
+            return mContainer.isInState(OVERVIEW) || mContainer.isInState(OVERVIEW_MODAL_TASK);
         }
 
         @Override
         protected boolean isRecentsModal() {
-            return mActivity.isInState(OVERVIEW_MODAL_TASK);
+            return mContainer.isInState(OVERVIEW_MODAL_TASK);
         }
 
         @Override
         protected void onUserControlledAnimationCreated(AnimatorPlaybackController animController) {
-            mActivity.getStateManager().setCurrentUserControlledAnimation(animController);
+            mContainer.getStateManager().setCurrentUserControlledAnimation(animController);
         }
     }
 
@@ -1423,6 +1417,10 @@
         if (mHotseatPredictionController != null) {
             mHotseatPredictionController.dump(prefix, writer);
         }
+        PredictionRowView<?> predictionRowView =
+                getAppsView().getFloatingHeaderView().findFixedRowByType(
+                        PredictionRowView.class);
+        predictionRowView.dump(prefix, writer);
     }
 
     @Override
diff --git a/quickstep/src/com/android/launcher3/uioverrides/SystemApiWrapper.kt b/quickstep/src/com/android/launcher3/uioverrides/SystemApiWrapper.kt
new file mode 100644
index 0000000..535b4c2
--- /dev/null
+++ b/quickstep/src/com/android/launcher3/uioverrides/SystemApiWrapper.kt
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2024 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.uioverrides
+
+import android.app.ActivityOptions
+import android.app.PendingIntent
+import android.content.Context
+import android.content.Intent
+import android.content.pm.ActivityInfo
+import android.content.pm.LauncherActivityInfo
+import android.content.pm.LauncherApps
+import android.content.pm.ShortcutInfo
+import android.os.Flags.allowPrivateProfile
+import android.os.UserHandle
+import android.os.UserManager
+import android.util.ArrayMap
+import android.window.RemoteTransition
+import com.android.launcher3.Flags.enablePrivateSpace
+import com.android.launcher3.Flags.enablePrivateSpaceInstallShortcut
+import com.android.launcher3.Flags.privateSpaceAppInstallerButton
+import com.android.launcher3.Flags.privateSpaceSysAppsSeparation
+import com.android.launcher3.Utilities
+import com.android.launcher3.proxy.ProxyActivityStarter
+import com.android.launcher3.util.ApiWrapper
+import com.android.launcher3.util.StartActivityParams
+import com.android.launcher3.util.UserIconInfo
+import com.android.quickstep.util.FadeOutRemoteTransition
+
+/** A wrapper for the hidden API calls */
+class SystemApiWrapper(context: Context?) : ApiWrapper(context) {
+
+    override fun getPersons(si: ShortcutInfo) = si.persons ?: Utilities.EMPTY_PERSON_ARRAY
+
+    override fun getActivityOverrides(): Map<String, LauncherActivityInfo> =
+        mContext.getSystemService(LauncherApps::class.java)!!.activityOverrides
+
+    override fun createFadeOutAnimOptions(): ActivityOptions =
+        ActivityOptions.makeBasic().apply {
+            remoteTransition = RemoteTransition(FadeOutRemoteTransition())
+        }
+
+    override fun queryAllUsers(): Map<UserHandle, UserIconInfo> {
+        if (!allowPrivateProfile() || !enablePrivateSpace()) {
+            return super.queryAllUsers()
+        }
+        val users = ArrayMap<UserHandle, UserIconInfo>()
+        mContext.getSystemService(UserManager::class.java)!!.userProfiles?.forEach { user ->
+            mContext.getSystemService(LauncherApps::class.java)!!.getLauncherUserInfo(user)?.apply {
+                users[user] =
+                    UserIconInfo(
+                        user,
+                        when (userType) {
+                            UserManager.USER_TYPE_PROFILE_MANAGED -> UserIconInfo.TYPE_WORK
+                            UserManager.USER_TYPE_PROFILE_CLONE -> UserIconInfo.TYPE_CLONED
+                            UserManager.USER_TYPE_PROFILE_PRIVATE -> UserIconInfo.TYPE_PRIVATE
+                            else -> UserIconInfo.TYPE_MAIN
+                        },
+                        userSerialNumber.toLong()
+                    )
+            }
+        }
+        return users
+    }
+
+    override fun getPreInstalledSystemPackages(user: UserHandle): List<String> =
+        if (allowPrivateProfile() && enablePrivateSpace() && privateSpaceSysAppsSeparation())
+            mContext
+                .getSystemService(LauncherApps::class.java)!!
+                .getPreInstalledSystemPackages(user)
+        else ArrayList()
+
+    override fun getAppMarketActivityIntent(packageName: String, user: UserHandle): Intent =
+        if (
+            allowPrivateProfile() &&
+                enablePrivateSpace() &&
+                (privateSpaceAppInstallerButton() || enablePrivateSpaceInstallShortcut())
+        )
+            ProxyActivityStarter.getLaunchIntent(
+                mContext,
+                StartActivityParams(null as PendingIntent?, 0).apply {
+                    intentSender =
+                        mContext
+                            .getSystemService(LauncherApps::class.java)!!
+                            .getAppMarketActivityIntent(packageName, user)
+                    options =
+                        ActivityOptions.makeBasic()
+                            .setPendingIntentBackgroundActivityStartMode(
+                                ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED
+                            )
+                            .toBundle()
+                    requireActivityResult = false
+                }
+            )
+        else super.getAppMarketActivityIntent(packageName, user)
+
+    /** Returns an intent which can be used to open Private Space Settings. */
+    override fun getPrivateSpaceSettingsIntent(): Intent? =
+        if (allowPrivateProfile() && enablePrivateSpace())
+            ProxyActivityStarter.getLaunchIntent(
+                mContext,
+                StartActivityParams(null as PendingIntent?, 0).apply {
+                    intentSender =
+                        mContext
+                            .getSystemService(LauncherApps::class.java)
+                            ?.privateSpaceSettingsIntent
+                            ?: return null
+                    options =
+                        ActivityOptions.makeBasic()
+                            .setPendingIntentBackgroundActivityStartMode(
+                                ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED
+                            )
+                            .toBundle()
+                    requireActivityResult = false
+                }
+            )
+        else null
+
+    override fun isNonResizeableActivity(lai: LauncherActivityInfo) =
+        lai.activityInfo.resizeMode == ActivityInfo.RESIZE_MODE_UNRESIZEABLE
+}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/flags/DebugFlag.java b/quickstep/src/com/android/launcher3/uioverrides/flags/DebugFlag.java
deleted file mode 100644
index 630ef39..0000000
--- a/quickstep/src/com/android/launcher3/uioverrides/flags/DebugFlag.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2023 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.uioverrides.flags;
-
-import static com.android.launcher3.uioverrides.flags.FlagsFactory.TEAMFOOD_FLAG;
-
-import androidx.annotation.NonNull;
-
-import com.android.launcher3.config.FeatureFlags.BooleanFlag;
-import com.android.launcher3.config.FeatureFlags.FlagState;
-
-class DebugFlag extends BooleanFlag {
-
-    public final String key;
-    public final String description;
-
-    @NonNull
-    public final FlagState defaultValue;
-
-    DebugFlag(String key, String description, FlagState defaultValue, boolean currentValue) {
-        super(currentValue);
-        this.key = key;
-        this.defaultValue = defaultValue;
-        this.description = description;
-    }
-
-    /**
-     * Returns {@code true} if this flag's value has been modified from its default.
-     * <p>
-     * This helps to identify which flags have been toggled in log dumps and bug reports to
-     * further help triaging and debugging.
-     */
-    boolean currentValueModified() {
-        switch (defaultValue) {
-            case ENABLED: return !get();
-            case TEAMFOOD: return TEAMFOOD_FLAG.get() != get();
-            case DISABLED: return get();
-            default: return true;
-        }
-    }
-
-    @Override
-    public String toString() {
-        return key + ": defaultValue=" + defaultValue + ", mCurrentValue=" + get();
-    }
-}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/flags/DevOptionsUiHelper.kt b/quickstep/src/com/android/launcher3/uioverrides/flags/DevOptionsUiHelper.kt
new file mode 100644
index 0000000..6b44ca7
--- /dev/null
+++ b/quickstep/src/com/android/launcher3/uioverrides/flags/DevOptionsUiHelper.kt
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2024 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.uioverrides.flags
+
+import android.os.Handler
+import android.provider.DeviceConfig
+import android.text.Html
+import android.view.inputmethod.EditorInfo
+import androidx.preference.Preference
+import androidx.preference.PreferenceGroup
+import androidx.preference.PreferenceViewHolder
+import androidx.preference.SwitchPreference
+import com.android.launcher3.ExtendedEditText
+import com.android.launcher3.R
+import com.android.quickstep.util.DeviceConfigHelper
+import com.android.quickstep.util.DeviceConfigHelper.Companion.NAMESPACE_LAUNCHER
+import com.android.quickstep.util.DeviceConfigHelper.DebugInfo
+
+/** Helper class to generate UI for Device Config */
+class DevOptionsUiHelper {
+
+    /** Inflates preferences for all server flags in the provider PreferenceGroup */
+    fun inflateServerFlags(parent: PreferenceGroup) {
+        val prefs = DeviceConfigHelper.prefs
+        // Sort the keys in the order of modified first followed by natural order
+        val allProps =
+            DeviceConfigHelper.allProps.values
+                .toList()
+                .sortedWith(
+                    Comparator.comparingInt { prop: DebugInfo<*> ->
+                            if (prefs.contains(prop.key)) 0 else 1
+                        }
+                        .thenComparing { prop: DebugInfo<*> -> prop.key }
+                )
+
+        // First add boolean flags
+        allProps.forEach {
+            if (it.isInt) return@forEach
+            val info = it as DebugInfo<Boolean>
+
+            val preference =
+                object : SwitchPreference(parent.context) {
+                    override fun onBindViewHolder(holder: PreferenceViewHolder) {
+                        super.onBindViewHolder(holder)
+                        holder.itemView.setOnLongClickListener {
+                            prefs.edit().remove(key).apply()
+                            setChecked(info.getBoolValue())
+                            summary = info.getSummary()
+                            true
+                        }
+                    }
+                }
+            preference.key = info.key
+            preference.isPersistent = false
+            preference.title = info.key
+            preference.summary = info.getSummary()
+            preference.setChecked(prefs.getBoolean(info.key, info.getBoolValue()))
+            preference.setOnPreferenceChangeListener { _, newVal ->
+                DeviceConfigHelper.prefs.edit().putBoolean(info.key, newVal as Boolean).apply()
+                preference.summary = info.getSummary()
+                true
+            }
+            parent.addPreference(preference)
+        }
+
+        // Apply Int flags
+        allProps.forEach {
+            if (!it.isInt) return@forEach
+            val info = it as DebugInfo<Int>
+
+            val preference =
+                object : Preference(parent.context) {
+                    override fun onBindViewHolder(holder: PreferenceViewHolder) {
+                        super.onBindViewHolder(holder)
+                        val textView = holder.findViewById(R.id.pref_edit_text) as ExtendedEditText
+                        textView.setText(info.getIntValueAsString())
+                        textView.setOnEditorActionListener { _, actionId, _ ->
+                            if (actionId == EditorInfo.IME_ACTION_DONE) {
+                                DeviceConfigHelper.prefs
+                                    .edit()
+                                    .putInt(key, textView.text.toString().toInt())
+                                    .apply()
+                                Handler().post { summary = info.getSummary() }
+                                true
+                            }
+                            false
+                        }
+                        textView.setOnBackKeyListener {
+                            textView.setText(info.getIntValueAsString())
+                            true
+                        }
+
+                        holder.itemView.setOnLongClickListener {
+                            prefs.edit().remove(key).apply()
+                            textView.setText(info.getIntValueAsString())
+                            summary = info.getSummary()
+                            true
+                        }
+                    }
+                }
+            preference.key = info.key
+            preference.isPersistent = false
+            preference.title = info.key
+            preference.summary = info.getSummary()
+            preference.widgetLayoutResource = R.layout.develop_options_edit_text
+            parent.addPreference(preference)
+        }
+    }
+
+    /**
+     * Returns the summary to show the description and whether the flag overrides the default value.
+     */
+    private fun DebugInfo<*>.getSummary() =
+        Html.fromHtml(
+            (if (DeviceConfigHelper.prefs.contains(this.key))
+                "<font color='red'><b>[OVERRIDDEN]</b></font><br>"
+            else "") + this.desc
+        )
+
+    private fun DebugInfo<Boolean>.getBoolValue() =
+        DeviceConfigHelper.prefs.getBoolean(
+            this.key,
+            DeviceConfig.getBoolean(NAMESPACE_LAUNCHER, this.key, this.valueInCode)
+        )
+
+    private fun DebugInfo<Int>.getIntValueAsString() =
+        DeviceConfigHelper.prefs
+            .getInt(this.key, DeviceConfig.getInt(NAMESPACE_LAUNCHER, this.key, this.valueInCode))
+            .toString()
+
+    companion object {
+        const val TAG = "DeviceConfigUIHelper"
+    }
+}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/flags/DeveloperOptionsUI.java b/quickstep/src/com/android/launcher3/uioverrides/flags/DeveloperOptionsUI.java
index 6713964..3f818ac 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/flags/DeveloperOptionsUI.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/flags/DeveloperOptionsUI.java
@@ -20,19 +20,8 @@
 import static android.view.View.GONE;
 import static android.view.View.VISIBLE;
 
-import static com.android.launcher3.LauncherPrefs.ALL_APPS_OVERVIEW_THRESHOLD;
-import static com.android.launcher3.LauncherPrefs.PRIVATE_SPACE_APPS;
-import static com.android.launcher3.config.FeatureFlags.LPNH_EXTRA_TOUCH_WIDTH_DP;
-import static com.android.launcher3.config.FeatureFlags.LPNH_HAPTIC_HINT_DELAY;
-import static com.android.launcher3.config.FeatureFlags.LPNH_HAPTIC_HINT_END_SCALE_PERCENT;
-import static com.android.launcher3.config.FeatureFlags.LPNH_HAPTIC_HINT_ITERATIONS;
-import static com.android.launcher3.config.FeatureFlags.LPNH_HAPTIC_HINT_SCALE_EXPONENT;
-import static com.android.launcher3.config.FeatureFlags.LPNH_HAPTIC_HINT_START_SCALE_PERCENT;
-import static com.android.launcher3.config.FeatureFlags.LPNH_SLOP_PERCENTAGE;
-import static com.android.launcher3.config.FeatureFlags.LPNH_TIMEOUT_MS;
 import static com.android.launcher3.settings.SettingsActivity.EXTRA_FRAGMENT_HIGHLIGHT_KEY;
 import static com.android.launcher3.uioverrides.plugins.PluginManagerWrapper.PLUGIN_CHANGED;
-import static com.android.launcher3.uioverrides.plugins.PluginManagerWrapper.pluginEnabledKey;
 import static com.android.launcher3.util.OnboardingPrefs.ALL_APPS_VISITED_COUNT;
 import static com.android.launcher3.util.OnboardingPrefs.HOME_BOUNCE_COUNT;
 import static com.android.launcher3.util.OnboardingPrefs.HOME_BOUNCE_SEEN;
@@ -51,7 +40,6 @@
 import android.text.Editable;
 import android.text.TextWatcher;
 import android.util.ArrayMap;
-import android.util.Log;
 import android.util.Pair;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -61,21 +49,18 @@
 
 import androidx.preference.Preference;
 import androidx.preference.PreferenceCategory;
-import androidx.preference.PreferenceDataStore;
 import androidx.preference.PreferenceFragmentCompat;
 import androidx.preference.PreferenceGroup;
 import androidx.preference.PreferenceScreen;
 import androidx.preference.PreferenceViewHolder;
-import androidx.preference.SeekBarPreference;
 import androidx.preference.SwitchPreference;
 
-import com.android.launcher3.ConstantItem;
-import com.android.launcher3.Flags;
 import com.android.launcher3.LauncherPrefs;
 import com.android.launcher3.R;
 import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.secondarydisplay.SecondaryDisplayLauncher;
 import com.android.launcher3.uioverrides.plugins.PluginManagerWrapper;
+import com.android.systemui.shared.plugins.PluginEnabler;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -90,19 +75,17 @@
 
     private static final String ACTION_PLUGIN_SETTINGS =
             "com.android.systemui.action.PLUGIN_SETTINGS";
-    private static final String TAG = "DeveloperOptionsUI";
     private static final String PLUGIN_PERMISSION = "com.android.systemui.permission.PLUGIN";
 
     private final PreferenceFragmentCompat mFragment;
     private final PreferenceScreen mPreferenceScreen;
 
-    private final FlagTogglerPrefUi mFlagTogglerPrefUi;
-
     private PreferenceCategory mPluginsCategory;
 
     public DeveloperOptionsUI(PreferenceFragmentCompat fragment, PreferenceCategory flags) {
         mFragment = fragment;
         mPreferenceScreen = fragment.getPreferenceScreen();
+        flags.getParent().removePreference(flags);
 
         // Add search bar
         View listView = mFragment.getListView();
@@ -112,20 +95,12 @@
         parent.addView(topBar, parent.indexOfChild(listView));
         initSearch(topBar.findViewById(R.id.filter_box));
 
-        mFlagTogglerPrefUi = new FlagTogglerPrefUi(mFragment.requireActivity(),
-                topBar.findViewById(R.id.flag_apply_btn));
-        mFlagTogglerPrefUi.applyTo(flags);
+        DevOptionsUiHelper uiHelper = new DevOptionsUiHelper();
+        uiHelper.inflateServerFlags(newCategory("Server flags"));
 
         loadPluginPrefs();
         maybeAddSandboxCategory();
         addOnboardingPrefsCatergory();
-        if (FeatureFlags.ENABLE_ALL_APPS_FROM_OVERVIEW.get()) {
-            addAllAppsFromOverviewCatergory();
-        }
-        addCustomLpnhCategory();
-        if (Flags.enablePrivateSpace()) {
-            addCustomPrivateAppsCategory();
-        }
     }
 
     private void filterPreferences(String query, PreferenceGroup pg) {
@@ -205,7 +180,7 @@
                 new ArrayMap<>();
 
         Set<String> pluginPermissionApps = pm.getPackagesHoldingPermissions(
-                new String[]{PLUGIN_PERMISSION}, MATCH_DISABLED_COMPONENTS)
+                        new String[]{PLUGIN_PERMISSION}, MATCH_DISABLED_COMPONENTS)
                 .stream()
                 .map(pi -> pi.packageName)
                 .collect(Collectors.toSet());
@@ -228,7 +203,7 @@
             }
         }
 
-        PreferenceDataStore enabler = manager.getPluginEnabler();
+        PluginEnabler enabler = manager.getPluginEnabler();
         plugins.forEach((key, si) -> {
             String packageName = key.first;
             List<ComponentName> componentNames = si.stream()
@@ -347,111 +322,10 @@
         return onboardingPref;
     }
 
-    private void addAllAppsFromOverviewCatergory() {
-        PreferenceCategory category = newCategory("All Apps from Overview Config");
-        category.addPreference(createSeekBarPreference("Threshold to open All Apps from Overview",
-                105, 500, 100, ALL_APPS_OVERVIEW_THRESHOLD));
-    }
-
-    private void addCustomLpnhCategory() {
-        PreferenceCategory category = newCategory("Long Press Nav Handle Config");
-        if (FeatureFlags.CUSTOM_LPNH_THRESHOLDS.get()) {
-            category.addPreference(createSeekBarPreference(
-                    "Slop multiplier (applied to edge slop, "
-                            + "which is generally already 50% higher than touch slop)",
-                    25, 200, 100, LPNH_SLOP_PERCENTAGE));
-            category.addPreference(createSeekBarPreference(
-                    "Extra width DP (how far outside the sides of the nav bar to trigger)",
-                    // Stashed taskbar is currently 220dp; -86 (x2) would result in 48dp touch area.
-                    -86, 100, 1, LPNH_EXTRA_TOUCH_WIDTH_DP));
-            category.addPreference(createSeekBarPreference("LPNH timeout",
-                    100, 500, 1, LPNH_TIMEOUT_MS));
-        }
-        if (FeatureFlags.ENABLE_SEARCH_HAPTIC_HINT.get()) {
-            category.addPreference(
-                    createSeekBarPreference("Haptic hint start scale",
-                            0, 100, 100, LPNH_HAPTIC_HINT_START_SCALE_PERCENT));
-            category.addPreference(createSeekBarPreference("Haptic hint end scale",
-                    0, 100, 100, LPNH_HAPTIC_HINT_END_SCALE_PERCENT));
-            category.addPreference(
-                    createSeekBarPreference("Haptic hint scale exponent",
-                            1, 5, 1, LPNH_HAPTIC_HINT_SCALE_EXPONENT));
-            category.addPreference(
-                    createSeekBarPreference("Haptic hint iterations (12 ms each)",
-                            0, 200, 1, LPNH_HAPTIC_HINT_ITERATIONS));
-            category.addPreference(createSeekBarPreference("Haptic hint delay (ms)",
-                    0, 400, 1, LPNH_HAPTIC_HINT_DELAY));
-        }
-    }
-
-    private void addCustomPrivateAppsCategory() {
-        PreferenceCategory category = newCategory("Apps in Private Space Config");
-        category.addPreference(createSeekBarPreference(
-                "Number of Apps to put in private region", 0, 100, 1, PRIVATE_SPACE_APPS));
-    }
-
-    private SeekBarPreference createSeekBarPreference(String title, int min,
-            int max, int scale, FeatureFlags.IntFlag flag) {
-        if (!(flag instanceof IntDebugFlag)) {
-            Log.e(TAG, "Cannot create seekbar preference with IntFlag. Use a launcher preference "
-                    + "flag or pref-backed IntDebugFlag instead");
-            return null;
-        }
-        IntDebugFlag debugflag = (IntDebugFlag) flag;
-        if (debugflag.launcherPrefFlag == null) {
-            Log.e(TAG, "Cannot create seekbar preference with IntDebugFlag. Use a launcher "
-                    + "preference flag or pref-backed IntDebugFlag instead");
-            return null;
-        }
-        SeekBarPreference seekBarPref = createSeekBarPreference(title, min, max, scale,
-                debugflag.launcherPrefFlag);
-        int value = flag.get();
-        seekBarPref.setValue(value);
-        // For some reason the initial value is not triggering the summary update, so call manually.
-        seekBarPref.setSummary(String.valueOf(scale == 1 ? value
-                : value / (float) scale));
-        return seekBarPref;
-    }
-
-    /**
-     * Create a preference with text and a seek bar. Should be added to a PreferenceCategory.
-     *
-     * @param title text to show for this seek bar
-     * @param min min value for the seek bar
-     * @param max max value for the seek bar
-     * @param scale how much to divide the value to convert int to float
-     * @param launcherPref used to store the current value
-     */
-    private SeekBarPreference createSeekBarPreference(String title, int min, int max, int scale,
-            ConstantItem<Integer> launcherPref) {
-        SeekBarPreference seekBarPref = new SeekBarPreference(getContext());
-        seekBarPref.setTitle(title);
-        seekBarPref.setSingleLineTitle(false);
-
-        seekBarPref.setMax(max);
-        seekBarPref.setMin(min);
-        seekBarPref.setUpdatesContinuously(true);
-        seekBarPref.setIconSpaceReserved(false);
-        // Don't directly save to shared prefs, use LauncherPrefs instead.
-        seekBarPref.setPersistent(false);
-        seekBarPref.setOnPreferenceChangeListener((preference, newValue) -> {
-            LauncherPrefs.get(getContext()).put(launcherPref, newValue);
-            preference.setSummary(String.valueOf(scale == 1 ? newValue
-                    : (int) newValue / (float) scale));
-            mFlagTogglerPrefUi.updateMenu();
-            return true;
-        });
-        int value = LauncherPrefs.get(getContext()).get(launcherPref);
-        seekBarPref.setValue(value);
-        // For some reason the initial value is not triggering the summary update, so call manually.
-        seekBarPref.setSummary(String.valueOf(scale == 1 ? value
-                : value / (float) scale));
-        return seekBarPref;
-    }
-
     private String toName(String action) {
         String str = action.replace("com.android.systemui.action.PLUGIN_", "")
                 .replace("com.android.launcher3.action.PLUGIN_", "");
+
         StringBuilder b = new StringBuilder();
         for (String s : str.split("_")) {
             if (b.length() != 0) {
@@ -466,11 +340,11 @@
     private static class PluginPreference extends SwitchPreference {
         private final String mPackageName;
         private final ResolveInfo mSettingsInfo;
-        private final PreferenceDataStore mPluginEnabler;
+        private final PluginEnabler mPluginEnabler;
         private final List<ComponentName> mComponentNames;
 
         PluginPreference(Context prefContext, ResolveInfo pluginInfo,
-                PreferenceDataStore pluginEnabler, List<ComponentName> componentNames) {
+                PluginEnabler pluginEnabler, List<ComponentName> componentNames) {
             super(prefContext);
             PackageManager pm = prefContext.getPackageManager();
             mPackageName = pluginInfo.serviceInfo.applicationInfo.packageName;
@@ -495,14 +369,9 @@
             setWidgetLayoutResource(R.layout.switch_preference_with_settings);
         }
 
-        private boolean isEnabled(ComponentName cn) {
-            return mPluginEnabler.getBoolean(pluginEnabledKey(cn), true);
-
-        }
-
         private boolean isPluginEnabled() {
             for (ComponentName componentName : mComponentNames) {
-                if (!isEnabled(componentName)) {
+                if (!mPluginEnabler.isEnabled(componentName)) {
                     return false;
                 }
             }
@@ -513,8 +382,9 @@
         protected boolean persistBoolean(boolean isEnabled) {
             boolean shouldSendBroadcast = false;
             for (ComponentName componentName : mComponentNames) {
-                if (isEnabled(componentName) != isEnabled) {
-                    mPluginEnabler.putBoolean(pluginEnabledKey(componentName), isEnabled);
+                if (mPluginEnabler.isEnabled(componentName) != isEnabled) {
+                    mPluginEnabler.setDisabled(componentName,
+                            isEnabled ? PluginEnabler.ENABLED : PluginEnabler.DISABLED_MANUALLY);
                     shouldSendBroadcast = true;
                 }
             }
diff --git a/quickstep/src/com/android/launcher3/uioverrides/flags/DeviceFlag.java b/quickstep/src/com/android/launcher3/uioverrides/flags/DeviceFlag.java
deleted file mode 100644
index 915f4ae..0000000
--- a/quickstep/src/com/android/launcher3/uioverrides/flags/DeviceFlag.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.launcher3.uioverrides.flags;
-
-import com.android.launcher3.config.FeatureFlags.FlagState;
-
-class DeviceFlag extends DebugFlag {
-
-    private final boolean mDefaultValueInCode;
-
-    DeviceFlag(String key, String description, FlagState defaultValue,
-            boolean currentValue, boolean defaultValueInCode) {
-        super(key, description, defaultValue, currentValue);
-        mDefaultValueInCode = defaultValueInCode;
-    }
-
-    @Override
-    boolean currentValueModified() {
-        return super.currentValueModified() || mDefaultValueInCode != get();
-    }
-
-    @Override
-    public String toString() {
-        return super.toString() + ", mDefaultValueInCode=" + mDefaultValueInCode;
-    }
-}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/flags/FlagTogglerPrefUi.java b/quickstep/src/com/android/launcher3/uioverrides/flags/FlagTogglerPrefUi.java
deleted file mode 100644
index 4326c67..0000000
--- a/quickstep/src/com/android/launcher3/uioverrides/flags/FlagTogglerPrefUi.java
+++ /dev/null
@@ -1,183 +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.uioverrides.flags;
-
-import static com.android.launcher3.config.FeatureFlags.FlagState.TEAMFOOD;
-import static com.android.launcher3.uioverrides.flags.FlagsFactory.TEAMFOOD_FLAG;
-
-import android.app.Activity;
-import android.content.Context;
-import android.os.Handler;
-import android.os.Process;
-import android.text.Html;
-import android.text.TextUtils;
-import android.util.Log;
-import android.view.View;
-import android.widget.Toast;
-
-import androidx.preference.PreferenceDataStore;
-import androidx.preference.PreferenceGroup;
-import androidx.preference.PreferenceViewHolder;
-import androidx.preference.SwitchPreference;
-
-import com.android.launcher3.LauncherPrefs;
-import com.android.launcher3.config.FeatureFlags;
-import com.android.launcher3.util.ActivityLifecycleCallbacksAdapter;
-
-import java.util.List;
-import java.util.Set;
-
-/**
- * Dev-build only UI allowing developers to toggle flag settings. See {@link FeatureFlags}.
- */
-public final class FlagTogglerPrefUi implements ActivityLifecycleCallbacksAdapter {
-
-    private static final String TAG = "FlagTogglerPrefFrag";
-
-    private final View mFlagsApplyButton;
-    private final Context mContext;
-
-    private final PreferenceDataStore mDataStore = new PreferenceDataStore() {
-
-        @Override
-        public void putBoolean(String key, boolean value) {
-            FlagsFactory.getSharedPreferences().edit().putBoolean(key, value).apply();
-            updateMenu();
-        }
-
-        @Override
-        public boolean getBoolean(String key, boolean defaultValue) {
-            return FlagsFactory.getSharedPreferences().getBoolean(key, defaultValue);
-        }
-    };
-
-    public FlagTogglerPrefUi(Activity activity, View flagsApplyButton) {
-        mFlagsApplyButton = flagsApplyButton;
-        mContext = mFlagsApplyButton.getContext();
-        activity.registerActivityLifecycleCallbacks(this);
-
-        mFlagsApplyButton.setOnClickListener(v -> {
-            FlagsFactory.getSharedPreferences().edit().commit();
-            Log.e(TAG,
-                    "Killing launcher process " + Process.myPid() + " to apply new flag values");
-            System.exit(0);
-        });
-    }
-
-    public void applyTo(PreferenceGroup parent) {
-        Set<String> modifiedPrefs = FlagsFactory.getSharedPreferences().getAll().keySet();
-        List<DebugFlag> flags = FlagsFactory.getDebugFlags();
-        flags.sort((f1, f2) -> {
-            // Sort first by any prefs that the user has changed, then alphabetically.
-            int changeComparison = Boolean.compare(
-                    modifiedPrefs.contains(f2.key), modifiedPrefs.contains(f1.key));
-            return changeComparison != 0
-                    ? changeComparison
-                    : f1.key.compareToIgnoreCase(f2.key);
-        });
-
-        // Ensure that teamfood flag comes on the top
-        if (flags.remove(TEAMFOOD_FLAG)) {
-            flags.add(0, (DebugFlag) TEAMFOOD_FLAG);
-        }
-
-        // For flag overrides we only want to store when the engineer chose to override the
-        // flag with a different value than the default. That way, when we flip flags in
-        // future, engineers will pick up the new value immediately. To accomplish this, we use a
-        // custom preference data store.
-        for (DebugFlag flag : flags) {
-            SwitchPreference switchPreference = new SwitchPreference(mContext) {
-                @Override
-                public void onBindViewHolder(PreferenceViewHolder holder) {
-                    super.onBindViewHolder(holder);
-                    holder.itemView.setOnLongClickListener(v -> {
-                        FlagsFactory.getSharedPreferences().edit().remove(flag.key).apply();
-                        setChecked(getFlagStateFromSharedPrefs(flag));
-                        updateSummary(this, flag);
-                        updateMenu();
-                        return true;
-                    });
-                }
-            };
-            switchPreference.setKey(flag.key);
-            switchPreference.setDefaultValue(FlagsFactory.getEnabledValue(flag.defaultValue));
-            switchPreference.setChecked(getFlagStateFromSharedPrefs(flag));
-            switchPreference.setTitle(flag.key);
-            updateSummary(switchPreference, flag);
-            switchPreference.setPreferenceDataStore(mDataStore);
-            switchPreference.setOnPreferenceChangeListener((p, v) -> {
-                new Handler().post(() -> updateSummary(switchPreference, flag));
-                return true;
-            });
-
-
-            parent.addPreference(switchPreference);
-        }
-        updateMenu();
-    }
-
-    /**
-     * Updates the summary to show the description and whether the flag overrides the default value.
-     */
-    private void updateSummary(SwitchPreference switchPreference, DebugFlag flag) {
-        String summary = flag.defaultValue == TEAMFOOD
-                ? "<font color='blue'><b>[TEAMFOOD]</b> </font>" : "";
-        if (FlagsFactory.getSharedPreferences().contains(flag.key)) {
-            summary += "<font color='red'><b>[OVERRIDDEN]</b> </font>";
-        }
-        if (!TextUtils.isEmpty(summary)) {
-            summary += "<br>";
-        }
-        switchPreference.setSummary(Html.fromHtml(summary + flag.description));
-    }
-
-    public void updateMenu() {
-        mFlagsApplyButton.setVisibility(anyChanged() ? View.VISIBLE : View.INVISIBLE);
-    }
-
-    @Override
-    public void onActivityStopped(Activity activity) {
-        if (anyChanged()) {
-            Toast.makeText(mContext, "Flag won't be applied until you restart launcher",
-                    Toast.LENGTH_LONG).show();
-        }
-    }
-
-    private boolean getFlagStateFromSharedPrefs(DebugFlag flag) {
-        boolean defaultValue = FlagsFactory.getEnabledValue(flag.defaultValue);
-        return mDataStore.getBoolean(flag.key, defaultValue);
-    }
-
-    private int getIntFlagStateFromSharedPrefs(IntDebugFlag flag) {
-        LauncherPrefs prefs = LauncherPrefs.get(mContext);
-        return flag.launcherPrefFlag == null ? flag.get() : prefs.get(flag.launcherPrefFlag);
-    }
-
-    private boolean anyChanged() {
-        for (DebugFlag flag : FlagsFactory.getDebugFlags()) {
-            if (getFlagStateFromSharedPrefs(flag) != flag.get()) {
-                return true;
-            }
-        }
-        for (IntDebugFlag flag : FlagsFactory.getIntDebugFlags()) {
-            if (getIntFlagStateFromSharedPrefs(flag) != flag.get()) {
-                return true;
-            }
-        }
-        return false;
-    }
-}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/flags/FlagsFactory.java b/quickstep/src/com/android/launcher3/uioverrides/flags/FlagsFactory.java
deleted file mode 100644
index 686ed64..0000000
--- a/quickstep/src/com/android/launcher3/uioverrides/flags/FlagsFactory.java
+++ /dev/null
@@ -1,256 +0,0 @@
-/*
- * Copyright (C) 2023 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.uioverrides.flags;
-
-import static android.app.ActivityThread.currentApplication;
-
-import static com.android.launcher3.BuildConfig.IS_DEBUG_DEVICE;
-import static com.android.launcher3.config.FeatureFlags.FlagState.DISABLED;
-import static com.android.launcher3.config.FeatureFlags.FlagState.ENABLED;
-import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
-
-import static java.util.Collections.unmodifiableList;
-
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.provider.DeviceConfig;
-import android.provider.DeviceConfig.Properties;
-import android.util.Log;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-import com.android.launcher3.ConstantItem;
-import com.android.launcher3.LauncherPrefs;
-import com.android.launcher3.config.FeatureFlags.BooleanFlag;
-import com.android.launcher3.config.FeatureFlags.FlagState;
-import com.android.launcher3.config.FeatureFlags.IntFlag;
-import com.android.launcher3.util.ScreenOnTracker;
-
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-/**
- * Helper class to create various flags for system build
- */
-public class FlagsFactory {
-
-    private static final String TAG = "FlagsFactory";
-
-    private static final FlagsFactory INSTANCE = new FlagsFactory();
-    private static final boolean FLAG_AUTO_APPLY_ENABLED = true;
-
-    private static final String FLAGS_PREF_NAME = "featureFlags";
-    public static final String NAMESPACE_LAUNCHER = "launcher";
-
-    private static final List<DebugFlag> sDebugFlags = new ArrayList<>();
-    private static final List<IntDebugFlag> sIntDebugFlags = new ArrayList<>();
-    private static SharedPreferences sSharedPreferences;
-
-    static final BooleanFlag TEAMFOOD_FLAG = getReleaseFlag(
-            0, "LAUNCHER_TEAMFOOD", DISABLED, "Enable this flag to opt-in all team food flags");
-
-    private final Set<String> mKeySet = new HashSet<>();
-    private boolean mRestartRequested = false;
-
-    private FlagsFactory() {
-        if (!FLAG_AUTO_APPLY_ENABLED) {
-            return;
-        }
-        DeviceConfig.addOnPropertiesChangedListener(
-                NAMESPACE_LAUNCHER, UI_HELPER_EXECUTOR, this::onPropertiesChanged);
-    }
-
-    static boolean getEnabledValue(FlagState flagState) {
-        if (IS_DEBUG_DEVICE) {
-            switch (flagState) {
-                case ENABLED:
-                    return true;
-                case TEAMFOOD:
-                    return TEAMFOOD_FLAG.get();
-                default:
-                    return false;
-            }
-        } else {
-            return flagState == ENABLED;
-        }
-    }
-
-    /**
-     * Creates a new debug flag. Debug flags always take their default value in release builds. On
-     * dogfood builds, they can be manually turned on using the flag toggle UI.
-     */
-    public static BooleanFlag getDebugFlag(
-            int bugId, String key, FlagState flagState, String description) {
-        if (IS_DEBUG_DEVICE) {
-            boolean defaultValue = getEnabledValue(flagState);
-            boolean currentValue = getSharedPreferences().getBoolean(key, defaultValue);
-            DebugFlag flag = new DebugFlag(key, description, flagState, currentValue);
-            sDebugFlags.add(flag);
-            return flag;
-        } else {
-            return new BooleanFlag(getEnabledValue(flagState));
-        }
-    }
-
-    /**
-     * Creates a new release flag. Release flags can be rolled out using server configurations and
-     * also allow manual overrides on debug builds.
-     */
-    public static BooleanFlag getReleaseFlag(
-            int bugId, String key, FlagState flagState, String description) {
-        INSTANCE.mKeySet.add(key);
-        boolean defaultValueInCode = getEnabledValue(flagState);
-        boolean defaultValue = DeviceConfig.getBoolean(NAMESPACE_LAUNCHER, key, defaultValueInCode);
-        if (IS_DEBUG_DEVICE) {
-            boolean currentValue = getSharedPreferences().getBoolean(key, defaultValue);
-            DebugFlag flag = new DeviceFlag(key, description,
-                    (defaultValue == defaultValueInCode) ? flagState
-                            : defaultValue ? ENABLED : DISABLED, currentValue, defaultValueInCode);
-            sDebugFlags.add(flag);
-            return flag;
-        } else {
-            return new BooleanFlag(defaultValue);
-        }
-    }
-
-    /**
-     * Creates a new integer flag. Integer flags are always release flags
-     */
-    public static IntFlag getIntFlag(
-            int bugId, String key, int defaultValueInCode, String description) {
-        return getIntFlag(bugId, key, defaultValueInCode, description, null);
-    }
-
-    /**
-     * Creates a new integer flag.
-     *
-     * @param launcherPrefFlag Set launcherPrefFlag to non-null if you want
-     * to modify the int flag in Launcher Developer Options and IntDebugFlag
-     * will be backed up by LauncherPrefs. Modified int value will be saved
-     * in LauncherPrefs.
-     */
-    public static IntFlag getIntFlag(
-            int bugId, String key, int defaultValueInCode, String description,
-            @Nullable ConstantItem<Integer> launcherPrefFlag) {
-        INSTANCE.mKeySet.add(key);
-        int defaultValue = DeviceConfig.getInt(NAMESPACE_LAUNCHER, key, defaultValueInCode);
-        if (IS_DEBUG_DEVICE) {
-            int currentValue;
-            if (launcherPrefFlag == null) {
-                currentValue = defaultValue;
-            } else {
-                currentValue = LauncherPrefs.get(currentApplication()).get(launcherPrefFlag);
-            }
-            IntDebugFlag flag = new IntDebugFlag(key, currentValue, defaultValueInCode,
-                    launcherPrefFlag);
-            sIntDebugFlags.add(flag);
-            return flag;
-        } else {
-            return new IntFlag(defaultValue);
-        }
-    }
-
-    static List<DebugFlag> getDebugFlags() {
-        if (!IS_DEBUG_DEVICE) {
-            return Collections.emptyList();
-        }
-        synchronized (sDebugFlags) {
-            return new ArrayList<>(sDebugFlags);
-        }
-    }
-
-    static List<IntDebugFlag> getIntDebugFlags() {
-        if (!IS_DEBUG_DEVICE) {
-            return unmodifiableList(Collections.emptyList());
-        }
-        synchronized (sIntDebugFlags) {
-            return unmodifiableList(sIntDebugFlags);
-        }
-    }
-
-    /** Returns the SharedPreferences instance backing Debug FeatureFlags. */
-    @NonNull
-    static SharedPreferences getSharedPreferences() {
-        if (sSharedPreferences == null) {
-            sSharedPreferences = currentApplication()
-                    .createDeviceProtectedStorageContext()
-                    .getSharedPreferences(FLAGS_PREF_NAME, Context.MODE_PRIVATE);
-        }
-        return sSharedPreferences;
-    }
-
-    /**
-     * Dumps the current flags state to the print writer
-     */
-    public static void dump(PrintWriter pw) {
-        if (!IS_DEBUG_DEVICE) {
-            return;
-        }
-        pw.println("DeviceFlags:");
-        pw.println("  BooleanFlags:");
-        synchronized (sDebugFlags) {
-            for (DebugFlag flag : sDebugFlags) {
-                if (flag instanceof DeviceFlag) {
-                    pw.println((flag.currentValueModified() ? "  ->" : "    ") + flag);
-                }
-            }
-        }
-        pw.println("  IntFlags:");
-        synchronized (sIntDebugFlags) {
-            for (IntFlag flag : sIntDebugFlags) {
-                pw.println("    " + flag);
-            }
-        }
-        pw.println("  DebugFlags:");
-        synchronized (sDebugFlags) {
-            for (DebugFlag flag : sDebugFlags) {
-                if (!(flag instanceof DeviceFlag)) {
-                    pw.println((flag.currentValueModified() ? "  ->" : "    ") + flag);
-                }
-            }
-        }
-    }
-
-    private void onPropertiesChanged(Properties properties) {
-        if (!Collections.disjoint(properties.getKeyset(), mKeySet)) {
-            // Schedule a restart
-            if (mRestartRequested) {
-                return;
-            }
-            Log.e(TAG, "Flag changed, scheduling restart");
-            mRestartRequested = true;
-            ScreenOnTracker sot = ScreenOnTracker.INSTANCE.get(currentApplication());
-            if (sot.isScreenOn()) {
-                sot.addListener(this::onScreenOnChanged);
-            } else {
-                onScreenOnChanged(false);
-            }
-        }
-    }
-
-    private void onScreenOnChanged(boolean isOn) {
-        if (mRestartRequested && !isOn) {
-            Log.e(TAG, "Restart requested, killing process");
-            System.exit(0);
-        }
-    }
-}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/flags/IntDebugFlag.java b/quickstep/src/com/android/launcher3/uioverrides/flags/IntDebugFlag.java
deleted file mode 100644
index 1350aa8..0000000
--- a/quickstep/src/com/android/launcher3/uioverrides/flags/IntDebugFlag.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2023 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.uioverrides.flags;
-
-import androidx.annotation.Nullable;
-
-import com.android.launcher3.ConstantItem;
-import com.android.launcher3.config.FeatureFlags.IntFlag;
-
-public class IntDebugFlag extends IntFlag {
-    public final String key;
-    private final int mDefaultValueInCode;
-    @Nullable
-    public final ConstantItem<Integer> launcherPrefFlag;
-
-    public IntDebugFlag(String key, int currentValue, int defaultValueInCode,
-            @Nullable ConstantItem<Integer> launcherPrefFlag) {
-        super(currentValue);
-        this.key = key;
-        mDefaultValueInCode = defaultValueInCode;
-        this.launcherPrefFlag = launcherPrefFlag;
-    }
-
-    @Override
-    public String toString() {
-        return key + ": mCurrentValue=" + get() + ", defaultValueInCode=" + mDefaultValueInCode;
-    }
-}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/plugins/PluginEnablerImpl.java b/quickstep/src/com/android/launcher3/uioverrides/plugins/PluginEnablerImpl.java
index faa900b..4e09f1f 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/plugins/PluginEnablerImpl.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/plugins/PluginEnablerImpl.java
@@ -18,12 +18,10 @@
 import android.content.Context;
 import android.content.SharedPreferences;
 
-import androidx.preference.PreferenceDataStore;
-
 import com.android.launcher3.LauncherPrefs;
 import com.android.systemui.shared.plugins.PluginEnabler;
 
-public class PluginEnablerImpl extends PreferenceDataStore implements PluginEnabler {
+public class PluginEnablerImpl implements PluginEnabler {
 
     private static final String PREFIX_PLUGIN_ENABLED = "PLUGIN_ENABLED_";
 
@@ -44,12 +42,12 @@
     }
 
     private void setState(ComponentName component, boolean enabled) {
-        putBoolean(pluginEnabledKey(component), enabled);
+        mSharedPrefs.edit().putBoolean(pluginEnabledKey(component), enabled).apply();
     }
 
     @Override
     public boolean isEnabled(ComponentName component) {
-        return getBoolean(pluginEnabledKey(component), true);
+        return mSharedPrefs.getBoolean(pluginEnabledKey(component), true);
     }
 
     @Override
@@ -57,17 +55,7 @@
         return isEnabled(componentName) ? ENABLED : DISABLED_MANUALLY;
     }
 
-    @Override
-    public void putBoolean(String key, boolean value) {
-        mSharedPrefs.edit().putBoolean(key, value).apply();
-    }
-
-    @Override
-    public boolean getBoolean(String key, boolean defValue) {
-        return mSharedPrefs.getBoolean(key, defValue);
-    }
-
-    static String pluginEnabledKey(ComponentName cn) {
+    private static String pluginEnabledKey(ComponentName cn) {
         return PREFIX_PLUGIN_ENABLED + cn.flattenToString();
     }
 }
diff --git a/quickstep/src/com/android/launcher3/uioverrides/plugins/PluginManagerWrapper.java b/quickstep/src/com/android/launcher3/uioverrides/plugins/PluginManagerWrapper.java
index 7f78713..a09d0a1 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/plugins/PluginManagerWrapper.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/plugins/PluginManagerWrapper.java
@@ -98,13 +98,6 @@
         return new PluginPrefs(mContext).getPluginList();
     }
 
-    /**
-     * Returns the string key used to store plugin enabled/disabled setting
-     */
-    public static String pluginEnabledKey(ComponentName cn) {
-        return PluginEnablerImpl.pluginEnabledKey(cn);
-    }
-
     public static boolean hasPlugins(Context context) {
         return PluginPrefs.hasPlugins(context);
     }
diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java b/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java
index 7875dae..2625919 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java
@@ -68,10 +68,13 @@
     @Override
     public void onBackInvoked(Launcher launcher) {
         // In predictive back swipe, onBackInvoked() will be called after onBackStarted().
-        // Because the 2nd InteractionJankMonitor.begin() will be ignore within timeout, it's safe
-        // to call InteractionJankMonitorWrapper.begin here.
-        InteractionJankMonitorWrapper.begin(launcher.getAppsView(),
-                Cuj.CUJ_LAUNCHER_CLOSE_ALL_APPS_BACK);
+        // In 3 button mode, onBackStarted() is not called but onBackInvoked() will be called.
+        // Thus In onBackInvoked(), we should only begin instrumenting if we didn't call
+        // onBackStarted() to start instrumenting CUJ_LAUNCHER_CLOSE_ALL_APPS_BACK.
+        if (!InteractionJankMonitorWrapper.isInstrumenting(Cuj.CUJ_LAUNCHER_CLOSE_ALL_APPS_BACK)) {
+            InteractionJankMonitorWrapper.begin(
+                    launcher.getAppsView(), Cuj.CUJ_LAUNCHER_CLOSE_ALL_APPS_BACK);
+        }
         super.onBackInvoked(launcher);
     }
 
diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java b/quickstep/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java
index a443c00..7fa121d 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java
@@ -18,12 +18,10 @@
 import static com.android.launcher3.Flags.enableScalingRevealHomeAnimation;
 import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_BACKGROUND;
 import static com.android.quickstep.TaskAnimationManager.ENABLE_SHELL_TRANSITIONS;
-import static com.android.window.flags.Flags.enableDesktopWindowingMode;
 
 import android.content.Context;
 import android.graphics.Color;
 
-import com.android.launcher3.BaseDraggingActivity;
 import com.android.launcher3.DeviceProfile;
 import com.android.launcher3.Launcher;
 import com.android.launcher3.allapps.AllAppsTransitionController;
@@ -64,7 +62,7 @@
 
     @Override
     public float[] getOverviewScaleAndOffset(Launcher launcher) {
-        return getOverviewScaleAndOffsetForBackgroundState(launcher);
+        return getOverviewScaleAndOffsetForBackgroundState(launcher.getOverviewPanel());
     }
 
     @Override
@@ -92,9 +90,8 @@
 
     @Override
     protected float getDepthUnchecked(Context context) {
-        if (enableDesktopWindowingMode()
-                && Launcher.getLauncher(context).areFreeformTasksVisible()) {
-            // Don't blur the background while freeform tasks are visible
+        if (Launcher.getLauncher(context).areDesktopTasksVisible()) {
+            // Don't blur the background while desktop tasks are visible
             return BaseDepthController.DEPTH_0_PERCENT;
         } else if (enableScalingRevealHomeAnimation()) {
             return BaseDepthController.DEPTH_70_PERCENT;
@@ -127,9 +124,7 @@
     }
 
     public static float[] getOverviewScaleAndOffsetForBackgroundState(
-            BaseDraggingActivity activity) {
-        return new float[] {
-                ((RecentsView) activity.getOverviewPanel()).getMaxScaleForFullScreen(),
-                NO_OFFSET};
+            RecentsView recentsView) {
+        return new float[] {recentsView.getMaxScaleForFullScreen(), NO_OFFSET};
     }
 }
diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/OverviewModalTaskState.java b/quickstep/src/com/android/launcher3/uioverrides/states/OverviewModalTaskState.java
index c63eaeb..3c291e6 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/states/OverviewModalTaskState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/states/OverviewModalTaskState.java
@@ -20,7 +20,6 @@
 import android.content.Context;
 import android.graphics.Rect;
 
-import com.android.launcher3.BaseDraggingActivity;
 import com.android.launcher3.Flags;
 import com.android.launcher3.Launcher;
 import com.android.launcher3.LauncherState;
@@ -51,7 +50,7 @@
 
     @Override
     public float[] getOverviewScaleAndOffset(Launcher launcher) {
-        return getOverviewScaleAndOffsetForModalState(launcher);
+        return getOverviewScaleAndOffsetForModalState(launcher.getOverviewPanel());
     }
 
     @Override
@@ -72,8 +71,7 @@
         return super.isTaskbarStashed(launcher);
     }
 
-    public static float[] getOverviewScaleAndOffsetForModalState(BaseDraggingActivity activity) {
-        RecentsView recentsView = activity.<RecentsView>getOverviewPanel();
+    public static float[] getOverviewScaleAndOffsetForModalState(RecentsView recentsView) {
         Rect taskSize = recentsView.getSelectedTaskBounds();
         Rect modalTaskSize = new Rect();
         recentsView.getModalTaskSize(modalTaskSize);
diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/QuickSwitchState.java b/quickstep/src/com/android/launcher3/uioverrides/states/QuickSwitchState.java
index 2587395..dfad409 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/states/QuickSwitchState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/states/QuickSwitchState.java
@@ -16,7 +16,6 @@
 package com.android.launcher3.uioverrides.states;
 
 import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_BACKGROUND;
-import static com.android.window.flags.Flags.enableDesktopWindowingMode;
 
 import android.graphics.Color;
 
@@ -46,11 +45,9 @@
 
     @Override
     public int getWorkspaceScrimColor(Launcher launcher) {
-        if (enableDesktopWindowingMode()) {
-            if (launcher.areFreeformTasksVisible()) {
-                // No scrim while freeform tasks are visible
-                return Color.TRANSPARENT;
-            }
+        if (launcher.areDesktopTasksVisible()) {
+            // No scrim while desktop tasks are visible
+            return Color.TRANSPARENT;
         }
         DeviceProfile dp = launcher.getDeviceProfile();
         if (dp.isTaskbarPresentInApps) {
diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/QuickstepAtomicAnimationFactory.java b/quickstep/src/com/android/launcher3/uioverrides/states/QuickstepAtomicAnimationFactory.java
index b401868..0368f3a 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/states/QuickstepAtomicAnimationFactory.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/states/QuickstepAtomicAnimationFactory.java
@@ -94,7 +94,7 @@
     @Override
     public void prepareForAtomicAnimation(LauncherState fromState, LauncherState toState,
             StateAnimationConfig config) {
-        RecentsView overview = mActivity.getOverviewPanel();
+        RecentsView overview = mContainer.getOverviewPanel();
         if ((fromState == OVERVIEW || fromState == OVERVIEW_SPLIT_SELECT) && toState == NORMAL) {
             overview.switchToScreenshot(() ->
                     overview.finishRecentsAnimation(true /* toRecents */, null));
@@ -118,7 +118,7 @@
             config.setInterpolator(ANIM_WORKSPACE_SCALE, DECELERATE);
             config.setInterpolator(ANIM_WORKSPACE_FADE, ACCELERATE);
 
-            if (DisplayController.getNavigationMode(mActivity).hasGestures
+            if (DisplayController.getNavigationMode(mContainer).hasGestures
                     && overview.getTaskViewCount() > 0) {
                 // Overview is going offscreen, so keep it at its current scale and opacity.
                 config.setInterpolator(ANIM_OVERVIEW_SCALE, FINAL_FRAME);
@@ -136,7 +136,7 @@
                 config.duration = Math.max(config.duration, scrollDuration);
 
                 // Sync scroll so that it ends before or at the same time as the taskbar animation.
-                if (mActivity.getDeviceProfile().isTaskbarPresent) {
+                if (mContainer.getDeviceProfile().isTaskbarPresent) {
                     config.duration = Math.min(
                             config.duration, QuickstepTransitionManager.getTaskbarToHomeDuration());
                 }
@@ -147,7 +147,7 @@
                 config.setInterpolator(ANIM_OVERVIEW_FADE, DECELERATE_1_7);
             }
 
-            Workspace<?> workspace = mActivity.getWorkspace();
+            Workspace<?> workspace = mContainer.getWorkspace();
             // Start from a higher workspace scale, but only if we're invisible so we don't jump.
             boolean isWorkspaceVisible = workspace.getVisibility() == VISIBLE;
             if (isWorkspaceVisible) {
@@ -160,7 +160,7 @@
                 workspace.setScaleX(WORKSPACE_PREPARE_SCALE);
                 workspace.setScaleY(WORKSPACE_PREPARE_SCALE);
             }
-            Hotseat hotseat = mActivity.getHotseat();
+            Hotseat hotseat = mContainer.getHotseat();
             boolean isHotseatVisible = hotseat.getVisibility() == VISIBLE && hotseat.getAlpha() > 0;
             if (!isHotseatVisible) {
                 hotseat.setScaleX(WORKSPACE_PREPARE_SCALE);
@@ -168,7 +168,7 @@
             }
         } else if ((fromState == NORMAL || fromState == HINT_STATE
                 || fromState == HINT_STATE_TWO_BUTTON) && toState == OVERVIEW) {
-            if (DisplayController.getNavigationMode(mActivity).hasGestures) {
+            if (DisplayController.getNavigationMode(mContainer).hasGestures) {
                 config.setInterpolator(ANIM_WORKSPACE_SCALE,
                         fromState == NORMAL ? ACCELERATE : OVERSHOOT_1_2);
                 config.setInterpolator(ANIM_WORKSPACE_TRANSLATE, ACCELERATE);
@@ -201,18 +201,18 @@
         } else if (fromState == HINT_STATE && toState == NORMAL) {
             config.setInterpolator(ANIM_DEPTH, DECELERATE_3);
             if (mHintToNormalDuration == -1) {
-                ValueAnimator va = getWorkspaceSpringScaleAnimator(mActivity,
-                        mActivity.getWorkspace(),
-                        toState.getWorkspaceScaleAndTranslation(mActivity).scale);
+                ValueAnimator va = getWorkspaceSpringScaleAnimator(mContainer,
+                        mContainer.getWorkspace(),
+                        toState.getWorkspaceScaleAndTranslation(mContainer).scale);
                 mHintToNormalDuration = (int) va.getDuration();
             }
             config.duration = Math.max(config.duration, mHintToNormalDuration);
         } else if (fromState == ALL_APPS && toState == NORMAL) {
-            AllAppsSwipeController.applyAllAppsToNormalConfig(mActivity, config);
+            AllAppsSwipeController.applyAllAppsToNormalConfig(mContainer, config);
         } else if (fromState == NORMAL && toState == ALL_APPS) {
-            AllAppsSwipeController.applyNormalToAllAppsAnimConfig(mActivity, config);
+            AllAppsSwipeController.applyNormalToAllAppsAnimConfig(mContainer, config);
         } else if (fromState == OVERVIEW && toState == OVERVIEW_SPLIT_SELECT) {
-            SplitAnimationTimings timings = mActivity.getDeviceProfile().isTablet
+            SplitAnimationTimings timings = mContainer.getDeviceProfile().isTablet
                     ? SplitAnimationTimings.TABLET_OVERVIEW_TO_SPLIT
                     : SplitAnimationTimings.PHONE_OVERVIEW_TO_SPLIT;
             config.setInterpolator(ANIM_OVERVIEW_ACTIONS_FADE, clampToProgress(LINEAR,
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java
index e8b5081..615e3e3 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java
@@ -47,6 +47,7 @@
 import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.statemanager.StateManager;
 import com.android.launcher3.touch.SingleAxisSwipeDetector;
+import com.android.launcher3.uioverrides.QuickstepLauncher;
 import com.android.launcher3.util.DisplayController;
 import com.android.launcher3.util.TouchController;
 import com.android.quickstep.TaskUtils;
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java
index 8ef35c0..5a19ed4 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java
@@ -84,7 +84,6 @@
 import com.android.quickstep.util.LayoutUtils;
 import com.android.quickstep.util.MotionPauseDetector;
 import com.android.quickstep.util.WorkspaceRevealAnim;
-import com.android.quickstep.views.LauncherRecentsView;
 import com.android.quickstep.views.RecentsView;
 import com.android.systemui.shared.system.InteractionJankMonitorWrapper;
 
@@ -108,7 +107,7 @@
     private final float mMaxYProgress;
     private final MotionPauseDetector mMotionPauseDetector;
     private final float mMotionPauseMinDisplacement;
-    private final LauncherRecentsView mRecentsView;
+    private final RecentsView mRecentsView;
     protected final AnimatorListener mClearStateOnCancelListener =
             newCancelListener(this::clearState);
 
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java
index de73630..05a55d0 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java
@@ -38,12 +38,12 @@
 
 import android.view.MotionEvent;
 
-import com.android.launcher3.Launcher;
 import com.android.launcher3.LauncherState;
 import com.android.launcher3.Utilities;
 import com.android.launcher3.states.StateAnimationConfig;
 import com.android.launcher3.touch.AbstractStateChangeTouchController;
 import com.android.launcher3.touch.SingleAxisSwipeDetector;
+import com.android.launcher3.uioverrides.QuickstepLauncher;
 import com.android.launcher3.util.DisplayController;
 import com.android.launcher3.util.NavigationMode;
 import com.android.quickstep.SystemUiProxy;
@@ -58,11 +58,12 @@
 
     protected final RecentsView mOverviewPanel;
 
-    public QuickSwitchTouchController(Launcher launcher) {
+    public QuickSwitchTouchController(QuickstepLauncher launcher) {
         this(launcher, SingleAxisSwipeDetector.HORIZONTAL);
     }
 
-    protected QuickSwitchTouchController(Launcher l, SingleAxisSwipeDetector.Direction dir) {
+    protected QuickSwitchTouchController(QuickstepLauncher l,
+            SingleAxisSwipeDetector.Direction dir) {
         super(l, dir);
         mOverviewPanel = l.getOverviewPanel();
     }
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/TaskViewTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/TaskViewTouchController.java
index e9f2d4f..300d697 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/TaskViewTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/TaskViewTouchController.java
@@ -21,6 +21,7 @@
 
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
+import android.content.Context;
 import android.os.VibrationEffect;
 import android.view.MotionEvent;
 import android.view.View;
@@ -28,7 +29,6 @@
 
 import com.android.app.animation.Interpolators;
 import com.android.launcher3.AbstractFloatingView;
-import com.android.launcher3.BaseDraggingActivity;
 import com.android.launcher3.LauncherAnimUtils;
 import com.android.launcher3.R;
 import com.android.launcher3.Utilities;
@@ -44,12 +44,13 @@
 import com.android.quickstep.orientation.RecentsPagedOrientationHandler;
 import com.android.quickstep.util.VibrationConstants;
 import com.android.quickstep.views.RecentsView;
+import com.android.quickstep.views.RecentsViewContainer;
 import com.android.quickstep.views.TaskView;
 
 /**
  * Touch controller for handling task view card swipes
  */
-public abstract class TaskViewTouchController<T extends BaseDraggingActivity>
+public abstract class TaskViewTouchController<CONTAINER extends Context & RecentsViewContainer>
         extends AnimatorListenerAdapter implements TouchController,
         SingleAxisSwipeDetector.Listener {
 
@@ -63,7 +64,7 @@
     public static final VibrationEffect TASK_DISMISS_VIBRATION_FALLBACK =
             VibrationConstants.EFFECT_TEXTURE_TICK;
 
-    protected final T mActivity;
+    protected final CONTAINER mContainer;
     private final SingleAxisSwipeDetector mDetector;
     private final RecentsView mRecentsView;
     private final int[] mTempCords = new int[2];
@@ -87,13 +88,13 @@
 
     private boolean mIsDismissHapticRunning = false;
 
-    public TaskViewTouchController(T activity) {
-        mActivity = activity;
-        mRecentsView = activity.getOverviewPanel();
-        mIsRtl = Utilities.isRtl(activity.getResources());
+    public TaskViewTouchController(CONTAINER container) {
+        mContainer = container;
+        mRecentsView = container.getOverviewPanel();
+        mIsRtl = Utilities.isRtl(container.getResources());
         SingleAxisSwipeDetector.Direction dir =
                 mRecentsView.getPagedOrientationHandler().getUpDownSwipeDirection();
-        mDetector = new SingleAxisSwipeDetector(activity, this, dir);
+        mDetector = new SingleAxisSwipeDetector(container, this, dir);
     }
 
     private boolean canInterceptTouch(MotionEvent ev) {
@@ -113,7 +114,7 @@
             return true;
         }
         if (AbstractFloatingView.getTopOpenViewWithType(
-                mActivity, TYPE_TOUCH_CONTROLLER_NO_INTERCEPT) != null) {
+                mContainer, TYPE_TOUCH_CONTROLLER_NO_INTERCEPT) != null) {
             return false;
         }
         return isRecentsInteractive();
@@ -159,7 +160,7 @@
                 for (int i = 0; i < mRecentsView.getTaskViewCount(); i++) {
                     TaskView view = mRecentsView.getTaskViewAt(i);
 
-                    if (mRecentsView.isTaskViewVisible(view) && mActivity.getDragLayer()
+                    if (mRecentsView.isTaskViewVisible(view) && mContainer.getDragLayer()
                             .isEventOverView(view, ev)) {
                         // Disable swiping up and down if the task overlay is modal.
                         if (isRecentsModal()) {
@@ -179,7 +180,7 @@
                         // - It's the focused task if in grid view
                         // - The task is snapped
                         mAllowGoingDown = i == mRecentsView.getCurrentPage()
-                                && DisplayController.getNavigationMode(mActivity).hasGestures
+                                && DisplayController.getNavigationMode(mContainer).hasGestures
                                 && (!mRecentsView.showAsGrid() || mTaskBeingDragged.isFocusedTask())
                                 && mRecentsView.isTaskInExpectedScrollPosition(i);
 
@@ -228,7 +229,7 @@
         RecentsPagedOrientationHandler orientationHandler =
                 mRecentsView.getPagedOrientationHandler();
         mCurrentAnimationIsGoingUp = goingUp;
-        BaseDragLayer dl = mActivity.getDragLayer();
+        BaseDragLayer dl = mContainer.getDragLayer();
         final int secondaryLayerDimension = orientationHandler.getSecondaryDimension(dl);
         long maxDuration = 2 * secondaryLayerDimension;
         int verticalFactor = orientationHandler.getTaskDragDisplacementFactor(mIsRtl);
@@ -372,10 +373,10 @@
                 MIN_TASK_DISMISS_ANIMATION_DURATION, MAX_TASK_DISMISS_ANIMATION_DURATION);
 
         mCurrentAnimation.setEndAction(this::clearState);
-        mCurrentAnimation.startWithVelocity(mActivity, goingToEnd, Math.abs(velocity),
+        mCurrentAnimation.startWithVelocity(mContainer, goingToEnd, Math.abs(velocity),
                 mEndDisplacement, animationDuration);
         if (goingUp && goingToEnd && !mIsDismissHapticRunning) {
-            VibratorWrapper.INSTANCE.get(mActivity).vibrate(TASK_DISMISS_VIBRATION_PRIMITIVE,
+            VibratorWrapper.INSTANCE.get(mContainer).vibrate(TASK_DISMISS_VIBRATION_PRIMITIVE,
                     TASK_DISMISS_VIBRATION_PRIMITIVE_SCALE, TASK_DISMISS_VIBRATION_FALLBACK);
             mIsDismissHapticRunning = true;
         }
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/TransposedQuickSwitchTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/TransposedQuickSwitchTouchController.java
index 8f9c014..b70cabe 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/TransposedQuickSwitchTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/TransposedQuickSwitchTouchController.java
@@ -15,13 +15,13 @@
  */
 package com.android.launcher3.uioverrides.touchcontrollers;
 
-import com.android.launcher3.Launcher;
 import com.android.launcher3.LauncherState;
 import com.android.launcher3.touch.SingleAxisSwipeDetector;
+import com.android.launcher3.uioverrides.QuickstepLauncher;
 
 public class TransposedQuickSwitchTouchController extends QuickSwitchTouchController {
 
-    public TransposedQuickSwitchTouchController(Launcher launcher) {
+    public TransposedQuickSwitchTouchController(QuickstepLauncher launcher) {
         super(launcher, SingleAxisSwipeDetector.VERTICAL);
     }
 
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/TwoButtonNavbarTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/TwoButtonNavbarTouchController.java
index 9f2c1d4..31c9b3e 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/TwoButtonNavbarTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/TwoButtonNavbarTouchController.java
@@ -27,10 +27,10 @@
 import android.view.MotionEvent;
 
 import com.android.launcher3.AbstractFloatingView;
-import com.android.launcher3.Launcher;
 import com.android.launcher3.LauncherState;
 import com.android.launcher3.touch.AbstractStateChangeTouchController;
 import com.android.launcher3.touch.SingleAxisSwipeDetector;
+import com.android.launcher3.uioverrides.QuickstepLauncher;
 import com.android.quickstep.SystemUiProxy;
 import com.android.quickstep.util.LayoutUtils;
 import com.android.quickstep.views.AllAppsEduView;
@@ -51,7 +51,7 @@
 
     private int mContinuousTouchCount = 0;
 
-    public TwoButtonNavbarTouchController(Launcher l) {
+    public TwoButtonNavbarTouchController(QuickstepLauncher l) {
         super(l, l.getDeviceProfile().isVerticalBarLayout()
                 ? SingleAxisSwipeDetector.HORIZONTAL : SingleAxisSwipeDetector.VERTICAL);
         mIsTransposed = l.getDeviceProfile().isVerticalBarLayout();
diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
index dc1c6a6..cceaf27 100644
--- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
+++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
@@ -22,8 +22,8 @@
 import static android.widget.Toast.LENGTH_SHORT;
 
 import static com.android.app.animation.Interpolators.ACCELERATE_DECELERATE;
-import static com.android.app.animation.Interpolators.EMPHASIZED;
 import static com.android.app.animation.Interpolators.DECELERATE;
+import static com.android.app.animation.Interpolators.EMPHASIZED;
 import static com.android.app.animation.Interpolators.LINEAR;
 import static com.android.app.animation.Interpolators.OVERSHOOT_1_2;
 import static com.android.launcher3.BaseActivity.EVENT_DESTROYED;
@@ -31,7 +31,6 @@
 import static com.android.launcher3.BaseActivity.INVISIBLE_BY_STATE_HANDLER;
 import static com.android.launcher3.BaseActivity.STATE_HANDLER_INVISIBILITY_FLAGS;
 import static com.android.launcher3.Flags.enableGridOnlyOverview;
-import static com.android.launcher3.LauncherPrefs.ALL_APPS_OVERVIEW_THRESHOLD;
 import static com.android.launcher3.PagedView.INVALID_PAGE;
 import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_BACKGROUND;
 import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.IGNORE;
@@ -61,7 +60,6 @@
 import static com.android.quickstep.util.ActiveGestureErrorDetector.GestureEvent.ON_SETTLED_ON_END_TARGET;
 import static com.android.quickstep.views.RecentsView.UPDATE_SYSUI_FLAGS_THRESHOLD;
 import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_RECENTS;
-import static com.android.window.flags.Flags.enableDesktopWindowingMode;
 
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
@@ -101,7 +99,6 @@
 import com.android.internal.util.LatencyTracker;
 import com.android.launcher3.AbstractFloatingView;
 import com.android.launcher3.DeviceProfile;
-import com.android.launcher3.LauncherPrefs;
 import com.android.launcher3.R;
 import com.android.launcher3.Utilities;
 import com.android.launcher3.anim.AnimationSuccessListener;
@@ -111,7 +108,6 @@
 import com.android.launcher3.logging.StatsLogManager.StatsLogger;
 import com.android.launcher3.statehandlers.DesktopVisibilityController;
 import com.android.launcher3.statemanager.BaseState;
-import com.android.launcher3.statemanager.StatefulActivity;
 import com.android.launcher3.taskbar.TaskbarThresholdUtils;
 import com.android.launcher3.taskbar.TaskbarUIController;
 import com.android.launcher3.uioverrides.QuickstepLauncher;
@@ -139,6 +135,7 @@
 import com.android.quickstep.util.TaskViewSimulator;
 import com.android.quickstep.util.TransformParams;
 import com.android.quickstep.views.RecentsView;
+import com.android.quickstep.views.RecentsViewContainer;
 import com.android.quickstep.views.TaskView;
 import com.android.quickstep.views.TaskView.TaskIdAttributeContainer;
 import com.android.systemui.shared.recents.model.Task;
@@ -163,7 +160,7 @@
 /**
  * Handles the navigation gestures when Launcher is the default home activity.
  */
-public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
+public abstract class AbsSwipeUpHandler<T extends RecentsViewContainer,
         Q extends RecentsView, S extends BaseState<S>>
         extends SwipeUpAnimationLogic implements OnApplyWindowInsetsListener,
         RecentsAnimationCallbacks.RecentsAnimationListener {
@@ -174,7 +171,7 @@
     // Fraction of the scroll and transform animation in which the current task fades out
     private static final float KQS_TASK_FADE_ANIMATION_FRACTION = 0.4f;
 
-    protected final BaseActivityInterface<S, T> mActivityInterface;
+    protected final BaseContainerInterface<S, T> mContainerInterface;
     protected final InputConsumerProxy mInputConsumerProxy;
     protected final ActivityInitListener mActivityInitListener;
     // Callbacks to be made once the recents animation starts
@@ -185,7 +182,7 @@
     protected @Nullable RecentsAnimationController mRecentsAnimationController;
     protected @Nullable RecentsAnimationController mDeferredCleanupRecentsAnimationController;
     protected RecentsAnimationTargets mRecentsAnimationTargets;
-    protected @Nullable T mActivity;
+    protected @Nullable T mContainer;
     protected @Nullable Q mRecentsView;
     protected Runnable mGestureEndCallback;
     protected MultiStateCallback mStateCallback;
@@ -195,7 +192,7 @@
     private final Runnable mLauncherOnDestroyCallback = () -> {
         ActiveGestureLog.INSTANCE.addLog("Launcher destroyed", LAUNCHER_DESTROYED);
         mRecentsView = null;
-        mActivity = null;
+        mContainer = null;
         mStateCallback.clearState(STATE_LAUNCHER_PRESENT);
     };
 
@@ -350,8 +347,9 @@
             long touchTimeMs, boolean continuingLastGesture,
             InputConsumerController inputConsumer) {
         super(context, deviceState, gestureState);
-        mActivityInterface = gestureState.getActivityInterface();
-        mActivityInitListener = mActivityInterface.createActivityInitListener(this::onActivityInit);
+        mContainerInterface = gestureState.getContainerInterface();
+        mActivityInitListener =
+                mContainerInterface.createActivityInitListener(this::onActivityInit);
         mInputConsumerProxy =
                 new InputConsumerProxy(context, /* rotationSupplier = */ () -> {
                     if (mRecentsView == null) {
@@ -361,7 +359,7 @@
                 }, inputConsumer, /* onTouchDownCallback = */ () -> {
                     endRunningWindowAnim(mGestureState.getEndTarget() == HOME /* cancel */);
                     endLauncherTransitionController();
-                }, new InputProxyHandlerFactory(mActivityInterface, mGestureState));
+                }, new InputProxyHandlerFactory(mContainerInterface, mGestureState));
         mTaskAnimationManager = taskAnimationManager;
         mTouchTimeMs = touchTimeMs;
         mContinuingLastGesture = continuingLastGesture;
@@ -378,8 +376,8 @@
         initStateCallbacks();
 
         mIsTransientTaskbar = mDp.isTaskbarPresent
-                && DisplayController.isTransientTaskbar(mActivity);
-        TaskbarUIController controller = mActivityInterface.getTaskbarController();
+                && DisplayController.isTransientTaskbar(context);
+        TaskbarUIController controller = mContainerInterface.getTaskbarController();
         mTaskbarAlreadyOpen = controller != null && !controller.isTaskbarStashed();
         mIsTaskbarAllAppsOpen = controller != null && controller.isTaskbarAllAppsOpen();
         mTaskbarAppWindowThreshold =
@@ -476,16 +474,16 @@
             return false;
         }
 
-        T createdActivity = mActivityInterface.getCreatedActivity();
-        if (createdActivity != null) {
-            initTransitionEndpoints(createdActivity.getDeviceProfile());
+        T createdContainer = (T) mContainerInterface.getCreatedContainer();
+        if (createdContainer != null) {
+            initTransitionEndpoints(createdContainer.getDeviceProfile());
         }
-        final T activity = mActivityInterface.getCreatedActivity();
-        if (mActivity == activity) {
+        final T container = (T) mContainerInterface.getCreatedContainer();
+        if (mContainer == container) {
             return true;
         }
 
-        if (mActivity != null) {
+        if (mContainer != null) {
             if (mStateCallback.hasStates(STATE_GESTURE_COMPLETED)) {
                 // If the activity has restarted between setting the page scroll settling callback
                 // and actually receiving the callback, just mark the gesture completed
@@ -500,23 +498,23 @@
             mStateCallback.setState(oldState);
         }
         mWasLauncherAlreadyVisible = alreadyOnHome;
-        mActivity = activity;
+        mContainer = container;
         // Override the visibility of the activity until the gesture actually starts and we swipe
         // up, or until we transition home and the home animation is composed
         if (alreadyOnHome) {
-            mActivity.clearForceInvisibleFlag(STATE_HANDLER_INVISIBILITY_FLAGS);
+            mContainer.clearForceInvisibleFlag(STATE_HANDLER_INVISIBILITY_FLAGS);
         } else {
-            mActivity.addForceInvisibleFlag(STATE_HANDLER_INVISIBILITY_FLAGS);
+            mContainer.addForceInvisibleFlag(STATE_HANDLER_INVISIBILITY_FLAGS);
         }
 
-        mRecentsView = activity.getOverviewPanel();
+        mRecentsView = container.getOverviewPanel();
         mRecentsView.setOnPageTransitionEndCallback(null);
 
         mStateCallback.setState(STATE_LAUNCHER_PRESENT);
         if (alreadyOnHome) {
             onLauncherStart();
         } else {
-            activity.addEventCallback(EVENT_STARTED, mLauncherOnStartCallback);
+            container.addEventCallback(EVENT_STARTED, mLauncherOnStartCallback);
         }
 
         // Set up a entire animation lifecycle callback to notify the current recents view when
@@ -541,8 +539,8 @@
 
         setupRecentsViewUi();
         mRecentsView.runOnPageScrollsInitialized(this::linkRecentsViewScroll);
-        mActivity.runOnBindToTouchInteractionService(this::onLauncherBindToService);
-        mActivity.addEventCallback(EVENT_DESTROYED, mLauncherOnDestroyCallback);
+        mContainer.runOnBindToTouchInteractionService(this::onLauncherBindToService);
+        mContainer.addEventCallback(EVENT_DESTROYED, mLauncherOnDestroyCallback);
         return true;
     }
 
@@ -554,8 +552,8 @@
     }
 
     private void onLauncherStart() {
-        final T activity = mActivityInterface.getCreatedActivity();
-        if (activity == null || mActivity != activity) {
+        final T container = (T) mContainerInterface.getCreatedContainer();
+        if (container == null || mContainer != container) {
             return;
         }
         if (mStateCallback.hasStates(STATE_HANDLER_INVALIDATED)) {
@@ -571,7 +569,7 @@
         // as that will set the state as BACKGROUND_APP, overriding the animation to NORMAL.
         if (mGestureState.getEndTarget() != HOME) {
             Runnable initAnimFactory = () -> {
-                mAnimationFactory = mActivityInterface.prepareRecentsUI(mDeviceState,
+                mAnimationFactory = mContainerInterface.prepareRecentsUI(mDeviceState,
                         mWasLauncherAlreadyVisible, this::onAnimatorPlaybackControllerCreated);
                 maybeUpdateRecentsAttachedState(false /* animate */);
                 if (mGestureState.getEndTarget() != null) {
@@ -588,14 +586,14 @@
                 initAnimFactory.run();
             }
         }
-        AbstractFloatingView.closeAllOpenViewsExcept(activity, mWasLauncherAlreadyVisible,
+        AbstractFloatingView.closeAllOpenViewsExcept(container, mWasLauncherAlreadyVisible,
                 AbstractFloatingView.TYPE_LISTENER);
 
         if (mWasLauncherAlreadyVisible) {
             mStateCallback.setState(STATE_LAUNCHER_DRAWN);
         } else {
             SafeCloseable traceToken = TraceHelper.INSTANCE.beginAsyncSection("WTS-init");
-            View dragLayer = activity.getDragLayer();
+            View dragLayer = container.getDragLayer();
             dragLayer.getViewTreeObserver().addOnDrawListener(new OnDrawListener() {
                 boolean mHandled = false;
 
@@ -609,7 +607,7 @@
                     traceToken.close();
                     dragLayer.post(() ->
                             dragLayer.getViewTreeObserver().removeOnDrawListener(this));
-                    if (activity != mActivity) {
+                    if (container != mContainer) {
                         return;
                     }
 
@@ -618,7 +616,7 @@
             });
         }
 
-        activity.getRootView().setOnApplyWindowInsetsListener(this);
+        container.getRootView().setOnApplyWindowInsetsListener(this);
         mStateCallback.setState(STATE_LAUNCHER_STARTED);
     }
 
@@ -634,21 +632,21 @@
 
         // For the duration of the gesture, in cases where an activity is launched while the
         // activity is not yet resumed, finish the animation to ensure we get resumed
-        mGestureState.getActivityInterface().setOnDeferredActivityLaunchCallback(
+        mGestureState.getContainerInterface().setOnDeferredActivityLaunchCallback(
                 mOnDeferredActivityLaunch);
 
         mGestureState.runOnceAtState(STATE_END_TARGET_SET,
                 () -> {
                     mDeviceState.getRotationTouchHelper()
                             .onEndTargetCalculated(mGestureState.getEndTarget(),
-                                    mActivityInterface);
+                                    mContainerInterface);
                 });
 
         notifyGestureStarted();
     }
 
     private void onDeferredActivityLaunch() {
-        mActivityInterface.switchRunningTaskViewToScreenshot(
+        mContainerInterface.switchRunningTaskViewToScreenshot(
                 null, () -> {
                     mTaskAnimationManager.finishRunningRecentsAnimation(true /* toHome */);
                 });
@@ -709,7 +707,7 @@
             public void onMotionPauseDetected() {
                 mHasMotionEverBeenPaused = true;
                 maybeUpdateRecentsAttachedState(true/* animate */, true/* moveRunningTask */);
-                Optional.ofNullable(mActivityInterface.getTaskbarController())
+                Optional.ofNullable(mContainerInterface.getTaskbarController())
                         .ifPresent(TaskbarUIController::startTranslationSpring);
                 if (!mIsInAllAppsRegion) {
                     performHapticFeedback();
@@ -815,7 +813,7 @@
      */
     private void setIsInAllAppsRegion(boolean isInAllAppsRegion) {
         if (mIsInAllAppsRegion == isInAllAppsRegion
-                || !mActivityInterface.allowAllAppsFromOverview()) {
+                || !mContainerInterface.allowAllAppsFromOverview()) {
             return;
         }
         mIsInAllAppsRegion = isInAllAppsRegion;
@@ -824,8 +822,9 @@
         VibratorWrapper.INSTANCE.get(mContext).vibrate(OVERVIEW_HAPTIC);
         maybeUpdateRecentsAttachedState(true);
 
-        if (mActivity != null) {
-            mActivity.getAppsView().getSearchUiManager().prepareToFocusEditText(mIsInAllAppsRegion);
+        if (mContainer != null) {
+            mContainer.getAppsView().getSearchUiManager()
+                    .prepareToFocusEditText(mIsInAllAppsRegion);
         }
 
         // Draw active task below Launcher so that All Apps can appear over it.
@@ -838,7 +837,7 @@
         if (!canCreateNewOrUpdateExistingLauncherTransitionController()) {
             return;
         }
-        initTransitionEndpoints(mActivity.getDeviceProfile());
+        initTransitionEndpoints(mContainer.getDeviceProfile());
         mAnimationFactory.createActivityInterface(mTransitionDragLength);
     }
 
@@ -849,7 +848,7 @@
      */
     private boolean canCreateNewOrUpdateExistingLauncherTransitionController() {
         return mGestureState.getEndTarget() != HOME
-                && !mHasEndedLauncherTransition && mActivity != null;
+                && !mHasEndedLauncherTransition && mContainer != null;
     }
 
     @Override
@@ -893,7 +892,7 @@
     @UiThread
     @Override
     public void onCurrentShiftUpdated() {
-        float threshold = LauncherPrefs.get(mContext).get(ALL_APPS_OVERVIEW_THRESHOLD) / 100f;
+        float threshold = DeviceConfigWrapper.get().getAllAppsOverviewThreshold() / 100f;
         setIsInAllAppsRegion(mCurrentShift.value >= threshold);
         updateSysUiFlags(mCurrentShift.value);
         applyScrollAndTransform();
@@ -933,11 +932,11 @@
             // needs to be canceled
             mRecentsAnimationController.setWillFinishToHome(swipeUpThresholdPassed);
 
-            if (mActivity == null) return;
+            if (mContainer == null) return;
             if (swipeUpThresholdPassed) {
-                mActivity.getSystemUiController().updateUiState(UI_STATE_FULLSCREEN_TASK, 0);
+                mContainer.getSystemUiController().updateUiState(UI_STATE_FULLSCREEN_TASK, 0);
             } else {
-                mActivity.getSystemUiController().updateUiState(
+                mContainer.getSystemUiController().updateUiState(
                         UI_STATE_FULLSCREEN_TASK, centermostTaskFlags);
             }
         }
@@ -947,7 +946,7 @@
     public void onRecentsAnimationStart(RecentsAnimationController controller,
             RecentsAnimationTargets targets) {
         super.onRecentsAnimationStart(controller, targets);
-        if (enableDesktopWindowingMode() && targets.hasDesktopTasks()) {
+        if (targets.hasDesktopTasks()) {
             mRemoteTargetHandles = mTargetGluer.assignTargetsForDesktop(targets);
         } else {
             int untrimmedAppCount = mRemoteTargetHandles.length;
@@ -965,7 +964,7 @@
 
         // 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) {
+        if (mContainer == null) {
             RemoteAnimationTarget 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
@@ -974,7 +973,7 @@
                     .getOrientationState();
             DeviceProfile dp = orientationState.getLauncherDeviceProfile();
             if (targets.minimizedHomeBounds != null && primaryTaskTarget != null) {
-                Rect overviewStackBounds = mActivityInterface
+                Rect overviewStackBounds = mContainerInterface
                         .getOverviewWindowBounds(targets.minimizedHomeBounds, primaryTaskTarget);
                 dp = dp.getMultiWindowProfile(mContext,
                         new WindowBounds(overviewStackBounds, targets.homeContentInsets));
@@ -1017,7 +1016,7 @@
 
     @UiThread
     public void onGestureStarted(boolean isLikelyToStartNewTask) {
-        mActivityInterface.closeOverlay();
+        mContainerInterface.closeOverlay();
         TaskUtils.closeSystemWindowsAsync(CLOSE_SYSTEM_WINDOWS_REASON_RECENTS);
 
         if (mRecentsView != null) {
@@ -1077,11 +1076,11 @@
      */
     @UiThread
     private void notifyGestureStarted() {
-        final T curActivity = mActivity;
+        final T curActivity = mContainer;
         if (curActivity != null) {
             // Once the gesture starts, we can no longer transition home through the button, so
             // reset the force override of the activity visibility
-            mActivity.clearForceInvisibleFlag(STATE_HANDLER_INVISIBILITY_FLAGS);
+            mContainer.clearForceInvisibleFlag(STATE_HANDLER_INVISIBILITY_FLAGS);
         }
     }
 
@@ -1150,7 +1149,7 @@
         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);
+        View postResumeLastTask = mContainerInterface.onSettledOnEndTarget(endTarget);
 
         if (endTarget != NEW_TASK) {
             InteractionJankMonitorWrapper.cancel(Cuj.CUJ_LAUNCHER_QUICK_SWITCH);
@@ -1170,13 +1169,11 @@
                 mStateCallback.setState(STATE_SCALED_CONTROLLER_HOME | STATE_CAPTURE_SCREENSHOT);
                 // Notify the SysUI to use fade-in animation when entering PiP
                 SystemUiProxy.INSTANCE.get(mContext).setPipAnimationTypeToAlpha();
-                if (enableDesktopWindowingMode()) {
+                DesktopVisibilityController desktopVisibilityController =
+                        mContainerInterface.getDesktopVisibilityController();
+                if (desktopVisibilityController != null) {
                     // Notify the SysUI to stash desktop apps if they are visible
-                    DesktopVisibilityController desktopVisibilityController =
-                            mActivityInterface.getDesktopVisibilityController();
-                    if (desktopVisibilityController != null) {
-                        desktopVisibilityController.onHomeActionTriggered();
-                    }
+                    desktopVisibilityController.onHomeActionTriggered();
                 }
                 break;
             case RECENTS:
@@ -1362,7 +1359,7 @@
             }
         }
         Interpolator interpolator;
-        S state = mActivityInterface.stateFromGestureEndTarget(endTarget);
+        S state = mContainerInterface.stateFromGestureEndTarget(endTarget);
         if (isKeyboardTaskFocusPending()) {
             interpolator = EMPHASIZED;
         } else if (state.displayOverviewTasksAsGrid(mDp)) {
@@ -1377,7 +1374,7 @@
             mInputConsumerProxy.enable();
         }
         if (endTarget == HOME) {
-            duration = mActivity != null && mActivity.getDeviceProfile().isTaskbarPresent
+            duration = mContainer != null && mContainer.getDeviceProfile().isTaskbarPresent
                     ? StaggeredWorkspaceAnim.DURATION_TASKBAR_MS
                     : StaggeredWorkspaceAnim.DURATION_MS;
             // Early detach the nav bar once the endTarget is determined as HOME
@@ -1514,14 +1511,14 @@
         if (mGestureState.getEndTarget().isLauncher) {
             // This is also called when the launcher is resumed, in order to clear the pending
             // widgets that have yet to be configured.
-            if (mActivity != null) {
-                DragView.removeAllViews(mActivity);
+            if (mContainer != null) {
+                DragView.removeAllViews(mContainer);
             }
 
             TaskStackChangeListeners.getInstance().registerTaskStackListener(
                     mActivityRestartListener);
 
-            mParallelRunningAnim = mActivityInterface.getParallelAnimationToLauncher(
+            mParallelRunningAnim = mContainerInterface.getParallelAnimationToLauncher(
                     mGestureState.getEndTarget(), duration,
                     mTaskAnimationManager.getCurrentCallbacks());
             if (mParallelRunningAnim != null) {
@@ -1619,7 +1616,7 @@
                 if (windowAnimation == null) {
                     continue;
                 }
-                DeviceProfile dp = mActivity == null ? null : mActivity.getDeviceProfile();
+                DeviceProfile dp = mContainer == null ? null : mContainer.getDeviceProfile();
                 windowAnimation.start(mContext, dp, velocityPxPerMs);
                 mRunningWindowAnim[i] = RunningWindowAnim.wrap(windowAnimation);
             }
@@ -1872,7 +1869,7 @@
                 }
                 // Make sure recents is in its final state
                 maybeUpdateRecentsAttachedState(false);
-                mActivityInterface.onSwipeUpToHomeComplete(mDeviceState);
+                mContainerInterface.onSwipeUpToHomeComplete(mDeviceState);
             }
         });
         if (mRecentsAnimationTargets != null) {
@@ -1946,8 +1943,8 @@
 
     private void reset() {
         mStateCallback.setStateOnUiThread(STATE_HANDLER_INVALIDATED);
-        if (mActivity != null) {
-            mActivity.removeEventCallback(EVENT_DESTROYED, mLauncherOnDestroyCallback);
+        if (mContainer != null) {
+            mContainer.removeEventCallback(EVENT_DESTROYED, mLauncherOnDestroyCallback);
         }
     }
 
@@ -1971,7 +1968,7 @@
     }
 
     private void invalidateHandler() {
-        if (!mActivityInterface.isInLiveTileMode() || mGestureState.getEndTarget() != RECENTS) {
+        if (!mContainerInterface.isInLiveTileMode() || mGestureState.getEndTarget() != RECENTS) {
             mInputConsumerProxy.destroy();
             mTaskAnimationManager.setLiveTileCleanUpHandler(null);
         }
@@ -2018,11 +2015,11 @@
      * continued quick switch gesture, which cancels the previous handler but doesn't invalidate it.
      */
     private void resetLauncherListeners() {
-        if (mActivity != null) {
-            mActivity.removeEventCallback(EVENT_STARTED, mLauncherOnStartCallback);
-            mActivity.removeEventCallback(EVENT_DESTROYED, mLauncherOnDestroyCallback);
+        if (mContainer != null) {
+            mContainer.removeEventCallback(EVENT_STARTED, mLauncherOnStartCallback);
+            mContainer.removeEventCallback(EVENT_DESTROYED, mLauncherOnDestroyCallback);
 
-            mActivity.getRootView().setOnApplyWindowInsetsListener(null);
+            mContainer.getRootView().setOnApplyWindowInsetsListener(null);
         }
         if (mRecentsView != null) {
             mRecentsView.removeOnScrollChangedListener(mOnRecentsScrollListener);
@@ -2031,11 +2028,11 @@
 
     private void resetStateForAnimationCancel() {
         boolean wasVisible = mWasLauncherAlreadyVisible || mGestureStarted;
-        mActivityInterface.onTransitionCancelled(wasVisible, mGestureState.getEndTarget());
+        mContainerInterface.onTransitionCancelled(wasVisible, mGestureState.getEndTarget());
 
         // Leave the pending invisible flag, as it may be used by wallpaper open animation.
-        if (mActivity != null) {
-            mActivity.clearForceInvisibleFlag(INVISIBLE_BY_STATE_HANDLER);
+        if (mContainer != null) {
+            mContainer.clearForceInvisibleFlag(INVISIBLE_BY_STATE_HANDLER);
         }
     }
 
@@ -2301,14 +2298,14 @@
                             onRestartPreviouslyAppearedTask();
                         }
                     } else {
-                        mActivityInterface.onLaunchTaskFailed();
+                        mContainerInterface.onLaunchTaskFailed();
                         if (mRecentsAnimationController != null) {
                             mRecentsAnimationController.finish(true /* toRecents */, null);
                         }
                     }
                 }, true /* freezeTaskList */);
             } else {
-                mActivityInterface.onLaunchTaskFailed();
+                mContainerInterface.onLaunchTaskFailed();
                 Toast.makeText(mContext, R.string.activity_not_available, LENGTH_SHORT).show();
                 if (mRecentsAnimationController != null) {
                     mRecentsAnimationController.finish(true /* toRecents */, null);
@@ -2400,12 +2397,12 @@
             finishRecentsAnimationOnTasksAppeared(null /* onFinishComplete */);
             return;
         }
-        if (mActivity == null) {
+        if (mContainer == null) {
             ActiveGestureLog.INSTANCE.addLog("Activity destroyed");
             finishRecentsAnimationOnTasksAppeared(null /* onFinishComplete */);
             return;
         }
-        animateSplashScreenExit(mActivity, appearedTaskTargets, taskTarget.leash);
+        animateSplashScreenExit(mContainer, appearedTaskTargets, taskTarget.leash);
     }
 
     private void animateSplashScreenExit(
@@ -2520,7 +2517,7 @@
             transaction.setAlpha(app.leash, 1f - fadeProgress);
             transaction.setPosition(app.leash,
                     /* x= */ app.startBounds.left
-                            + (mActivity.getDeviceProfile().overviewPageSpacing
+                            + (mContainer.getDeviceProfile().overviewPageSpacing
                             * (mRecentsView.isRtl() ? fadeProgress : -fadeProgress)),
                     /* y= */ 0f);
             transaction.setScale(app.leash, 1f, 1f);
@@ -2571,7 +2568,7 @@
 
     // Scaling of RecentsView during quick switch based on amount of recents scroll
     private float getScaleProgressDueToScroll() {
-        if (mActivity == null || !mActivity.getDeviceProfile().isTablet || mRecentsView == null
+        if (mContainer == null || !mContainer.getDeviceProfile().isTablet || mRecentsView == null
                 || !shouldLinkRecentsViewScroll()) {
             return 0;
         }
diff --git a/quickstep/src/com/android/quickstep/BaseActivityInterface.java b/quickstep/src/com/android/quickstep/BaseActivityInterface.java
index 24c99e3..00cd60b 100644
--- a/quickstep/src/com/android/quickstep/BaseActivityInterface.java
+++ b/quickstep/src/com/android/quickstep/BaseActivityInterface.java
@@ -18,14 +18,11 @@
 import static com.android.app.animation.Interpolators.ACCELERATE_2;
 import static com.android.app.animation.Interpolators.INSTANT;
 import static com.android.app.animation.Interpolators.LINEAR;
-import static com.android.launcher3.LauncherAnimUtils.VIEW_BACKGROUND_COLOR;
 import static com.android.launcher3.MotionEventsUtils.isTrackpadMultiFingerSwipe;
 import static com.android.quickstep.AbsSwipeUpHandler.RECENTS_ATTACH_DURATION;
 import static com.android.quickstep.GestureState.GestureEndTarget.LAST_TASK;
-import static com.android.quickstep.GestureState.GestureEndTarget.RECENTS;
 import static com.android.quickstep.util.RecentsAtomicAnimationFactory.INDEX_RECENTS_FADE_ANIM;
 import static com.android.quickstep.util.RecentsAtomicAnimationFactory.INDEX_RECENTS_TRANSLATE_X_ANIM;
-import static com.android.window.flags.Flags.enableDesktopWindowingMode;
 import static com.android.quickstep.views.RecentsView.ADJACENT_PAGE_HORIZONTAL_OFFSET;
 import static com.android.quickstep.views.RecentsView.FULLSCREEN_PROGRESS;
 import static com.android.quickstep.views.RecentsView.RECENTS_SCALE_PROPERTY;
@@ -34,23 +31,12 @@
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.animation.AnimatorSet;
-import android.animation.ObjectAnimator;
-import android.content.Context;
-import android.content.res.Resources;
 import android.graphics.Color;
-import android.graphics.PointF;
-import android.graphics.Rect;
-import android.view.Gravity;
 import android.view.MotionEvent;
-import android.view.RemoteAnimationTarget;
-import android.view.View;
 
 import androidx.annotation.Nullable;
 import androidx.annotation.UiThread;
 
-import com.android.launcher3.DeviceProfile;
-import com.android.launcher3.Flags;
-import com.android.launcher3.R;
 import com.android.launcher3.anim.AnimatorPlaybackController;
 import com.android.launcher3.anim.PendingAnimation;
 import com.android.launcher3.statehandlers.DepthController;
@@ -58,29 +44,23 @@
 import com.android.launcher3.statemanager.BaseState;
 import com.android.launcher3.statemanager.StatefulActivity;
 import com.android.launcher3.taskbar.TaskbarUIController;
-import com.android.launcher3.touch.PagedOrientationHandler;
 import com.android.launcher3.util.DisplayController;
 import com.android.launcher3.util.NavigationMode;
-import com.android.launcher3.views.ScrimView;
-import com.android.quickstep.orientation.RecentsPagedOrientationHandler;
-import com.android.quickstep.util.ActivityInitListener;
 import com.android.quickstep.util.AnimatorControllerWithResistance;
 import com.android.quickstep.views.RecentsView;
+import com.android.quickstep.views.RecentsViewContainer;
 import com.android.systemui.shared.recents.model.ThumbnailData;
 
 import java.util.HashMap;
 import java.util.Optional;
 import java.util.function.Consumer;
-import java.util.function.Predicate;
 
 /**
  * Utility class which abstracts out the logical differences between Launcher and RecentsActivity.
  */
 public abstract class BaseActivityInterface<STATE_TYPE extends BaseState<STATE_TYPE>,
-        ACTIVITY_TYPE extends StatefulActivity<STATE_TYPE>> {
-
-    public final boolean rotationSupportedByActivity;
-
+        ACTIVITY_TYPE extends StatefulActivity<STATE_TYPE> & RecentsViewContainer> extends
+        BaseContainerInterface<STATE_TYPE, ACTIVITY_TYPE> {
     private final STATE_TYPE mBackgroundState;
 
     private STATE_TYPE mTargetState;
@@ -101,7 +81,7 @@
      */
     public void onTransitionCancelled(boolean activityVisible,
             @Nullable GestureState.GestureEndTarget endTarget) {
-        ACTIVITY_TYPE activity = getCreatedActivity();
+        ACTIVITY_TYPE activity = getCreatedContainer();
         if (activity == null) {
             return;
         }
@@ -109,67 +89,37 @@
         if (endTarget != null) {
             // We were on our way to this state when we got canceled, end there instead.
             startState = stateFromGestureEndTarget(endTarget);
-            if (enableDesktopWindowingMode()) {
-                DesktopVisibilityController controller = getDesktopVisibilityController();
-                if (controller != null && controller.areFreeformTasksVisible()
-                        && endTarget == LAST_TASK) {
-                    // When we are cancelling the transition and going back to last task, move to
-                    // rest state instead when desktop tasks are visible.
-                    // If a fullscreen task is visible, launcher goes to normal state when the
-                    // activity is stopped. This does not happen when freeform tasks are visible
-                    // on top of launcher. Force the launcher state to rest state here.
-                    startState = activity.getStateManager().getRestState();
-                    // Do not animate the transition
-                    activityVisible = false;
-                }
+            DesktopVisibilityController controller = getDesktopVisibilityController();
+            if (controller != null && controller.areDesktopTasksVisible()
+                    && endTarget == LAST_TASK) {
+                // When we are cancelling the transition and going back to last task, move to
+                // rest state instead when desktop tasks are visible.
+                // If a fullscreen task is visible, launcher goes to normal state when the
+                // activity is stopped. This does not happen when desktop tasks are visible
+                // on top of launcher. Force the launcher state to rest state here.
+                startState = activity.getStateManager().getRestState();
+                // Do not animate the transition
+                activityVisible = false;
             }
         }
         activity.getStateManager().goToState(startState, activityVisible);
     }
 
-    public abstract int getSwipeUpDestinationAndLength(
-            DeviceProfile dp, Context context, Rect outRect,
-            RecentsPagedOrientationHandler orientationHandler);
-
-    /** Called when the animation to home has fully settled. */
-    public void onSwipeUpToHomeComplete(RecentsAnimationDeviceState deviceState) {}
-
-    public abstract void onAssistantVisibilityChanged(float visibility);
-
-    public abstract AnimationFactory prepareRecentsUI(RecentsAnimationDeviceState deviceState,
-            boolean activityVisible, Consumer<AnimatorControllerWithResistance> callback);
-
-    public abstract ActivityInitListener createActivityInitListener(
-            Predicate<Boolean> onInitListener);
-
-    /**
-     * Sets a callback to be run when an activity launch happens while launcher is not yet resumed.
-     */
-    public void setOnDeferredActivityLaunchCallback(Runnable r) {}
-
     @Nullable
-    public abstract ACTIVITY_TYPE getCreatedActivity();
+    public abstract ACTIVITY_TYPE getCreatedContainer();
 
     @Nullable
     public DepthController getDepthController() {
         return null;
     }
 
-    @Nullable
-    public DesktopVisibilityController getDesktopVisibilityController() {
-        return null;
-    }
-
-    @Nullable
-    public abstract TaskbarUIController getTaskbarController();
-
     public final boolean isResumed() {
-        ACTIVITY_TYPE activity = getCreatedActivity();
+        ACTIVITY_TYPE activity = getCreatedContainer();
         return activity != null && activity.hasBeenResumed();
     }
 
     public final boolean isStarted() {
-        ACTIVITY_TYPE activity = getCreatedActivity();
+        ACTIVITY_TYPE activity = getCreatedContainer();
         return activity != null && activity.isStarted();
     }
 
@@ -180,14 +130,6 @@
     @UiThread
     public abstract boolean switchToRecentsIfVisible(Animator.AnimatorListener animatorListener);
 
-    public abstract Rect getOverviewWindowBounds(
-            Rect homeBounds, RemoteAnimationTarget target);
-
-    public abstract boolean allowMinimizeSplitScreen();
-
-    /** @return whether to allow going to All Apps from Overview. */
-    public abstract boolean allowAllAppsFromOverview();
-
     public boolean deferStartingActivity(RecentsAnimationDeviceState deviceState, MotionEvent ev) {
         TaskbarUIController controller = getTaskbarController();
         boolean isEventOverBubbleBarStashHandle =
@@ -197,20 +139,6 @@
     }
 
     /**
-     * @return Whether the gesture in progress should be cancelled.
-     */
-    public boolean shouldCancelCurrentGesture() {
-        return false;
-    }
-
-    public abstract void onExitOverview(RotationTouchHelper deviceState,
-            Runnable exitRunnable);
-
-    public abstract boolean isInLiveTileMode();
-
-    public abstract void onLaunchTaskFailed();
-
-    /**
      * Closes any overlays.
      */
     public void closeOverlay() {
@@ -220,7 +148,7 @@
 
     public void switchRunningTaskViewToScreenshot(HashMap<Integer, ThumbnailData> thumbnailDatas,
             Runnable runnable) {
-        ACTIVITY_TYPE activity = getCreatedActivity();
+        ACTIVITY_TYPE activity = getCreatedContainer();
         if (activity == null) {
             return;
         }
@@ -234,230 +162,9 @@
         recentsView.switchToScreenshot(thumbnailDatas, runnable);
     }
 
-    /**
-     * Calculates the taskView size for the provided device configuration.
-     */
-    public final void calculateTaskSize(Context context, DeviceProfile dp, Rect outRect,
-            PagedOrientationHandler orientedState) {
-        if (dp.isTablet) {
-            if (Flags.enableGridOnlyOverview()) {
-                calculateGridTaskSize(context, dp, outRect, orientedState);
-            } else {
-                calculateFocusTaskSize(context, dp, outRect);
-            }
-        } else {
-            Resources res = context.getResources();
-            float maxScale = res.getFloat(R.dimen.overview_max_scale);
-            int taskMargin = dp.overviewTaskMarginPx;
-            calculateTaskSizeInternal(
-                    context,
-                    dp,
-                    dp.overviewTaskThumbnailTopMarginPx,
-                    dp.getOverviewActionsClaimedSpace(),
-                    res.getDimensionPixelSize(R.dimen.overview_minimum_next_prev_size) + taskMargin,
-                    maxScale,
-                    Gravity.CENTER,
-                    outRect);
-        }
-    }
-
-    /**
-     * Calculates the taskView size for carousel during app to overview animation on tablets.
-     */
-    public final void calculateCarouselTaskSize(Context context, DeviceProfile dp, Rect outRect,
-            PagedOrientationHandler orientedState) {
-        if (dp.isTablet && dp.isGestureMode) {
-            Resources res = context.getResources();
-            float minScale = res.getFloat(R.dimen.overview_carousel_min_scale);
-            Rect gridRect = new Rect();
-            calculateGridSize(dp, context, gridRect);
-            calculateTaskSizeInternal(context, dp, gridRect, minScale, Gravity.CENTER | Gravity.TOP,
-                    outRect);
-        } else {
-            calculateTaskSize(context, dp, outRect, orientedState);
-        }
-    }
-
-    private void calculateFocusTaskSize(Context context, DeviceProfile dp, Rect outRect) {
-        Resources res = context.getResources();
-        float maxScale = res.getFloat(R.dimen.overview_max_scale);
-        Rect gridRect = new Rect();
-        calculateGridSize(dp, context, gridRect);
-        calculateTaskSizeInternal(context, dp, gridRect, maxScale, Gravity.CENTER, outRect);
-    }
-
-    private void calculateTaskSizeInternal(Context context, DeviceProfile dp, int claimedSpaceAbove,
-            int claimedSpaceBelow, int minimumHorizontalPadding, float maxScale, int gravity,
-            Rect outRect) {
-        Rect insets = dp.getInsets();
-
-        Rect potentialTaskRect = new Rect(0, 0, dp.widthPx, dp.heightPx);
-        potentialTaskRect.inset(insets.left, insets.top, insets.right, insets.bottom);
-        potentialTaskRect.inset(
-                minimumHorizontalPadding,
-                claimedSpaceAbove,
-                minimumHorizontalPadding,
-                claimedSpaceBelow);
-
-        calculateTaskSizeInternal(context, dp, potentialTaskRect, maxScale, gravity, outRect);
-    }
-
-    private void calculateTaskSizeInternal(Context context, DeviceProfile dp,
-            Rect potentialTaskRect, float targetScale, int gravity, Rect outRect) {
-        PointF taskDimension = getTaskDimension(context, dp);
-
-        float scale = Math.min(
-                potentialTaskRect.width() / taskDimension.x,
-                potentialTaskRect.height() / taskDimension.y);
-        scale = Math.min(scale, targetScale);
-        int outWidth = Math.round(scale * taskDimension.x);
-        int outHeight = Math.round(scale * taskDimension.y);
-
-        Gravity.apply(gravity, outWidth, outHeight, potentialTaskRect, outRect);
-    }
-
-    private static PointF getTaskDimension(Context context, DeviceProfile dp) {
-        PointF dimension = new PointF();
-        getTaskDimension(context, dp, dimension);
-        return dimension;
-    }
-
-    /**
-     * Gets the dimension of the task in the current system state.
-     */
-    public static void getTaskDimension(Context context, DeviceProfile dp, PointF out) {
-        out.x = dp.widthPx;
-        out.y = dp.heightPx;
-        if (dp.isTablet && !DisplayController.isTransientTaskbar(context)) {
-            out.y -= dp.taskbarHeight;
-        }
-    }
-
-    /**
-     * Calculates the overview grid size for the provided device configuration.
-     */
-    public final void calculateGridSize(DeviceProfile dp, Context context, Rect outRect) {
-        Rect insets = dp.getInsets();
-        int topMargin = dp.overviewTaskThumbnailTopMarginPx;
-        int bottomMargin = dp.getOverviewActionsClaimedSpace();
-        if (dp.isTaskbarPresent && Flags.enableGridOnlyOverview()) {
-            topMargin += context.getResources().getDimensionPixelSize(
-                    R.dimen.overview_top_margin_grid_only);
-            bottomMargin += context.getResources().getDimensionPixelSize(
-                    R.dimen.overview_bottom_margin_grid_only);
-        }
-        int sideMargin = dp.overviewGridSideMargin;
-
-        outRect.set(0, 0, dp.widthPx, dp.heightPx);
-        outRect.inset(Math.max(insets.left, sideMargin), insets.top + topMargin,
-                Math.max(insets.right, sideMargin), Math.max(insets.bottom, bottomMargin));
-    }
-
-    /**
-     * Calculates the overview grid non-focused task size for the provided device configuration.
-     */
-    public final void calculateGridTaskSize(Context context, DeviceProfile dp, Rect outRect,
-            PagedOrientationHandler orientedState) {
-        Resources res = context.getResources();
-        Rect potentialTaskRect = new Rect();
-        if (Flags.enableGridOnlyOverview()) {
-            calculateGridSize(dp, context, potentialTaskRect);
-        } else {
-            calculateFocusTaskSize(context, dp, potentialTaskRect);
-        }
-
-        float rowHeight = (potentialTaskRect.height() + dp.overviewTaskThumbnailTopMarginPx
-                - dp.overviewRowSpacing) / 2f;
-
-        PointF taskDimension = getTaskDimension(context, dp);
-        float scale = (rowHeight - dp.overviewTaskThumbnailTopMarginPx) / taskDimension.y;
-        int outWidth = Math.round(scale * taskDimension.x);
-        int outHeight = Math.round(scale * taskDimension.y);
-
-        int gravity = Gravity.TOP;
-        gravity |= orientedState.getRecentsRtlSetting(res) ? Gravity.RIGHT : Gravity.LEFT;
-        Gravity.apply(gravity, outWidth, outHeight, potentialTaskRect, outRect);
-    }
-
-    /**
-     * Calculates the modal taskView size for the provided device configuration
-     */
-    public final void calculateModalTaskSize(Context context, DeviceProfile dp, Rect outRect,
-            PagedOrientationHandler orientedState) {
-        calculateTaskSize(context, dp, outRect, orientedState);
-        boolean isGridOnlyOverview = dp.isTablet && Flags.enableGridOnlyOverview();
-        int claimedSpaceBelow = isGridOnlyOverview
-                ? dp.overviewActionsTopMarginPx + dp.overviewActionsHeight + dp.stashedTaskbarHeight
-                : (dp.heightPx - outRect.bottom - dp.getInsets().bottom);
-        int minimumHorizontalPadding = 0;
-        if (!isGridOnlyOverview) {
-            float maxScale = context.getResources().getFloat(R.dimen.overview_modal_max_scale);
-            minimumHorizontalPadding =
-                    Math.round((dp.availableWidthPx - outRect.width() * maxScale) / 2);
-        }
-        calculateTaskSizeInternal(
-                context,
-                dp,
-                dp.overviewTaskMarginPx,
-                claimedSpaceBelow,
-                minimumHorizontalPadding,
-                1f /*maxScale*/,
-                Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM,
-                outRect);
-    }
-
-    /**
-     * Called when the gesture ends and the animation starts towards the given target. Used to add
-     * an optional additional animation with the same duration.
-     */
-    public @Nullable Animator getParallelAnimationToLauncher(
-            GestureState.GestureEndTarget endTarget, long duration,
-            RecentsAnimationCallbacks callbacks) {
-        if (endTarget == RECENTS) {
-            ACTIVITY_TYPE activity = getCreatedActivity();
-            if (activity == null) {
-                return null;
-            }
-            RecentsView recentsView = activity.getOverviewPanel();
-            STATE_TYPE state = stateFromGestureEndTarget(endTarget);
-            ScrimView scrimView = activity.getScrimView();
-            ObjectAnimator anim = ObjectAnimator.ofArgb(scrimView, VIEW_BACKGROUND_COLOR,
-                    getOverviewScrimColorForState(activity, state));
-            anim.setDuration(duration);
-            anim.setInterpolator(recentsView == null || !recentsView.isKeyboardTaskFocusPending()
-                    ? LINEAR : INSTANT);
-            return anim;
-        }
-        return null;
-    }
-
-    /**
-     * Returns the color of the scrim behind overview when at rest in this state.
-     * Return {@link Color#TRANSPARENT} for no scrim.
-     */
-    protected abstract int getOverviewScrimColorForState(ACTIVITY_TYPE activity, STATE_TYPE state);
-
-    /**
-     * Returns the expected STATE_TYPE from the provided GestureEndTarget.
-     */
-    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) {
-        TaskbarUIController taskbarUIController = getTaskbarController();
-        if (taskbarUIController != null) {
-            taskbarUIController.setSystemGestureInProgress(false);
-            return taskbarUIController.getRootView();
-        }
-        return null;
-    }
 
     protected void runOnInitBackgroundStateUI(Runnable callback) {
-        ACTIVITY_TYPE activity = getCreatedActivity();
+        ACTIVITY_TYPE activity = getCreatedContainer();
         if (activity != null && activity.getStateManager().getState() == mBackgroundState) {
             callback.run();
             onInitBackgroundStateUI();
@@ -508,7 +215,7 @@
         DefaultAnimationFactory(Consumer<AnimatorControllerWithResistance> callback) {
             mCallback = callback;
 
-            mActivity = getCreatedActivity();
+            mActivity = getCreatedContainer();
             mStartState = mActivity.getStateManager().getState();
         }
 
diff --git a/quickstep/src/com/android/quickstep/BaseContainerInterface.java b/quickstep/src/com/android/quickstep/BaseContainerInterface.java
new file mode 100644
index 0000000..9955183
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/BaseContainerInterface.java
@@ -0,0 +1,377 @@
+/*
+ * Copyright (C) 2024 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.app.animation.Interpolators.INSTANT;
+import static com.android.app.animation.Interpolators.LINEAR;
+import static com.android.launcher3.LauncherAnimUtils.VIEW_BACKGROUND_COLOR;
+import static com.android.quickstep.GestureState.GestureEndTarget.LAST_TASK;
+import static com.android.quickstep.GestureState.GestureEndTarget.RECENTS;
+
+import android.animation.Animator;
+import android.animation.ObjectAnimator;
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Color;
+import android.graphics.PointF;
+import android.graphics.Rect;
+import android.view.Gravity;
+import android.view.MotionEvent;
+import android.view.RemoteAnimationTarget;
+import android.view.View;
+
+import androidx.annotation.Nullable;
+
+import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.Flags;
+import com.android.launcher3.R;
+import com.android.launcher3.statehandlers.DesktopVisibilityController;
+import com.android.launcher3.statemanager.BaseState;
+import com.android.launcher3.taskbar.TaskbarUIController;
+import com.android.launcher3.touch.PagedOrientationHandler;
+import com.android.launcher3.util.DisplayController;
+import com.android.launcher3.views.ScrimView;
+import com.android.quickstep.orientation.RecentsPagedOrientationHandler;
+import com.android.quickstep.util.ActivityInitListener;
+import com.android.quickstep.util.AnimatorControllerWithResistance;
+import com.android.quickstep.views.RecentsView;
+import com.android.quickstep.views.RecentsViewContainer;
+import com.android.systemui.shared.recents.model.ThumbnailData;
+
+import java.util.HashMap;
+import java.util.function.Consumer;
+import java.util.function.Predicate;
+
+public abstract class BaseContainerInterface<STATE_TYPE extends BaseState<STATE_TYPE>,
+        CONTAINER_TYPE extends RecentsViewContainer> {
+
+    public boolean rotationSupportedByActivity = false;
+
+    @Nullable
+    public abstract CONTAINER_TYPE getCreatedContainer();
+
+    public abstract boolean isInLiveTileMode();
+
+    public abstract void onAssistantVisibilityChanged(float assistantVisibility);
+
+    public abstract boolean allowMinimizeSplitScreen();
+
+    public abstract boolean isResumed();
+
+    public abstract boolean isStarted();
+    public abstract boolean deferStartingActivity(RecentsAnimationDeviceState deviceState,
+            MotionEvent ev);
+
+    /** @return whether to allow going to All Apps from Overview. */
+    public abstract boolean allowAllAppsFromOverview();
+
+    /**
+     * Returns the color of the scrim behind overview when at rest in this state.
+     * Return {@link Color#TRANSPARENT} for no scrim.
+     */
+    protected abstract int getOverviewScrimColorForState(CONTAINER_TYPE container,
+            STATE_TYPE state);
+
+    public abstract int getSwipeUpDestinationAndLength(
+            DeviceProfile dp, Context context, Rect outRect,
+            RecentsPagedOrientationHandler orientationHandler);
+
+    @Nullable
+    public abstract TaskbarUIController getTaskbarController();
+
+    public abstract BaseActivityInterface.AnimationFactory prepareRecentsUI(
+            RecentsAnimationDeviceState deviceState, boolean activityVisible,
+            Consumer<AnimatorControllerWithResistance> callback);
+
+    public abstract ActivityInitListener createActivityInitListener(
+            Predicate<Boolean> onInitListener);
+    /**
+     * Returns the expected STATE_TYPE from the provided GestureEndTarget.
+     */
+    public abstract STATE_TYPE stateFromGestureEndTarget(GestureState.GestureEndTarget endTarget);
+
+    public abstract void switchRunningTaskViewToScreenshot(HashMap<Integer,
+            ThumbnailData> thumbnailDatas, Runnable runnable);
+
+    public abstract void closeOverlay();
+
+    public abstract Rect getOverviewWindowBounds(
+            Rect homeBounds, RemoteAnimationTarget target);
+
+    public abstract void onLaunchTaskFailed();
+
+    public abstract void onExitOverview(RotationTouchHelper deviceState,
+            Runnable exitRunnable);
+
+    /** Called when the animation to home has fully settled. */
+    public void onSwipeUpToHomeComplete(RecentsAnimationDeviceState deviceState) {}
+
+    /**
+     * Sets a callback to be run when an activity launch happens while launcher is not yet resumed.
+     */
+    public void setOnDeferredActivityLaunchCallback(Runnable r) {}
+    /**
+     * @return Whether the gesture in progress should be cancelled.
+     */
+    public boolean shouldCancelCurrentGesture() {
+        return false;
+    }
+
+    @Nullable
+    public DesktopVisibilityController getDesktopVisibilityController() {
+        return null;
+    }
+
+    /**
+     * Called when the gesture ends and the animation starts towards the given target. Used to add
+     * an optional additional animation with the same duration.
+     */
+    public @Nullable Animator getParallelAnimationToLauncher(
+            GestureState.GestureEndTarget endTarget, long duration,
+            RecentsAnimationCallbacks callbacks) {
+        if (endTarget == RECENTS) {
+            CONTAINER_TYPE container = getCreatedContainer();
+            if (container == null) {
+                return null;
+            }
+            RecentsView recentsView = container.getOverviewPanel();
+            STATE_TYPE state = stateFromGestureEndTarget(endTarget);
+            ScrimView scrimView = container.getScrimView();
+            ObjectAnimator anim = ObjectAnimator.ofArgb(scrimView, VIEW_BACKGROUND_COLOR,
+                    getOverviewScrimColorForState(container, state));
+            anim.setDuration(duration);
+            anim.setInterpolator(recentsView == null || !recentsView.isKeyboardTaskFocusPending()
+                    ? LINEAR : INSTANT);
+            return anim;
+        }
+        return null;
+    }
+
+    /**
+     * 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) {
+        TaskbarUIController taskbarUIController = getTaskbarController();
+        if (taskbarUIController != null) {
+            taskbarUIController.setSystemGestureInProgress(false);
+            return taskbarUIController.getRootView();
+        }
+        return null;
+    }
+
+    /**
+     * Called when the current gesture transition is cancelled.
+     * @param activityVisible Whether the user can see the changes we make here, so try to animate.
+     * @param endTarget If the gesture ended before we got cancelled, where we were headed.
+     */
+    public void onTransitionCancelled(boolean activityVisible,
+            @Nullable GestureState.GestureEndTarget endTarget) {
+        RecentsViewContainer container = getCreatedContainer();
+        if (container == null) {
+            return;
+        }
+        RecentsView recentsView = container.getOverviewPanel();
+        BaseState startState = recentsView.getStateManager().getRestState();
+        if (endTarget != null) {
+            // We were on our way to this state when we got canceled, end there instead.
+            startState = stateFromGestureEndTarget(endTarget);
+            DesktopVisibilityController controller = getDesktopVisibilityController();
+            if (controller != null && controller.areDesktopTasksVisible()
+                    && endTarget == LAST_TASK) {
+                // When we are cancelling the transition and going back to last task, move to
+                // rest state instead when desktop tasks are visible.
+                // If a fullscreen task is visible, launcher goes to normal state when the
+                // activity is stopped. This does not happen when desktop tasks are visible
+                // on top of launcher. Force the launcher state to rest state here.
+                startState = recentsView.getStateManager().getRestState();
+                // Do not animate the transition
+                activityVisible = false;
+            }
+        }
+        recentsView.getStateManager().goToState(startState, activityVisible);
+    }
+
+    public final void calculateTaskSize(Context context, DeviceProfile dp, Rect outRect,
+            PagedOrientationHandler orientedState) {
+        if (dp.isTablet) {
+            if (Flags.enableGridOnlyOverview()) {
+                calculateGridTaskSize(context, dp, outRect, orientedState);
+            } else {
+                calculateFocusTaskSize(context, dp, outRect);
+            }
+        } else {
+            Resources res = context.getResources();
+            float maxScale = res.getFloat(R.dimen.overview_max_scale);
+            int taskMargin = dp.overviewTaskMarginPx;
+            calculateTaskSizeInternal(
+                    context,
+                    dp,
+                    dp.overviewTaskThumbnailTopMarginPx,
+                    dp.getOverviewActionsClaimedSpace(),
+                    res.getDimensionPixelSize(R.dimen.overview_minimum_next_prev_size) + taskMargin,
+                    maxScale,
+                    Gravity.CENTER,
+                    outRect);
+        }
+    }
+
+    /**
+     * Calculates the taskView size for carousel during app to overview animation on tablets.
+     */
+    public final void calculateCarouselTaskSize(Context context, DeviceProfile dp, Rect outRect,
+            PagedOrientationHandler orientedState) {
+        if (dp.isTablet && dp.isGestureMode) {
+            Resources res = context.getResources();
+            float minScale = res.getFloat(R.dimen.overview_carousel_min_scale);
+            Rect gridRect = new Rect();
+            calculateGridSize(dp, context, gridRect);
+            calculateTaskSizeInternal(context, dp, gridRect, minScale, Gravity.CENTER | Gravity.TOP,
+                    outRect);
+        } else {
+            calculateTaskSize(context, dp, outRect, orientedState);
+        }
+    }
+
+    private void calculateFocusTaskSize(Context context, DeviceProfile dp, Rect outRect) {
+        Resources res = context.getResources();
+        float maxScale = res.getFloat(R.dimen.overview_max_scale);
+        Rect gridRect = new Rect();
+        calculateGridSize(dp, context, gridRect);
+        calculateTaskSizeInternal(context, dp, gridRect, maxScale, Gravity.CENTER, outRect);
+    }
+
+    private void calculateTaskSizeInternal(Context context, DeviceProfile dp, int claimedSpaceAbove,
+            int claimedSpaceBelow, int minimumHorizontalPadding, float maxScale, int gravity,
+            Rect outRect) {
+        Rect insets = dp.getInsets();
+
+        Rect potentialTaskRect = new Rect(0, 0, dp.widthPx, dp.heightPx);
+        potentialTaskRect.inset(insets.left, insets.top, insets.right, insets.bottom);
+        potentialTaskRect.inset(
+                minimumHorizontalPadding,
+                claimedSpaceAbove,
+                minimumHorizontalPadding,
+                claimedSpaceBelow);
+
+        calculateTaskSizeInternal(context, dp, potentialTaskRect, maxScale, gravity, outRect);
+    }
+
+    private void calculateTaskSizeInternal(Context context, DeviceProfile dp,
+            Rect potentialTaskRect, float targetScale, int gravity, Rect outRect) {
+        PointF taskDimension = getTaskDimension(context, dp);
+
+        float scale = Math.min(
+                potentialTaskRect.width() / taskDimension.x,
+                potentialTaskRect.height() / taskDimension.y);
+        scale = Math.min(scale, targetScale);
+        int outWidth = Math.round(scale * taskDimension.x);
+        int outHeight = Math.round(scale * taskDimension.y);
+
+        Gravity.apply(gravity, outWidth, outHeight, potentialTaskRect, outRect);
+    }
+
+    private static PointF getTaskDimension(Context context, DeviceProfile dp) {
+        PointF dimension = new PointF();
+        getTaskDimension(context, dp, dimension);
+        return dimension;
+    }
+
+    /**
+     * Gets the dimension of the task in the current system state.
+     */
+    public static void getTaskDimension(Context context, DeviceProfile dp, PointF out) {
+        out.x = dp.widthPx;
+        out.y = dp.heightPx;
+        if (dp.isTablet && !DisplayController.isTransientTaskbar(context)) {
+            out.y -= dp.taskbarHeight;
+        }
+    }
+
+    /**
+     * Calculates the overview grid size for the provided device configuration.
+     */
+    public final void calculateGridSize(DeviceProfile dp, Context context, Rect outRect) {
+        Rect insets = dp.getInsets();
+        int topMargin = dp.overviewTaskThumbnailTopMarginPx;
+        int bottomMargin = dp.getOverviewActionsClaimedSpace();
+        if (dp.isTaskbarPresent && Flags.enableGridOnlyOverview()) {
+            topMargin += context.getResources().getDimensionPixelSize(
+                    R.dimen.overview_top_margin_grid_only);
+            bottomMargin += context.getResources().getDimensionPixelSize(
+                    R.dimen.overview_bottom_margin_grid_only);
+        }
+        int sideMargin = dp.overviewGridSideMargin;
+
+        outRect.set(0, 0, dp.widthPx, dp.heightPx);
+        outRect.inset(Math.max(insets.left, sideMargin), insets.top + topMargin,
+                Math.max(insets.right, sideMargin), Math.max(insets.bottom, bottomMargin));
+    }
+
+    /**
+     * Calculates the overview grid non-focused task size for the provided device configuration.
+     */
+    public final void calculateGridTaskSize(Context context, DeviceProfile dp, Rect outRect,
+            PagedOrientationHandler orientedState) {
+        Resources res = context.getResources();
+        Rect potentialTaskRect = new Rect();
+        if (Flags.enableGridOnlyOverview()) {
+            calculateGridSize(dp, context, potentialTaskRect);
+        } else {
+            calculateFocusTaskSize(context, dp, potentialTaskRect);
+        }
+
+        float rowHeight = (potentialTaskRect.height() + dp.overviewTaskThumbnailTopMarginPx
+                - dp.overviewRowSpacing) / 2f;
+
+        PointF taskDimension = getTaskDimension(context, dp);
+        float scale = (rowHeight - dp.overviewTaskThumbnailTopMarginPx) / taskDimension.y;
+        int outWidth = Math.round(scale * taskDimension.x);
+        int outHeight = Math.round(scale * taskDimension.y);
+
+        int gravity = Gravity.TOP;
+        gravity |= orientedState.getRecentsRtlSetting(res) ? Gravity.RIGHT : Gravity.LEFT;
+        Gravity.apply(gravity, outWidth, outHeight, potentialTaskRect, outRect);
+    }
+
+    /**
+     * Calculates the modal taskView size for the provided device configuration
+     */
+    public final void calculateModalTaskSize(Context context, DeviceProfile dp, Rect outRect,
+            PagedOrientationHandler orientedState) {
+        calculateTaskSize(context, dp, outRect, orientedState);
+        boolean isGridOnlyOverview = dp.isTablet && Flags.enableGridOnlyOverview();
+        int claimedSpaceBelow = isGridOnlyOverview
+                ? dp.overviewActionsTopMarginPx + dp.overviewActionsHeight + dp.stashedTaskbarHeight
+                : (dp.heightPx - outRect.bottom - dp.getInsets().bottom);
+        int minimumHorizontalPadding = 0;
+        if (!isGridOnlyOverview) {
+            float maxScale = context.getResources().getFloat(R.dimen.overview_modal_max_scale);
+            minimumHorizontalPadding =
+                    Math.round((dp.availableWidthPx - outRect.width() * maxScale) / 2);
+        }
+        calculateTaskSizeInternal(
+                context,
+                dp,
+                dp.overviewTaskMarginPx,
+                claimedSpaceBelow,
+                minimumHorizontalPadding,
+                1f /*maxScale*/,
+                Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM,
+                outRect);
+    }
+}
diff --git a/quickstep/src/com/android/quickstep/DesktopSystemShortcut.kt b/quickstep/src/com/android/quickstep/DesktopSystemShortcut.kt
new file mode 100644
index 0000000..aa0f728
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/DesktopSystemShortcut.kt
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2024 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 android.view.View
+import com.android.launcher3.AbstractFloatingViewHelper
+import com.android.launcher3.R
+import com.android.launcher3.logging.StatsLogManager.LauncherEvent
+import com.android.launcher3.popup.SystemShortcut
+import com.android.quickstep.views.RecentsView
+import com.android.quickstep.views.RecentsViewContainer
+import com.android.quickstep.views.TaskView.TaskIdAttributeContainer
+import com.android.window.flags.Flags
+
+/** A menu item, "Desktop", that allows the user to bring the current app into Desktop Windowing. */
+class DesktopSystemShortcut(
+    container: RecentsViewContainer,
+    private val mTaskContainer: TaskIdAttributeContainer,
+    abstractFloatingViewHelper: AbstractFloatingViewHelper
+) :
+    SystemShortcut<RecentsViewContainer>(
+        R.drawable.ic_caption_desktop_button_foreground,
+        R.string.recent_task_option_desktop,
+        container,
+        mTaskContainer.itemInfo,
+        mTaskContainer.taskView,
+        abstractFloatingViewHelper
+    ) {
+    override fun onClick(view: View) {
+        dismissTaskMenuView()
+        val recentsView = mTarget!!.getOverviewPanel<RecentsView<*, *>>()
+        recentsView.moveTaskToDesktop(mTaskContainer) {
+            mTarget.statsLogManager
+                .logger()
+                .withItemInfo(mTaskContainer.itemInfo)
+                .log(LauncherEvent.LAUNCHER_SYSTEM_SHORTCUT_DESKTOP_TAP)
+        }
+    }
+
+    companion object {
+        /** Creates a factory for creating Desktop system shorcuts. */
+        @JvmOverloads
+        fun createFactory(
+            abstractFloatingViewHelper: AbstractFloatingViewHelper = AbstractFloatingViewHelper()
+        ): TaskShortcutFactory {
+            return object : TaskShortcutFactory {
+                override fun getShortcuts(
+                    container: RecentsViewContainer,
+                    taskContainer: TaskIdAttributeContainer
+                ): List<DesktopSystemShortcut>? {
+                    return if (!Flags.enableDesktopWindowingMode()) null
+                    else if (!taskContainer.task.isDockable) null
+                    else
+                        listOf(
+                            DesktopSystemShortcut(
+                                container,
+                                taskContainer,
+                                abstractFloatingViewHelper
+                            )
+                        )
+                }
+
+                override fun showForSplitscreen() = true
+            }
+        }
+    }
+}
diff --git a/quickstep/src/com/android/quickstep/DeviceConfigWrapper.kt b/quickstep/src/com/android/quickstep/DeviceConfigWrapper.kt
new file mode 100644
index 0000000..1cc54d8
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/DeviceConfigWrapper.kt
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2024 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 com.android.quickstep.util.DeviceConfigHelper
+import com.android.quickstep.util.DeviceConfigHelper.PropReader
+import java.io.PrintWriter
+
+/** Various configurations specific to nav-bar functionalities */
+class DeviceConfigWrapper private constructor(propReader: PropReader) {
+
+    val customLpnhThresholds =
+        propReader.get(
+            "CUSTOM_LPNH_THRESHOLDS",
+            true,
+            "Add dev options and server side control to customize the LPNH trigger slop and milliseconds"
+        )
+
+    val customLphThresholds =
+        propReader.get(
+            "CUSTOM_LPH_THRESHOLDS",
+            false,
+            "Server side control to customize LPH timeout and touch slop"
+        )
+
+    val overrideLpnhLphThresholds =
+        propReader.get(
+            "OVERRIDE_LPNH_LPH_THRESHOLDS",
+            false,
+            "Enable AGSA override for LPNH and LPH timeout and touch slop"
+        )
+
+    val lpnhTimeoutMs =
+        propReader.get("LPNH_TIMEOUT_MS", 450, "Controls lpnh timeout in milliseconds")
+
+    val lpnhSlopPercentage =
+        propReader.get("LPNH_SLOP_PERCENTAGE", 100, "Controls touch slop percentage for lpnh")
+
+    val enableLpnhTwoStages =
+        propReader.get(
+            "ENABLE_LPNH_TWO_STAGES",
+            false,
+            "Enable two stage for LPNH duration and touch slop"
+        )
+
+    val twoStageMultiplier =
+        propReader.get(
+            "TWO_STAGE_MULTIPLIER",
+            2,
+            "Extends the duration and touch slop if the initial slop is passed"
+        )
+
+    val animateLpnh = propReader.get("ANIMATE_LPNH", false, "Animates navbar when long pressing")
+
+    val shrinkNavHandleOnPress =
+        propReader.get(
+            "SHRINK_NAV_HANDLE_ON_PRESS",
+            false,
+            "Shrinks navbar when long pressing if ANIMATE_LPNH is enabled"
+        )
+
+    val enableLongPressNavHandle =
+        propReader.get(
+            "ENABLE_LONG_PRESS_NAV_HANDLE",
+            true,
+            "Enables long pressing on the bottom bar nav handle to trigger events."
+        )
+
+    val enableSearchHapticHint =
+        propReader.get(
+            "ENABLE_SEARCH_HAPTIC_HINT",
+            true,
+            "Enables haptic hint while long pressing on the bottom bar nav handle."
+        )
+
+    val enableSearchHapticCommit =
+        propReader.get(
+            "ENABLE_SEARCH_HAPTIC_COMMIT",
+            true,
+            "Enables haptic hint at end of long pressing on the bottom bar nav handle."
+        )
+
+    val lpnhHapticHintStartScalePercent =
+        propReader.get("LPNH_HAPTIC_HINT_START_SCALE_PERCENT", 0, "Haptic hint start scale.")
+
+    val lpnhHapticHintEndScalePercent =
+        propReader.get("LPNH_HAPTIC_HINT_END_SCALE_PERCENT", 100, "Haptic hint end scale.")
+
+    val lpnhHapticHintScaleExponent =
+        propReader.get("LPNH_HAPTIC_HINT_SCALE_EXPONENT", 1, "Haptic hint scale exponent.")
+
+    val lpnhHapticHintIterations =
+        propReader.get("LPNH_HAPTIC_HINT_ITERATIONS", 50, "Haptic hint number of iterations.")
+
+    val enableLpnhDeepPress =
+        propReader.get(
+            "ENABLE_LPNH_DEEP_PRESS",
+            true,
+            "Long press of nav handle is instantly triggered if deep press is detected."
+        )
+
+    val lpnhHapticHintDelay =
+        propReader.get("LPNH_HAPTIC_HINT_DELAY", 0, "Delay before haptic hint starts.")
+
+    val lpnhExtraTouchWidthDp =
+        propReader.get(
+            "LPNH_EXTRA_TOUCH_WIDTH_DP",
+            0,
+            "Controls extra dp on the nav bar sides to trigger LPNH. Can be negative for a smaller touch region."
+        )
+
+    val allAppsOverviewThreshold =
+        propReader.get(
+            "ALL_APPS_OVERVIEW_THRESHOLD",
+            180,
+            "Threshold to open All Apps from Overview"
+        )
+
+    /** Dump config values. */
+    fun dump(prefix: String, writer: PrintWriter) {
+        writer.println("$prefix DeviceConfigWrapper:")
+        writer.println("$prefix\tcustomLpnhThresholds=$customLpnhThresholds")
+        writer.println("$prefix\tcustomLphThresholds=$customLphThresholds")
+        writer.println("$prefix\toverrideLpnhLphThresholds=$overrideLpnhLphThresholds")
+        writer.println("$prefix\tlpnhSlopPercentage=$lpnhSlopPercentage")
+        writer.println("$prefix\tanimateLpnh=$animateLpnh")
+        writer.println("$prefix\tshrinkNavHandleOnPress=$shrinkNavHandleOnPress")
+        writer.println("$prefix\tlpnhTimeoutMs=$lpnhTimeoutMs")
+        writer.println("$prefix\tenableLongPressNavHandle=$enableLongPressNavHandle")
+        writer.println("$prefix\tenableSearchHapticHint=$enableSearchHapticHint")
+        writer.println("$prefix\tenableSearchHapticCommit=$enableSearchHapticCommit")
+        writer.println("$prefix\tlpnhHapticHintStartScalePercent=$lpnhHapticHintStartScalePercent")
+        writer.println("$prefix\tlpnhHapticHintEndScalePercent=$lpnhHapticHintEndScalePercent")
+        writer.println("$prefix\tlpnhHapticHintScaleExponent=$lpnhHapticHintScaleExponent")
+        writer.println("$prefix\tlpnhHapticHintIterations=$lpnhHapticHintIterations")
+        writer.println("$prefix\tenableLpnhDeepPress=$enableLpnhDeepPress")
+        writer.println("$prefix\tlpnhHapticHintDelay=$lpnhHapticHintDelay")
+        writer.println("$prefix\tlpnhExtraTouchWidthDp=$lpnhExtraTouchWidthDp")
+        writer.println("$prefix\tallAppsOverviewThreshold=$allAppsOverviewThreshold")
+    }
+
+    companion object {
+        val configHelper by lazy { DeviceConfigHelper(::DeviceConfigWrapper) }
+
+        @JvmStatic fun get() = configHelper.config
+    }
+}
diff --git a/quickstep/src/com/android/quickstep/FallbackActivityInterface.java b/quickstep/src/com/android/quickstep/FallbackActivityInterface.java
index 27e8726..9e896fd 100644
--- a/quickstep/src/com/android/quickstep/FallbackActivityInterface.java
+++ b/quickstep/src/com/android/quickstep/FallbackActivityInterface.java
@@ -96,13 +96,13 @@
 
     @Nullable
     @Override
-    public RecentsActivity getCreatedActivity() {
+    public RecentsActivity getCreatedContainer() {
         return RecentsActivity.ACTIVITY_TRACKER.getCreatedActivity();
     }
 
     @Override
     public FallbackTaskbarUIController getTaskbarController() {
-        RecentsActivity activity = getCreatedActivity();
+        RecentsActivity activity = getCreatedContainer();
         if (activity == null) {
             return null;
         }
@@ -112,7 +112,7 @@
     @Nullable
     @Override
     public RecentsView getVisibleRecentsView() {
-        RecentsActivity activity = getCreatedActivity();
+        RecentsActivity activity = getCreatedContainer();
         if (activity != null) {
             if (activity.hasBeenResumed() || isInLiveTileMode()) {
                 return activity.getOverviewPanel();
@@ -154,7 +154,7 @@
 
     @Override
     public void onExitOverview(RotationTouchHelper deviceState, Runnable exitRunnable) {
-        final StateManager<RecentsState> stateManager = getCreatedActivity().getStateManager();
+        final StateManager<RecentsState> stateManager = getCreatedContainer().getStateManager();
         if (stateManager.getState() == HOME) {
             exitRunnable.run();
             notifyRecentsOfOrientation(deviceState);
@@ -177,7 +177,7 @@
 
     @Override
     public boolean isInLiveTileMode() {
-        RecentsActivity activity = getCreatedActivity();
+        RecentsActivity activity = getCreatedContainer();
         return activity != null && activity.getStateManager().getState() == DEFAULT &&
                 activity.isStarted();
     }
@@ -185,7 +185,7 @@
     @Override
     public void onLaunchTaskFailed() {
         // TODO: probably go back to overview instead.
-        RecentsActivity activity = getCreatedActivity();
+        RecentsActivity activity = getCreatedContainer();
         if (activity == null) {
             return;
         }
@@ -209,7 +209,7 @@
 
     private void notifyRecentsOfOrientation(RotationTouchHelper rotationTouchHelper) {
         // reset layout on swipe to home
-        RecentsView recentsView = getCreatedActivity().getOverviewPanel();
+        RecentsView recentsView = getCreatedContainer().getOverviewPanel();
         recentsView.setLayoutRotation(rotationTouchHelper.getCurrentActiveRotation(),
                 rotationTouchHelper.getDisplayRotation());
     }
diff --git a/quickstep/src/com/android/quickstep/FallbackSwipeHandler.java b/quickstep/src/com/android/quickstep/FallbackSwipeHandler.java
index b42eb06..92cdf72 100644
--- a/quickstep/src/com/android/quickstep/FallbackSwipeHandler.java
+++ b/quickstep/src/com/android/quickstep/FallbackSwipeHandler.java
@@ -223,7 +223,7 @@
         public AnimatorPlaybackController createActivityAnimationToHome() {
             // copied from {@link LauncherSwipeHandlerV2.LauncherHomeAnimationFactory}
             long accuracy = 2 * Math.max(mDp.widthPx, mDp.heightPx);
-            return mActivity.getStateManager().createAnimationToNewWorkspace(
+            return mContainer.getStateManager().createAnimationToNewWorkspace(
                     RecentsState.HOME, accuracy, StateAnimationConfig.SKIP_ALL_ANIMATIONS);
         }
     }
diff --git a/quickstep/src/com/android/quickstep/GestureState.java b/quickstep/src/com/android/quickstep/GestureState.java
index d02909c..6b33c0a 100644
--- a/quickstep/src/com/android/quickstep/GestureState.java
+++ b/quickstep/src/com/android/quickstep/GestureState.java
@@ -37,10 +37,10 @@
 import androidx.annotation.Nullable;
 
 import com.android.launcher3.statemanager.BaseState;
-import com.android.launcher3.statemanager.StatefulActivity;
 import com.android.quickstep.TopTaskTracker.CachedTaskInfo;
 import com.android.quickstep.util.ActiveGestureErrorDetector;
 import com.android.quickstep.util.ActiveGestureLog;
+import com.android.quickstep.views.RecentsViewContainer;
 import com.android.systemui.shared.recents.model.ThumbnailData;
 
 import java.io.PrintWriter;
@@ -151,7 +151,7 @@
     // Needed to interact with the current activity
     private final Intent mHomeIntent;
     private final Intent mOverviewIntent;
-    private final BaseActivityInterface mActivityInterface;
+    private final BaseContainerInterface mContainerInterface;
     private final MultiStateCallback mStateCallback;
     private final int mGestureId;
 
@@ -189,7 +189,7 @@
     public GestureState(OverviewComponentObserver componentObserver, int gestureId) {
         mHomeIntent = componentObserver.getHomeIntent();
         mOverviewIntent = componentObserver.getOverviewIntent();
-        mActivityInterface = componentObserver.getActivityInterface();
+        mContainerInterface = componentObserver.getActivityInterface();
         mStateCallback = new MultiStateCallback(
                 STATE_NAMES.toArray(new String[0]), GestureState::getTrackedEventForState);
         mGestureId = gestureId;
@@ -198,7 +198,7 @@
     public GestureState(GestureState other) {
         mHomeIntent = other.mHomeIntent;
         mOverviewIntent = other.mOverviewIntent;
-        mActivityInterface = other.mActivityInterface;
+        mContainerInterface = other.mContainerInterface;
         mStateCallback = other.mStateCallback;
         mGestureId = other.mGestureId;
         mRunningTask = other.mRunningTask;
@@ -212,7 +212,7 @@
         // Do nothing, only used for initializing the gesture state prior to user unlock
         mHomeIntent = new Intent();
         mOverviewIntent = new Intent();
-        mActivityInterface = null;
+        mContainerInterface = null;
         mStateCallback = new MultiStateCallback(
                 STATE_NAMES.toArray(new String[0]), GestureState::getTrackedEventForState);
         mGestureId = -1;
@@ -268,9 +268,9 @@
     /**
      * @return the interface to the activity handing the UI updates for this gesture.
      */
-    public <S extends BaseState<S>,
-            T extends StatefulActivity<S>> BaseActivityInterface<S, T> getActivityInterface() {
-        return mActivityInterface;
+    public <S extends BaseState<S>, T extends RecentsViewContainer>
+            BaseContainerInterface<S, T> getContainerInterface() {
+        return mContainerInterface;
     }
 
     /**
diff --git a/quickstep/src/com/android/quickstep/HomeVisibilityState.kt b/quickstep/src/com/android/quickstep/HomeVisibilityState.kt
new file mode 100644
index 0000000..241e16d
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/HomeVisibilityState.kt
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2024 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 android.os.RemoteException
+import android.util.Log
+import com.android.launcher3.config.FeatureFlags
+import com.android.launcher3.util.Executors
+import com.android.wm.shell.shared.IHomeTransitionListener.Stub
+import com.android.wm.shell.shared.IShellTransitions
+
+/** Class to track visibility state of Launcher */
+class HomeVisibilityState {
+
+    var isHomeVisible = true
+        private set
+
+    private var listeners = mutableSetOf<VisibilityChangeListener>()
+
+    fun addListener(l: VisibilityChangeListener) = listeners.add(l)
+
+    fun removeListener(l: VisibilityChangeListener) = listeners.remove(l)
+
+    fun init(transitions: IShellTransitions?) {
+        if (!FeatureFlags.enableHomeTransitionListener()) return
+        try {
+            transitions?.setHomeTransitionListener(
+                object : Stub() {
+                    override fun onHomeVisibilityChanged(isVisible: Boolean) {
+                        Executors.MAIN_EXECUTOR.execute {
+                            isHomeVisible = isVisible
+                            listeners.forEach { it.onHomeVisibilityChanged(isVisible) }
+                        }
+                    }
+                }
+            )
+        } catch (e: RemoteException) {
+            Log.w(TAG, "Failed call setHomeTransitionListener", e)
+        }
+    }
+
+    interface VisibilityChangeListener {
+        fun onHomeVisibilityChanged(isVisible: Boolean)
+    }
+
+    override fun toString() = "{HomeVisibilityState isHomeVisible=$isHomeVisible}"
+
+    companion object {
+
+        private const val TAG = "HomeVisibilityState"
+    }
+}
diff --git a/quickstep/src/com/android/quickstep/LauncherActivityInterface.java b/quickstep/src/com/android/quickstep/LauncherActivityInterface.java
index 97c48e6..7655c59 100644
--- a/quickstep/src/com/android/quickstep/LauncherActivityInterface.java
+++ b/quickstep/src/com/android/quickstep/LauncherActivityInterface.java
@@ -35,7 +35,7 @@
 import androidx.annotation.UiThread;
 
 import com.android.launcher3.DeviceProfile;
-import com.android.launcher3.Launcher;
+import com.android.launcher3.Flags;
 import com.android.launcher3.LauncherAnimUtils;
 import com.android.launcher3.LauncherInitListener;
 import com.android.launcher3.LauncherState;
@@ -85,7 +85,7 @@
 
     @Override
     public void onSwipeUpToHomeComplete(RecentsAnimationDeviceState deviceState) {
-        Launcher launcher = getCreatedActivity();
+        QuickstepLauncher launcher = getCreatedContainer();
         if (launcher == null) {
             return;
         }
@@ -102,7 +102,7 @@
 
     @Override
     public void onAssistantVisibilityChanged(float visibility) {
-        Launcher launcher = getCreatedActivity();
+        QuickstepLauncher launcher = getCreatedContainer();
         if (launcher == null) {
             return;
         }
@@ -144,7 +144,7 @@
 
     @Override
     public void setOnDeferredActivityLaunchCallback(Runnable r) {
-        Launcher launcher = getCreatedActivity();
+        QuickstepLauncher launcher = getCreatedContainer();
         if (launcher == null) {
             return;
         }
@@ -153,14 +153,14 @@
 
     @Nullable
     @Override
-    public QuickstepLauncher getCreatedActivity() {
+    public QuickstepLauncher getCreatedContainer() {
         return QuickstepLauncher.ACTIVITY_TRACKER.getCreatedActivity();
     }
 
     @Nullable
     @Override
     public DepthController getDepthController() {
-        QuickstepLauncher launcher = getCreatedActivity();
+        QuickstepLauncher launcher = getCreatedContainer();
         if (launcher == null) {
             return null;
         }
@@ -170,7 +170,7 @@
     @Nullable
     @Override
     public DesktopVisibilityController getDesktopVisibilityController() {
-        QuickstepLauncher launcher = getCreatedActivity();
+        QuickstepLauncher launcher = getCreatedContainer();
         if (launcher == null) {
             return null;
         }
@@ -180,7 +180,7 @@
     @Nullable
     @Override
     public LauncherTaskbarUIController getTaskbarController() {
-        QuickstepLauncher launcher = getCreatedActivity();
+        QuickstepLauncher launcher = getCreatedContainer();
         if (launcher == null) {
             return null;
         }
@@ -190,7 +190,7 @@
     @Nullable
     @Override
     public RecentsView getVisibleRecentsView() {
-        Launcher launcher = getVisibleLauncher();
+        QuickstepLauncher launcher = getVisibleLauncher();
         RecentsView recentsView =
                 launcher != null && launcher.getStateManager().getState().overviewUi
                         ? launcher.getOverviewPanel() : null;
@@ -204,15 +204,24 @@
 
     @Nullable
     @UiThread
-    private Launcher getVisibleLauncher() {
-        Launcher launcher = getCreatedActivity();
-        return (launcher != null) && launcher.isStarted()
-                && (isInLiveTileMode() || launcher.hasBeenResumed()) ? launcher : null;
+    private QuickstepLauncher getVisibleLauncher() {
+        QuickstepLauncher launcher = getCreatedContainer();
+        if (launcher == null) {
+            return null;
+        }
+        if (launcher.isStarted() && (isInLiveTileMode() || launcher.hasBeenResumed())) {
+            return launcher;
+        }
+        if (Flags.useActivityOverlay()
+                && SystemUiProxy.INSTANCE.get(launcher).getHomeVisibilityState().isHomeVisible()) {
+            return launcher;
+        }
+        return null;
     }
 
     @Override
     public boolean switchToRecentsIfVisible(Animator.AnimatorListener animatorListener) {
-        Launcher launcher = getVisibleLauncher();
+        QuickstepLauncher launcher = getVisibleLauncher();
         if (launcher == null) {
             return false;
         }
@@ -233,7 +242,7 @@
 
     @Override
     public void onExitOverview(RotationTouchHelper deviceState, Runnable exitRunnable) {
-        final StateManager<LauncherState> stateManager = getCreatedActivity().getStateManager();
+        final StateManager<LauncherState> stateManager = getCreatedContainer().getStateManager();
         stateManager.addStateListener(
                 new StateManager.StateListener<LauncherState>() {
                     @Override
@@ -250,7 +259,7 @@
 
     private void notifyRecentsOfOrientation(RotationTouchHelper rotationTouchHelper) {
         // reset layout on swipe to home
-        RecentsView recentsView = getCreatedActivity().getOverviewPanel();
+        RecentsView recentsView = getCreatedContainer().getOverviewPanel();
         recentsView.setLayoutRotation(rotationTouchHelper.getCurrentActiveRotation(),
                 rotationTouchHelper.getDisplayRotation());
     }
@@ -269,12 +278,12 @@
     public boolean allowAllAppsFromOverview() {
         return FeatureFlags.ENABLE_ALL_APPS_FROM_OVERVIEW.get()
                 // If floating search bar would not show in overview, don't allow all apps gesture.
-                && OVERVIEW.areElementsVisible(getCreatedActivity(), FLOATING_SEARCH_BAR);
+                && OVERVIEW.areElementsVisible(getCreatedContainer(), FLOATING_SEARCH_BAR);
     }
 
     @Override
     public boolean isInLiveTileMode() {
-        Launcher launcher = getCreatedActivity();
+        QuickstepLauncher launcher = getCreatedContainer();
 
         return launcher != null
                 && launcher.getStateManager().getState() == OVERVIEW
@@ -284,7 +293,7 @@
 
     @Override
     public void onLaunchTaskFailed() {
-        Launcher launcher = getCreatedActivity();
+        QuickstepLauncher launcher = getCreatedContainer();
         if (launcher == null) {
             return;
         }
@@ -294,7 +303,7 @@
     @Override
     public void closeOverlay() {
         super.closeOverlay();
-        Launcher launcher = getCreatedActivity();
+        QuickstepLauncher launcher = getCreatedContainer();
         if (launcher == null) {
             return;
         }
@@ -327,9 +336,8 @@
     }
 
     @Override
-    protected int getOverviewScrimColorForState(QuickstepLauncher launcher,
-            LauncherState state) {
-        return state.getWorkspaceScrimColor(launcher);
+    protected int getOverviewScrimColorForState(QuickstepLauncher activity, LauncherState state) {
+        return state.getWorkspaceScrimColor(activity);
     }
 
     @Override
diff --git a/quickstep/src/com/android/quickstep/LauncherBackAnimationController.java b/quickstep/src/com/android/quickstep/LauncherBackAnimationController.java
index 2d25295..79b09fd 100644
--- a/quickstep/src/com/android/quickstep/LauncherBackAnimationController.java
+++ b/quickstep/src/com/android/quickstep/LauncherBackAnimationController.java
@@ -39,6 +39,7 @@
 import android.os.RemoteException;
 import android.util.Log;
 import android.util.Pair;
+import android.view.Choreographer;
 import android.view.IRemoteAnimationFinishedCallback;
 import android.view.IRemoteAnimationRunner;
 import android.view.RemoteAnimationTarget;
@@ -99,7 +100,7 @@
     private final int mWindowScaleMarginX;
     private float mWindowScaleEndCornerRadius;
     private float mWindowScaleStartCornerRadius;
-    private final Interpolator mProgressInterpolator = Interpolators.STANDARD_DECELERATE;
+    private final Interpolator mProgressInterpolator = Interpolators.BACK_GESTURE;
     private final Interpolator mVerticalMoveInterpolator = new DecelerateInterpolator();
     private final PointF mInitialTouchPos = new PointF();
 
@@ -302,7 +303,7 @@
         if (mScrimLayer == null) {
             addScrimLayer();
         }
-        mTransaction.apply();
+        applyTransaction();
     }
 
     private void setLauncherTargetViewVisible(boolean isVisible) {
@@ -342,7 +343,8 @@
             return;
         }
         if (mScrimLayer.isValid()) {
-            mTransaction.remove(mScrimLayer).apply();
+            mTransaction.remove(mScrimLayer);
+            applyTransaction();
         }
         mScrimLayer = null;
     }
@@ -396,7 +398,11 @@
             mTransaction.setWindowCrop(mBackTarget.leash, mStartRect);
             mTransaction.setCornerRadius(mBackTarget.leash, cornerRadius);
         }
+        applyTransaction();
+    }
 
+    private void applyTransaction() {
+        mTransaction.setFrameTimelineVsync(Choreographer.getInstance().getVsyncId());
         mTransaction.apply();
     }
 
@@ -511,7 +517,7 @@
             float value = (Float) animation.getAnimatedValue();
             if (mScrimLayer != null && mScrimLayer.isValid()) {
                 mTransaction.setAlpha(mScrimLayer, value * mScrimAlpha);
-                mTransaction.apply();
+                applyTransaction();
             }
         });
         mScrimAlphaAnimator.addListener(new AnimatorListenerAdapter() {
diff --git a/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java b/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java
index f678bea..6647057 100644
--- a/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java
+++ b/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java
@@ -75,7 +75,7 @@
     protected HomeAnimationFactory createHomeAnimationFactory(ArrayList<IBinder> launchCookies,
             long duration, boolean isTargetTranslucent, boolean appCanEnterPip,
             RemoteAnimationTarget runningTaskTarget) {
-        if (mActivity == null) {
+        if (mContainer == null) {
             mStateCallback.addChangeListener(STATE_LAUNCHER_PRESENT | STATE_HANDLER_INVALIDATED,
                     isPresent -> mRecentsView.startHome());
             return new HomeAnimationFactory() {
@@ -91,9 +91,9 @@
         boolean canUseWorkspaceView = workspaceView != null && workspaceView.isAttachedToWindow()
                 && workspaceView.getHeight() > 0;
 
-        mActivity.getRootView().setForceHideBackArrow(true);
+        mContainer.getRootView().setForceHideBackArrow(true);
         if (!TaskAnimationManager.ENABLE_SHELL_TRANSITIONS) {
-            mActivity.setHintUserWillBeActive();
+            mContainer.setHintUserWillBeActive();
         }
 
         if (!canUseWorkspaceView || appCanEnterPip || mIsSwipeForSplit) {
@@ -108,10 +108,10 @@
 
     private HomeAnimationFactory createIconHomeAnimationFactory(View workspaceView) {
         RectF iconLocation = new RectF();
-        FloatingIconView floatingIconView = getFloatingIconView(mActivity, workspaceView, null,
-                mActivity.getTaskbarUIController() == null
+        FloatingIconView floatingIconView = getFloatingIconView(mContainer, workspaceView, null,
+                mContainer.getTaskbarUIController() == null
                         ? null
-                        : mActivity.getTaskbarUIController().findMatchingView(workspaceView),
+                        : mContainer.getTaskbarUIController().findMatchingView(workspaceView),
                 true /* hideOriginal */, iconLocation, false /* isOpening */);
 
         // We want the window alpha to be 0 once this threshold is met, so that the
@@ -171,7 +171,7 @@
         Size windowSize = new Size(crop.width(), crop.height());
         int fallbackBackgroundColor =
                 FloatingWidgetView.getDefaultBackgroundColor(mContext, runningTaskTarget);
-        FloatingWidgetView floatingWidgetView = FloatingWidgetView.getFloatingWidgetView(mActivity,
+        FloatingWidgetView floatingWidgetView = FloatingWidgetView.getFloatingWidgetView(mContainer,
                 hostView, backgroundLocation, windowSize, tvs.getCurrentCornerRadius(),
                 isTargetTranslucent, fallbackBackgroundColor);
 
@@ -248,7 +248,7 @@
             }
         }
 
-        return mActivity.getFirstMatchForAppClose(launchCookieItemId,
+        return mContainer.getFirstMatchForAppClose(launchCookieItemId,
                 runningTaskView.getTask().key.getComponent().getPackageName(),
                 UserHandle.of(runningTaskView.getTask().key.userId),
                 false /* supportsAllAppsState */);
@@ -292,18 +292,18 @@
             // Return an empty APC here since we have an non-user controlled animation
             // to home.
             long accuracy = 2 * Math.max(mDp.widthPx, mDp.heightPx);
-            return mActivity.getStateManager().createAnimationToNewWorkspace(
+            return mContainer.getStateManager().createAnimationToNewWorkspace(
                     NORMAL, accuracy, StateAnimationConfig.SKIP_ALL_ANIMATIONS);
         }
 
         @Override
         public void playAtomicAnimation(float velocity) {
             if (enableScalingRevealHomeAnimation()) {
-                if (mActivity != null) {
-                    new ScalingWorkspaceRevealAnim(mActivity).start();
+                if (mContainer != null) {
+                    new ScalingWorkspaceRevealAnim(mContainer).start();
                 }
             } else {
-                new StaggeredWorkspaceAnim(mActivity, velocity, true /* animateOverviewScrim */,
+                new StaggeredWorkspaceAnim(mContainer, velocity, true /* animateOverviewScrim */,
                         getViewIgnoredInWorkspaceRevealAnimation())
                         .start();
             }
diff --git a/quickstep/src/com/android/quickstep/OverviewCommandHelper.java b/quickstep/src/com/android/quickstep/OverviewCommandHelper.java
index 0db50bf..68923ee 100644
--- a/quickstep/src/com/android/quickstep/OverviewCommandHelper.java
+++ b/quickstep/src/com/android/quickstep/OverviewCommandHelper.java
@@ -40,6 +40,7 @@
 import com.android.quickstep.RecentsAnimationCallbacks.RecentsAnimationListener;
 import com.android.quickstep.util.ActiveGestureLog;
 import com.android.quickstep.views.RecentsView;
+import com.android.quickstep.views.RecentsViewContainer;
 import com.android.quickstep.views.TaskView;
 import com.android.systemui.shared.recents.model.ThumbnailData;
 import com.android.systemui.shared.system.InteractionJankMonitorWrapper;
@@ -191,7 +192,8 @@
      * Executes the task and returns true if next task can be executed. If false, then the next
      * task is deferred until {@link #scheduleNextTask} is called
      */
-    private <T extends StatefulActivity<?>> boolean executeCommand(CommandInfo cmd) {
+    private <T extends StatefulActivity<?> & RecentsViewContainer> boolean executeCommand(
+            CommandInfo cmd) {
         if (mWaitForToggleCommandComplete && cmd.type == TYPE_TOGGLE) {
             return true;
         }
@@ -200,7 +202,7 @@
         RecentsView visibleRecentsView = activityInterface.getVisibleRecentsView();
         RecentsView createdRecentsView;
         if (visibleRecentsView == null) {
-            T activity = activityInterface.getCreatedActivity();
+            T activity = activityInterface.getCreatedContainer();
             createdRecentsView = activity == null ? null : activity.getOverviewPanel();
             DeviceProfile dp = activity == null ? null : activity.getDeviceProfile();
             TaskbarUIController uiController = activityInterface.getTaskbarController();
@@ -296,7 +298,7 @@
             return false;
         }
 
-        final T activity = activityInterface.getCreatedActivity();
+        final T activity = activityInterface.getCreatedContainer();
         if (activity != null) {
             InteractionJankMonitorWrapper.begin(
                     activity.getRootView(),
@@ -327,7 +329,7 @@
                 interactionHandler.onGestureCancelled();
                 cmd.removeListener(this);
 
-                T createdActivity = activityInterface.getCreatedActivity();
+                T createdActivity = activityInterface.getCreatedContainer();
                 if (createdActivity == null) {
                     return;
                 }
diff --git a/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java b/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java
index c3a4351..dfbae65 100644
--- a/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java
+++ b/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java
@@ -208,7 +208,7 @@
         RecentsAnimationDeviceState rads = new RecentsAnimationDeviceState(mContext);
         OverviewComponentObserver observer = new OverviewComponentObserver(mContext, rads);
         try {
-            return observer.getActivityInterface().getCreatedActivity();
+            return observer.getActivityInterface().getCreatedContainer();
         } finally {
             observer.onDestroy();
             rads.destroy();
diff --git a/quickstep/src/com/android/quickstep/RecentTasksList.java b/quickstep/src/com/android/quickstep/RecentTasksList.java
index 4c1b1e0..879fccb 100644
--- a/quickstep/src/com/android/quickstep/RecentTasksList.java
+++ b/quickstep/src/com/android/quickstep/RecentTasksList.java
@@ -270,9 +270,13 @@
 
         int numVisibleTasks = 0;
         for (GroupedRecentTaskInfo rawTask : rawTasks) {
-            if (enableDesktopWindowingMode() && rawTask.getType() == TYPE_FREEFORM) {
-                GroupTask desktopTask = createDesktopTask(rawTask);
-                allTasks.add(desktopTask);
+            if (rawTask.getType() == TYPE_FREEFORM) {
+                // TYPE_FREEFORM tasks is only created when enableDesktopWindowingMode() is true,
+                // leftover TYPE_FREEFORM tasks created when flag was on should be ignored.
+                if (enableDesktopWindowingMode()) {
+                    GroupTask desktopTask = createDesktopTask(rawTask);
+                    allTasks.add(desktopTask);
+                }
                 continue;
             }
             ActivityManager.RecentTaskInfo taskInfo1 = rawTask.getTaskInfo1();
diff --git a/quickstep/src/com/android/quickstep/RecentsActivity.java b/quickstep/src/com/android/quickstep/RecentsActivity.java
index 81ab6be..f57f4c8 100644
--- a/quickstep/src/com/android/quickstep/RecentsActivity.java
+++ b/quickstep/src/com/android/quickstep/RecentsActivity.java
@@ -33,6 +33,7 @@
 import android.animation.AnimatorListenerAdapter;
 import android.animation.AnimatorSet;
 import android.app.ActivityOptions;
+import android.content.Context;
 import android.content.Intent;
 import android.content.res.Configuration;
 import android.os.Bundle;
@@ -85,6 +86,7 @@
 import com.android.quickstep.util.TISBindHelper;
 import com.android.quickstep.views.OverviewActionsView;
 import com.android.quickstep.views.RecentsView;
+import com.android.quickstep.views.RecentsViewContainer;
 import com.android.quickstep.views.TaskView;
 
 import java.io.FileDescriptor;
@@ -95,7 +97,8 @@
  * A recents activity that shows the recently launched tasks as swipable task cards.
  * See {@link com.android.quickstep.views.RecentsView}.
  */
-public final class RecentsActivity extends StatefulActivity<RecentsState> {
+public final class RecentsActivity extends StatefulActivity<RecentsState> implements
+        RecentsViewContainer {
     private static final String TAG = "RecentsActivity";
 
     public static final ActivityTracker<RecentsActivity> ACTIVITY_TRACKER =
@@ -109,7 +112,7 @@
     private RecentsDragLayer mDragLayer;
     private ScrimView mScrimView;
     private FallbackRecentsView mFallbackRecentsView;
-    private OverviewActionsView mActionsView;
+    private OverviewActionsView<?> mActionsView;
     private TISBindHelper mTISBindHelper;
     private @Nullable FallbackTaskbarUIController mTaskbarUIController;
 
@@ -224,11 +227,12 @@
     }
 
     @Override
-    public <T extends View> T getOverviewPanel() {
-        return (T) mFallbackRecentsView;
+    public FallbackRecentsView getOverviewPanel() {
+        return mFallbackRecentsView;
     }
 
-    public OverviewActionsView getActionsView() {
+    @Override
+    public OverviewActionsView<?> getActionsView() {
         return mActionsView;
     }
 
diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java b/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java
index c56a621..4b4f914 100644
--- a/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java
+++ b/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java
@@ -60,7 +60,6 @@
 import androidx.annotation.Nullable;
 import androidx.annotation.VisibleForTesting;
 
-import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.util.DisplayController;
 import com.android.launcher3.util.DisplayController.DisplayInfoChangeListener;
 import com.android.launcher3.util.DisplayController.Info;
@@ -68,6 +67,7 @@
 import com.android.launcher3.util.SettingsCache;
 import com.android.quickstep.TopTaskTracker.CachedTaskInfo;
 import com.android.quickstep.util.ActiveGestureLog;
+import com.android.quickstep.util.AssistStateManager;
 import com.android.quickstep.util.GestureExclusionManager;
 import com.android.quickstep.util.GestureExclusionManager.ExclusionListener;
 import com.android.quickstep.util.NavBarPosition;
@@ -97,7 +97,7 @@
     private final DisplayController mDisplayController;
 
     private final GestureExclusionManager mExclusionManager;
-
+    private final AssistStateManager mAssistStateManager;
 
     private final RotationTouchHelper mRotationTouchHelper;
     private final TaskStackChangeListener mPipListener;
@@ -148,6 +148,7 @@
         mContext = context;
         mDisplayController = DisplayController.INSTANCE.get(context);
         mExclusionManager = exclusionManager;
+        mAssistStateManager = AssistStateManager.INSTANCE.get(context);
         mIsOneHandedModeSupported = SystemProperties.getBoolean(SUPPORT_ONE_HANDED_MODE, false);
         mRotationTouchHelper = RotationTouchHelper.INSTANCE.get(context);
         if (isInstanceForTouches) {
@@ -588,9 +589,8 @@
                 : QUICKSTEP_TOUCH_SLOP_RATIO_TWO_BUTTON;
         float touchSlop = ViewConfiguration.get(mContext).getScaledTouchSlop();
 
-        if (FeatureFlags.CUSTOM_LPNH_THRESHOLDS.get()) {
-            float customSlopMultiplier =
-                    FeatureFlags.LPNH_SLOP_PERCENTAGE.get() / 100f;
+        if (mAssistStateManager.getLPNHCustomSlopMultiplier().isPresent()) {
+            float customSlopMultiplier = mAssistStateManager.getLPNHCustomSlopMultiplier().get();
             return customSlopMultiplier * slopMultiplier * touchSlop;
         } else {
             return slopMultiplier * touchSlop;
diff --git a/quickstep/src/com/android/quickstep/RemoteTargetGluer.java b/quickstep/src/com/android/quickstep/RemoteTargetGluer.java
index ffbb064..7f2aded 100644
--- a/quickstep/src/com/android/quickstep/RemoteTargetGluer.java
+++ b/quickstep/src/com/android/quickstep/RemoteTargetGluer.java
@@ -17,7 +17,6 @@
 package com.android.quickstep;
 
 import static com.android.quickstep.util.SplitScreenUtils.convertShellSplitBoundsToLauncher;
-import static com.android.window.flags.Flags.enableDesktopWindowingMode;
 import static com.android.wm.shell.util.SplitBounds.KEY_EXTRA_SPLIT_BOUNDS;
 
 import android.app.WindowConfiguration;
@@ -58,7 +57,7 @@
     /**
      * Use this constructor if remote targets are split-screen independent
      */
-    public RemoteTargetGluer(Context context, BaseActivityInterface sizingStrategy,
+    public RemoteTargetGluer(Context context, BaseContainerInterface sizingStrategy,
             RemoteAnimationTargets targets, boolean forDesktop) {
         init(context, sizingStrategy, targets.apps.length, forDesktop);
     }
@@ -67,18 +66,16 @@
      * Use this constructor if you want the number of handles created to match the number of active
      * running tasks
      */
-    public RemoteTargetGluer(Context context, BaseActivityInterface sizingStrategy) {
-        if (enableDesktopWindowingMode()) {
-            DesktopVisibilityController desktopVisibilityController =
-                    LauncherActivityInterface.INSTANCE.getDesktopVisibilityController();
-            if (desktopVisibilityController != null) {
-                int visibleTasksCount = desktopVisibilityController.getVisibleFreeformTasksCount();
-                if (visibleTasksCount > 0) {
-                    // Allocate +1 to account for a new task added to the desktop mode
-                    int numHandles = visibleTasksCount + 1;
-                    init(context, sizingStrategy, numHandles, true /* forDesktop */);
-                    return;
-                }
+    public RemoteTargetGluer(Context context, BaseContainerInterface sizingStrategy) {
+        DesktopVisibilityController desktopVisibilityController =
+                LauncherActivityInterface.INSTANCE.getDesktopVisibilityController();
+        if (desktopVisibilityController != null) {
+            int visibleTasksCount = desktopVisibilityController.getVisibleDesktopTasksCount();
+            if (visibleTasksCount > 0) {
+                // Allocate +1 to account for a new task added to the desktop mode
+                int numHandles = visibleTasksCount + 1;
+                init(context, sizingStrategy, numHandles, true /* forDesktop */);
+                return;
             }
         }
 
@@ -87,13 +84,13 @@
         init(context, sizingStrategy, DEFAULT_NUM_HANDLES, false /* forDesktop */);
     }
 
-    private void init(Context context, BaseActivityInterface sizingStrategy, int numHandles,
+    private void init(Context context, BaseContainerInterface sizingStrategy, int numHandles,
             boolean forDesktop) {
         mRemoteTargetHandles = createHandles(context, sizingStrategy, numHandles, forDesktop);
     }
 
     private RemoteTargetHandle[] createHandles(Context context,
-            BaseActivityInterface sizingStrategy, int numHandles, boolean forDesktop) {
+            BaseContainerInterface sizingStrategy, int numHandles, boolean forDesktop) {
         RemoteTargetHandle[] handles = new RemoteTargetHandle[numHandles];
         for (int i = 0; i < numHandles; i++) {
             TaskViewSimulator tvs = new TaskViewSimulator(context, sizingStrategy);
diff --git a/quickstep/src/com/android/quickstep/RotationTouchHelper.java b/quickstep/src/com/android/quickstep/RotationTouchHelper.java
index 2d47097..bf50d70 100644
--- a/quickstep/src/com/android/quickstep/RotationTouchHelper.java
+++ b/quickstep/src/com/android/quickstep/RotationTouchHelper.java
@@ -345,14 +345,14 @@
     }
 
     void onEndTargetCalculated(GestureState.GestureEndTarget endTarget,
-            BaseActivityInterface activityInterface) {
+            BaseContainerInterface containerInterface) {
         if (endTarget == GestureState.GestureEndTarget.RECENTS) {
             mInOverview = true;
             if (!mTaskListFrozen) {
                 // If we're in landscape w/o ever quickswitching, show the navbar in landscape
                 enableMultipleRegions(true);
             }
-            activityInterface.onExitOverview(this, mExitOverviewRunnable);
+            containerInterface.onExitOverview(this, mExitOverviewRunnable);
         } else if (endTarget == GestureState.GestureEndTarget.HOME
                 || endTarget == GestureState.GestureEndTarget.ALL_APPS) {
             enableMultipleRegions(false);
diff --git a/quickstep/src/com/android/quickstep/SwipeUpAnimationLogic.java b/quickstep/src/com/android/quickstep/SwipeUpAnimationLogic.java
index b920c10..5ff9787 100644
--- a/quickstep/src/com/android/quickstep/SwipeUpAnimationLogic.java
+++ b/quickstep/src/com/android/quickstep/SwipeUpAnimationLogic.java
@@ -86,7 +86,7 @@
         updateIsGestureForSplit(TopTaskTracker.INSTANCE.get(context)
                 .getRunningSplitTaskIds().length);
 
-        mTargetGluer = new RemoteTargetGluer(mContext, mGestureState.getActivityInterface());
+        mTargetGluer = new RemoteTargetGluer(mContext, mGestureState.getContainerInterface());
         mRemoteTargetHandles = mTargetGluer.getRemoteTargetHandles();
         runActionOnRemoteHandles(remoteTargetHandle ->
                 remoteTargetHandle.getTaskViewSimulator().getOrientationState().update(
@@ -97,9 +97,10 @@
 
     protected void initTransitionEndpoints(DeviceProfile dp) {
         mDp = dp;
-        mTransitionDragLength = mGestureState.getActivityInterface().getSwipeUpDestinationAndLength(
-                dp, mContext, TEMP_RECT, mRemoteTargetHandles[0].getTaskViewSimulator()
-                        .getOrientationState().getOrientationHandler());
+        mTransitionDragLength = mGestureState.getContainerInterface()
+                .getSwipeUpDestinationAndLength(dp, mContext, TEMP_RECT,
+                        mRemoteTargetHandles[0].getTaskViewSimulator().getOrientationState()
+                                .getOrientationHandler());
         mDragLengthFactor = (float) dp.heightPx / mTransitionDragLength;
 
         for (RemoteTargetHandle remoteHandle : mRemoteTargetHandles) {
diff --git a/quickstep/src/com/android/quickstep/SystemUiProxy.java b/quickstep/src/com/android/quickstep/SystemUiProxy.java
index b6272da..30bb863 100644
--- a/quickstep/src/com/android/quickstep/SystemUiProxy.java
+++ b/quickstep/src/com/android/quickstep/SystemUiProxy.java
@@ -63,7 +63,6 @@
 import com.android.internal.logging.InstanceId;
 import com.android.internal.util.ScreenshotRequest;
 import com.android.internal.view.AppearanceRegion;
-import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.util.MainThreadInitializedObject;
 import com.android.launcher3.util.Preconditions;
 import com.android.quickstep.util.ActiveGestureLog;
@@ -82,6 +81,7 @@
 import com.android.wm.shell.back.IBackAnimation;
 import com.android.wm.shell.bubbles.IBubbles;
 import com.android.wm.shell.bubbles.IBubblesListener;
+import com.android.wm.shell.common.bubbles.BubbleBarLocation;
 import com.android.wm.shell.common.pip.IPip;
 import com.android.wm.shell.common.pip.IPipAnimationListener;
 import com.android.wm.shell.common.split.SplitScreenConstants.PersistentSnapPosition;
@@ -91,7 +91,6 @@
 import com.android.wm.shell.onehanded.IOneHanded;
 import com.android.wm.shell.recents.IRecentTasks;
 import com.android.wm.shell.recents.IRecentTasksListener;
-import com.android.wm.shell.shared.IHomeTransitionListener;
 import com.android.wm.shell.shared.IShellTransitions;
 import com.android.wm.shell.splitscreen.ISplitScreen;
 import com.android.wm.shell.splitscreen.ISplitScreenListener;
@@ -157,7 +156,7 @@
     private IOnBackInvokedCallback mBackToLauncherCallback;
     private IRemoteAnimationRunner mBackToLauncherRunner;
     private IDragAndDrop mDragAndDrop;
-    private IHomeTransitionListener mHomeTransitionListener;
+    private final HomeVisibilityState mHomeVisibilityState = new HomeVisibilityState();
 
     // Used to dedupe calls to SystemUI
     private int mLastShelfHeight;
@@ -269,7 +268,7 @@
         setBubblesListener(mBubblesListener);
         registerSplitScreenListener(mSplitScreenListener);
         registerSplitSelectListener(mSplitSelectListener);
-        setHomeTransitionListener(mHomeTransitionListener);
+        mHomeVisibilityState.init(mShellTransitions);
         setStartingWindowListener(mStartingWindowListener);
         setLauncherUnlockAnimationController(
                 mLauncherActivityClass, mLauncherUnlockAnimationController);
@@ -455,6 +454,17 @@
     }
 
     @Override
+    public void setOverrideHomeButtonLongPress(long duration, float slopMultiplier) {
+        if (mSystemUiProxy != null) {
+            try {
+                mSystemUiProxy.setOverrideHomeButtonLongPress(duration, slopMultiplier);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed call setOverrideHomeButtonLongPress", e);
+            }
+        }
+    }
+
+    @Override
     public void notifyAccessibilityButtonClicked(int displayId) {
         if (mSystemUiProxy != null) {
             try {
@@ -808,6 +818,32 @@
         }
     }
 
+    /**
+     * Tells SysUI to update the bubble bar location to the new location.
+     * @param location new location for the bubble bar
+     */
+    public void setBubbleBarLocation(BubbleBarLocation location) {
+        try {
+            mBubbles.setBubbleBarLocation(location);
+        } catch (RemoteException e) {
+            Log.w(TAG, "Failed call setBubbleBarLocation");
+        }
+    }
+
+    /**
+     * Tells SysUI the bounds for the bubble bar
+     * @param bubbleBarBounds bounds of the bubble bar in display coordinates
+     */
+    public void setBubbleBarBounds(Rect bubbleBarBounds) {
+        try {
+            if (mBubbles != null) {
+                mBubbles.setBubbleBarBounds(bubbleBarBounds);
+            }
+        } catch (RemoteException e) {
+            Log.w(TAG, "Failed call setBubbleBarBounds");
+        }
+    }
+
     //
     // Splitscreen
     //
@@ -1102,22 +1138,8 @@
         mRemoteTransitions.remove(remoteTransition);
     }
 
-    public void setHomeTransitionListener(IHomeTransitionListener listener) {
-        if (!FeatureFlags.enableHomeTransitionListener()) {
-            return;
-        }
-
-        mHomeTransitionListener = listener;
-
-        if (mShellTransitions != null) {
-            try {
-                mShellTransitions.setHomeTransitionListener(listener);
-            } catch (RemoteException e) {
-                Log.w(TAG, "Failed call setHomeTransitionListener", e);
-            }
-        } else  {
-            Log.w(TAG, "Unable to call setHomeTransitionListener because ShellTransitions is null");
-        }
+    public HomeVisibilityState getHomeVisibilityState() {
+        return mHomeVisibilityState;
     }
 
     /**
@@ -1453,6 +1475,17 @@
         }
     }
 
+    /** Call shell to move a task with given `taskId` to desktop  */
+    public void moveToDesktop(int taskId) {
+        if (mDesktopMode != null) {
+            try {
+                mDesktopMode.moveToDesktop(taskId);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed call moveToDesktop", e);
+            }
+        }
+    }
+
     //
     // Unfold transition
     //
@@ -1558,7 +1591,7 @@
         pw.println("\tmSplitSelectListener=" + mSplitSelectListener);
         pw.println("\tmOneHanded=" + mOneHanded);
         pw.println("\tmShellTransitions=" + mShellTransitions);
-        pw.println("\tmHomeTransitionListener=" + mHomeTransitionListener);
+        pw.println("\tmHomeVisibilityState=" + mHomeVisibilityState);
         pw.println("\tmStartingWindow=" + mStartingWindow);
         pw.println("\tmStartingWindowListener=" + mStartingWindowListener);
         pw.println("\tmSysuiUnlockAnimationController=" + mSysuiUnlockAnimationController);
diff --git a/quickstep/src/com/android/quickstep/TaskAnimationManager.java b/quickstep/src/com/android/quickstep/TaskAnimationManager.java
index 4e62d60..3b1ed46 100644
--- a/quickstep/src/com/android/quickstep/TaskAnimationManager.java
+++ b/quickstep/src/com/android/quickstep/TaskAnimationManager.java
@@ -77,10 +77,11 @@
                         mLiveTileRestartListener);
                 return;
             }
-            BaseActivityInterface activityInterface = mLastGestureState.getActivityInterface();
-            if (activityInterface.isInLiveTileMode()
-                    && activityInterface.getCreatedActivity() != null) {
-                RecentsView recentsView = activityInterface.getCreatedActivity().getOverviewPanel();
+            BaseContainerInterface containerInterface = mLastGestureState.getContainerInterface();
+            if (containerInterface.isInLiveTileMode()
+                    && containerInterface.getCreatedContainer() != null) {
+                RecentsView recentsView = containerInterface.getCreatedContainer()
+                        .getOverviewPanel();
                 if (recentsView != null) {
                     recentsView.launchSideTaskInLiveTileModeForRestartedApp(task.taskId);
                     TaskStackChangeListeners.getInstance().unregisterTaskStackListener(
@@ -135,10 +136,10 @@
             cleanUpRecentsAnimation(mCallbacks);
         }
 
-        final BaseActivityInterface activityInterface = gestureState.getActivityInterface();
+        final BaseContainerInterface containerInterface = gestureState.getContainerInterface();
         mLastGestureState = gestureState;
         RecentsAnimationCallbacks newCallbacks = new RecentsAnimationCallbacks(
-                SystemUiProxy.INSTANCE.get(mCtx), activityInterface.allowMinimizeSplitScreen());
+                SystemUiProxy.INSTANCE.get(mCtx), containerInterface.allowMinimizeSplitScreen());
         mCallbacks = newCallbacks;
         mCallbacks.addListener(new RecentsAnimationCallbacks.RecentsAnimationListener() {
             @Override
@@ -208,17 +209,18 @@
             @Override
             public void onTasksAppeared(RemoteAnimationTarget[] appearedTaskTargets) {
                 RemoteAnimationTarget appearedTaskTarget = appearedTaskTargets[0];
-                BaseActivityInterface activityInterface = mLastGestureState.getActivityInterface();
+                BaseContainerInterface containerInterface =
+                        mLastGestureState.getContainerInterface();
 
                 for (RemoteAnimationTarget compat : appearedTaskTargets) {
                     if (compat.windowConfiguration.getActivityType() == ACTIVITY_TYPE_HOME
-                            && activityInterface.getCreatedActivity() instanceof RecentsActivity
+                            && containerInterface.getCreatedContainer() instanceof RecentsActivity
                             && DisplayController.getNavigationMode(mCtx) != NO_BUTTON) {
                         // The only time we get onTasksAppeared() in button navigation with a
                         // 3p launcher is if the user goes to overview first, and in this case we
                         // can immediately finish the transition
                         RecentsView recentsView =
-                                activityInterface.getCreatedActivity().getOverviewPanel();
+                                containerInterface.getCreatedContainer().getOverviewPanel();
                         if (recentsView != null) {
                             recentsView.finishRecentsAnimation(true, null);
                         }
@@ -232,12 +234,12 @@
                 if (nonAppTargets == null) {
                     nonAppTargets = new RemoteAnimationTarget[0];
                 }
-                if ((activityInterface.isInLiveTileMode()
+                if ((containerInterface.isInLiveTileMode()
                             || mLastGestureState.getEndTarget() == RECENTS
                             || isNonRecentsStartedTasksAppeared(appearedTaskTargets))
-                        && activityInterface.getCreatedActivity() != null) {
+                        && containerInterface.getCreatedContainer() != null) {
                     RecentsView recentsView =
-                            activityInterface.getCreatedActivity().getOverviewPanel();
+                            containerInterface.getCreatedContainer().getOverviewPanel();
                     if (recentsView != null) {
                         ActiveGestureLog.INSTANCE.addLog(
                                 new ActiveGestureLog.CompoundString("Launching side task id=")
@@ -272,13 +274,13 @@
 
             @Override
             public boolean onSwitchToScreenshot(Runnable onFinished) {
-                if (!activityInterface.isInLiveTileMode()
-                        || activityInterface.getCreatedActivity() == null) {
+                if (!containerInterface.isInLiveTileMode()
+                        || containerInterface.getCreatedContainer() == null) {
                     // No need to switch since tile is already a screenshot.
                     onFinished.run();
                 } else {
                     final RecentsView recentsView =
-                            activityInterface.getCreatedActivity().getOverviewPanel();
+                            containerInterface.getCreatedContainer().getOverviewPanel();
                     if (recentsView != null) {
                         recentsView.switchToScreenshot(onFinished);
                     } else {
@@ -295,7 +297,7 @@
         if (ENABLE_SHELL_TRANSITIONS) {
             final ActivityOptions options = ActivityOptions.makeBasic();
             // Use regular (non-transient) launch for all apps page to control IME.
-            if (!activityInterface.allowAllAppsFromOverview()) {
+            if (!containerInterface.allowAllAppsFromOverview()) {
                 options.setTransientLaunch();
             }
             options.setSourceInfo(ActivityOptions.SourceInfo.TYPE_RECENTS_ANIMATION, eventTime);
@@ -332,10 +334,10 @@
         if (mLastGestureState == null) {
             return;
         }
-        BaseActivityInterface activityInterface = mLastGestureState.getActivityInterface();
-        if (activityInterface.isInLiveTileMode()
-                && activityInterface.getCreatedActivity() != null) {
-            RecentsView recentsView = activityInterface.getCreatedActivity().getOverviewPanel();
+        BaseContainerInterface containerInterface = mLastGestureState.getContainerInterface();
+        if (containerInterface.isInLiveTileMode()
+                && containerInterface.getCreatedContainer() != null) {
+            RecentsView recentsView = containerInterface.getCreatedContainer().getOverviewPanel();
             if (recentsView != null) {
                 recentsView.switchToScreenshot(null,
                         () -> recentsView.finishRecentsAnimation(true /* toRecents */,
diff --git a/quickstep/src/com/android/quickstep/TaskOverlayFactory.java b/quickstep/src/com/android/quickstep/TaskOverlayFactory.java
index cc582d1..18b8e3e 100644
--- a/quickstep/src/com/android/quickstep/TaskOverlayFactory.java
+++ b/quickstep/src/com/android/quickstep/TaskOverlayFactory.java
@@ -33,7 +33,6 @@
 import androidx.annotation.RequiresApi;
 
 import com.android.launcher3.BaseActivity;
-import com.android.launcher3.BaseDraggingActivity;
 import com.android.launcher3.Flags;
 import com.android.launcher3.R;
 import com.android.launcher3.model.data.ItemInfo;
@@ -46,6 +45,7 @@
 import com.android.quickstep.views.GroupedTaskView;
 import com.android.quickstep.views.OverviewActionsView;
 import com.android.quickstep.views.RecentsView;
+import com.android.quickstep.views.RecentsViewContainer;
 import com.android.quickstep.views.TaskThumbnailView;
 import com.android.quickstep.views.TaskView;
 import com.android.quickstep.views.TaskView.TaskIdAttributeContainer;
@@ -63,14 +63,15 @@
     public static List<SystemShortcut> getEnabledShortcuts(TaskView taskView,
             TaskIdAttributeContainer taskContainer) {
         final ArrayList<SystemShortcut> shortcuts = new ArrayList<>();
-        final BaseDraggingActivity activity = BaseActivity.fromContext(taskView.getContext());
+        final RecentsViewContainer container =
+                RecentsViewContainer.containerFromContext(taskView.getContext());
         boolean hasMultipleTasks = taskView.getTaskIds()[1] != -1;
         for (TaskShortcutFactory menuOption : MENU_OPTIONS) {
             if (hasMultipleTasks && !menuOption.showForSplitscreen()) {
                 continue;
             }
 
-            List<SystemShortcut> menuShortcuts = menuOption.getShortcuts(activity, taskContainer);
+            List<SystemShortcut> menuShortcuts = menuOption.getShortcuts(container, taskContainer);
             if (menuShortcuts == null) {
                 continue;
             }
@@ -79,15 +80,16 @@
         RecentsOrientedState orientedState = taskView.getRecentsView().getPagedViewOrientedState();
         boolean canLauncherRotate = orientedState.isRecentsActivityRotationAllowed();
         boolean isInLandscape = orientedState.getTouchRotation() != ROTATION_0;
-        boolean isTablet = activity.getDeviceProfile().isTablet;
+        boolean isTablet = container.getDeviceProfile().isTablet;
 
         boolean isGridOnlyOverview = isTablet && Flags.enableGridOnlyOverview();
-        // Add overview actions to the menu when in in-place rotate landscape mode, or in
-        // grid-only overview.
-        if ((!canLauncherRotate && isInLandscape) || isGridOnlyOverview) {
+        // Add overview actions to the menu when:
+        // - single task is showing
+        // - in in-place rotate landscape mode, or in grid-only overview.
+        if (!hasMultipleTasks && ((!canLauncherRotate && isInLandscape) || isGridOnlyOverview)) {
             // Add screenshot action to task menu.
             List<SystemShortcut> screenshotShortcuts = TaskShortcutFactory.SCREENSHOT
-                    .getShortcuts(activity, taskContainer);
+                    .getShortcuts(container, taskContainer);
             if (screenshotShortcuts != null) {
                 shortcuts.addAll(screenshotShortcuts);
             }
@@ -96,7 +98,7 @@
             // or in grid-only overview.
             if (orientedState.getDisplayRotation() == ROTATION_0 || isGridOnlyOverview) {
                 List<SystemShortcut> modalShortcuts = TaskShortcutFactory.MODAL
-                        .getShortcuts(activity, taskContainer);
+                        .getShortcuts(container, taskContainer);
                 if (modalShortcuts != null) {
                     shortcuts.addAll(modalShortcuts);
                 }
@@ -136,6 +138,7 @@
             TaskShortcutFactory.PIN,
             TaskShortcutFactory.INSTALL,
             TaskShortcutFactory.FREE_FORM,
+            DesktopSystemShortcut.Companion.createFactory(),
             TaskShortcutFactory.WELLBEING,
             TaskShortcutFactory.SAVE_APP_PAIR
     };
@@ -253,9 +256,9 @@
         /**
          * Gets the system shortcut for the screenshot that will be added to the task menu.
          */
-        public SystemShortcut getScreenshotShortcut(BaseDraggingActivity activity,
+        public SystemShortcut getScreenshotShortcut(RecentsViewContainer container,
                 ItemInfo iteminfo, View originalView) {
-            return new ScreenshotSystemShortcut(activity, iteminfo, originalView);
+            return new ScreenshotSystemShortcut(container, iteminfo, originalView);
         }
 
         /**
@@ -303,19 +306,19 @@
 
         private class ScreenshotSystemShortcut extends SystemShortcut {
 
-            private final BaseDraggingActivity mActivity;
+            private final RecentsViewContainer mContainer;
 
-            ScreenshotSystemShortcut(BaseDraggingActivity activity, ItemInfo itemInfo,
+            ScreenshotSystemShortcut(RecentsViewContainer container, ItemInfo itemInfo,
                     View originalView) {
-                super(R.drawable.ic_screenshot, R.string.action_screenshot, activity, itemInfo,
+                super(R.drawable.ic_screenshot, R.string.action_screenshot, container, itemInfo,
                         originalView);
-                mActivity = activity;
+                mContainer = container;
             }
 
             @Override
             public void onClick(View view) {
                 saveScreenshot(mThumbnailView.getTaskView().getTask());
-                dismissTaskMenuView(mActivity);
+                dismissTaskMenuView();
             }
         }
 
diff --git a/quickstep/src/com/android/quickstep/TaskShortcutFactory.java b/quickstep/src/com/android/quickstep/TaskShortcutFactory.java
index 147a3e2..9d10ac1 100644
--- a/quickstep/src/com/android/quickstep/TaskShortcutFactory.java
+++ b/quickstep/src/com/android/quickstep/TaskShortcutFactory.java
@@ -22,7 +22,6 @@
 import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_SYSTEM_SHORTCUT_FREE_FORM_TAP;
 import static com.android.window.flags.Flags.enableDesktopWindowingMode;
 
-import android.app.Activity;
 import android.app.ActivityOptions;
 import android.graphics.Bitmap;
 import android.graphics.Color;
@@ -39,7 +38,6 @@
 
 import androidx.annotation.Nullable;
 
-import com.android.launcher3.BaseDraggingActivity;
 import com.android.launcher3.DeviceProfile;
 import com.android.launcher3.R;
 import com.android.launcher3.config.FeatureFlags;
@@ -50,9 +48,11 @@
 import com.android.launcher3.popup.SystemShortcut.AppInfo;
 import com.android.launcher3.util.InstantAppResolver;
 import com.android.launcher3.util.SplitConfigurationOptions.SplitPositionOption;
+import com.android.launcher3.views.ActivityContext;
 import com.android.quickstep.orientation.RecentsPagedOrientationHandler;
 import com.android.quickstep.views.GroupedTaskView;
 import com.android.quickstep.views.RecentsView;
+import com.android.quickstep.views.RecentsViewContainer;
 import com.android.quickstep.views.TaskThumbnailView;
 import com.android.quickstep.views.TaskView;
 import com.android.quickstep.views.TaskView.TaskIdAttributeContainer;
@@ -74,7 +74,7 @@
  */
 public interface TaskShortcutFactory {
     @Nullable
-    default List<SystemShortcut> getShortcuts(BaseDraggingActivity activity,
+    default List<SystemShortcut> getShortcuts(RecentsViewContainer container,
             TaskIdAttributeContainer taskContainer) {
         return null;
     }
@@ -94,7 +94,7 @@
 
     TaskShortcutFactory APP_INFO = new TaskShortcutFactory() {
         @Override
-        public List<SystemShortcut> getShortcuts(BaseDraggingActivity activity,
+        public List<SystemShortcut> getShortcuts(RecentsViewContainer container,
                 TaskIdAttributeContainer taskContainer) {
             TaskView taskView = taskContainer.getTaskView();
             AppInfo.SplitAccessibilityInfo accessibilityInfo =
@@ -102,7 +102,7 @@
                             TaskUtils.getTitle(taskView.getContext(), taskContainer.getTask()),
                             taskContainer.getA11yNodeId()
                     );
-            return Collections.singletonList(new AppInfo(activity, taskContainer.getItemInfo(),
+            return Collections.singletonList(new AppInfo(container, taskContainer.getItemInfo(),
                     taskView, accessibilityInfo));
         }
 
@@ -116,9 +116,9 @@
         private final TaskView mTaskView;
         private final SplitPositionOption mSplitPositionOption;
 
-        public SplitSelectSystemShortcut(BaseDraggingActivity target, TaskView taskView,
+        public SplitSelectSystemShortcut(RecentsViewContainer container, TaskView taskView,
                 SplitPositionOption option) {
-            super(option.iconResId, option.textResId, target, taskView.getItemInfo(), taskView);
+            super(option.iconResId, option.textResId, container, taskView.getItemInfo(), taskView);
             mTaskView = taskView;
             mSplitPositionOption = option;
         }
@@ -133,25 +133,26 @@
      * A menu item, "Save app pair", that allows the user to preserve the current app combination as
      * one persistent icon on the Home screen, allowing for quick split screen launching.
      */
-    class SaveAppPairSystemShortcut extends SystemShortcut<BaseDraggingActivity> {
+    class SaveAppPairSystemShortcut extends SystemShortcut<RecentsViewContainer> {
         private final GroupedTaskView mTaskView;
 
-        public SaveAppPairSystemShortcut(BaseDraggingActivity activity, GroupedTaskView taskView,
-                int iconResId) {
-            super(iconResId, R.string.save_app_pair, activity,
+
+        public SaveAppPairSystemShortcut(RecentsViewContainer container, GroupedTaskView taskView,
+            int iconResId) {
+                super(iconResId, R.string.save_app_pair, container,
                     taskView.getItemInfo(), taskView);
             mTaskView = taskView;
         }
 
         @Override
         public void onClick(View view) {
-            dismissTaskMenuView(mTarget);
+            dismissTaskMenuView();
             ((RecentsView) mTarget.getOverviewPanel())
                     .getSplitSelectController().getAppPairsController().saveAppPair(mTaskView);
         }
     }
 
-    class FreeformSystemShortcut extends SystemShortcut<BaseDraggingActivity> {
+    class FreeformSystemShortcut extends SystemShortcut<RecentsViewContainer> {
         private static final String TAG = "FreeformSystemShortcut";
 
         private Handler mHandler;
@@ -161,20 +162,20 @@
         private final TaskView mTaskView;
         private final LauncherEvent mLauncherEvent;
 
-        public FreeformSystemShortcut(int iconRes, int textRes, BaseDraggingActivity activity,
+        public FreeformSystemShortcut(int iconRes, int textRes, RecentsViewContainer container,
                 TaskIdAttributeContainer taskContainer, LauncherEvent launcherEvent) {
-            super(iconRes, textRes, activity, taskContainer.getItemInfo(),
+            super(iconRes, textRes, container, taskContainer.getItemInfo(),
                     taskContainer.getTaskView());
             mLauncherEvent = launcherEvent;
             mHandler = new Handler(Looper.getMainLooper());
             mTaskView = taskContainer.getTaskView();
-            mRecentsView = activity.getOverviewPanel();
+            mRecentsView = container.getOverviewPanel();
             mThumbnailView = taskContainer.getThumbnailView();
         }
 
         @Override
         public void onClick(View view) {
-            dismissTaskMenuView(mTarget);
+            dismissTaskMenuView();
             RecentsView rv = mTarget.getOverviewPanel();
             rv.switchToScreenshot(() -> {
                 rv.finishRecentsAnimation(true /* toRecents */, false /* shouldPip */, () -> {
@@ -252,11 +253,11 @@
             }
         }
 
-        private ActivityOptions makeLaunchOptions(Activity activity) {
+        private ActivityOptions makeLaunchOptions(RecentsViewContainer container) {
             ActivityOptions activityOptions = ActivityOptions.makeBasic();
             activityOptions.setLaunchWindowingMode(WINDOWING_MODE_FREEFORM);
             // Arbitrary bounds only because freeform is in dev mode right now
-            final View decorView = activity.getWindow().getDecorView();
+            final View decorView = container.getWindow().getDecorView();
             final WindowInsets insets = decorView.getRootWindowInsets();
             final Rect r = new Rect(0, 0, decorView.getWidth() / 2, decorView.getHeight() / 2);
             r.offsetTo(insets.getSystemWindowInsetLeft() + 50,
@@ -277,9 +278,9 @@
      */
     TaskShortcutFactory SPLIT_SELECT = new TaskShortcutFactory() {
         @Override
-        public List<SystemShortcut> getShortcuts(BaseDraggingActivity activity,
+        public List<SystemShortcut> getShortcuts(RecentsViewContainer container,
                 TaskIdAttributeContainer taskContainer) {
-            DeviceProfile deviceProfile = activity.getDeviceProfile();
+            DeviceProfile deviceProfile = container.getDeviceProfile();
             final Task task = taskContainer.getTask();
             final int intentFlags = task.key.baseIntent.getFlags();
             final TaskView taskView = taskContainer.getTaskView();
@@ -291,7 +292,7 @@
                     !deviceProfile.isTaskbarPresent && recentsView.getTaskViewCount() < 2;
             boolean isTaskSplitNotSupported = !task.isDockable ||
                     (intentFlags & FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) != 0;
-            boolean hideForExistingMultiWindow = activity.getDeviceProfile().isMultiWindowMode;
+            boolean hideForExistingMultiWindow = container.getDeviceProfile().isMultiWindowMode;
             boolean isFocusedTask = deviceProfile.isTablet && taskView.isFocusedTask();
             boolean isTaskInExpectedScrollPosition =
                     recentsView.isTaskInExpectedScrollPosition(recentsView.indexOfChild(taskView));
@@ -304,7 +305,7 @@
             return orientationHandler.getSplitPositionOptions(deviceProfile)
                     .stream()
                     .map((Function<SplitPositionOption, SystemShortcut>) option ->
-                            new SplitSelectSystemShortcut(activity, taskView, option))
+                            new SplitSelectSystemShortcut(container, taskView, option))
                     .collect(Collectors.toList());
         }
     };
@@ -312,9 +313,9 @@
     TaskShortcutFactory SAVE_APP_PAIR = new TaskShortcutFactory() {
         @Nullable
         @Override
-        public List<SystemShortcut> getShortcuts(BaseDraggingActivity activity,
+        public List<SystemShortcut> getShortcuts(RecentsViewContainer container,
                 TaskIdAttributeContainer taskContainer) {
-            DeviceProfile deviceProfile = activity.getDeviceProfile();
+            DeviceProfile deviceProfile = container.getDeviceProfile();
             final TaskView taskView = taskContainer.getTaskView();
             final RecentsView recentsView = taskView.getRecentsView();
             boolean isLargeTileFocusedTask = deviceProfile.isTablet && taskView.isFocusedTask();
@@ -348,7 +349,8 @@
                     : R.drawable.ic_save_app_pair_up_down;
 
             return Collections.singletonList(
-                    new SaveAppPairSystemShortcut(activity, (GroupedTaskView) taskView, iconResId));
+                    new SaveAppPairSystemShortcut(container,
+                            (GroupedTaskView) taskView, iconResId));
         }
 
         @Override
@@ -359,25 +361,25 @@
 
     TaskShortcutFactory FREE_FORM = new TaskShortcutFactory() {
         @Override
-        public List<SystemShortcut> getShortcuts(BaseDraggingActivity activity,
+        public List<SystemShortcut> getShortcuts(RecentsViewContainer container,
                 TaskIdAttributeContainer taskContainer) {
             final Task task = taskContainer.getTask();
             if (!task.isDockable) {
                 return null;
             }
-            if (!isAvailable(activity, task.key.displayId)) {
+            if (!isAvailable(container)) {
                 return null;
             }
 
             return Collections.singletonList(new FreeformSystemShortcut(
                     R.drawable.ic_caption_desktop_button_foreground,
-                    R.string.recent_task_option_freeform, activity, taskContainer,
+                    R.string.recent_task_option_freeform, container, taskContainer,
                     LAUNCHER_SYSTEM_SHORTCUT_FREE_FORM_TAP));
         }
 
-        private boolean isAvailable(BaseDraggingActivity activity, int displayId) {
+        private boolean isAvailable(RecentsViewContainer container) {
             return Settings.Global.getInt(
-                    activity.getContentResolver(),
+                    container.asContext().getContentResolver(),
                     Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0
                     && !enableDesktopWindowingMode();
         }
@@ -385,9 +387,9 @@
 
     TaskShortcutFactory PIN = new TaskShortcutFactory() {
         @Override
-        public List<SystemShortcut> getShortcuts(BaseDraggingActivity activity,
+        public List<SystemShortcut> getShortcuts(RecentsViewContainer container,
                 TaskIdAttributeContainer taskContainer) {
-            if (!SystemUiProxy.INSTANCE.get(activity).isActive()) {
+            if (!SystemUiProxy.INSTANCE.get(container.asContext()).isActive()) {
                 return null;
             }
             if (!ActivityManagerWrapper.getInstance().isScreenPinningEnabled()) {
@@ -397,17 +399,17 @@
                 // We shouldn't be able to pin while an app is locked.
                 return null;
             }
-            return Collections.singletonList(new PinSystemShortcut(activity, taskContainer));
+            return Collections.singletonList(new PinSystemShortcut(container, taskContainer));
         }
     };
 
-    class PinSystemShortcut extends SystemShortcut<BaseDraggingActivity> {
+    class PinSystemShortcut extends SystemShortcut<RecentsViewContainer> {
 
         private static final String TAG = "PinSystemShortcut";
 
         private final TaskView mTaskView;
 
-        public PinSystemShortcut(BaseDraggingActivity target,
+        public PinSystemShortcut(RecentsViewContainer target,
                 TaskIdAttributeContainer taskContainer) {
             super(R.drawable.ic_pin, R.string.recent_task_option_pin, target,
                     taskContainer.getItemInfo(), taskContainer.getTaskView());
@@ -417,10 +419,10 @@
         @Override
         public void onClick(View view) {
             if (mTaskView.launchTaskAnimated() != null) {
-                SystemUiProxy.INSTANCE.get(mTarget).startScreenPinning(
+                SystemUiProxy.INSTANCE.get(mTarget.asContext()).startScreenPinning(
                         mTaskView.getTask().key.id);
             }
-            dismissTaskMenuView(mTarget);
+            dismissTaskMenuView();
             mTarget.getStatsLogManager().logger().withItemInfo(mTaskView.getItemInfo())
                     .log(LauncherEvent.LAUNCHER_SYSTEM_SHORTCUT_PIN_TAP);
         }
@@ -428,12 +430,12 @@
 
     TaskShortcutFactory INSTALL = new TaskShortcutFactory() {
         @Override
-        public List<SystemShortcut> getShortcuts(BaseDraggingActivity activity,
+        public List<SystemShortcut> getShortcuts(RecentsViewContainer container,
                 TaskIdAttributeContainer taskContainer) {
             Task t = taskContainer.getTask();
-            return InstantAppResolver.newInstance(activity).isInstantApp(
+            return InstantAppResolver.newInstance(container.asContext()).isInstantApp(
                     t.getTopComponent().getPackageName(), t.getKey().userId)
-                    ? Collections.singletonList(new SystemShortcut.Install(activity,
+                    ? Collections.singletonList(new SystemShortcut.Install(container,
                     taskContainer.getItemInfo(), taskContainer.getTaskView()))
                     : null;
         }
@@ -441,10 +443,10 @@
 
     TaskShortcutFactory WELLBEING = new TaskShortcutFactory() {
         @Override
-        public List<SystemShortcut> getShortcuts(BaseDraggingActivity activity,
+        public List<SystemShortcut> getShortcuts(RecentsViewContainer container,
                 TaskIdAttributeContainer taskContainer) {
-            SystemShortcut<BaseDraggingActivity> wellbeingShortcut =
-                    WellbeingModel.SHORTCUT_FACTORY.getShortcut(activity,
+            SystemShortcut<ActivityContext> wellbeingShortcut =
+                    WellbeingModel.SHORTCUT_FACTORY.getShortcut(container,
                             taskContainer.getItemInfo(), taskContainer.getTaskView());
             return createSingletonShortcutList(wellbeingShortcut);
         }
@@ -452,11 +454,11 @@
 
     TaskShortcutFactory SCREENSHOT = new TaskShortcutFactory() {
         @Override
-        public List<SystemShortcut> getShortcuts(BaseDraggingActivity activity,
+        public List<SystemShortcut> getShortcuts(RecentsViewContainer container,
                 TaskIdAttributeContainer taskContainer) {
             SystemShortcut screenshotShortcut =
                     taskContainer.getThumbnailView().getTaskOverlay()
-                            .getScreenshotShortcut(activity, taskContainer.getItemInfo(),
+                            .getScreenshotShortcut(container, taskContainer.getItemInfo(),
                                     taskContainer.getTaskView());
             return createSingletonShortcutList(screenshotShortcut);
         }
@@ -464,7 +466,7 @@
 
     TaskShortcutFactory MODAL = new TaskShortcutFactory() {
         @Override
-        public List<SystemShortcut> getShortcuts(BaseDraggingActivity activity,
+        public List<SystemShortcut> getShortcuts(RecentsViewContainer container,
                 TaskIdAttributeContainer taskContainer) {
             SystemShortcut modalStateSystemShortcut =
                     taskContainer.getThumbnailView().getTaskOverlay()
diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java
index 66d7144..7035d6e 100644
--- a/quickstep/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java
@@ -95,7 +95,6 @@
 import com.android.launcher3.testing.TestLogging;
 import com.android.launcher3.testing.shared.ResourceUtils;
 import com.android.launcher3.testing.shared.TestProtocol;
-import com.android.launcher3.uioverrides.flags.FlagsFactory;
 import com.android.launcher3.uioverrides.plugins.PluginManagerWrapper;
 import com.android.launcher3.util.DisplayController;
 import com.android.launcher3.util.LockedUserState;
@@ -120,6 +119,7 @@
 import com.android.quickstep.util.ActiveGestureLog.CompoundString;
 import com.android.quickstep.util.AssistStateManager;
 import com.android.quickstep.util.AssistUtils;
+import com.android.quickstep.views.RecentsViewContainer;
 import com.android.systemui.shared.recents.IOverviewProxy;
 import com.android.systemui.shared.recents.ISystemUiProxy;
 import com.android.systemui.shared.system.ActivityManagerWrapper;
@@ -317,7 +317,7 @@
         public void enterStageSplitFromRunningApp(boolean leftOrTop) {
             executeForTouchInteractionService(tis -> {
                 StatefulActivity activity =
-                        tis.mOverviewComponentObserver.getActivityInterface().getCreatedActivity();
+                        tis.mOverviewComponentObserver.getActivityInterface().getCreatedContainer();
                 if (activity != null) {
                     activity.enterStageSplitFromRunningApp(leftOrTop);
                 }
@@ -594,7 +594,7 @@
         mAllAppsActionManager.setHomeAndOverviewSame(isHomeAndOverviewSame);
 
         StatefulActivity newOverviewActivity = mOverviewComponentObserver.getActivityInterface()
-                .getCreatedActivity();
+                .getCreatedContainer();
         if (newOverviewActivity != null) {
             mTaskbarManager.setActivity(newOverviewActivity);
         }
@@ -602,23 +602,21 @@
     }
 
     private PendingIntent createAllAppsPendingIntent() {
-        final Intent homeIntent = new Intent(mOverviewComponentObserver.getHomeIntent())
-                .setAction(INTENT_ACTION_ALL_APPS_TOGGLE);
-
         if (FeatureFlags.ENABLE_ALL_APPS_SEARCH_IN_TASKBAR.get()) {
             return new PendingIntent(new IIntentSender.Stub() {
                 @Override
                 public void send(int code, Intent intent, String resolvedType,
                         IBinder allowlistToken, IIntentReceiver finishedReceiver,
                         String requiredPermission, Bundle options) {
-                    MAIN_EXECUTOR.execute(() -> mTaskbarManager.toggleAllApps(homeIntent));
+                    MAIN_EXECUTOR.execute(() -> mTaskbarManager.toggleAllApps());
                 }
             });
         } else {
             return PendingIntent.getActivity(
                     this,
                     GLOBAL_ACTION_ACCESSIBILITY_ALL_APPS,
-                    homeIntent,
+                    new Intent(mOverviewComponentObserver.getHomeIntent())
+                            .setAction(INTENT_ACTION_ALL_APPS_TOGGLE),
                     PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
         }
     }
@@ -830,8 +828,8 @@
             }
         }
 
-        boolean cancelGesture = mGestureState.getActivityInterface() != null
-                && mGestureState.getActivityInterface().shouldCancelCurrentGesture();
+        boolean cancelGesture = mGestureState.getContainerInterface() != null
+                && mGestureState.getContainerInterface().shouldCancelCurrentGesture();
         boolean cleanUpConsumer = (action == ACTION_UP || action == ACTION_CANCEL || cancelGesture)
                 && mConsumer != null
                 && !mConsumer.getActiveConsumerInHierarchy().isConsumerDetachedFromGesture();
@@ -1148,7 +1146,7 @@
 
         TopTaskTracker.CachedTaskInfo runningTask = gestureState.getRunningTask();
         // Use overview input consumer for sharesheets on top of home.
-        boolean forceOverviewInputConsumer = gestureState.getActivityInterface().isStarted()
+        boolean forceOverviewInputConsumer = gestureState.getContainerInterface().isStarted()
                 && runningTask != null
                 && runningTask.isRootChooseActivity();
 
@@ -1172,7 +1170,7 @@
         // with shell-transitions, home is resumed during recents animation, so
         // explicitly check against recents animation too.
         boolean launcherResumedThroughShellTransition =
-                gestureState.getActivityInterface().isResumed()
+                gestureState.getContainerInterface().isResumed()
                         && !previousGestureState.isRecentsAnimationRunning();
         // If a task fragment within Launcher is resumed
         boolean launcherChildActivityResumed = useActivityOverlay()
@@ -1182,7 +1180,7 @@
                 && !launcherResumedThroughShellTransition
                 && !previousGestureState.isRecentsAnimationRunning();
 
-        if (gestureState.getActivityInterface().isInLiveTileMode()) {
+        if (gestureState.getContainerInterface().isInLiveTileMode()) {
             return createOverviewInputConsumer(
                     previousGestureState,
                     gestureState,
@@ -1230,7 +1228,7 @@
 
         final AbsSwipeUpHandler.Factory factory = getSwipeUpHandlerFactory();
         final boolean shouldDefer = !mOverviewComponentObserver.isHomeAndOverviewSame()
-                || gestureState.getActivityInterface().deferStartingActivity(mDeviceState, event);
+                || gestureState.getContainerInterface().deferStartingActivity(mDeviceState, event);
         final boolean disableHorizontalSwipe = mDeviceState.isInExclusionRegion(event);
         return new OtherActivityInputConsumer(this, mDeviceState, mTaskAnimationManager,
                 gestureState, shouldDefer, this::onConsumerInactive,
@@ -1264,18 +1262,19 @@
             MotionEvent event,
             boolean forceOverviewInputConsumer,
             CompoundString reasonString) {
-        StatefulActivity activity = gestureState.getActivityInterface().getCreatedActivity();
-        if (activity == null) {
+        RecentsViewContainer container = gestureState.getContainerInterface().getCreatedContainer();
+        if (container == null) {
             return getDefaultInputConsumer(
                     reasonString.append(SUBSTRING_PREFIX)
                             .append("activity == null, trying to use default input consumer"));
         }
 
-        boolean hasWindowFocus = activity.getRootView().hasWindowFocus();
+        boolean hasWindowFocus = container.getRootView().hasWindowFocus();
         boolean isPreviousGestureAnimatingToLauncher =
                 previousGestureState.isRunningAnimationToLauncher()
                         || mDeviceState.isPredictiveBackToHomeInProgress();
-        boolean isInLiveTileMode = gestureState.getActivityInterface().isInLiveTileMode();
+        boolean isInLiveTileMode = gestureState.getContainerInterface().isInLiveTileMode();
+
         reasonString.append(SUBSTRING_PREFIX)
                 .append(hasWindowFocus
                         ? "activity has window focus"
@@ -1289,14 +1288,14 @@
                 || isInLiveTileMode) {
             reasonString.append(SUBSTRING_PREFIX)
                     .append("overview should have focus, using OverviewInputConsumer");
-            return new OverviewInputConsumer(gestureState, activity, mInputMonitorCompat,
+            return new OverviewInputConsumer(gestureState, container, mInputMonitorCompat,
                     false /* startingInActivityBounds */);
         } else {
             reasonString.append(SUBSTRING_PREFIX).append(
                     "overview shouldn't have focus, using OverviewWithoutFocusInputConsumer");
             final boolean disableHorizontalSwipe = mDeviceState.isInExclusionRegion(event);
-            return new OverviewWithoutFocusInputConsumer(activity, mDeviceState, gestureState,
-                    mInputMonitorCompat, disableHorizontalSwipe);
+            return new OverviewWithoutFocusInputConsumer(container.asContext(), mDeviceState,
+                    gestureState, mInputMonitorCompat, disableHorizontalSwipe);
         }
     }
 
@@ -1369,7 +1368,7 @@
                 mOverviewComponentObserver.getActivityInterface();
         final Intent overviewIntent = new Intent(
                 mOverviewComponentObserver.getOverviewIntentIgnoreSysUiState());
-        if (activityInterface.getCreatedActivity() != null && fromInit) {
+        if (activityInterface.getCreatedContainer() != null && fromInit) {
             // The activity has been created before the initialization of overview service. It is
             // usually happens when booting or launcher is the top activity, so we should already
             // have the latest state.
@@ -1391,7 +1390,7 @@
         }
         final BaseActivityInterface activityInterface =
                 mOverviewComponentObserver.getActivityInterface();
-        final BaseDraggingActivity activity = activityInterface.getCreatedActivity();
+        final BaseDraggingActivity activity = activityInterface.getCreatedContainer();
         if (activity == null || activity.isStarted()) {
             // We only care about the existing background activity.
             return;
@@ -1421,7 +1420,6 @@
     @Override
     protected void dump(FileDescriptor fd, PrintWriter pw, String[] rawArgs) {
         // Dump everything
-        FlagsFactory.dump(pw);
         if (LockedUserState.get(this).isUserUnlocked()) {
             PluginManagerWrapper.INSTANCE.get(getBaseContext()).dump(pw);
         }
@@ -1441,7 +1439,7 @@
         DisplayController.INSTANCE.get(this).dump(pw);
         pw.println("TouchState:");
         BaseDraggingActivity createdOverviewActivity = mOverviewComponentObserver == null ? null
-                : mOverviewComponentObserver.getActivityInterface().getCreatedActivity();
+                : mOverviewComponentObserver.getActivityInterface().getCreatedContainer();
         boolean resumed = mOverviewComponentObserver != null
                 && mOverviewComponentObserver.getActivityInterface().isResumed();
         pw.println("  createdOverviewActivity=" + createdOverviewActivity);
@@ -1456,6 +1454,7 @@
         pw.println("AssistStateManager:");
         AssistStateManager.INSTANCE.get(this).dump("  ", pw);
         SystemUiProxy.INSTANCE.get(this).dump(pw);
+        DeviceConfigWrapper.get().dump("   ", pw);
     }
 
     private AbsSwipeUpHandler createLauncherSwipeHandler(
diff --git a/quickstep/src/com/android/quickstep/fallback/FallbackNavBarTouchController.java b/quickstep/src/com/android/quickstep/fallback/FallbackNavBarTouchController.java
index 69de3b0..ec531d8 100644
--- a/quickstep/src/com/android/quickstep/fallback/FallbackNavBarTouchController.java
+++ b/quickstep/src/com/android/quickstep/fallback/FallbackNavBarTouchController.java
@@ -24,9 +24,9 @@
 import com.android.launcher3.util.DisplayController;
 import com.android.launcher3.util.NavigationMode;
 import com.android.launcher3.util.TouchController;
-import com.android.quickstep.RecentsActivity;
 import com.android.quickstep.util.NavBarPosition;
 import com.android.quickstep.util.TriggerSwipeUpTouchTracker;
+import com.android.quickstep.views.RecentsViewContainer;
 
 /**
  * In 0-button mode, intercepts swipe up from the nav bar on FallbackRecentsView to go home.
@@ -34,17 +34,18 @@
 public class FallbackNavBarTouchController implements TouchController,
         TriggerSwipeUpTouchTracker.OnSwipeUpListener {
 
-    private final RecentsActivity mActivity;
+    private final RecentsViewContainer mContainer;
     @Nullable
     private final TriggerSwipeUpTouchTracker mTriggerSwipeUpTracker;
 
-    public FallbackNavBarTouchController(RecentsActivity activity) {
-        mActivity = activity;
-        NavigationMode sysUINavigationMode = DisplayController.getNavigationMode(mActivity);
+    public FallbackNavBarTouchController(RecentsViewContainer container) {
+        mContainer = container;
+        NavigationMode sysUINavigationMode =
+                DisplayController.getNavigationMode(mContainer.asContext());
         if (sysUINavigationMode == NavigationMode.NO_BUTTON) {
             NavBarPosition navBarPosition = new NavBarPosition(sysUINavigationMode,
-                    DisplayController.INSTANCE.get(mActivity).getInfo());
-            mTriggerSwipeUpTracker = new TriggerSwipeUpTouchTracker(mActivity,
+                    DisplayController.INSTANCE.get(mContainer.asContext()).getInfo());
+            mTriggerSwipeUpTracker = new TriggerSwipeUpTouchTracker(mContainer.asContext(),
                     true /* disableHorizontalSwipe */, navBarPosition, this);
         } else {
             mTriggerSwipeUpTracker = null;
@@ -75,6 +76,6 @@
 
     @Override
     public void onSwipeUp(boolean wasFling, PointF finalVelocity) {
-        mActivity.<FallbackRecentsView>getOverviewPanel().startHome();
+        mContainer.<FallbackRecentsView>getOverviewPanel().startHome();
     }
 }
diff --git a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsStateController.java b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsStateController.java
index 69eaf6a..2e76356 100644
--- a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsStateController.java
+++ b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsStateController.java
@@ -49,7 +49,9 @@
 import com.android.launcher3.util.MultiPropertyFactory;
 import com.android.quickstep.RecentsActivity;
 import com.android.quickstep.views.ClearAllButton;
+import com.android.quickstep.views.OverviewActionsView;
 import com.android.quickstep.views.RecentsView;
+import com.android.quickstep.views.RecentsViewContainer;
 
 /**
  * State controller for fallback recents activity
diff --git a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
index 32d8be9..d881a1f 100644
--- a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
+++ b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
@@ -36,6 +36,7 @@
 import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.desktop.DesktopRecentsTransitionController;
 import com.android.launcher3.logging.StatsLogManager;
+import com.android.launcher3.statemanager.StateManager;
 import com.android.launcher3.statemanager.StateManager.StateListener;
 import com.android.launcher3.util.SplitConfigurationOptions;
 import com.android.launcher3.util.SplitConfigurationOptions.SplitSelectSource;
@@ -67,7 +68,7 @@
 
     public FallbackRecentsView(Context context, AttributeSet attrs, int defStyleAttr) {
         super(context, attrs, defStyleAttr, FallbackActivityInterface.INSTANCE);
-        mActivity.getStateManager().addStateListener(this);
+        mContainer.getStateManager().addStateListener(this);
     }
 
     @Override
@@ -80,13 +81,18 @@
 
     @Override
     protected void handleStartHome(boolean animated) {
-        mActivity.startHome();
-        AbstractFloatingView.closeAllOpenViews(mActivity, mActivity.isStarted());
+        mContainer.startHome();
+        AbstractFloatingView.closeAllOpenViews(mContainer, mContainer.isStarted());
     }
 
     @Override
     protected boolean canStartHomeSafely() {
-        return mActivity.canStartHomeSafely();
+        return mContainer.canStartHomeSafely();
+    }
+
+    @Override
+    public StateManager<RecentsState> getStateManager() {
+        return mContainer.getStateManager();
     }
 
     /**
@@ -210,10 +216,10 @@
     public void setModalStateEnabled(int taskId, boolean animate) {
         if (taskId != INVALID_TASK_ID) {
             setSelectedTask(taskId);
-            mActivity.getStateManager().goToState(RecentsState.MODAL_TASK, animate);
+            mContainer.getStateManager().goToState(RecentsState.MODAL_TASK, animate);
         } else {
-            if (mActivity.isInState(RecentsState.MODAL_TASK)) {
-                mActivity.getStateManager().goToState(DEFAULT, animate);
+            if (mContainer.isInState(RecentsState.MODAL_TASK)) {
+                mContainer.getStateManager().goToState(DEFAULT, animate);
             }
         }
     }
@@ -223,13 +229,13 @@
             @SplitConfigurationOptions.StagePosition int stagePosition,
             StatsLogManager.EventEnum splitEvent) {
         super.initiateSplitSelect(taskView, stagePosition, splitEvent);
-        mActivity.getStateManager().goToState(OVERVIEW_SPLIT_SELECT);
+        mContainer.getStateManager().goToState(OVERVIEW_SPLIT_SELECT);
     }
 
     @Override
     public void onStateTransitionStart(RecentsState toState) {
         setOverviewStateEnabled(true);
-        setOverviewGridEnabled(toState.displayOverviewTasksAsGrid(mActivity.getDeviceProfile()));
+        setOverviewGridEnabled(toState.displayOverviewTasksAsGrid(mContainer.getDeviceProfile()));
         setOverviewFullscreenEnabled(toState.isFullScreen());
         if (toState == MODAL_TASK) {
             setOverviewSelectEnabled(true);
@@ -280,7 +286,7 @@
     public void setOverviewStateEnabled(boolean enabled) {
         super.setOverviewStateEnabled(enabled);
         if (enabled) {
-            RecentsState state = mActivity.getStateManager().getState();
+            RecentsState state = mContainer.getStateManager().getState();
             setDisallowScrollToClearAll(!state.hasClearAllButton());
         }
     }
@@ -289,18 +295,18 @@
     public boolean onTouchEvent(MotionEvent ev) {
         boolean result = super.onTouchEvent(ev);
         // Do not let touch escape to siblings below this view.
-        return result || mActivity.getStateManager().getState().overviewUi();
+        return result || mContainer.getStateManager().getState().overviewUi();
     }
 
     @Override
     public void initiateSplitSelect(SplitSelectSource splitSelectSource) {
         super.initiateSplitSelect(splitSelectSource);
-        mActivity.getStateManager().goToState(OVERVIEW_SPLIT_SELECT);
+        mContainer.getStateManager().goToState(OVERVIEW_SPLIT_SELECT);
     }
 
     @Override
     protected boolean canLaunchFullscreenTask() {
-        return !mActivity.isInState(OVERVIEW_SPLIT_SELECT);
+        return !mContainer.isInState(OVERVIEW_SPLIT_SELECT);
     }
 
     /** Returns if app pairs are supported in this launcher. */
diff --git a/quickstep/src/com/android/quickstep/fallback/RecentsState.java b/quickstep/src/com/android/quickstep/fallback/RecentsState.java
index 8b5f091..84937a2 100644
--- a/quickstep/src/com/android/quickstep/fallback/RecentsState.java
+++ b/quickstep/src/com/android/quickstep/fallback/RecentsState.java
@@ -26,7 +26,8 @@
 import com.android.launcher3.R;
 import com.android.launcher3.statemanager.BaseState;
 import com.android.launcher3.util.Themes;
-import com.android.quickstep.RecentsActivity;
+import com.android.quickstep.views.RecentsView;
+import com.android.quickstep.views.RecentsViewContainer;
 
 /**
  * State definition for Fallback recents
@@ -126,12 +127,13 @@
     /**
      * For this state, what color scrim should be drawn behind overview.
      */
-    public int getScrimColor(RecentsActivity activity) {
-        return hasFlag(FLAG_SCRIM) ? Themes.getAttrColor(activity, R.attr.overviewScrimColor)
+    public int getScrimColor(Context context) {
+        return hasFlag(FLAG_SCRIM)
+                ? Themes.getAttrColor(context, R.attr.overviewScrimColor)
                 : Color.TRANSPARENT;
     }
 
-    public float[] getOverviewScaleAndOffset(RecentsActivity activity) {
+    public float[] getOverviewScaleAndOffset(RecentsViewContainer container) {
         return new float[] { NO_SCALE, NO_OFFSET };
     }
 
@@ -161,8 +163,8 @@
         }
 
         @Override
-        public float[] getOverviewScaleAndOffset(RecentsActivity activity) {
-            return getOverviewScaleAndOffsetForModalState(activity);
+        public float[] getOverviewScaleAndOffset(RecentsViewContainer container) {
+            return getOverviewScaleAndOffsetForModalState(container.getOverviewPanel());
         }
     }
 
@@ -172,8 +174,8 @@
         }
 
         @Override
-        public float[] getOverviewScaleAndOffset(RecentsActivity activity) {
-            return getOverviewScaleAndOffsetForBackgroundState(activity);
+        public float[] getOverviewScaleAndOffset(RecentsViewContainer container) {
+            return getOverviewScaleAndOffsetForBackgroundState(container.getOverviewPanel());
         }
     }
 
@@ -183,7 +185,7 @@
         }
 
         @Override
-        public float[] getOverviewScaleAndOffset(RecentsActivity activity) {
+        public float[] getOverviewScaleAndOffset(RecentsViewContainer container) {
             return new float[] { NO_SCALE, 1 };
         }
     }
diff --git a/quickstep/src/com/android/quickstep/fallback/RecentsTaskController.java b/quickstep/src/com/android/quickstep/fallback/RecentsTaskController.java
index db4927a..2cb398c 100644
--- a/quickstep/src/com/android/quickstep/fallback/RecentsTaskController.java
+++ b/quickstep/src/com/android/quickstep/fallback/RecentsTaskController.java
@@ -26,7 +26,7 @@
 
     @Override
     protected boolean isRecentsInteractive() {
-        return mActivity.hasWindowFocus() || mActivity.getStateManager().getState().hasLiveTile();
+        return mContainer.hasWindowFocus() || mContainer.getStateManager().getState().hasLiveTile();
     }
 
     @Override
diff --git a/quickstep/src/com/android/quickstep/inputconsumers/AssistantInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/AssistantInputConsumer.java
index ba012c9..222ccd3 100644
--- a/quickstep/src/com/android/quickstep/inputconsumers/AssistantInputConsumer.java
+++ b/quickstep/src/com/android/quickstep/inputconsumers/AssistantInputConsumer.java
@@ -43,13 +43,13 @@
 import android.view.ViewConfiguration;
 
 import com.android.app.animation.Interpolators;
-import com.android.launcher3.BaseDraggingActivity;
 import com.android.launcher3.R;
-import com.android.quickstep.BaseActivityInterface;
+import com.android.quickstep.BaseContainerInterface;
 import com.android.quickstep.GestureState;
 import com.android.quickstep.InputConsumer;
 import com.android.quickstep.RecentsAnimationDeviceState;
 import com.android.quickstep.SystemUiProxy;
+import com.android.quickstep.views.RecentsViewContainer;
 import com.android.systemui.shared.system.InputMonitorCompat;
 
 import java.util.function.Consumer;
@@ -78,7 +78,7 @@
     private float mTimeFraction;
     private long mDragTime;
     private float mLastProgress;
-    private BaseActivityInterface mActivityInterface;
+    private BaseContainerInterface mContainerInterface;
 
     private final float mDragDistThreshold;
     private final float mFlingDistThreshold;
@@ -106,7 +106,7 @@
         float slop = ViewConfiguration.get(context).getScaledTouchSlop();
 
         mSquaredSlop = slop * slop;
-        mActivityInterface = gestureState.getActivityInterface();
+        mContainerInterface = gestureState.getContainerInterface();
 
         boolean flingDisabled = deviceState.isAssistantGestureIsConstrained()
                 || deviceState.isInDeferredGestureRegion(startEvent);
@@ -237,9 +237,9 @@
     }
 
     private void startAssistantInternal() {
-        BaseDraggingActivity launcherActivity = mActivityInterface.getCreatedActivity();
-        if (launcherActivity != null) {
-            launcherActivity.getRootView().performHapticFeedback(
+        RecentsViewContainer container = mContainerInterface.getCreatedContainer();
+        if (container != null) {
+            container.getRootView().performHapticFeedback(
                 13, // HapticFeedbackConstants.GESTURE_END
                 HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);
         }
diff --git a/quickstep/src/com/android/quickstep/inputconsumers/NavHandleLongPressInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/NavHandleLongPressInputConsumer.java
index e4a8619..075e539 100644
--- a/quickstep/src/com/android/quickstep/inputconsumers/NavHandleLongPressInputConsumer.java
+++ b/quickstep/src/com/android/quickstep/inputconsumers/NavHandleLongPressInputConsumer.java
@@ -20,6 +20,7 @@
 import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_LONG_PRESS_NAVBAR;
 import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_LONG_PRESS_STASHED_TASKBAR;
 import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
+import static com.android.launcher3.util.LogConfig.NAV_HANDLE_LONG_PRESS;
 
 import android.content.Context;
 import android.util.Log;
@@ -27,13 +28,14 @@
 import android.view.ViewConfiguration;
 
 import com.android.launcher3.Utilities;
-import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.logging.StatsLogManager;
 import com.android.launcher3.util.DisplayController;
+import com.android.quickstep.DeviceConfigWrapper;
 import com.android.quickstep.InputConsumer;
 import com.android.quickstep.NavHandle;
 import com.android.quickstep.RecentsAnimationDeviceState;
 import com.android.quickstep.TopTaskTracker;
+import com.android.quickstep.util.AssistStateManager;
 import com.android.systemui.shared.system.InputMonitorCompat;
 
 /**
@@ -42,14 +44,19 @@
 public class NavHandleLongPressInputConsumer extends DelegateInputConsumer {
 
     private static final String TAG = "NavHandleLongPressIC";
+    private static final boolean DEBUG_NAV_HANDLE = Utilities.isPropertyEnabled(
+            NAV_HANDLE_LONG_PRESS);
 
     private final NavHandleLongPressHandler mNavHandleLongPressHandler;
     private final float mNavHandleWidth;
     private final float mScreenWidth;
 
     private final Runnable mTriggerLongPress = this::triggerLongPress;
-    private final float mTouchSlopSquared;
+    private final float mTouchSlopSquaredOriginal;
+    private float mTouchSlopSquared;
+    private final float mOuterTouchSlopSquared;
     private final int mLongPressTimeout;
+    private final int mOuterLongPressTimeout;
     private final boolean mDeepPressEnabled;
     private final NavHandle mNavHandle;
     private final StatsLogManager mStatsLogManager;
@@ -63,13 +70,24 @@
             NavHandle navHandle) {
         super(delegate, inputMonitor);
         mScreenWidth = DisplayController.INSTANCE.get(context).getInfo().currentSize.x;
-        mDeepPressEnabled = FeatureFlags.ENABLE_LPNH_DEEP_PRESS.get();
-        if (FeatureFlags.CUSTOM_LPNH_THRESHOLDS.get()) {
-            mLongPressTimeout = FeatureFlags.LPNH_TIMEOUT_MS.get();
+        mDeepPressEnabled = DeviceConfigWrapper.get().getEnableLpnhDeepPress();
+        int twoStageMultiplier = DeviceConfigWrapper.get().getTwoStageMultiplier();
+        AssistStateManager assistStateManager = AssistStateManager.INSTANCE.get(context);
+        if (assistStateManager.getLPNHDurationMillis().isPresent()) {
+            mLongPressTimeout = assistStateManager.getLPNHDurationMillis().get().intValue();
         } else {
             mLongPressTimeout = ViewConfiguration.getLongPressTimeout();
         }
-        mTouchSlopSquared = deviceState.getSquaredTouchSlop();
+        mOuterLongPressTimeout = mLongPressTimeout * twoStageMultiplier;
+        mTouchSlopSquaredOriginal = deviceState.getSquaredTouchSlop();
+        mTouchSlopSquared = mTouchSlopSquaredOriginal;
+        mOuterTouchSlopSquared = mTouchSlopSquared * (twoStageMultiplier * twoStageMultiplier);
+        if (DEBUG_NAV_HANDLE) {
+            Log.d(TAG, "mLongPressTimeout=" + mLongPressTimeout);
+            Log.d(TAG, "mOuterLongPressTimeout=" + mOuterLongPressTimeout);
+            Log.d(TAG, "mTouchSlopSquared=" + mTouchSlopSquared);
+            Log.d(TAG, "mOuterTouchSlopSquared=" + mOuterTouchSlopSquared);
+        }
         mNavHandle = navHandle;
         mNavHandleWidth = navHandle.getNavHandleWidth(context);
         mNavHandleLongPressHandler = NavHandleLongPressHandler.newInstance(context);
@@ -107,22 +125,44 @@
                     mCurrentDownEvent.recycle();
                 }
                 mCurrentDownEvent = MotionEvent.obtain(ev);
+                mTouchSlopSquared = mTouchSlopSquaredOriginal;
                 mDeepPressLogged = false;
                 if (isInNavBarHorizontalArea(ev.getRawX())) {
                     mNavHandleLongPressHandler.onTouchStarted(mNavHandle);
                     MAIN_EXECUTOR.getHandler().postDelayed(mTriggerLongPress, mLongPressTimeout);
                 }
+                if (DEBUG_NAV_HANDLE) {
+                    Log.d(TAG, "ACTION_DOWN");
+                }
             }
             case MotionEvent.ACTION_MOVE -> {
                 if (!MAIN_EXECUTOR.getHandler().hasCallbacks(mTriggerLongPress)) {
                     break;
                 }
 
-                float touchSlopSquared = mTouchSlopSquared;
                 float dx = ev.getX() - mCurrentDownEvent.getX();
                 float dy = ev.getY() - mCurrentDownEvent.getY();
                 double distanceSquared = (dx * dx) + (dy * dy);
-                if (distanceSquared > touchSlopSquared) {
+                if (DEBUG_NAV_HANDLE) {
+                    Log.d(TAG, "ACTION_MOVE distanceSquared=" + distanceSquared);
+                }
+                if (DeviceConfigWrapper.get().getEnableLpnhTwoStages()) {
+                    if (mTouchSlopSquared < distanceSquared
+                            && distanceSquared <= mOuterTouchSlopSquared) {
+                        MAIN_EXECUTOR.getHandler().removeCallbacks(mTriggerLongPress);
+                        int delay = mOuterLongPressTimeout
+                                - (int) (ev.getEventTime() - ev.getDownTime());
+                        MAIN_EXECUTOR.getHandler().postDelayed(mTriggerLongPress, delay);
+                        mTouchSlopSquared = mOuterTouchSlopSquared;
+                        if (DEBUG_NAV_HANDLE) {
+                            Log.d(TAG, "Touch in middle region!");
+                        }
+                    }
+                }
+                if (distanceSquared > mTouchSlopSquared) {
+                    if (DEBUG_NAV_HANDLE) {
+                        Log.d(TAG, "Touch slop out. mTouchSlopSquared=" + mTouchSlopSquared);
+                    }
                     cancelLongPress("touch slop passed");
                 }
             }
@@ -151,6 +191,9 @@
     }
 
     private void triggerLongPress() {
+        if (DEBUG_NAV_HANDLE) {
+            Log.d(TAG, "triggerLongPress");
+        }
         String runningPackage = mTopTaskTracker.getCachedTopTask(
                 /* filterOnlyVisibleRecents */ true).getPackageName();
         mStatsLogManager.logger().withPackageName(runningPackage).log(
@@ -173,14 +216,18 @@
     }
 
     private void cancelLongPress(String reason) {
+        if (DEBUG_NAV_HANDLE) {
+            Log.d(TAG, "cancelLongPress");
+        }
         MAIN_EXECUTOR.getHandler().removeCallbacks(mTriggerLongPress);
         mNavHandleLongPressHandler.onTouchFinished(mNavHandle, reason);
     }
 
     private boolean isInNavBarHorizontalArea(float x) {
         float areaFromMiddle = mNavHandleWidth / 2.0f;
-        if (FeatureFlags.CUSTOM_LPNH_THRESHOLDS.get()) {
-            areaFromMiddle += Utilities.dpToPx(FeatureFlags.LPNH_EXTRA_TOUCH_WIDTH_DP.get());
+        if (DeviceConfigWrapper.get().getCustomLpnhThresholds()) {
+            areaFromMiddle += Utilities.dpToPx(
+                    DeviceConfigWrapper.get().getLpnhExtraTouchWidthDp());
         }
         int minAccessibleSize = Utilities.dpToPx(24);  // Half of 48dp because this is per side.
         if (areaFromMiddle < minAccessibleSize) {
diff --git a/quickstep/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java
index fbbfc16..9f39476 100644
--- a/quickstep/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java
+++ b/quickstep/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java
@@ -49,7 +49,6 @@
 import com.android.launcher3.util.TraceHelper;
 import com.android.quickstep.AbsSwipeUpHandler;
 import com.android.quickstep.AbsSwipeUpHandler.Factory;
-import com.android.quickstep.BaseActivityInterface;
 import com.android.quickstep.GestureState;
 import com.android.quickstep.InputConsumer;
 import com.android.quickstep.RecentsAnimationCallbacks;
@@ -86,8 +85,6 @@
     private final CachedEventDispatcher mRecentsViewDispatcher = new CachedEventDispatcher();
     private final InputMonitorCompat mInputMonitorCompat;
     private final InputEventReceiver mInputEventReceiver;
-    private final BaseActivityInterface mActivityInterface;
-
     private final AbsSwipeUpHandler.Factory mHandlerFactory;
 
     private final Consumer<OtherActivityInputConsumer> mOnCompleteCallback;
@@ -135,7 +132,6 @@
         mTaskAnimationManager = taskAnimationManager;
         mGestureState = gestureState;
         mHandlerFactory = handlerFactory;
-        mActivityInterface = mGestureState.getActivityInterface();
 
         mMotionPauseDetector = new MotionPauseDetector(base, false,
                 mNavBarPosition.isLeftEdge() || mNavBarPosition.isRightEdge()
diff --git a/quickstep/src/com/android/quickstep/inputconsumers/OverviewInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/OverviewInputConsumer.java
index 7d3a860..bb8d1d7 100644
--- a/quickstep/src/com/android/quickstep/inputconsumers/OverviewInputConsumer.java
+++ b/quickstep/src/com/android/quickstep/inputconsumers/OverviewInputConsumer.java
@@ -28,24 +28,24 @@
 
 import com.android.launcher3.Utilities;
 import com.android.launcher3.statemanager.BaseState;
-import com.android.launcher3.statemanager.StatefulActivity;
 import com.android.launcher3.testing.TestLogging;
 import com.android.launcher3.testing.shared.TestProtocol;
 import com.android.launcher3.views.BaseDragLayer;
-import com.android.quickstep.BaseActivityInterface;
+import com.android.quickstep.BaseContainerInterface;
 import com.android.quickstep.GestureState;
 import com.android.quickstep.InputConsumer;
 import com.android.quickstep.TaskUtils;
+import com.android.quickstep.views.RecentsViewContainer;
 import com.android.systemui.shared.system.InputMonitorCompat;
 
 /**
  * Input consumer for handling touch on the recents/Launcher activity.
  */
-public class OverviewInputConsumer<S extends BaseState<S>, T extends StatefulActivity<S>>
+public class OverviewInputConsumer<S extends BaseState<S>, T extends RecentsViewContainer>
         implements InputConsumer {
 
-    private final T mActivity;
-    private final BaseActivityInterface<?, T> mActivityInterface;
+    private final T mContainer;
+    private final BaseContainerInterface<?, T> mContainerInterface;
     private final BaseDragLayer mTarget;
     private final InputMonitorCompat mInputMonitor;
 
@@ -56,14 +56,14 @@
     private boolean mHasSetTouchModeForFirstDPadEvent;
     private boolean mIsWaitingForAttachToWindow;
 
-    public OverviewInputConsumer(GestureState gestureState, T activity,
+    public OverviewInputConsumer(GestureState gestureState, T container,
             @Nullable InputMonitorCompat inputMonitor, boolean startingInActivityBounds) {
-        mActivity = activity;
+        mContainer = container;
         mInputMonitor = inputMonitor;
         mStartingInActivityBounds = startingInActivityBounds;
-        mActivityInterface = gestureState.getActivityInterface();
+        mContainerInterface = gestureState.getContainerInterface();
 
-        mTarget = activity.getDragLayer();
+        mTarget = container.getDragLayer();
         mTarget.getLocationOnScreen(mLocationOnScreen);
     }
 
@@ -91,7 +91,7 @@
         if (!mTargetHandledTouch && handled) {
             mTargetHandledTouch = true;
             if (!mStartingInActivityBounds) {
-                mActivityInterface.closeOverlay();
+                mContainerInterface.closeOverlay();
                 TaskUtils.closeSystemWindowsAsync(CLOSE_SYSTEM_WINDOWS_REASON_RECENTS);
             }
             if (mInputMonitor != null) {
@@ -100,13 +100,13 @@
             }
         }
         if (mHasSetTouchModeForFirstDPadEvent) {
-            mActivity.getRootView().clearFocus();
+            mContainer.getRootView().clearFocus();
         }
     }
 
     @Override
     public void onHoverEvent(MotionEvent ev) {
-        mActivity.dispatchGenericMotionEvent(ev);
+        mContainer.dispatchGenericMotionEvent(ev);
     }
 
     @Override
@@ -115,7 +115,8 @@
             case KeyEvent.KEYCODE_VOLUME_DOWN:
             case KeyEvent.KEYCODE_VOLUME_UP:
             case KeyEvent.KEYCODE_VOLUME_MUTE:
-                MediaSessionManager mgr = mActivity.getSystemService(MediaSessionManager.class);
+                MediaSessionManager mgr = mContainer.asContext()
+                        .getSystemService(MediaSessionManager.class);
                 mgr.dispatchVolumeKeyEventAsSystemService(ev,
                         AudioManager.USE_DEFAULT_STREAM_TYPE);
                 break;
@@ -124,7 +125,7 @@
                 if (mHasSetTouchModeForFirstDPadEvent) {
                     break;
                 }
-                View viewRoot = mActivity.getRootView();
+                View viewRoot = mContainer.getRootView();
                 if (viewRoot.isAttachedToWindow()) {
                     setTouchModeChanged(viewRoot);
                     break;
@@ -150,7 +151,7 @@
             default:
                 break;
         }
-        mActivity.dispatchKeyEvent(ev);
+        mContainer.dispatchKeyEvent(ev);
     }
 
     private void setTouchModeChanged(@NonNull View viewRoot) {
diff --git a/quickstep/src/com/android/quickstep/inputconsumers/ScreenPinnedInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/ScreenPinnedInputConsumer.java
index a8bf333..d73c23f 100644
--- a/quickstep/src/com/android/quickstep/inputconsumers/ScreenPinnedInputConsumer.java
+++ b/quickstep/src/com/android/quickstep/inputconsumers/ScreenPinnedInputConsumer.java
@@ -19,12 +19,12 @@
 import android.view.HapticFeedbackConstants;
 import android.view.MotionEvent;
 
-import com.android.launcher3.BaseDraggingActivity;
 import com.android.launcher3.R;
 import com.android.quickstep.GestureState;
 import com.android.quickstep.InputConsumer;
 import com.android.quickstep.SystemUiProxy;
 import com.android.quickstep.util.MotionPauseDetector;
+import com.android.quickstep.views.RecentsViewContainer;
 
 /**
  * An input consumer that detects swipe up and hold to exit screen pinning mode.
@@ -44,10 +44,10 @@
         mMotionPauseDetector = new MotionPauseDetector(context, true /* makePauseHarderToTrigger*/);
         mMotionPauseDetector.setOnMotionPauseListener(() -> {
             SystemUiProxy.INSTANCE.get(context).stopScreenPinning();
-            BaseDraggingActivity launcherActivity = gestureState.getActivityInterface()
-                    .getCreatedActivity();
-            if (launcherActivity != null) {
-                launcherActivity.getRootView().performHapticFeedback(
+            RecentsViewContainer container = gestureState.getContainerInterface()
+                    .getCreatedContainer();
+            if (container != null) {
+                container.getRootView().performHapticFeedback(
                         HapticFeedbackConstants.LONG_PRESS,
                         HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);
             }
diff --git a/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java b/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java
index e078a49..a09e027 100644
--- a/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java
+++ b/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java
@@ -113,7 +113,7 @@
             new CopyOnWriteArrayList<>();
 
     public StatsLogCompatManager(Context context) {
-        mContext = context;
+        super(context);
     }
 
     @Override
diff --git a/quickstep/src/com/android/quickstep/orientation/PortraitPagedViewHandler.java b/quickstep/src/com/android/quickstep/orientation/PortraitPagedViewHandler.java
index 0476fe8..1be908b 100644
--- a/quickstep/src/com/android/quickstep/orientation/PortraitPagedViewHandler.java
+++ b/quickstep/src/com/android/quickstep/orientation/PortraitPagedViewHandler.java
@@ -213,7 +213,8 @@
     @Override
     public int getTaskMenuHeight(float taskInsetMargin, DeviceProfile deviceProfile,
             float taskMenuX, float taskMenuY) {
-        return (int) (deviceProfile.availableHeightPx - taskInsetMargin - taskMenuY);
+        return (int) (deviceProfile.heightPx - deviceProfile.getInsets().top - taskMenuY
+                    - deviceProfile.getOverviewActionsClaimedSpaceBelow());
     }
 
     @Override
diff --git a/quickstep/src/com/android/quickstep/util/AnimatorControllerWithResistance.java b/quickstep/src/com/android/quickstep/util/AnimatorControllerWithResistance.java
index 16f2065..c9647f5 100644
--- a/quickstep/src/com/android/quickstep/util/AnimatorControllerWithResistance.java
+++ b/quickstep/src/com/android/quickstep/util/AnimatorControllerWithResistance.java
@@ -18,7 +18,6 @@
 import static com.android.app.animation.Interpolators.DECELERATE;
 import static com.android.app.animation.Interpolators.LINEAR;
 import static com.android.launcher3.Flags.enableGridOnlyOverview;
-import static com.android.launcher3.LauncherPrefs.ALL_APPS_OVERVIEW_THRESHOLD;
 import static com.android.quickstep.views.RecentsView.RECENTS_SCALE_PROPERTY;
 import static com.android.quickstep.views.RecentsView.TASK_SECONDARY_TRANSLATION;
 
@@ -35,17 +34,17 @@
 
 import com.android.launcher3.DeviceProfile;
 import com.android.launcher3.Launcher;
-import com.android.launcher3.LauncherPrefs;
 import com.android.launcher3.LauncherState;
 import com.android.launcher3.Utilities;
 import com.android.launcher3.anim.AnimatorPlaybackController;
 import com.android.launcher3.anim.PendingAnimation;
 import com.android.launcher3.statemanager.StateManager;
-import com.android.launcher3.statemanager.StatefulActivity;
 import com.android.launcher3.states.StateAnimationConfig;
 import com.android.launcher3.touch.AllAppsSwipeController;
+import com.android.quickstep.DeviceConfigWrapper;
 import com.android.quickstep.orientation.RecentsPagedOrientationHandler;
 import com.android.quickstep.views.RecentsView;
+import com.android.quickstep.views.RecentsViewContainer;
 
 /**
  * Controls an animation that can go beyond progress = 1, at which point resistance should be
@@ -159,11 +158,12 @@
         PendingAnimation resistAnim = createRecentsResistanceAnim(params);
 
         // Apply All Apps animation during the resistance animation.
-        if (recentsOrientedState.getActivityInterface().allowAllAppsFromOverview()) {
-            StatefulActivity activity =
-                    recentsOrientedState.getActivityInterface().getCreatedActivity();
-            if (activity != null) {
-                StateManager<LauncherState> stateManager = activity.getStateManager();
+        if (recentsOrientedState.getContainerInterface().allowAllAppsFromOverview()) {
+            RecentsViewContainer container =
+                    recentsOrientedState.getContainerInterface().getCreatedContainer();
+            if (container != null) {
+                RecentsView recentsView = container.getOverviewPanel();
+                StateManager<LauncherState> stateManager = recentsView.getStateManager();
                 if (stateManager.isInStableState(LauncherState.BACKGROUND_APP)
                         && stateManager.isInTransition()) {
 
@@ -186,12 +186,12 @@
     private static float getAllAppsThreshold(Context context,
             RecentsOrientedState recentsOrientedState, DeviceProfile dp) {
         int transitionDragLength =
-                recentsOrientedState.getActivityInterface().getSwipeUpDestinationAndLength(
+                recentsOrientedState.getContainerInterface().getSwipeUpDestinationAndLength(
                         dp, context, TEMP_RECT,
                         recentsOrientedState.getOrientationHandler());
         float dragLengthFactor = (float) dp.heightPx / transitionDragLength;
         // -1s are because 0-1 is reserved for the normal transition.
-        float threshold = LauncherPrefs.get(context).get(ALL_APPS_OVERVIEW_THRESHOLD) / 100f;
+        float threshold = DeviceConfigWrapper.get().getAllAppsOverviewThreshold() / 100f;
         return (threshold - 1) / (dragLengthFactor - 1);
     }
 
@@ -204,7 +204,7 @@
         Rect startRect = new Rect();
         RecentsPagedOrientationHandler orientationHandler = params.recentsOrientedState
                 .getOrientationHandler();
-        params.recentsOrientedState.getActivityInterface()
+        params.recentsOrientedState.getContainerInterface()
                 .calculateTaskSize(params.context, params.dp, startRect, orientationHandler);
         long distanceToCover = startRect.bottom;
         PendingAnimation resistAnim = params.resistAnim != null
@@ -304,14 +304,14 @@
             this.translationProperty = translationProperty;
             if (dp.isTablet) {
                 resistanceParams =
-                        recentsOrientedState.getActivityInterface().allowAllAppsFromOverview()
+                        recentsOrientedState.getContainerInterface().allowAllAppsFromOverview()
                                 ? RecentsResistanceParams.FROM_APP_TO_ALL_APPS_TABLET
                                 : enableGridOnlyOverview()
                                         ? RecentsResistanceParams.FROM_APP_TABLET_GRID_ONLY
                                         : RecentsResistanceParams.FROM_APP_TABLET;
             } else {
                 resistanceParams =
-                        recentsOrientedState.getActivityInterface().allowAllAppsFromOverview()
+                        recentsOrientedState.getContainerInterface().allowAllAppsFromOverview()
                                 ? RecentsResistanceParams.FROM_APP_TO_ALL_APPS
                                 : RecentsResistanceParams.FROM_APP;
             }
diff --git a/quickstep/src/com/android/quickstep/util/AppPairsController.java b/quickstep/src/com/android/quickstep/util/AppPairsController.java
index f4da867..3f06571 100644
--- a/quickstep/src/com/android/quickstep/util/AppPairsController.java
+++ b/quickstep/src/com/android/quickstep/util/AppPairsController.java
@@ -42,10 +42,8 @@
 import androidx.annotation.VisibleForTesting;
 
 import com.android.internal.jank.Cuj;
-import com.android.launcher3.Launcher;
 import com.android.launcher3.LauncherAppState;
 import com.android.launcher3.LauncherSettings;
-import com.android.launcher3.R;
 import com.android.launcher3.accessibility.LauncherAccessibilityDelegate;
 import com.android.launcher3.allapps.AllAppsStore;
 import com.android.launcher3.apppairs.AppPairIcon;
@@ -57,8 +55,10 @@
 import com.android.launcher3.model.data.ItemInfo;
 import com.android.launcher3.model.data.WorkspaceItemInfo;
 import com.android.launcher3.taskbar.TaskbarActivityContext;
+import com.android.launcher3.uioverrides.QuickstepLauncher;
 import com.android.launcher3.util.ComponentKey;
 import com.android.launcher3.util.SplitConfigurationOptions.StagePosition;
+import com.android.launcher3.views.ActivityContext;
 import com.android.quickstep.SystemUiProxy;
 import com.android.quickstep.TopTaskTracker;
 import com.android.quickstep.views.GroupedTaskView;
@@ -153,16 +153,14 @@
 
         IconCache iconCache = LauncherAppState.getInstance(mContext).getIconCache();
         MODEL_EXECUTOR.execute(() -> {
-            newAppPair.getContents().forEach(member -> {
+            newAppPair.getAppContents().forEach(member -> {
                 member.title = "";
                 member.bitmap = iconCache.getDefaultIcon(newAppPair.user);
                 iconCache.getTitleAndIcon(member, member.usingLowResIcon());
             });
-            newAppPair.title = getDefaultTitle(newAppPair.getFirstApp().title,
-                    newAppPair.getSecondApp().title);
             MAIN_EXECUTOR.execute(() -> {
                 LauncherAccessibilityDelegate delegate =
-                        Launcher.getLauncher(mContext).getAccessibilityDelegate();
+                        QuickstepLauncher.getLauncher(mContext).getAccessibilityDelegate();
                 if (delegate != null) {
                     delegate.addToWorkspace(newAppPair, true, (success) -> {
                         if (success) {
@@ -241,7 +239,8 @@
             return null;
         }
 
-        AllAppsStore appsStore = Launcher.getLauncher(mContext).getAppsView().getAppsStore();
+        AllAppsStore appsStore = ActivityContext.lookupContext(mContext)
+                .getAppsView().getAppsStore();
 
         // Lookup by ComponentKey
         AppInfo appInfo = appsStore.getApp(key);
@@ -489,13 +488,6 @@
     }
 
     /**
-     * Returns a formatted default title for the app pair.
-     */
-    public String getDefaultTitle(CharSequence app1, CharSequence app2) {
-        return mContext.getString(R.string.app_pair_default_title, app1, app2);
-    }
-
-    /**
      * Gets the TopTaskTracker, which is a cached record of the top running Task.
      */
     @VisibleForTesting
diff --git a/quickstep/src/com/android/quickstep/util/AssistStateManager.java b/quickstep/src/com/android/quickstep/util/AssistStateManager.java
index a854656..a3904bc 100644
--- a/quickstep/src/com/android/quickstep/util/AssistStateManager.java
+++ b/quickstep/src/com/android/quickstep/util/AssistStateManager.java
@@ -52,6 +52,38 @@
         return Optional.empty();
     }
 
+    /** Get the Launcher overridden long press nav handle duration to trigger Assistant. */
+    public Optional<Long> getLPNHDurationMillis() {
+        return Optional.empty();
+    }
+
+    /**
+     * Get the Launcher overridden long press nav handle touch slop multiplier to trigger Assistant.
+     */
+    public Optional<Float> getLPNHCustomSlopMultiplier() {
+        return Optional.empty();
+    }
+
+    /** Get the Launcher overridden long press home duration to trigger Assistant. */
+    public Optional<Long> getLPHDurationMillis() {
+        return Optional.empty();
+    }
+
+    /** Get the Launcher overridden long press home touch slop multiplier to trigger Assistant. */
+    public Optional<Float> getLPHCustomSlopMultiplier() {
+        return Optional.empty();
+    }
+
+    /** Get the long press duration data source. */
+    public int getDurationDataSource() {
+        return 0;
+    }
+
+    /** Get the long press touch slop multiplier data source. */
+    public int getSlopDataSource() {
+        return 0;
+    }
+
     /** Return {@code true} if the Settings toggle is enabled. */
     public boolean isSettingsAllEntrypointsEnabled() {
         return false;
diff --git a/quickstep/src/com/android/quickstep/util/DeviceConfigHelper.kt b/quickstep/src/com/android/quickstep/util/DeviceConfigHelper.kt
new file mode 100644
index 0000000..544c64d
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/util/DeviceConfigHelper.kt
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2024 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.app.ActivityThread
+import android.content.Context
+import android.content.SharedPreferences
+import android.content.SharedPreferences.OnSharedPreferenceChangeListener
+import android.provider.DeviceConfig
+import android.provider.DeviceConfig.OnPropertiesChangedListener
+import android.provider.DeviceConfig.Properties
+import androidx.annotation.WorkerThread
+import com.android.launcher3.BuildConfig
+import com.android.launcher3.util.Executors
+
+/** Utility class to manage a set of device configurations */
+class DeviceConfigHelper<ConfigType>(private val factory: (PropReader) -> ConfigType) {
+
+    var config: ConfigType
+        private set
+    private val allKeys: Set<String>
+    private val propertiesListener = OnPropertiesChangedListener { onDevicePropsChanges(it) }
+    private val sharedPrefChangeListener = OnSharedPreferenceChangeListener { _, _ ->
+        recreateConfig()
+    }
+
+    private val changeListeners = mutableListOf<Runnable>()
+
+    init {
+        // Initialize the default config once.
+        allKeys = HashSet()
+        config =
+            factory(
+                PropReader(
+                    object : PropProvider {
+                        override fun <T : Any> get(key: String, fallback: T): T {
+                            if (fallback is Int)
+                                return DeviceConfig.getInt(NAMESPACE_LAUNCHER, key, fallback) as T
+                            else if (fallback is Boolean)
+                                return DeviceConfig.getBoolean(NAMESPACE_LAUNCHER, key, fallback)
+                                    as T
+                            else return fallback
+                        }
+                    }
+                )
+            )
+
+        DeviceConfig.addOnPropertiesChangedListener(
+            NAMESPACE_LAUNCHER,
+            Executors.UI_HELPER_EXECUTOR,
+            propertiesListener
+        )
+        if (BuildConfig.IS_DEBUG_DEVICE) {
+            prefs.registerOnSharedPreferenceChangeListener(sharedPrefChangeListener)
+        }
+    }
+
+    @WorkerThread
+    private fun onDevicePropsChanges(properties: Properties) {
+        if (NAMESPACE_LAUNCHER != properties.namespace) return
+        if (!allKeys.any(properties.keyset::contains)) return
+        recreateConfig()
+    }
+
+    private fun recreateConfig() {
+        val myProps =
+            DeviceConfig.getProperties(NAMESPACE_LAUNCHER, *allKeys.toTypedArray<String>())
+        config =
+            factory(
+                PropReader(
+                    object : PropProvider {
+                        override fun <T : Any> get(key: String, fallback: T): T {
+                            if (fallback is Int) return myProps.getInt(key, fallback) as T
+                            else if (fallback is Boolean)
+                                return myProps.getBoolean(key, fallback) as T
+                            else return fallback
+                        }
+                    }
+                )
+            )
+        Executors.MAIN_EXECUTOR.execute { changeListeners.forEach(Runnable::run) }
+    }
+
+    /** Adds a listener for property changes */
+    fun addChangeListener(r: Runnable) = changeListeners.add(r)
+
+    /** Removes a previously added listener */
+    fun removeChangeListener(r: Runnable) = changeListeners.remove(r)
+
+    fun close() {
+        DeviceConfig.removeOnPropertiesChangedListener(propertiesListener)
+        if (BuildConfig.IS_DEBUG_DEVICE) {
+            prefs.unregisterOnSharedPreferenceChangeListener(sharedPrefChangeListener)
+        }
+    }
+
+    internal interface PropProvider {
+        fun <T : Any> get(key: String, fallback: T): T
+    }
+
+    /** The reader is sent to the config for initialization */
+    class PropReader internal constructor(private val f: PropProvider) {
+
+        @JvmOverloads
+        fun <T : Any> get(key: String, fallback: T, desc: String? = null): T {
+            val v = f.get(key, fallback)
+            if (BuildConfig.IS_DEBUG_DEVICE && desc != null) {
+                if (v is Int) {
+                    allProps[key] = DebugInfo(key, desc, true, fallback)
+                    return prefs.getInt(key, v) as T
+                } else if (v is Boolean) {
+                    allProps[key] = DebugInfo(key, desc, false, fallback)
+                    return prefs.getBoolean(key, v) as T
+                }
+            }
+            return v
+        }
+    }
+
+    class DebugInfo<T>(
+        val key: String,
+        val desc: String,
+        val isInt: Boolean,
+        val valueInCode: T,
+    )
+
+    companion object {
+        const val NAMESPACE_LAUNCHER = "launcher"
+
+        val allProps = mutableMapOf<String, DebugInfo<*>>()
+
+        private const val FLAGS_PREF_NAME = "featureFlags"
+
+        val prefs: SharedPreferences by lazy {
+            ActivityThread.currentApplication()
+                .createDeviceProtectedStorageContext()
+                .getSharedPreferences(FLAGS_PREF_NAME, Context.MODE_PRIVATE)
+        }
+    }
+}
diff --git a/quickstep/src/com/android/quickstep/util/FadeOutRemoteTransition.kt b/quickstep/src/com/android/quickstep/util/FadeOutRemoteTransition.kt
index 24e261f..e6e94e6 100644
--- a/quickstep/src/com/android/quickstep/util/FadeOutRemoteTransition.kt
+++ b/quickstep/src/com/android/quickstep/util/FadeOutRemoteTransition.kt
@@ -20,25 +20,15 @@
 import android.os.RemoteException
 import android.view.SurfaceControl
 import android.view.SurfaceControl.Transaction
-import android.window.IRemoteTransition
 import android.window.IRemoteTransitionFinishedCallback
+import android.window.RemoteTransitionStub
 import android.window.TransitionInfo
 import com.android.launcher3.anim.AnimatorListeners.forEndCallback
 import com.android.launcher3.util.Executors
 import com.android.wm.shell.shared.TransitionUtil
 
 /** Remote animation which fades out the closing targets */
-class FadeOutRemoteTransition : IRemoteTransition.Stub() {
-
-    override fun mergeAnimation(
-        iBinder: IBinder,
-        transitionInfo: TransitionInfo,
-        transaction: Transaction,
-        mergeTarget: IBinder,
-        finishCB: IRemoteTransitionFinishedCallback
-    ) {
-        // Do not report finish if we don't know how to handle this transition.
-    }
+class FadeOutRemoteTransition : RemoteTransitionStub() {
 
     override fun startAnimation(
         transition: IBinder,
@@ -78,6 +68,4 @@
 
         Executors.MAIN_EXECUTOR.execute { anim.start() }
     }
-
-    override fun onTransitionConsumed(transition: IBinder?, aborted: Boolean) {}
 }
diff --git a/quickstep/src/com/android/quickstep/util/InputProxyHandlerFactory.java b/quickstep/src/com/android/quickstep/util/InputProxyHandlerFactory.java
index 8209c09..843619d 100644
--- a/quickstep/src/com/android/quickstep/util/InputProxyHandlerFactory.java
+++ b/quickstep/src/com/android/quickstep/util/InputProxyHandlerFactory.java
@@ -17,11 +17,11 @@
 
 import androidx.annotation.UiThread;
 
-import com.android.launcher3.statemanager.StatefulActivity;
-import com.android.quickstep.BaseActivityInterface;
+import com.android.quickstep.BaseContainerInterface;
 import com.android.quickstep.GestureState;
 import com.android.quickstep.InputConsumer;
 import com.android.quickstep.inputconsumers.OverviewInputConsumer;
+import com.android.quickstep.views.RecentsViewContainer;
 
 import java.util.function.Supplier;
 
@@ -31,13 +31,13 @@
  */
 public class InputProxyHandlerFactory implements Supplier<InputConsumer> {
 
-    private final BaseActivityInterface mActivityInterface;
+    private final BaseContainerInterface mContainerInterface;
     private final GestureState mGestureState;
 
     @UiThread
-    public InputProxyHandlerFactory(BaseActivityInterface activityInterface,
+    public InputProxyHandlerFactory(BaseContainerInterface activityInterface,
             GestureState gestureState) {
-        mActivityInterface = activityInterface;
+        mContainerInterface = activityInterface;
         mGestureState = gestureState;
     }
 
@@ -46,8 +46,8 @@
      */
     @Override
     public InputConsumer get() {
-        StatefulActivity activity = mActivityInterface.getCreatedActivity();
-        return activity == null ? InputConsumer.NO_OP
-                : new OverviewInputConsumer(mGestureState, activity, null, true);
+        RecentsViewContainer container = mContainerInterface.getCreatedContainer();
+        return container == null ? InputConsumer.NO_OP
+                : new OverviewInputConsumer(mGestureState, container, null, true);
     }
 }
diff --git a/quickstep/src/com/android/quickstep/util/LauncherUnfoldAnimationController.java b/quickstep/src/com/android/quickstep/util/LauncherUnfoldAnimationController.java
index 61ba5ac..4474f33 100644
--- a/quickstep/src/com/android/quickstep/util/LauncherUnfoldAnimationController.java
+++ b/quickstep/src/com/android/quickstep/util/LauncherUnfoldAnimationController.java
@@ -30,9 +30,9 @@
 import com.android.launcher3.DeviceProfile;
 import com.android.launcher3.DeviceProfile.OnDeviceProfileChangeListener;
 import com.android.launcher3.Hotseat;
-import com.android.launcher3.Launcher;
 import com.android.launcher3.Workspace;
 import com.android.launcher3.config.FeatureFlags;
+import com.android.launcher3.uioverrides.QuickstepLauncher;
 import com.android.launcher3.util.HorizontalInsettableView;
 import com.android.quickstep.SystemUiProxy;
 import com.android.quickstep.util.unfold.LauncherJankMonitorTransitionProgressListener;
@@ -56,7 +56,7 @@
     private static final FloatProperty<Hotseat> HOTSEAT_SCALE_PROPERTY =
             HOTSEAT_SCALE_PROPERTY_FACTORY.get(SCALE_INDEX_UNFOLD_ANIMATION);
 
-    private final Launcher mLauncher;
+    private final QuickstepLauncher mLauncher;
     private final ScopedUnfoldTransitionProgressProvider mProgressProvider;
     private final NaturalRotationUnfoldProgressProvider mNaturalOrientationProgressProvider;
     private final UnfoldMoveFromCenterHotseatAnimator mUnfoldMoveFromCenterHotseatAnimator;
@@ -73,7 +73,7 @@
     private HorizontalInsettableView mQsbInsettable;
 
     public LauncherUnfoldAnimationController(
-            Launcher launcher,
+            QuickstepLauncher launcher,
             WindowManager windowManager,
             UnfoldTransitionProgressProvider unfoldTransitionProgressProvider,
             RotationChangeProvider rotationChangeProvider) {
diff --git a/quickstep/src/com/android/quickstep/util/RecentsAtomicAnimationFactory.java b/quickstep/src/com/android/quickstep/util/RecentsAtomicAnimationFactory.java
index 1d008da..0b05c2e 100644
--- a/quickstep/src/com/android/quickstep/util/RecentsAtomicAnimationFactory.java
+++ b/quickstep/src/com/android/quickstep/util/RecentsAtomicAnimationFactory.java
@@ -19,39 +19,40 @@
 
 import android.animation.Animator;
 import android.animation.ObjectAnimator;
+import android.content.Context;
 
 import androidx.dynamicanimation.animation.DynamicAnimation;
 
 import com.android.launcher3.anim.SpringAnimationBuilder;
 import com.android.launcher3.statemanager.StateManager.AtomicAnimationFactory;
-import com.android.launcher3.statemanager.StatefulActivity;
 import com.android.quickstep.views.RecentsView;
+import com.android.quickstep.views.RecentsViewContainer;
 
-public class RecentsAtomicAnimationFactory<ACTIVITY_TYPE extends StatefulActivity, STATE_TYPE>
-        extends AtomicAnimationFactory<STATE_TYPE> {
+public class RecentsAtomicAnimationFactory<CONTAINER extends Context & RecentsViewContainer,
+        STATE_TYPE> extends AtomicAnimationFactory<STATE_TYPE> {
 
     public static final int INDEX_RECENTS_FADE_ANIM = AtomicAnimationFactory.NEXT_INDEX + 0;
     public static final int INDEX_RECENTS_TRANSLATE_X_ANIM = AtomicAnimationFactory.NEXT_INDEX + 1;
 
     private static final int MY_ANIM_COUNT = 2;
 
-    protected final ACTIVITY_TYPE mActivity;
+    protected final CONTAINER mContainer;
 
-    public RecentsAtomicAnimationFactory(ACTIVITY_TYPE activity) {
+    public RecentsAtomicAnimationFactory(CONTAINER container) {
         super(MY_ANIM_COUNT);
-        mActivity = activity;
+        mContainer = container;
     }
 
     @Override
     public Animator createStateElementAnimation(int index, float... values) {
         switch (index) {
             case INDEX_RECENTS_FADE_ANIM:
-                ObjectAnimator alpha = ObjectAnimator.ofFloat(mActivity.getOverviewPanel(),
+                ObjectAnimator alpha = ObjectAnimator.ofFloat(mContainer.getOverviewPanel(),
                         RecentsView.CONTENT_ALPHA, values);
                 return alpha;
             case INDEX_RECENTS_TRANSLATE_X_ANIM: {
-                RecentsView rv = mActivity.getOverviewPanel();
-                return new SpringAnimationBuilder(mActivity)
+                RecentsView rv = mContainer.getOverviewPanel();
+                return new SpringAnimationBuilder(mContainer)
                         .setMinimumVisibleChange(DynamicAnimation.MIN_VISIBLE_CHANGE_SCALE)
                         .setDampingRatio(0.8f)
                         .setStiffness(250)
diff --git a/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java b/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java
index cba628b..9335e7e 100644
--- a/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java
+++ b/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java
@@ -50,7 +50,7 @@
 import com.android.launcher3.touch.PagedOrientationHandler;
 import com.android.launcher3.util.DisplayController;
 import com.android.launcher3.util.SettingsCache;
-import com.android.quickstep.BaseActivityInterface;
+import com.android.quickstep.BaseContainerInterface;
 import com.android.quickstep.SystemUiProxy;
 import com.android.quickstep.TaskAnimationManager;
 import com.android.quickstep.orientation.RecentsPagedOrientationHandler;
@@ -118,7 +118,7 @@
                     | FLAG_SWIPE_UP_NOT_RUNNING;
 
     private final Context mContext;
-    private final BaseActivityInterface mActivityInterface;
+    private final BaseContainerInterface mContainerInterface;
     private final OrientationEventListener mOrientationListener;
     private final SettingsCache mSettingsCache;
     private final SettingsCache.OnChangeListener mRotationChangeListener =
@@ -138,10 +138,10 @@
      *                              is enabled
      * @see #setRotationWatcherEnabled(boolean)
      */
-    public RecentsOrientedState(Context context, BaseActivityInterface activityInterface,
+    public RecentsOrientedState(Context context, BaseContainerInterface containerInterface,
             IntConsumer rotationChangeListener) {
         mContext = context;
-        mActivityInterface = activityInterface;
+        mContainerInterface = containerInterface;
         mOrientationListener = new OrientationEventListener(context) {
             @Override
             public void onOrientationChanged(int degrees) {
@@ -153,7 +153,7 @@
             }
         };
 
-        mFlags = mActivityInterface.rotationSupportedByActivity
+        mFlags = mContainerInterface.rotationSupportedByActivity
                 ? FLAG_MULTIPLE_ORIENTATION_SUPPORTED_BY_ACTIVITY : 0;
 
         mFlags |= FLAG_SWIPE_UP_NOT_RUNNING;
@@ -161,8 +161,8 @@
         initFlags();
     }
 
-    public BaseActivityInterface getActivityInterface() {
-        return mActivityInterface;
+    public BaseContainerInterface getContainerInterface() {
+        return mContainerInterface;
     }
 
     /**
diff --git a/quickstep/src/com/android/quickstep/util/ScalingWorkspaceRevealAnim.kt b/quickstep/src/com/android/quickstep/util/ScalingWorkspaceRevealAnim.kt
index 33736ad..48c2407 100644
--- a/quickstep/src/com/android/quickstep/util/ScalingWorkspaceRevealAnim.kt
+++ b/quickstep/src/com/android/quickstep/util/ScalingWorkspaceRevealAnim.kt
@@ -20,7 +20,6 @@
 import com.android.app.animation.Interpolators
 import com.android.app.animation.Interpolators.EMPHASIZED
 import com.android.app.animation.Interpolators.LINEAR
-import com.android.launcher3.Launcher
 import com.android.launcher3.LauncherAnimUtils.HOTSEAT_SCALE_PROPERTY_FACTORY
 import com.android.launcher3.LauncherAnimUtils.SCALE_INDEX_WORKSPACE_STATE
 import com.android.launcher3.LauncherAnimUtils.WORKSPACE_SCALE_PROPERTY_FACTORY
@@ -39,7 +38,7 @@
  * Creates an animation where the workspace and hotseat fade in while revealing from the center of
  * the screen outwards radially. This is used in conjunction with the swipe up to home animation.
  */
-class ScalingWorkspaceRevealAnim(launcher: Launcher) {
+class ScalingWorkspaceRevealAnim(launcher: QuickstepLauncher) {
     companion object {
         private const val FADE_DURATION_MS = 200L
         private const val SCALE_DURATION_MS = 1000L
diff --git a/quickstep/src/com/android/quickstep/util/SlideInRemoteTransition.kt b/quickstep/src/com/android/quickstep/util/SlideInRemoteTransition.kt
index 1347291..dbeedd3 100644
--- a/quickstep/src/com/android/quickstep/util/SlideInRemoteTransition.kt
+++ b/quickstep/src/com/android/quickstep/util/SlideInRemoteTransition.kt
@@ -23,8 +23,8 @@
 import android.os.RemoteException
 import android.view.SurfaceControl
 import android.view.SurfaceControl.Transaction
-import android.window.IRemoteTransition
 import android.window.IRemoteTransitionFinishedCallback
+import android.window.RemoteTransitionStub
 import android.window.TransitionInfo
 import com.android.launcher3.anim.AnimatorListeners.forEndCallback
 import com.android.launcher3.util.Executors
@@ -36,19 +36,9 @@
     private val pageSpacing: Int,
     private val cornerRadius: Float,
     private val interpolator: TimeInterpolator,
-) : IRemoteTransition.Stub() {
+) : RemoteTransitionStub() {
     private val animationDurationMs = 500L
 
-    override fun mergeAnimation(
-        iBinder: IBinder,
-        transitionInfo: TransitionInfo,
-        transaction: Transaction,
-        mergeTarget: IBinder,
-        finishCB: IRemoteTransitionFinishedCallback
-    ) {
-        // Do not report finish if we don't know how to handle this transition.
-    }
-
     override fun startAnimation(
         transition: IBinder,
         info: TransitionInfo,
@@ -116,6 +106,4 @@
 
         Executors.MAIN_EXECUTOR.execute { anim.start() }
     }
-
-    override fun onTransitionConsumed(transition: IBinder?, aborted: Boolean) {}
 }
diff --git a/quickstep/src/com/android/quickstep/util/SplitAnimationController.kt b/quickstep/src/com/android/quickstep/util/SplitAnimationController.kt
index 6b27004..021c455 100644
--- a/quickstep/src/com/android/quickstep/util/SplitAnimationController.kt
+++ b/quickstep/src/com/android/quickstep/util/SplitAnimationController.kt
@@ -24,6 +24,7 @@
 import android.animation.ValueAnimator
 import android.app.ActivityManager.RunningTaskInfo
 import android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW
+import android.content.Context
 import android.graphics.Bitmap
 import android.graphics.Rect
 import android.graphics.RectF
@@ -41,8 +42,9 @@
 import com.android.app.animation.Interpolators
 import com.android.launcher3.DeviceProfile
 import com.android.launcher3.Flags.enableOverviewIconMenu
-import com.android.launcher3.Launcher
+import com.android.launcher3.InsettableFrameLayout
 import com.android.launcher3.QuickstepTransitionManager
+import com.android.launcher3.R
 import com.android.launcher3.Utilities
 import com.android.launcher3.anim.PendingAnimation
 import com.android.launcher3.apppairs.AppPairIcon
@@ -50,8 +52,8 @@
 import com.android.launcher3.logging.StatsLogManager.EventEnum
 import com.android.launcher3.statehandlers.DepthController
 import com.android.launcher3.statemanager.StateManager
-import com.android.launcher3.statemanager.StatefulActivity
 import com.android.launcher3.taskbar.TaskbarActivityContext
+import com.android.launcher3.uioverrides.QuickstepLauncher
 import com.android.launcher3.util.MultiPropertyFactory.MULTI_PROPERTY_VALUE
 import com.android.launcher3.util.SplitConfigurationOptions.SplitSelectSource
 import com.android.launcher3.views.BaseDragLayer
@@ -61,6 +63,7 @@
 import com.android.quickstep.views.GroupedTaskView
 import com.android.quickstep.views.IconAppChipView
 import com.android.quickstep.views.RecentsView
+import com.android.quickstep.views.RecentsViewContainer
 import com.android.quickstep.views.SplitInstructionsView
 import com.android.quickstep.views.TaskThumbnailView
 import com.android.quickstep.views.TaskView
@@ -268,13 +271,58 @@
         }
     }
 
+    /**
+     * Creates and returns a view to fade in at .4 animation progress and adds it to the provided
+     * [pendingAnimation]. Assumes that animation will be the final split placeholder launch anim.
+     *
+     * [secondPlaceholderEndingBounds] refers to the second placeholder view that gets added on
+     * screen, not the logical second app.
+     * For landscape it's the left app and for portrait the top one.
+     */
+    fun addDividerPlaceholderViewToAnim(pendingAnimation: PendingAnimation,
+                                        container: RecentsViewContainer,
+                                        secondPlaceholderEndingBounds: Rect,
+                                        context: Context) : View {
+        val mSplitDividerPlaceholderView = View(context)
+        val recentsView = container.getOverviewPanel<RecentsView<*, *>>()
+        val dp : com.android.launcher3.DeviceProfile = container.getDeviceProfile()
+        // Add it before/under the most recently added first floating taskView
+        val firstAddedSplitViewIndex: Int = container.getDragLayer().indexOfChild(
+                recentsView.splitSelectController.firstFloatingTaskView)
+        container.getDragLayer().addView(mSplitDividerPlaceholderView, firstAddedSplitViewIndex)
+        val lp = mSplitDividerPlaceholderView.layoutParams as InsettableFrameLayout.LayoutParams
+        lp.topMargin = 0
+
+        if (dp.isLeftRightSplit) {
+            lp.height = secondPlaceholderEndingBounds.height()
+            lp.width = container.asContext().resources.
+                getDimensionPixelSize(R.dimen.split_divider_handle_region_height)
+            mSplitDividerPlaceholderView.translationX = secondPlaceholderEndingBounds.right - lp.width / 2f
+            mSplitDividerPlaceholderView.translationY = 0f
+        } else {
+            lp.height = container.asContext().resources
+                    .getDimensionPixelSize(R.dimen.split_divider_handle_region_height)
+            lp.width = secondPlaceholderEndingBounds.width()
+            mSplitDividerPlaceholderView.translationY = secondPlaceholderEndingBounds.top - lp.height / 2f
+            mSplitDividerPlaceholderView.translationX = 0f
+        }
+
+        mSplitDividerPlaceholderView.alpha = 0f
+        mSplitDividerPlaceholderView.setBackgroundColor(container.asContext().resources
+                .getColor(R.color.taskbar_background_dark))
+        val timings = AnimUtils.getDeviceSplitToConfirmTimings(dp.isTablet)
+        pendingAnimation.setViewAlpha(mSplitDividerPlaceholderView, 1f,
+                Interpolators.clampToProgress(timings.stagedRectScaleXInterpolator, 0.4f, 1f))
+        return mSplitDividerPlaceholderView
+    }
+
     /** Does not play any animation if user is not currently in split selection state. */
-    fun playPlaceholderDismissAnim(launcher: StatefulActivity<*>, splitDismissEvent: EventEnum) {
+    fun playPlaceholderDismissAnim(container: RecentsViewContainer, splitDismissEvent: EventEnum) {
         if (!splitSelectStateController.isSplitSelectActive) {
             return
         }
 
-        val anim = createPlaceholderDismissAnim(launcher, splitDismissEvent, null /*duration*/)
+        val anim = createPlaceholderDismissAnim(container, splitDismissEvent, null /*duration*/)
         anim.start()
     }
 
@@ -283,18 +331,18 @@
      * for why split is being dismissed
      */
     fun createPlaceholderDismissAnim(
-        launcher: StatefulActivity<*>,
+        container: RecentsViewContainer,
         splitDismissEvent: EventEnum,
         duration: Long?
     ): AnimatorSet {
         val animatorSet = AnimatorSet()
         duration?.let { animatorSet.duration = it }
-        val recentsView: RecentsView<*, *> = launcher.getOverviewPanel()
+        val recentsView: RecentsView<*, *> = container.getOverviewPanel()
         val floatingTask: FloatingTaskView =
             splitSelectStateController.firstFloatingTaskView ?: return animatorSet
 
         // We are in split selection state currently, transitioning to another state
-        val dragLayer: BaseDragLayer<*> = launcher.dragLayer
+        val dragLayer: BaseDragLayer<*> = container.dragLayer
         val onScreenRectF = RectF()
         Utilities.getBoundsForViewInDragLayer(
             dragLayer,
@@ -320,7 +368,7 @@
                     floatingTask,
                     onScreenRectF,
                     floatingTask.stagePosition,
-                    launcher.deviceProfile
+                    container.deviceProfile
                 )
             )
         )
@@ -329,7 +377,7 @@
                 override fun onAnimationEnd(animation: Animator) {
                     splitSelectStateController.resetState()
                     safeRemoveViewFromDragLayer(
-                        launcher,
+                        container,
                         splitSelectStateController.splitInstructionsView
                     )
                 }
@@ -343,11 +391,11 @@
      * Returns a [PendingAnimation] to animate in the chip to instruct a user to select a second app
      * for splitscreen
      */
-    fun getShowSplitInstructionsAnim(launcher: StatefulActivity<*>): PendingAnimation {
-        safeRemoveViewFromDragLayer(launcher, splitSelectStateController.splitInstructionsView)
-        val splitInstructionsView = SplitInstructionsView.getSplitInstructionsView(launcher)
+    fun getShowSplitInstructionsAnim(container: RecentsViewContainer): PendingAnimation {
+        safeRemoveViewFromDragLayer(container, splitSelectStateController.splitInstructionsView)
+        val splitInstructionsView = SplitInstructionsView.getSplitInstructionsView(container)
         splitSelectStateController.splitInstructionsView = splitInstructionsView
-        val timings = AnimUtils.getDeviceOverviewToSplitTimings(launcher.deviceProfile.isTablet)
+        val timings = AnimUtils.getDeviceOverviewToSplitTimings(container.deviceProfile.isTablet)
         val anim = PendingAnimation(100 /*duration */)
         splitInstructionsView.alpha = 0f
         anim.setViewAlpha(
@@ -374,8 +422,8 @@
     }
 
     /** Removes the split instructions view from [launcher] drag layer. */
-    fun removeSplitInstructionsView(launcher: StatefulActivity<*>) {
-        safeRemoveViewFromDragLayer(launcher, splitSelectStateController.splitInstructionsView)
+    fun removeSplitInstructionsView(container: RecentsViewContainer) {
+        safeRemoveViewFromDragLayer(container, splitSelectStateController.splitInstructionsView)
     }
 
     /**
@@ -384,22 +432,23 @@
      * TODO(b/276361926): Remove the [resetCallback] option once contextual launches
      */
     fun playAnimPlaceholderToFullscreen(
-        launcher: StatefulActivity<*>,
+        container: RecentsViewContainer,
         view: View,
         resetCallback: Optional<Runnable>
     ) {
         val stagedTaskView = view as FloatingTaskView
 
-        val isTablet: Boolean = launcher.deviceProfile.isTablet
+        val isTablet: Boolean = container.deviceProfile.isTablet
         val duration =
             if (isTablet) SplitAnimationTimings.TABLET_CONFIRM_DURATION
             else SplitAnimationTimings.PHONE_CONFIRM_DURATION
+
         val pendingAnimation = PendingAnimation(duration.toLong())
         val firstTaskStartingBounds = Rect()
         val firstTaskEndingBounds = Rect()
 
         stagedTaskView.getBoundsOnScreen(firstTaskStartingBounds)
-        launcher.dragLayer.getBoundsOnScreen(firstTaskEndingBounds)
+        container.dragLayer.getBoundsOnScreen(firstTaskEndingBounds)
         splitSelectStateController.setLaunchingFirstAppFullscreen()
 
         stagedTaskView.addConfirmAnimation(
@@ -589,7 +638,7 @@
         }
 
         // Else we are in Launcher and can launch with the full icon stretch-and-split animation.
-        val launcher = Launcher.getLauncher(launchingIconView.context)
+        val launcher = QuickstepLauncher.getLauncher(launchingIconView.context)
         val dp = launcher.deviceProfile
 
         // Create an AnimatorSet that will run both shell and launcher transitions together
@@ -671,6 +720,7 @@
                 appIcon2,
                 dividerPos
             )
+        floatingView.bringToFront()
 
         // Launcher animation: animate the floating view, expanding to fill the display surface
         progressUpdater.addUpdateListener(
@@ -879,11 +929,30 @@
             }
         }
 
+        if (splitRoot1 != null) {
+            // Set the highest level split root alpha; we could technically use the parent of
+            // either splitRoot1 or splitRoot2
+            val parentToken = splitRoot1.parent
+            var rootLayer: Change? = null
+            if (parentToken != null) {
+                rootLayer = transitionInfo.getChange(parentToken)
+            }
+            if (rootLayer != null && rootLayer.leash != null) {
+                openingTargets.add(rootLayer.leash)
+            }
+        }
+
         val animTransaction = Transaction()
         val animator = ValueAnimator.ofFloat(0f, 1f)
         animator.setDuration(QuickstepTransitionManager.SPLIT_LAUNCH_DURATION.toLong())
         animator.addUpdateListener { valueAnimator: ValueAnimator ->
-            val progress = valueAnimator.animatedFraction
+            val progress =
+                    Interpolators.clampToProgress(
+                            Interpolators.LINEAR,
+                            valueAnimator.animatedFraction,
+                            0.8f,
+                            1f
+                    )
             for (leash in openingTargets) {
                 animTransaction.setAlpha(leash, progress)
             }
@@ -905,26 +974,13 @@
             }
         )
 
-        if (splitRoot1 != null) {
-            // Set the highest level split root alpha; we could technically use the parent of
-            // either splitRoot1 or splitRoot2
-            val parentToken = splitRoot1.parent
-            var rootLayer: Change? = null
-            if (parentToken != null) {
-                rootLayer = transitionInfo.getChange(parentToken)
-            }
-            if (rootLayer != null && rootLayer.leash != null) {
-                t.setAlpha(rootLayer.leash, 1f)
-            }
-        }
-
         t.apply()
         animator.start()
     }
 
-    private fun safeRemoveViewFromDragLayer(launcher: StatefulActivity<*>, view: View?) {
+    private fun safeRemoveViewFromDragLayer(container: RecentsViewContainer, view: View?) {
         if (view != null) {
-            launcher.dragLayer.removeView(view)
+            container.dragLayer.removeView(view)
         }
     }
 }
diff --git a/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java b/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java
index d8cbbf9..c257be6 100644
--- a/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java
+++ b/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java
@@ -35,7 +35,6 @@
 import static com.android.quickstep.util.SplitSelectDataHolder.SPLIT_TASK_PENDINGINTENT;
 import static com.android.quickstep.util.SplitSelectDataHolder.SPLIT_TASK_SHORTCUT;
 import static com.android.quickstep.util.SplitSelectDataHolder.SPLIT_TASK_TASK;
-import static com.android.window.flags.Flags.enableDesktopWindowingMode;
 import static com.android.wm.shell.common.split.SplitScreenConstants.KEY_EXTRA_WIDGET_INTENT;
 import static com.android.wm.shell.common.split.SplitScreenConstants.SNAP_TO_50_50;
 
@@ -64,15 +63,15 @@
 import android.view.RemoteAnimationAdapter;
 import android.view.RemoteAnimationTarget;
 import android.view.SurfaceControl;
-import android.window.IRemoteTransition;
 import android.window.IRemoteTransitionFinishedCallback;
 import android.window.RemoteTransition;
+import android.window.RemoteTransitionStub;
 import android.window.TransitionInfo;
 
 import androidx.annotation.Nullable;
+import androidx.annotation.VisibleForTesting;
 
 import com.android.internal.logging.InstanceId;
-import com.android.launcher3.Launcher;
 import com.android.launcher3.R;
 import com.android.launcher3.anim.PendingAnimation;
 import com.android.launcher3.apppairs.AppPairIcon;
@@ -82,9 +81,9 @@
 import com.android.launcher3.model.data.ItemInfo;
 import com.android.launcher3.statehandlers.DepthController;
 import com.android.launcher3.statemanager.StateManager;
-import com.android.launcher3.statemanager.StatefulActivity;
 import com.android.launcher3.testing.TestLogging;
 import com.android.launcher3.testing.shared.TestProtocol;
+import com.android.launcher3.uioverrides.QuickstepLauncher;
 import com.android.launcher3.util.BackPressHandler;
 import com.android.launcher3.util.ComponentKey;
 import com.android.launcher3.util.SplitConfigurationOptions.StagePosition;
@@ -100,6 +99,7 @@
 import com.android.quickstep.views.FloatingTaskView;
 import com.android.quickstep.views.GroupedTaskView;
 import com.android.quickstep.views.RecentsView;
+import com.android.quickstep.views.RecentsViewContainer;
 import com.android.quickstep.views.SplitInstructionsView;
 import com.android.systemui.animation.RemoteAnimationRunnerCompat;
 import com.android.systemui.shared.recents.model.Task;
@@ -121,7 +121,7 @@
 public class SplitSelectStateController {
     private static final String TAG = "SplitSelectStateCtor";
 
-    private StatefulActivity mContext;
+    private RecentsViewContainer mContainer;
     private final Handler mHandler;
     private final RecentsModel mRecentTasksModel;
     @Nullable
@@ -132,6 +132,7 @@
     private final StatsLogManager mStatsLogManager;
     private final SystemUiProxy mSystemUiProxy;
     private final StateManager mStateManager;
+    @Nullable
     private SplitFromDesktopController mSplitFromDesktopController;
     @Nullable
     private DepthController mDepthController;
@@ -178,7 +179,7 @@
         public void onBackInvoked() {
             // When exiting from split selection, leave current context to go to
             // homescreen as well
-            getSplitAnimationController().playPlaceholderDismissAnim(mContext,
+            getSplitAnimationController().playPlaceholderDismissAnim(mContainer,
                     LAUNCHER_SPLIT_SELECTION_EXIT_HOME);
             if (mActivityBackCallback != null) {
                 mActivityBackCallback.run();
@@ -186,11 +187,11 @@
         }
     };
 
-    public SplitSelectStateController(StatefulActivity context, Handler handler,
+    public SplitSelectStateController(RecentsViewContainer container, Handler handler,
             StateManager stateManager, DepthController depthController,
             StatsLogManager statsLogManager, SystemUiProxy systemUiProxy, RecentsModel recentsModel,
             Runnable activityBackCallback) {
-        mContext = context;
+        mContainer = container;
         mHandler = handler;
         mStatsLogManager = statsLogManager;
         mSystemUiProxy = systemUiProxy;
@@ -199,15 +200,18 @@
         mRecentTasksModel = recentsModel;
         mActivityBackCallback = activityBackCallback;
         mSplitAnimationController = new SplitAnimationController(this);
-        mAppPairsController = new AppPairsController(context, this, statsLogManager);
-        mSplitSelectDataHolder = new SplitSelectDataHolder(mContext);
+        mAppPairsController = new AppPairsController(mContainer.asContext(), this, statsLogManager);
+        mSplitSelectDataHolder = new SplitSelectDataHolder(mContainer.asContext());
     }
 
     public void onDestroy() {
-        mContext = null;
+        mContainer = null;
         mActivityBackCallback = null;
         mAppPairsController.onDestroy();
         mSplitSelectDataHolder.onDestroy();
+        if (mSplitFromDesktopController != null) {
+            mSplitFromDesktopController.onDestroy();
+        }
     }
 
     /**
@@ -642,8 +646,13 @@
         }
     }
 
-    public void initSplitFromDesktopController(Launcher launcher) {
-        mSplitFromDesktopController = new SplitFromDesktopController(launcher);
+    public void initSplitFromDesktopController(QuickstepLauncher launcher) {
+        initSplitFromDesktopController(new SplitFromDesktopController(launcher));
+    }
+
+    @VisibleForTesting
+    void initSplitFromDesktopController(SplitFromDesktopController controller) {
+        mSplitFromDesktopController = controller;
     }
 
     private RemoteTransition getShellRemoteTransition(int firstTaskId, int secondTaskId,
@@ -721,7 +730,7 @@
     /**
      * Requires Shell Transitions
      */
-    private class RemoteSplitLaunchTransitionRunner extends IRemoteTransition.Stub {
+    private class RemoteSplitLaunchTransitionRunner extends RemoteTransitionStub {
 
         private final int mInitialTaskId;
         private final int mSecondTaskId;
@@ -770,13 +779,6 @@
         }
 
         @Override
-        public void mergeAnimation(IBinder transition, TransitionInfo info,
-                SurfaceControl.Transaction t, IBinder mergeTarget,
-                IRemoteTransitionFinishedCallback finishedCallback) {
-            // Do not report finish if we don't know how to handle this transition.
-        }
-
-        @Override
         public void onTransitionConsumed(IBinder transition, boolean aborted)
                 throws RemoteException {
             MAIN_EXECUTOR.execute(() -> {
@@ -946,7 +948,7 @@
     public class SplitFromDesktopController {
         private static final String TAG = "SplitFromDesktopController";
 
-        private final Launcher mLauncher;
+        private final QuickstepLauncher mLauncher;
         private final OverviewComponentObserver mOverviewComponentObserver;
         private final int mSplitPlaceholderSize;
         private final int mSplitPlaceholderInset;
@@ -954,7 +956,7 @@
         private ISplitSelectListener mSplitSelectListener;
         private Drawable mAppIcon;
 
-        public SplitFromDesktopController(Launcher launcher) {
+        public SplitFromDesktopController(QuickstepLauncher launcher) {
             mLauncher = launcher;
             RecentsAnimationDeviceState deviceState = new RecentsAnimationDeviceState(
                     launcher.getApplicationContext());
@@ -968,7 +970,6 @@
                 @Override
                 public boolean onRequestSplitSelect(ActivityManager.RunningTaskInfo taskInfo,
                         int splitPosition, Rect taskBounds) {
-                    if (!enableDesktopWindowingMode()) return false;
                     MAIN_EXECUTOR.execute(() -> enterSplitSelect(taskInfo, splitPosition,
                             taskBounds));
                     return true;
@@ -977,6 +978,11 @@
             SystemUiProxy.INSTANCE.get(mLauncher).registerSplitSelectListener(mSplitSelectListener);
         }
 
+        void onDestroy() {
+            SystemUiProxy.INSTANCE.get(mLauncher).unregisterSplitSelectListener(
+                    mSplitSelectListener);
+        }
+
         /**
          * Enter split select from desktop mode.
          * @param taskInfo the desktop task to move to split stage
diff --git a/quickstep/src/com/android/quickstep/util/SplitToWorkspaceController.java b/quickstep/src/com/android/quickstep/util/SplitToWorkspaceController.java
index 2282c46..b6e6bf7 100644
--- a/quickstep/src/com/android/quickstep/util/SplitToWorkspaceController.java
+++ b/quickstep/src/com/android/quickstep/util/SplitToWorkspaceController.java
@@ -17,7 +17,6 @@
 package com.android.quickstep.util;
 
 import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
-import static com.android.window.flags.Flags.enableDesktopWindowingMode;
 
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
@@ -36,7 +35,6 @@
 
 import com.android.internal.jank.Cuj;
 import com.android.launcher3.DeviceProfile;
-import com.android.launcher3.Launcher;
 import com.android.launcher3.LauncherAppState;
 import com.android.launcher3.R;
 import com.android.launcher3.anim.PendingAnimation;
@@ -47,6 +45,7 @@
 import com.android.launcher3.model.data.ItemInfo;
 import com.android.launcher3.model.data.PackageItemInfo;
 import com.android.launcher3.model.data.WorkspaceItemInfo;
+import com.android.launcher3.uioverrides.QuickstepLauncher;
 import com.android.quickstep.views.FloatingTaskView;
 import com.android.quickstep.views.RecentsView;
 import com.android.systemui.shared.system.InteractionJankMonitorWrapper;
@@ -54,13 +53,14 @@
 /** Handles when the stage split lands on the home screen. */
 public class SplitToWorkspaceController {
 
-    private final Launcher mLauncher;
+    private final QuickstepLauncher mLauncher;
     private final SplitSelectStateController mController;
 
     private final int mHalfDividerSize;
     private final IconCache mIconCache;
 
-    public SplitToWorkspaceController(Launcher launcher, SplitSelectStateController controller) {
+    public SplitToWorkspaceController(QuickstepLauncher launcher,
+            SplitSelectStateController controller) {
         mLauncher = launcher;
         mController = controller;
         mIconCache = LauncherAppState.getInstanceNoCreate().getIconCache();
@@ -163,6 +163,10 @@
                 new RectF(firstTaskStartingBounds), firstTaskEndingBounds,
                 false /* fadeWithThumbnail */, true /* isStagedTask */);
 
+        View mSplitDividerPlaceholderView = recentsView.getSplitSelectController()
+                .getSplitAnimationController().addDividerPlaceholderViewToAnim(pendingAnimation,
+                        mLauncher, secondTaskEndingBounds, view.getContext());
+
         FloatingTaskView secondFloatingTaskView = FloatingTaskView.getFloatingTaskView(mLauncher,
                 view, bitmap, icon, secondTaskStartingBounds);
         secondFloatingTaskView.setAlpha(1);
@@ -173,6 +177,11 @@
             private boolean mIsCancelled = false;
 
             @Override
+            public void onAnimationStart(Animator animation) {
+                mController.launchSplitTasks(aBoolean -> cleanUp());
+            }
+
+            @Override
             public void onAnimationCancel(Animator animation) {
                 mIsCancelled = true;
                 cleanUp();
@@ -181,7 +190,6 @@
             @Override
             public void onAnimationEnd(Animator animation) {
                 if (!mIsCancelled) {
-                    mController.launchSplitTasks(aBoolean -> cleanUp());
                     InteractionJankMonitorWrapper.end(Cuj.CUJ_SPLIT_SCREEN_ENTER);
                 }
             }
@@ -189,6 +197,7 @@
             private void cleanUp() {
                 mLauncher.getDragLayer().removeView(firstFloatingTaskView);
                 mLauncher.getDragLayer().removeView(secondFloatingTaskView);
+                mLauncher.getDragLayer().removeView(mSplitDividerPlaceholderView);
                 mController.getSplitAnimationController().removeSplitInstructionsView(mLauncher);
                 mController.resetState();
             }
@@ -197,8 +206,6 @@
     }
 
     private boolean shouldIgnoreSecondSplitLaunch() {
-        return (!FeatureFlags.enableSplitContextually()
-                && !enableDesktopWindowingMode())
-                || !mController.isSplitSelectActive();
+        return !FeatureFlags.enableSplitContextually() || !mController.isSplitSelectActive();
     }
 }
diff --git a/quickstep/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java b/quickstep/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java
index d6d6a11..997a842 100644
--- a/quickstep/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java
+++ b/quickstep/src/com/android/quickstep/util/StaggeredWorkspaceAnim.java
@@ -38,7 +38,6 @@
 import com.android.launcher3.CellLayout;
 import com.android.launcher3.DeviceProfile;
 import com.android.launcher3.Hotseat;
-import com.android.launcher3.Launcher;
 import com.android.launcher3.LauncherState;
 import com.android.launcher3.QuickstepTransitionManager;
 import com.android.launcher3.R;
@@ -75,13 +74,13 @@
     private final AnimatorSet mAnimators = new AnimatorSet();
     private final @Nullable View mIgnoredView;
 
-    public StaggeredWorkspaceAnim(Launcher launcher, float velocity, boolean animateOverviewScrim,
-            @Nullable View ignoredView) {
+    public StaggeredWorkspaceAnim(QuickstepLauncher launcher, float velocity,
+            boolean animateOverviewScrim, @Nullable View ignoredView) {
         this(launcher, velocity, animateOverviewScrim, ignoredView, true);
     }
 
-    public StaggeredWorkspaceAnim(Launcher launcher, float velocity, boolean animateOverviewScrim,
-            @Nullable View ignoredView, boolean staggerWorkspace) {
+    public StaggeredWorkspaceAnim(QuickstepLauncher launcher, float velocity,
+            boolean animateOverviewScrim, @Nullable View ignoredView, boolean staggerWorkspace) {
         prepareToAnimate(launcher, animateOverviewScrim);
 
         mIgnoredView = ignoredView;
@@ -124,7 +123,8 @@
                 for (int i = hotseatIcons.getChildCount() - 1; i >= 0; i--) {
                     View child = hotseatIcons.getChildAt(i);
                     CellLayoutLayoutParams lp = ((CellLayoutLayoutParams) child.getLayoutParams());
-                    addStaggeredAnimationForView(child, lp.getCellY() + 1, totalRows, duration);
+                    addStaggeredAnimationForView(child, lp.getCellY() + 1,
+                            totalRows, duration);
                 }
             } else {
                 final int hotseatRow, qsbRow;
@@ -194,7 +194,8 @@
         for (int i = itemsContainer.getChildCount() - 1; i >= 0; i--) {
             View child = itemsContainer.getChildAt(i);
             CellLayoutLayoutParams lp = ((CellLayoutLayoutParams) child.getLayoutParams());
-            addStaggeredAnimationForView(child, lp.getCellY() + lp.cellVSpan, totalRows, duration);
+            addStaggeredAnimationForView(child, lp.getCellY() + lp.cellVSpan,
+                    totalRows, duration);
         }
 
         mAnimators.addListener(new AnimatorListenerAdapter() {
@@ -209,7 +210,7 @@
     /**
      * Setup workspace with 0 duration to prepare for our staggered animation.
      */
-    private void prepareToAnimate(Launcher launcher, boolean animateOverviewScrim) {
+    private void prepareToAnimate(QuickstepLauncher launcher, boolean animateOverviewScrim) {
         StateAnimationConfig config = new StateAnimationConfig();
         config.animFlags = SKIP_OVERVIEW | SKIP_DEPTH_CONTROLLER | SKIP_SCRIM;
         config.duration = 0;
@@ -294,12 +295,10 @@
         mAnimators.play(alpha);
     }
 
-    private void addDepthAnimationForState(Launcher launcher, LauncherState state, long duration) {
-        if (!(launcher instanceof QuickstepLauncher)) {
-            return;
-        }
+    private void addDepthAnimationForState(QuickstepLauncher launcher, LauncherState state,
+            long duration) {
         PendingAnimation builder = new PendingAnimation(duration);
-        DepthController depthController = ((QuickstepLauncher) launcher).getDepthController();
+        DepthController depthController = launcher.getDepthController();
         depthController.setStateWithAnimation(state, new StateAnimationConfig(), builder);
         mAnimators.play(builder.buildAnim());
     }
diff --git a/quickstep/src/com/android/quickstep/util/TaskRemovedDuringLaunchListener.java b/quickstep/src/com/android/quickstep/util/TaskRemovedDuringLaunchListener.java
index cdadd71..89d8cc4 100644
--- a/quickstep/src/com/android/quickstep/util/TaskRemovedDuringLaunchListener.java
+++ b/quickstep/src/com/android/quickstep/util/TaskRemovedDuringLaunchListener.java
@@ -24,8 +24,8 @@
 
 import androidx.annotation.NonNull;
 
-import com.android.launcher3.BaseActivity;
 import com.android.quickstep.RecentsModel;
+import com.android.quickstep.views.RecentsViewContainer;
 
 /**
  * This class tracks the failure of a task launch through the TaskView.launchTask() call, in an
@@ -38,7 +38,7 @@
  */
 public class TaskRemovedDuringLaunchListener {
 
-    private BaseActivity mActivity;
+    private RecentsViewContainer mContainer;
     private int mLaunchedTaskId = INVALID_TASK_ID;
     private Runnable mTaskLaunchFailedCallback = null;
 
@@ -49,16 +49,16 @@
      * Registers a failure listener callback if it detects a scenario in which an app launch
      * failed before the transition finished.
      */
-    public void register(BaseActivity activity, int launchedTaskId,
+    public void register(RecentsViewContainer container, int launchedTaskId,
             @NonNull Runnable taskLaunchFailedCallback) {
         // The normal task launch case, Launcher stops and updates its state correctly
-        activity.addEventCallback(EVENT_STOPPED, mUnregisterCallback);
+        container.addEventCallback(EVENT_STOPPED, mUnregisterCallback);
         // The transition hasn't finished but Launcher was resumed, check if the launch failed
-        activity.addEventCallback(EVENT_RESUMED, mResumeCallback);
+        container.addEventCallback(EVENT_RESUMED, mResumeCallback);
         // If we somehow don't get any of the above signals, then just unregister this listener
-        activity.addEventCallback(EVENT_DESTROYED, mUnregisterCallback);
+        container.addEventCallback(EVENT_DESTROYED, mUnregisterCallback);
 
-        mActivity = activity;
+        mContainer = container;
         mLaunchedTaskId = launchedTaskId;
         mTaskLaunchFailedCallback = taskLaunchFailedCallback;
     }
@@ -67,11 +67,11 @@
      * Unregisters the failure listener.
      */
     private void unregister() {
-        mActivity.removeEventCallback(EVENT_STOPPED, mUnregisterCallback);
-        mActivity.removeEventCallback(EVENT_RESUMED, mResumeCallback);
-        mActivity.removeEventCallback(EVENT_DESTROYED, mUnregisterCallback);
+        mContainer.removeEventCallback(EVENT_STOPPED, mUnregisterCallback);
+        mContainer.removeEventCallback(EVENT_RESUMED, mResumeCallback);
+        mContainer.removeEventCallback(EVENT_DESTROYED, mUnregisterCallback);
 
-        mActivity = null;
+        mContainer = null;
         mLaunchedTaskId = INVALID_TASK_ID;
         mTaskLaunchFailedCallback = null;
     }
diff --git a/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java b/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java
index 1152de2..fcb865f 100644
--- a/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java
+++ b/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java
@@ -51,6 +51,7 @@
 import com.android.launcher3.util.SplitConfigurationOptions.SplitBounds;
 import com.android.launcher3.util.TraceHelper;
 import com.android.quickstep.BaseActivityInterface;
+import com.android.quickstep.BaseContainerInterface;
 import com.android.quickstep.TaskAnimationManager;
 import com.android.quickstep.util.SurfaceTransaction.SurfaceProperties;
 import com.android.quickstep.views.TaskView.FullscreenDrawParams;
@@ -70,7 +71,7 @@
     private final float[] mTempPoint = new float[2];
 
     private final Context mContext;
-    private final BaseActivityInterface mSizeStrategy;
+    private final BaseContainerInterface mSizeStrategy;
 
     @NonNull
     private RecentsOrientedState mOrientationState;
@@ -122,7 +123,7 @@
     private int mTaskRectTranslationX;
     private int mTaskRectTranslationY;
 
-    public TaskViewSimulator(Context context, BaseActivityInterface sizeStrategy) {
+    public TaskViewSimulator(Context context, BaseContainerInterface sizeStrategy) {
         mContext = context;
         mSizeStrategy = sizeStrategy;
 
diff --git a/quickstep/src/com/android/quickstep/util/UnfoldMoveFromCenterHotseatAnimator.java b/quickstep/src/com/android/quickstep/util/UnfoldMoveFromCenterHotseatAnimator.java
index c8141b4..4aea1b8 100644
--- a/quickstep/src/com/android/quickstep/util/UnfoldMoveFromCenterHotseatAnimator.java
+++ b/quickstep/src/com/android/quickstep/util/UnfoldMoveFromCenterHotseatAnimator.java
@@ -20,7 +20,7 @@
 import android.view.WindowManager;
 
 import com.android.launcher3.Hotseat;
-import com.android.launcher3.Launcher;
+import com.android.launcher3.uioverrides.QuickstepLauncher;
 import com.android.systemui.unfold.updates.RotationChangeProvider;
 
 /**
@@ -28,10 +28,10 @@
  */
 public class UnfoldMoveFromCenterHotseatAnimator extends BaseUnfoldMoveFromCenterAnimator {
 
-    private final Launcher mLauncher;
+    private final QuickstepLauncher mLauncher;
 
-    public UnfoldMoveFromCenterHotseatAnimator(Launcher launcher, WindowManager windowManager,
-            RotationChangeProvider rotationChangeProvider) {
+    public UnfoldMoveFromCenterHotseatAnimator(QuickstepLauncher launcher,
+            WindowManager windowManager, RotationChangeProvider rotationChangeProvider) {
         super(windowManager, rotationChangeProvider);
         mLauncher = launcher;
     }
diff --git a/quickstep/src/com/android/quickstep/util/UnfoldMoveFromCenterWorkspaceAnimator.java b/quickstep/src/com/android/quickstep/util/UnfoldMoveFromCenterWorkspaceAnimator.java
index c05b38f..0ec3ae0 100644
--- a/quickstep/src/com/android/quickstep/util/UnfoldMoveFromCenterWorkspaceAnimator.java
+++ b/quickstep/src/com/android/quickstep/util/UnfoldMoveFromCenterWorkspaceAnimator.java
@@ -19,9 +19,9 @@
 import android.view.WindowManager;
 
 import com.android.launcher3.CellLayout;
-import com.android.launcher3.Launcher;
 import com.android.launcher3.ShortcutAndWidgetContainer;
 import com.android.launcher3.Workspace;
+import com.android.launcher3.uioverrides.QuickstepLauncher;
 import com.android.systemui.unfold.updates.RotationChangeProvider;
 
 /**
@@ -29,10 +29,10 @@
  */
 public class UnfoldMoveFromCenterWorkspaceAnimator extends BaseUnfoldMoveFromCenterAnimator {
 
-    private final Launcher mLauncher;
+    private final QuickstepLauncher mLauncher;
 
-    public UnfoldMoveFromCenterWorkspaceAnimator(Launcher launcher, WindowManager windowManager,
-            RotationChangeProvider rotationChangeProvider) {
+    public UnfoldMoveFromCenterWorkspaceAnimator(QuickstepLauncher launcher,
+            WindowManager windowManager, RotationChangeProvider rotationChangeProvider) {
         super(windowManager, rotationChangeProvider);
         mLauncher = launcher;
     }
diff --git a/quickstep/src/com/android/quickstep/util/unfold/LauncherUnfoldTransitionController.kt b/quickstep/src/com/android/quickstep/util/unfold/LauncherUnfoldTransitionController.kt
index 54d317d..09563f5 100644
--- a/quickstep/src/com/android/quickstep/util/unfold/LauncherUnfoldTransitionController.kt
+++ b/quickstep/src/com/android/quickstep/util/unfold/LauncherUnfoldTransitionController.kt
@@ -21,15 +21,15 @@
 import com.android.launcher3.Alarm
 import com.android.launcher3.DeviceProfile
 import com.android.launcher3.DeviceProfile.OnDeviceProfileChangeListener
-import com.android.launcher3.Launcher
 import com.android.launcher3.anim.PendingAnimation
 import com.android.launcher3.config.FeatureFlags
+import com.android.launcher3.uioverrides.QuickstepLauncher
 import com.android.launcher3.util.ActivityLifecycleCallbacksAdapter
 import com.android.systemui.unfold.UnfoldTransitionProgressProvider.TransitionProgressListener
 
 /** Controls animations that are happening during unfolding foldable devices */
 class LauncherUnfoldTransitionController(
-    private val launcher: Launcher,
+    private val launcher: QuickstepLauncher,
     private val progressProvider: ProxyUnfoldTransitionProvider
 ) : OnDeviceProfileChangeListener, ActivityLifecycleCallbacksAdapter, TransitionProgressListener {
 
diff --git a/quickstep/src/com/android/quickstep/util/unfold/UnfoldAnimationBuilder.kt b/quickstep/src/com/android/quickstep/util/unfold/UnfoldAnimationBuilder.kt
index d2c4728..2f90ee7 100644
--- a/quickstep/src/com/android/quickstep/util/unfold/UnfoldAnimationBuilder.kt
+++ b/quickstep/src/com/android/quickstep/util/unfold/UnfoldAnimationBuilder.kt
@@ -20,7 +20,6 @@
 import com.android.app.animation.Interpolators.LINEAR
 import com.android.app.animation.Interpolators.clampToProgress
 import com.android.launcher3.CellLayout
-import com.android.launcher3.Launcher
 import com.android.launcher3.LauncherAnimUtils.HOTSEAT_SCALE_PROPERTY_FACTORY
 import com.android.launcher3.LauncherAnimUtils.SCALE_INDEX_UNFOLD_ANIMATION
 import com.android.launcher3.LauncherAnimUtils.VIEW_TRANSLATE_X
@@ -28,6 +27,7 @@
 import com.android.launcher3.LauncherAnimUtils.WORKSPACE_SCALE_PROPERTY_FACTORY
 import com.android.launcher3.Workspace
 import com.android.launcher3.anim.PendingAnimation
+import com.android.launcher3.uioverrides.QuickstepLauncher
 import com.android.launcher3.util.HorizontalInsettableView
 
 private typealias ViewGroupAction = (ViewGroup, Boolean) -> Unit
@@ -112,7 +112,7 @@
      * Builds an animation for the unfold experience and adds it to the provided PendingAnimation
      */
     fun buildUnfoldAnimation(
-        launcher: Launcher,
+        launcher: QuickstepLauncher,
         isVerticalFold: Boolean,
         screenSize: Point,
         anim: PendingAnimation
diff --git a/quickstep/src/com/android/quickstep/views/ClearAllButton.java b/quickstep/src/com/android/quickstep/views/ClearAllButton.java
index 32ef904..b8afd9d 100644
--- a/quickstep/src/com/android/quickstep/views/ClearAllButton.java
+++ b/quickstep/src/com/android/quickstep/views/ClearAllButton.java
@@ -17,15 +17,28 @@
 package com.android.quickstep.views;
 
 import static com.android.launcher3.Flags.enableGridOnlyOverview;
+import static com.android.quickstep.util.BorderAnimator.DEFAULT_BORDER_COLOR;
 
 import android.content.Context;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.graphics.Canvas;
+import android.graphics.Rect;
 import android.util.AttributeSet;
 import android.util.FloatProperty;
 import android.widget.Button;
 
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
 import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.Flags;
+import com.android.launcher3.R;
 import com.android.launcher3.statemanager.StatefulActivity;
 import com.android.quickstep.orientation.RecentsPagedOrientationHandler;
+import com.android.quickstep.util.BorderAnimator;
+
+import kotlin.Unit;
 
 public class ClearAllButton extends Button {
 
@@ -55,7 +68,7 @@
                 }
             };
 
-    private final StatefulActivity mActivity;
+    private final RecentsViewContainer mContainer;
     private float mScrollAlpha = 1;
     private float mContentAlpha = 1;
     private float mVisibilityAlpha = 1;
@@ -71,11 +84,71 @@
     private float mScrollOffsetPrimary;
 
     private int mSidePadding;
+    private int mOutlinePadding;
+    private boolean mBorderEnabled;
+    @Nullable
+    private final BorderAnimator mFocusBorderAnimator;
 
     public ClearAllButton(Context context, AttributeSet attrs) {
         super(context, attrs);
         mIsRtl = getLayoutDirection() == LAYOUT_DIRECTION_RTL;
-        mActivity = StatefulActivity.fromContext(context);
+        mContainer = RecentsViewContainer.containerFromContext(context);
+
+        if (Flags.enableFocusOutline()) {
+            TypedArray styledAttrs = context.obtainStyledAttributes(attrs,
+                    R.styleable.ClearAllButton);
+            Resources resources = getResources();
+            mOutlinePadding = resources.getDimensionPixelSize(
+                    R.dimen.recents_clear_all_outline_padding);
+            mFocusBorderAnimator =
+                    BorderAnimator.createSimpleBorderAnimator(
+                            /* borderRadiusPx= */ resources.getDimensionPixelSize(
+                                    R.dimen.recents_clear_all_outline_radius),
+                            /* borderWidthPx= */ context.getResources().getDimensionPixelSize(
+                                    R.dimen.keyboard_quick_switch_border_width),
+                            /* boundsBuilder= */ this::updateBorderBounds,
+                            /* targetView= */ this,
+                            /* borderColor= */ styledAttrs.getColor(
+                                    R.styleable.ClearAllButton_focusBorderColor,
+                                    DEFAULT_BORDER_COLOR));
+            styledAttrs.recycle();
+        } else {
+            mFocusBorderAnimator = null;
+        }
+    }
+
+    private Unit updateBorderBounds(@NonNull Rect bounds) {
+        bounds.set(0, 0, getWidth(), getHeight());
+        // Make the value negative to form a padding between button and outline
+        bounds.inset(-mOutlinePadding, -mOutlinePadding);
+        return Unit.INSTANCE;
+    }
+
+    @Override
+    public void onFocusChanged(boolean gainFocus, int direction, Rect previouslyFocusedRect) {
+        super.onFocusChanged(gainFocus, direction, previouslyFocusedRect);
+        if (mFocusBorderAnimator != null && mBorderEnabled) {
+            mFocusBorderAnimator.setBorderVisibility(gainFocus, /* animated= */ true);
+        }
+    }
+
+    /**
+     * Enable or disable showing border on focus change
+     */
+    public void setBorderEnabled(boolean enabled) {
+        mBorderEnabled = enabled;
+        if (mFocusBorderAnimator != null) {
+            mFocusBorderAnimator.setBorderVisibility(/* visible= */
+                    enabled && isFocused(), /* animated= */true);
+        }
+    }
+
+    @Override
+    public void draw(Canvas canvas) {
+        if (mFocusBorderAnimator != null) {
+            mFocusBorderAnimator.drawBorder(canvas);
+        }
+        super.draw(canvas);
     }
 
     @Override
@@ -253,7 +326,7 @@
      * Get the Y translation that is set in the original layout position, before scrolling.
      */
     private float getOriginalTranslationY() {
-        DeviceProfile deviceProfile = mActivity.getDeviceProfile();
+        DeviceProfile deviceProfile = mContainer.getDeviceProfile();
         if (deviceProfile.isTablet) {
             if (enableGridOnlyOverview()) {
                 return (getRecentsView().getLastComputedTaskSize().height()
diff --git a/quickstep/src/com/android/quickstep/views/DesktopAppSelectView.java b/quickstep/src/com/android/quickstep/views/DesktopAppSelectView.java
index a5be142..6a9a268 100644
--- a/quickstep/src/com/android/quickstep/views/DesktopAppSelectView.java
+++ b/quickstep/src/com/android/quickstep/views/DesktopAppSelectView.java
@@ -33,6 +33,7 @@
 import com.android.launcher3.Launcher;
 import com.android.launcher3.R;
 import com.android.launcher3.Utilities;
+import com.android.launcher3.uioverrides.QuickstepLauncher;
 
 /**
  * Floating view show on launcher home screen that notifies the user that an app will be launched to
@@ -47,7 +48,7 @@
     private static final int SHOW_CONTENT_ALPHA_DURATION = 83;
     private static final int HIDE_DURATION = 83;
 
-    private final Launcher mLauncher;
+    private final RecentsViewContainer mContainer;
 
     private View mText;
     private View mCloseButton;
@@ -71,7 +72,7 @@
     public DesktopAppSelectView(Context context, AttributeSet attrs, int defStyleAttr,
             int defStyleRes) {
         super(context, attrs, defStyleAttr, defStyleRes);
-        mLauncher = Launcher.getLauncher(context);
+        mContainer = RecentsViewContainer.containerFromContext(context);
     }
 
     /**
@@ -104,7 +105,7 @@
     }
 
     private void show() {
-        mLauncher.getDragLayer().addView(this);
+        mContainer.getDragLayer().addView(this);
 
         // Set up initial values
         getBackground().setAlpha(0);
@@ -163,7 +164,7 @@
             @Override
             public void onAnimationEnd(Animator animation) {
                 super.onAnimationEnd(animation);
-                mLauncher.getDragLayer().removeView(DesktopAppSelectView.this);
+                mContainer.getDragLayer().removeView(DesktopAppSelectView.this);
                 mHideAnimation = null;
             }
         });
diff --git a/quickstep/src/com/android/quickstep/views/DesktopTaskView.java b/quickstep/src/com/android/quickstep/views/DesktopTaskView.java
index 10b4168..78b1763 100644
--- a/quickstep/src/com/android/quickstep/views/DesktopTaskView.java
+++ b/quickstep/src/com/android/quickstep/views/DesktopTaskView.java
@@ -118,7 +118,7 @@
         mBackgroundView = findViewById(R.id.background);
 
         int topMarginPx =
-                mActivity.getDeviceProfile().overviewTaskThumbnailTopMarginPx;
+                mContainer.getDeviceProfile().overviewTaskThumbnailTopMarginPx;
         FrameLayout.LayoutParams params = (LayoutParams) mBackgroundView.getLayoutParams();
         params.topMargin = topMarginPx;
         mBackgroundView.setLayoutParams(params);
@@ -303,7 +303,7 @@
 
     @Override
     protected void setThumbnailOrientation(RecentsOrientedState orientationState) {
-        DeviceProfile deviceProfile = mActivity.getDeviceProfile();
+        DeviceProfile deviceProfile = mContainer.getDeviceProfile();
         int thumbnailTopMargin = deviceProfile.overviewTaskThumbnailTopMarginPx;
 
         LayoutParams snapshotParams = (LayoutParams) mSnapshotView.getLayoutParams();
@@ -420,7 +420,7 @@
 
         setMeasuredDimension(containerWidth, containerHeight);
 
-        int thumbnailTopMarginPx = mActivity.getDeviceProfile().overviewTaskThumbnailTopMarginPx;
+        int thumbnailTopMarginPx = mContainer.getDeviceProfile().overviewTaskThumbnailTopMarginPx;
         containerHeight -= thumbnailTopMarginPx;
 
         int thumbnails = mSnapshotViewMap.size();
@@ -428,8 +428,8 @@
             return;
         }
 
-        int windowWidth = mActivity.getDeviceProfile().widthPx;
-        int windowHeight = mActivity.getDeviceProfile().heightPx;
+        int windowWidth = mContainer.getDeviceProfile().widthPx;
+        int windowHeight = mContainer.getDeviceProfile().heightPx;
 
         float scaleWidth = containerWidth / (float) windowWidth;
         float scaleHeight = containerHeight / (float) windowHeight;
diff --git a/quickstep/src/com/android/quickstep/views/DigitalWellBeingToast.java b/quickstep/src/com/android/quickstep/views/DigitalWellBeingToast.java
index 840382d..8fa5375 100644
--- a/quickstep/src/com/android/quickstep/views/DigitalWellBeingToast.java
+++ b/quickstep/src/com/android/quickstep/views/DigitalWellBeingToast.java
@@ -45,8 +45,6 @@
 import androidx.annotation.Nullable;
 import androidx.annotation.StringRes;
 
-import com.android.launcher3.BaseActivity;
-import com.android.launcher3.BaseDraggingActivity;
 import com.android.launcher3.DeviceProfile;
 import com.android.launcher3.R;
 import com.android.launcher3.Utilities;
@@ -83,7 +81,7 @@
 
     private static final String TAG = DigitalWellBeingToast.class.getSimpleName();
 
-    private final BaseDraggingActivity mActivity;
+    private final RecentsViewContainer mContainer;
     private final TaskView mTaskView;
     private final LauncherApps mLauncherApps;
 
@@ -102,10 +100,10 @@
     private float mSplitOffsetTranslationY;
     private float mSplitOffsetTranslationX;
 
-    public DigitalWellBeingToast(BaseDraggingActivity activity, TaskView taskView) {
-        mActivity = activity;
+    public DigitalWellBeingToast(RecentsViewContainer container, TaskView taskView) {
+        mContainer = container;
         mTaskView = taskView;
-        mLauncherApps = activity.getSystemService(LauncherApps.class);
+        mLauncherApps = container.asContext().getSystemService(LauncherApps.class);
     }
 
     private void setNoLimit() {
@@ -120,9 +118,10 @@
         mAppUsageLimitTimeMs = appUsageLimitTimeMs;
         mAppRemainingTimeMs = appRemainingTimeMs;
         mHasLimit = true;
-        TextView toast = mActivity.getViewCache().getView(R.layout.digital_wellbeing_toast,
-                mActivity, mTaskView);
-        toast.setText(prefixTextWithIcon(mActivity, R.drawable.ic_hourglass_top, getText()));
+        TextView toast = mContainer.getViewCache().getView(R.layout.digital_wellbeing_toast,
+                mContainer.asContext(), mTaskView);
+        toast.setText(prefixTextWithIcon(mContainer.asContext(), R.drawable.ic_hourglass_top,
+                getText()));
         toast.setOnClickListener(this::openAppUsageSettings);
         replaceBanner(toast);
 
@@ -170,14 +169,14 @@
     public void setSplitConfiguration(SplitBounds splitBounds) {
         mSplitBounds = splitBounds;
         if (mSplitBounds == null
-                || !mActivity.getDeviceProfile().isTablet
+                || !mContainer.getDeviceProfile().isTablet
                 || mTaskView.isFocusedTask()) {
             mSplitBannerConfig = SPLIT_BANNER_FULLSCREEN;
             return;
         }
 
         // For portrait grid only height of task changes, not width. So we keep the text the same
-        if (!mActivity.getDeviceProfile().isLeftRightSplit) {
+        if (!mContainer.getDeviceProfile().isLeftRightSplit) {
             mSplitBannerConfig = SPLIT_GRID_BANNER_LARGE;
             return;
         }
@@ -226,7 +225,7 @@
 
         // Use a specific string for usage less than one minute but non-zero.
         if (duration.compareTo(Duration.ZERO) > 0) {
-            return mActivity.getString(durationLessThanOneMinuteStringId);
+            return mContainer.asContext().getString(durationLessThanOneMinuteStringId);
         }
 
         // Otherwise, return 0-minute string.
@@ -250,7 +249,7 @@
                 R.string.shorter_duration_less_than_one_minute,
                 false /* forceFormatWidth */);
         if (forContentDesc || mSplitBannerConfig == SPLIT_BANNER_FULLSCREEN) {
-            return mActivity.getString(
+            return mContainer.asContext().getString(
                     R.string.time_left_for_app,
                     readableDuration);
         }
@@ -270,11 +269,12 @@
                         mTask.getTopComponent().getPackageName()).addFlags(
                         Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
         try {
-            final BaseActivity activity = BaseActivity.fromContext(view.getContext());
+            final RecentsViewContainer container =
+                    RecentsViewContainer.containerFromContext(view.getContext());
             final ActivityOptions options = ActivityOptions.makeScaleUpAnimation(
                     view, 0, 0,
                     view.getWidth(), view.getHeight());
-            activity.startActivity(intent, options.toBundle());
+            container.asContext().startActivity(intent, options.toBundle());
 
             // TODO: add WW logging on the app usage settings click.
         } catch (ActivityNotFoundException e) {
@@ -286,7 +286,7 @@
     private String getContentDescriptionForTask(
             Task task, long appUsageLimitTimeMs, long appRemainingTimeMs) {
         return appUsageLimitTimeMs >= 0 && appRemainingTimeMs >= 0 ?
-                mActivity.getString(
+                mContainer.asContext().getString(
                         R.string.task_contents_description_with_remaining_time,
                         task.titleDescription,
                         getText(appRemainingTimeMs, true /* forContentDesc */)) :
@@ -303,7 +303,7 @@
             mBanner.setOutlineProvider(mOldBannerOutlineProvider);
             mTaskView.removeView(mBanner);
             mBanner.setOnClickListener(null);
-            mActivity.getViewCache().recycleView(R.layout.digital_wellbeing_toast, mBanner);
+            mContainer.getViewCache().recycleView(R.layout.digital_wellbeing_toast, mBanner);
         }
     }
 
@@ -318,7 +318,7 @@
     private void setupAndAddBanner() {
         FrameLayout.LayoutParams layoutParams =
                 (FrameLayout.LayoutParams) mBanner.getLayoutParams();
-        DeviceProfile deviceProfile = mActivity.getDeviceProfile();
+        DeviceProfile deviceProfile = mContainer.getDeviceProfile();
         layoutParams.bottomMargin = ((ViewGroup.MarginLayoutParams)
                 mTaskView.getThumbnail().getLayoutParams()).bottomMargin;
         RecentsPagedOrientationHandler orientationHandler = mTaskView.getPagedOrientationHandler();
diff --git a/quickstep/src/com/android/quickstep/views/FloatingAppPairBackground.kt b/quickstep/src/com/android/quickstep/views/FloatingAppPairBackground.kt
index 1c1e167..0d49309 100644
--- a/quickstep/src/com/android/quickstep/views/FloatingAppPairBackground.kt
+++ b/quickstep/src/com/android/quickstep/views/FloatingAppPairBackground.kt
@@ -26,7 +26,6 @@
 import android.os.Build
 import android.view.animation.Interpolator
 import com.android.app.animation.Interpolators
-import com.android.launcher3.Launcher
 import com.android.launcher3.R
 import com.android.launcher3.Utilities
 import com.android.quickstep.util.AnimUtils
@@ -55,7 +54,7 @@
         private val ARRAY_OF_ZEROES = FloatArray(8)
     }
 
-    private val launcher: Launcher
+    private val container: RecentsViewContainer
     private val backgroundPaint = Paint(Paint.ANTI_ALIAS_FLAG)
 
     // Animation interpolators
@@ -70,15 +69,15 @@
     private val desiredSplitRatio: Float
 
     init {
-        launcher = Launcher.getLauncher(context)
-        val dp = launcher.deviceProfile
+        container = RecentsViewContainer.containerFromContext(context)
+        val dp = container.deviceProfile
         // Set up background paint color
         val ta = context.theme.obtainStyledAttributes(R.styleable.FolderIconPreview)
         backgroundPaint.style = Paint.Style.FILL
         backgroundPaint.color = ta.getColor(R.styleable.FolderIconPreview_folderPreviewColor, 0)
         ta.recycle()
         // Set up timings and interpolators
-        val timings = AnimUtils.getDeviceAppPairLaunchTimings(launcher.deviceProfile.isTablet)
+        val timings = AnimUtils.getDeviceAppPairLaunchTimings(container.deviceProfile.isTablet)
         expandXInterpolator =
             Interpolators.clampToProgress(
                 timings.getStagedRectScaleXInterpolator(),
@@ -105,9 +104,9 @@
             )
 
         // Find device-specific measurements
-        deviceCornerRadius = QuickStepContract.getWindowCornerRadius(launcher)
+        deviceCornerRadius = QuickStepContract.getWindowCornerRadius(container.asContext())
         deviceHalfDividerSize =
-            launcher.resources.getDimensionPixelSize(R.dimen.multi_window_task_divider_size) / 2f
+                container.asContext().resources.getDimensionPixelSize(R.dimen.multi_window_task_divider_size) / 2f
         val dividerCenterPos = dividerPos + deviceHalfDividerSize
         desiredSplitRatio =
             if (dp.isLeftRightSplit) dividerCenterPos / dp.widthPx
@@ -115,7 +114,7 @@
     }
 
     override fun draw(canvas: Canvas) {
-        if (launcher.deviceProfile.isLeftRightSplit) {
+        if (container.deviceProfile.isLeftRightSplit) {
             drawLeftRightSplit(canvas)
         } else {
             drawTopBottomSplit(canvas)
@@ -150,39 +149,37 @@
         val dividerCenterPos = width * desiredSplitRatio
 
         // The left half of the background image
-        val leftSide = RectF(
-            0f,
-            0f,
-            dividerCenterPos - changingDividerSize,
-            height
-        )
+        val leftSide = RectF(0f, 0f, dividerCenterPos - changingDividerSize, height)
         // The right half of the background image
-        val rightSide = RectF(
-            dividerCenterPos + changingDividerSize,
-            0f,
-            width,
-            height
-        )
+        val rightSide = RectF(dividerCenterPos + changingDividerSize, 0f, width, height)
 
         // Draw background
         drawCustomRoundedRect(
             canvas,
             leftSide,
             floatArrayOf(
-                cornerRadiusX, cornerRadiusY,
-                changingInnerRadiusX, changingInnerRadiusY,
-                changingInnerRadiusX, changingInnerRadiusY,
-                cornerRadiusX, cornerRadiusY
+                cornerRadiusX,
+                cornerRadiusY,
+                changingInnerRadiusX,
+                changingInnerRadiusY,
+                changingInnerRadiusX,
+                changingInnerRadiusY,
+                cornerRadiusX,
+                cornerRadiusY,
             )
         )
         drawCustomRoundedRect(
             canvas,
             rightSide,
             floatArrayOf(
-                changingInnerRadiusX, changingInnerRadiusY,
-                cornerRadiusX, cornerRadiusY,
-                cornerRadiusX, cornerRadiusY,
-                changingInnerRadiusX, changingInnerRadiusY
+                changingInnerRadiusX,
+                changingInnerRadiusY,
+                cornerRadiusX,
+                cornerRadiusY,
+                cornerRadiusX,
+                cornerRadiusY,
+                changingInnerRadiusX,
+                changingInnerRadiusY,
             )
         )
 
@@ -250,39 +247,37 @@
         val dividerCenterPos = height * desiredSplitRatio
 
         // The top half of the background image
-        val topSide = RectF(
-            0f,
-            0f,
-            width,
-            dividerCenterPos - changingDividerSize
-        )
+        val topSide = RectF(0f, 0f, width, dividerCenterPos - changingDividerSize)
         // The bottom half of the background image
-        val bottomSide = RectF(
-            0f,
-            dividerCenterPos + changingDividerSize,
-            width,
-            height
-        )
+        val bottomSide = RectF(0f, dividerCenterPos + changingDividerSize, width, height)
 
         // Draw background
         drawCustomRoundedRect(
             canvas,
             topSide,
             floatArrayOf(
-                cornerRadiusX, cornerRadiusY,
-                cornerRadiusX, cornerRadiusY,
-                changingInnerRadiusX, changingInnerRadiusY,
-                changingInnerRadiusX, changingInnerRadiusY
+                cornerRadiusX,
+                cornerRadiusY,
+                cornerRadiusX,
+                cornerRadiusY,
+                changingInnerRadiusX,
+                changingInnerRadiusY,
+                changingInnerRadiusX,
+                changingInnerRadiusY
             )
         )
         drawCustomRoundedRect(
             canvas,
             bottomSide,
             floatArrayOf(
-                changingInnerRadiusX, changingInnerRadiusY,
-                changingInnerRadiusX, changingInnerRadiusY,
-                cornerRadiusX, cornerRadiusY,
-                cornerRadiusX, cornerRadiusY
+                changingInnerRadiusX,
+                changingInnerRadiusY,
+                changingInnerRadiusX,
+                changingInnerRadiusY,
+                cornerRadiusX,
+                cornerRadiusY,
+                cornerRadiusX,
+                cornerRadiusY
             )
         )
 
@@ -338,8 +333,10 @@
             // Fallback rectangle with uniform rounded corners
             val scaleFactorX = floatingView.scaleX
             val scaleFactorY = floatingView.scaleY
-            val cornerRadiusX = QuickStepContract.getWindowCornerRadius(launcher) / scaleFactorX
-            val cornerRadiusY = QuickStepContract.getWindowCornerRadius(launcher) / scaleFactorY
+            val cornerRadiusX =
+                QuickStepContract.getWindowCornerRadius(container.asContext()) / scaleFactorX
+            val cornerRadiusY =
+                QuickStepContract.getWindowCornerRadius(container.asContext()) / scaleFactorY
             c.drawRoundRect(rect, cornerRadiusX, cornerRadiusY, backgroundPaint)
         }
     }
diff --git a/quickstep/src/com/android/quickstep/views/FloatingTaskView.java b/quickstep/src/com/android/quickstep/views/FloatingTaskView.java
index 18922a6..0e451b5 100644
--- a/quickstep/src/com/android/quickstep/views/FloatingTaskView.java
+++ b/quickstep/src/com/android/quickstep/views/FloatingTaskView.java
@@ -36,12 +36,10 @@
 import androidx.annotation.Nullable;
 
 import com.android.launcher3.AbstractFloatingView;
-import com.android.launcher3.BaseActivity;
 import com.android.launcher3.InsettableFrameLayout;
 import com.android.launcher3.R;
 import com.android.launcher3.Utilities;
 import com.android.launcher3.anim.PendingAnimation;
-import com.android.launcher3.statemanager.StatefulActivity;
 import com.android.launcher3.taskbar.TaskbarActivityContext;
 import com.android.launcher3.util.SplitConfigurationOptions;
 import com.android.launcher3.views.BaseDragLayer;
@@ -54,7 +52,7 @@
 
 /**
  * Create an instance via
- * {@link #getFloatingTaskView(StatefulActivity, View, Bitmap, Drawable, RectF)} to
+ * {@link #getFloatingTaskView(RecentsViewContainer, View, Bitmap, Drawable, RectF)} to
  * which will have the thumbnail from the provided existing TaskView overlaying the taskview itself.
  *
  * Can then animate the taskview using
@@ -67,32 +65,32 @@
 
     public static final FloatProperty<FloatingTaskView> PRIMARY_TRANSLATE_OFFSCREEN =
             new FloatProperty<FloatingTaskView>("floatingTaskPrimaryTranslateOffscreen") {
-        @Override
-        public void setValue(FloatingTaskView view, float translation) {
-            ((RecentsView) view.mActivity.getOverviewPanel()).getPagedOrientationHandler()
-                    .setFloatingTaskPrimaryTranslation(
-                            view,
-                            translation,
-                            view.mActivity.getDeviceProfile()
-                    );
-        }
+                @Override
+                public void setValue(FloatingTaskView view, float translation) {
+                    ((RecentsView) view.mContainer.getOverviewPanel()).getPagedOrientationHandler()
+                            .setFloatingTaskPrimaryTranslation(
+                                    view,
+                                    translation,
+                                    view.mContainer.getDeviceProfile()
+                            );
+                }
 
-        @Override
-        public Float get(FloatingTaskView view) {
-            return ((RecentsView) view.mActivity.getOverviewPanel())
-                    .getPagedOrientationHandler()
-                    .getFloatingTaskPrimaryTranslation(
-                            view,
-                            view.mActivity.getDeviceProfile()
-                    );
-        }
-    };
+                @Override
+                public Float get(FloatingTaskView view) {
+                        return ((RecentsView) view.mContainer.getOverviewPanel())
+                                .getPagedOrientationHandler()
+                                .getFloatingTaskPrimaryTranslation(
+                                        view,
+                                        view.mContainer.getDeviceProfile()
+                                );
+                }
+            };
 
     private int mSplitHolderSize;
     private FloatingTaskThumbnailView mThumbnailView;
     private SplitPlaceholderView mSplitPlaceholderView;
     private RectF mStartingPosition;
-    private final StatefulActivity mActivity;
+    private final RecentsViewContainer mContainer;
     private final boolean mIsRtl;
     private final FullscreenDrawParams mFullscreenParams;
     private RecentsPagedOrientationHandler mOrientationHandler;
@@ -110,7 +108,7 @@
 
     public FloatingTaskView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
         super(context, attrs, defStyleAttr);
-        mActivity = BaseActivity.fromContext(context);
+        mContainer = RecentsViewContainer.containerFromContext(context);
         mIsRtl = Utilities.isRtl(getResources());
         mFullscreenParams = new FullscreenDrawParams(context);
 
@@ -126,7 +124,7 @@
         mSplitPlaceholderView.setAlpha(0);
     }
 
-    private void init(StatefulActivity launcher, View originalView, @Nullable Bitmap thumbnail,
+    private void init(RecentsViewContainer launcher, View originalView, @Nullable Bitmap thumbnail,
             Drawable icon, RectF positionOut) {
         mStartingPosition = positionOut;
         updateInitialPositionForView(originalView);
@@ -153,7 +151,7 @@
      * Configures and returns a an instance of {@link FloatingTaskView} initially matching the
      * appearance of {@code originalView}.
      */
-    public static FloatingTaskView getFloatingTaskView(StatefulActivity launcher,
+    public static FloatingTaskView getFloatingTaskView(RecentsViewContainer launcher,
             View originalView, @Nullable Bitmap thumbnail, Drawable icon, RectF positionOut) {
         final ViewGroup dragLayer = launcher.getDragLayer();
         final FloatingTaskView floatingView = (FloatingTaskView) launcher.getLayoutInflater()
@@ -167,7 +165,7 @@
             // Add to top if not
             openTaskViewIndex = dragLayer.getChildCount();
         }
-        dragLayer.addView(floatingView, openTaskViewIndex - 1);
+        dragLayer.addView(floatingView, openTaskViewIndex);
         return floatingView;
     }
 
@@ -179,13 +177,13 @@
             originalView.getBoundsOnScreen(mTmpRect);
             mStartingPosition.set(mTmpRect);
             int[] dragLayerPositionRelativeToScreen =
-                    mActivity.getDragLayer().getLocationOnScreen();
+                    mContainer.getDragLayer().getLocationOnScreen();
             mStartingPosition.offset(
                     -dragLayerPositionRelativeToScreen[0],
                     -dragLayerPositionRelativeToScreen[1]);
         } else {
             Rect viewBounds = new Rect(0, 0, originalView.getWidth(), originalView.getHeight());
-            Utilities.getBoundsForViewInDragLayer(mActivity.getDragLayer(), originalView,
+            Utilities.getBoundsForViewInDragLayer(mContainer.getDragLayer(), originalView,
                     viewBounds, false /* ignoreTransform */, null /* recycle */,
                     mStartingPosition);
         }
@@ -235,7 +233,7 @@
         // Position the floating view exactly on top of the original
         lp.topMargin = Math.round(pos.top);
         if (mIsRtl) {
-            lp.setMarginStart(mActivity.getDeviceProfile().widthPx - Math.round(pos.right));
+            lp.setMarginStart(mContainer.getDeviceProfile().widthPx - Math.round(pos.right));
         } else {
             lp.setMarginStart(Math.round(pos.left));
         }
@@ -252,7 +250,7 @@
      */
     public void addStagingAnimation(PendingAnimation animation, RectF startingBounds,
             Rect endBounds, boolean fadeWithThumbnail, boolean isStagedTask) {
-        boolean isTablet = mActivity.getDeviceProfile().isTablet;
+        boolean isTablet = mContainer.getDeviceProfile().isTablet;
         boolean splittingFromOverview = fadeWithThumbnail;
         SplitAnimationTimings timings;
 
@@ -276,7 +274,7 @@
     public void addConfirmAnimation(PendingAnimation animation, RectF startingBounds,
             Rect endBounds, boolean fadeWithThumbnail, boolean isStagedTask) {
         SplitAnimationTimings timings =
-                AnimUtils.getDeviceSplitToConfirmTimings(mActivity.getDeviceProfile().isTablet);
+                AnimUtils.getDeviceSplitToConfirmTimings(mContainer.getDeviceProfile().isTablet);
 
         addAnimation(animation, startingBounds, endBounds, fadeWithThumbnail, isStagedTask,
                 timings);
@@ -291,7 +289,7 @@
             Rect endBounds, boolean fadeWithThumbnail, boolean isStagedTask,
             SplitAnimationTimings timings) {
         mFullscreenParams.setIsStagedTask(isStagedTask);
-        final BaseDragLayer dragLayer = mActivity.getDragLayer();
+        final BaseDragLayer dragLayer = mContainer.getDragLayer();
         int[] dragLayerBounds = new int[2];
         dragLayer.getLocationOnScreen(dragLayerBounds);
         SplitOverlayProperties prop = new SplitOverlayProperties(endBounds,
@@ -299,7 +297,6 @@
 
         ValueAnimator transitionAnimator = ValueAnimator.ofFloat(0, 1);
         animation.add(transitionAnimator);
-        long animDuration = animation.getDuration();
         RectF floatingTaskViewBounds = new RectF();
 
         if (fadeWithThumbnail) {
@@ -391,7 +388,7 @@
         mOrientationHandler.updateSplitIconParams(iconView, onScreenRectCenterX,
                 onScreenRectCenterY, mFullscreenParams.mScaleX, mFullscreenParams.mScaleY,
                 iconView.getDrawableWidth(), iconView.getDrawableHeight(),
-                mActivity.getDeviceProfile(), mStagePosition);
+                mContainer.getDeviceProfile(), mStagePosition);
     }
 
     public int getStagePosition() {
diff --git a/quickstep/src/com/android/quickstep/views/FloatingWidgetView.java b/quickstep/src/com/android/quickstep/views/FloatingWidgetView.java
index 6431bdf..4dde635 100644
--- a/quickstep/src/com/android/quickstep/views/FloatingWidgetView.java
+++ b/quickstep/src/com/android/quickstep/views/FloatingWidgetView.java
@@ -33,10 +33,10 @@
 
 import androidx.annotation.Nullable;
 
-import com.android.launcher3.Launcher;
 import com.android.launcher3.R;
 import com.android.launcher3.Utilities;
 import com.android.launcher3.dragndrop.DragLayer;
+import com.android.launcher3.uioverrides.QuickstepLauncher;
 import com.android.launcher3.util.Themes;
 import com.android.launcher3.views.FloatingView;
 import com.android.launcher3.views.ListenerView;
@@ -49,7 +49,7 @@
         OnGlobalLayoutListener, FloatingView {
     private static final Matrix sTmpMatrix = new Matrix();
 
-    private final Launcher mLauncher;
+    private final QuickstepLauncher mLauncher;
     private final ListenerView mListenerView;
     private final FloatingWidgetBackgroundView mBackgroundView;
     private final RectF mBackgroundOffset = new RectF();
@@ -80,7 +80,7 @@
 
     public FloatingWidgetView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
         super(context, attrs, defStyleAttr);
-        mLauncher = Launcher.getLauncher(context);
+        mLauncher = QuickstepLauncher.getLauncher(context);
         mListenerView = new ListenerView(context, attrs);
         mBackgroundView = new FloatingWidgetBackgroundView(context, attrs, defStyleAttr);
         addView(mBackgroundView);
@@ -283,7 +283,7 @@
      * @param windowSize               the size of the window when launched
      * @param windowCornerRadius       the corner radius of the window
      */
-    public static FloatingWidgetView getFloatingWidgetView(Launcher launcher,
+    public static FloatingWidgetView getFloatingWidgetView(QuickstepLauncher launcher,
             LauncherAppWidgetHostView originalView, RectF widgetBackgroundPosition,
             Size windowSize, float windowCornerRadius, boolean appTargetsAreTranslucent,
             int fallbackBackgroundColor) {
@@ -305,7 +305,8 @@
      */
     public static int getDefaultBackgroundColor(
             Context context, RemoteAnimationTarget target) {
-        return (target != null && target.taskInfo.taskDescription != null)
+        return (target != null && target.taskInfo != null
+                && target.taskInfo.taskDescription != null)
                 ? target.taskInfo.taskDescription.getBackgroundColor()
                 : Themes.getColorBackground(context);
     }
diff --git a/quickstep/src/com/android/quickstep/views/GroupedTaskView.java b/quickstep/src/com/android/quickstep/views/GroupedTaskView.java
index 259927d..9e1c856 100644
--- a/quickstep/src/com/android/quickstep/views/GroupedTaskView.java
+++ b/quickstep/src/com/android/quickstep/views/GroupedTaskView.java
@@ -41,11 +41,11 @@
 import com.android.systemui.shared.system.InteractionJankMonitorWrapper;
 import com.android.wm.shell.common.split.SplitScreenConstants.PersistentSnapPosition;
 
+import kotlin.Unit;
+
 import java.util.HashMap;
 import java.util.function.Consumer;
 
-import kotlin.Unit;
-
 /**
  * TaskView that contains and shows thumbnails for not one, BUT TWO(!!) tasks
  *
@@ -81,7 +81,7 @@
 
     public GroupedTaskView(Context context, AttributeSet attrs, int defStyleAttr) {
         super(context, attrs, defStyleAttr);
-        mDigitalWellBeingToast2 = new DigitalWellBeingToast(mActivity, this);
+        mDigitalWellBeingToast2 = new DigitalWellBeingToast(mContainer, this);
     }
 
     @Override
@@ -356,7 +356,7 @@
         if (initSplitTaskId == INVALID_TASK_ID) {
             getPagedOrientationHandler().measureGroupedTaskViewThumbnailBounds(mSnapshotView,
                     mSnapshotView2, widthSize, heightSize, mSplitBoundsConfig,
-                    mActivity.getDeviceProfile(), getLayoutDirection() == LAYOUT_DIRECTION_RTL);
+                    mContainer.getDeviceProfile(), getLayoutDirection() == LAYOUT_DIRECTION_RTL);
             // Should we be having a separate translation step apart from the measuring above?
             // The following only applies to large screen for now, but for future reference
             // we'd want to abstract this out in PagedViewHandlers to get the primary/secondary
@@ -373,7 +373,7 @@
             container.getThumbnailView().measure(widthMeasureSpec,
                     View.MeasureSpec.makeMeasureSpec(
                             heightSize -
-                                    mActivity.getDeviceProfile().overviewTaskThumbnailTopMarginPx,
+                                    mContainer.getDeviceProfile().overviewTaskThumbnailTopMarginPx,
                             MeasureSpec.EXACTLY));
         }
         if (!enableOverviewIconMenu()) {
@@ -392,7 +392,7 @@
 
     @Override
     public void setOrientationState(RecentsOrientedState orientationState) {
-        DeviceProfile deviceProfile = mActivity.getDeviceProfile();
+        DeviceProfile deviceProfile = mContainer.getDeviceProfile();
         if (enableOverviewIconMenu() && mSplitBoundsConfig != null) {
             ViewGroup.LayoutParams layoutParams = getLayoutParams();
             Pair<Point, Point> groupedTaskViewSizes =
@@ -425,7 +425,7 @@
             return;
         }
 
-        DeviceProfile deviceProfile = mActivity.getDeviceProfile();
+        DeviceProfile deviceProfile = mContainer.getDeviceProfile();
         int taskIconHeight = deviceProfile.overviewTaskIconSizePx;
         boolean isRtl = getLayoutDirection() == LAYOUT_DIRECTION_RTL;
 
diff --git a/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java b/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
index cd4fab6..06c2aa3 100644
--- a/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
@@ -26,7 +26,6 @@
 import static com.android.launcher3.LauncherState.OVERVIEW_SPLIT_SELECT;
 import static com.android.launcher3.LauncherState.SPRING_LOADED;
 import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_SPLIT_SELECTION_EXIT_HOME;
-import static com.android.window.flags.Flags.enableDesktopWindowingMode;
 
 import android.annotation.TargetApi;
 import android.content.Context;
@@ -73,7 +72,7 @@
 
     public LauncherRecentsView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
         super(context, attrs, defStyleAttr, LauncherActivityInterface.INSTANCE);
-        mActivity.getStateManager().addStateListener(this);
+        getStateManager().addStateListener(this);
     }
 
     @Override
@@ -86,28 +85,33 @@
 
     @Override
     protected void handleStartHome(boolean animated) {
-        StateManager stateManager = mActivity.getStateManager();
+        StateManager stateManager = getStateManager();
         animated &= stateManager.shouldAnimateStateChange();
         stateManager.goToState(NORMAL, animated);
         if (FeatureFlags.enableSplitContextually()) {
             mSplitSelectStateController.getSplitAnimationController()
-                    .playPlaceholderDismissAnim(mActivity, LAUNCHER_SPLIT_SELECTION_EXIT_HOME);
+                    .playPlaceholderDismissAnim(mContainer, LAUNCHER_SPLIT_SELECTION_EXIT_HOME);
         }
-        AbstractFloatingView.closeAllOpenViews(mActivity, animated);
+        AbstractFloatingView.closeAllOpenViews(mContainer, animated);
     }
 
     @Override
     protected boolean canStartHomeSafely() {
-        return mActivity.canStartHomeSafely();
+        return mContainer.canStartHomeSafely();
+    }
+
+    @Override
+    public StateManager<LauncherState> getStateManager() {
+        return mContainer.getStateManager();
     }
 
     @Override
     protected void onTaskLaunchAnimationEnd(boolean success) {
         if (success) {
-            mActivity.getStateManager().moveToRestState();
+            getStateManager().moveToRestState();
         } else {
-            LauncherState state = mActivity.getStateManager().getState();
-            mActivity.getAllAppsController().setState(state);
+            LauncherState state = getStateManager().getState();
+            mContainer.getAllAppsController().setState(state);
         }
         super.onTaskLaunchAnimationEnd(success);
     }
@@ -116,14 +120,14 @@
     public void onTaskIconChanged(int taskId) {
         super.onTaskIconChanged(taskId);
         // If Launcher needs to return to split select state, do it now, after the icon has updated.
-        if (mActivity.hasPendingSplitSelectInfo()) {
-            PendingSplitSelectInfo recoveryData = mActivity.getPendingSplitSelectInfo();
+        if (mContainer.hasPendingSplitSelectInfo()) {
+            PendingSplitSelectInfo recoveryData = mContainer.getPendingSplitSelectInfo();
             if (recoveryData.getStagedTaskId() == taskId) {
                 initiateSplitSelect(
                         getTaskViewByTaskId(recoveryData.getStagedTaskId()),
                         recoveryData.getStagePosition(), recoveryData.getSource()
                 );
-                mActivity.finishSplitSelectRecovery();
+                mContainer.finishSplitSelectRecovery();
             }
         }
     }
@@ -140,7 +144,7 @@
     public void onStateTransitionStart(LauncherState toState) {
         setOverviewStateEnabled(toState.overviewUi);
 
-        setOverviewGridEnabled(toState.displayOverviewTasksAsGrid(mActivity.getDeviceProfile()));
+        setOverviewGridEnabled(toState.displayOverviewTasksAsGrid(mContainer.getDeviceProfile()));
         setOverviewFullscreenEnabled(toState.getOverviewFullscreenProgress() == 1);
         if (toState == OVERVIEW_MODAL_TASK) {
             setOverviewSelectEnabled(true);
@@ -154,8 +158,8 @@
         }
 
         setFreezeViewVisibility(true);
-        if (mActivity.getDesktopVisibilityController() != null) {
-            mActivity.getDesktopVisibilityController().onLauncherStateChanged(toState);
+        if (mContainer.getDesktopVisibilityController() != null) {
+            mContainer.getDesktopVisibilityController().onLauncherStateChanged(toState);
         }
     }
 
@@ -187,8 +191,8 @@
     public void setOverviewStateEnabled(boolean enabled) {
         super.setOverviewStateEnabled(enabled);
         if (enabled) {
-            LauncherState state = mActivity.getStateManager().getState();
-            boolean hasClearAllButton = (state.getVisibleElements(mActivity)
+            LauncherState state = getStateManager().getState();
+            boolean hasClearAllButton = (state.getVisibleElements(mContainer)
                     & CLEAR_ALL_BUTTON) != 0;
             setDisallowScrollToClearAll(!hasClearAllButton);
         }
@@ -198,30 +202,28 @@
     public boolean onTouchEvent(MotionEvent ev) {
         boolean result = super.onTouchEvent(ev);
         // Do not let touch escape to siblings below this view.
-        return result || mActivity.getStateManager().getState().overviewUi;
+        return result || getStateManager().getState().overviewUi;
     }
 
     @Override
     protected DepthController getDepthController() {
-        return mActivity.getDepthController();
+        return mContainer.getDepthController();
     }
 
     @Override
     public void setModalStateEnabled(int taskId, boolean animate) {
         if (taskId != INVALID_TASK_ID) {
             setSelectedTask(taskId);
-            mActivity.getStateManager().goToState(LauncherState.OVERVIEW_MODAL_TASK, animate);
-        } else {
-            if (mActivity.isInState(LauncherState.OVERVIEW_MODAL_TASK)) {
-                mActivity.getStateManager().goToState(LauncherState.OVERVIEW, animate);
-            }
+            getStateManager().goToState(LauncherState.OVERVIEW_MODAL_TASK, animate);
+        } else if (mContainer.isInState(LauncherState.OVERVIEW_MODAL_TASK)) {
+            getStateManager().goToState(LauncherState.OVERVIEW, animate);
         }
     }
 
     @Override
     protected void onDismissAnimationEnds() {
         super.onDismissAnimationEnds();
-        if (mActivity.isInState(OVERVIEW_SPLIT_SELECT)) {
+        if (mContainer.isInState(OVERVIEW_SPLIT_SELECT)) {
             // We want to keep the tasks translations in this temporary state
             // after resetting the rest above
             setTaskViewsPrimarySplitTranslation(mTaskViewsPrimarySplitTranslation);
@@ -234,13 +236,13 @@
             @SplitConfigurationOptions.StagePosition int stagePosition,
             StatsLogManager.EventEnum splitEvent) {
         super.initiateSplitSelect(taskView, stagePosition, splitEvent);
-        mActivity.getStateManager().goToState(LauncherState.OVERVIEW_SPLIT_SELECT);
+        getStateManager().goToState(LauncherState.OVERVIEW_SPLIT_SELECT);
     }
 
     @Override
     public void initiateSplitSelect(SplitSelectSource splitSelectSource) {
         super.initiateSplitSelect(splitSelectSource);
-        mActivity.getStateManager().goToState(LauncherState.OVERVIEW_SPLIT_SELECT);
+        getStateManager().goToState(LauncherState.OVERVIEW_SPLIT_SELECT);
     }
 
     @Override
@@ -248,7 +250,7 @@
         if (FeatureFlags.enableSplitContextually()) {
             return !mSplitSelectStateController.isSplitSelectActive();
         } else {
-            return !mActivity.isInState(OVERVIEW_SPLIT_SELECT);
+            return !mContainer.isInState(OVERVIEW_SPLIT_SELECT);
         }
     }
 
@@ -257,7 +259,7 @@
             RotationTouchHelper rotationTouchHelper) {
         super.onGestureAnimationStart(runningTasks, rotationTouchHelper);
         DesktopVisibilityController desktopVisibilityController =
-                mActivity.getDesktopVisibilityController();
+                mContainer.getDesktopVisibilityController();
         if (desktopVisibilityController != null) {
             desktopVisibilityController.setRecentsGestureStart();
         }
@@ -265,14 +267,15 @@
 
     @Override
     public void onGestureAnimationEnd() {
-        DesktopVisibilityController desktopVisibilityController = null;
+        DesktopVisibilityController desktopVisibilityController =
+                mContainer.getDesktopVisibilityController();
         boolean showDesktopApps = false;
         GestureState.GestureEndTarget endTarget = null;
-        if (enableDesktopWindowingMode()) {
-            desktopVisibilityController = mActivity.getDesktopVisibilityController();
+        if (desktopVisibilityController != null) {
+            desktopVisibilityController = mContainer.getDesktopVisibilityController();
             endTarget = mCurrentGestureEndTarget;
             if (endTarget == GestureState.GestureEndTarget.LAST_TASK
-                    && desktopVisibilityController.areFreeformTasksVisible()) {
+                    && desktopVisibilityController.areDesktopTasksVisible()) {
                 // Recents gesture was cancelled and we are returning to the previous task.
                 // After super class has handled clean up, show desktop apps on top again
                 showDesktopApps = true;
@@ -283,7 +286,7 @@
             desktopVisibilityController.setRecentsGestureEnd(endTarget);
         }
         if (showDesktopApps) {
-            SystemUiProxy.INSTANCE.get(mActivity).showDesktopApps(mActivity.getDisplayId(),
+            SystemUiProxy.INSTANCE.get(mContainer).showDesktopApps(mContainer.getDisplayId(),
                     null /* transition */);
         }
     }
diff --git a/quickstep/src/com/android/quickstep/views/OverviewActionsView.java b/quickstep/src/com/android/quickstep/views/OverviewActionsView.java
index 384a8d8..5188d4a 100644
--- a/quickstep/src/com/android/quickstep/views/OverviewActionsView.java
+++ b/quickstep/src/com/android/quickstep/views/OverviewActionsView.java
@@ -24,6 +24,7 @@
 import android.view.View.OnClickListener;
 import android.widget.Button;
 import android.widget.FrameLayout;
+import android.widget.LinearLayout;
 
 import androidx.annotation.IntDef;
 import androidx.annotation.Nullable;
@@ -107,6 +108,7 @@
 
     private MultiValueAlpha mMultiValueAlpha;
 
+    protected LinearLayout mActionButtons;
     // The screenshot button is implemented as a Button in launcher3 and NexusLauncher, but is an
     // ImageButton in go launcher (does not share a common class with Button). Take care when
     // casting this.
@@ -151,7 +153,8 @@
     @Override
     protected void onFinishInflate() {
         super.onFinishInflate();
-        mMultiValueAlpha = new MultiValueAlpha(findViewById(R.id.action_buttons), NUM_ALPHAS);
+        mActionButtons = findViewById(R.id.action_buttons);
+        mMultiValueAlpha = new MultiValueAlpha(mActionButtons, NUM_ALPHAS);
         mMultiValueAlpha.setUpdateVisibility(true);
 
         mScreenshotButton = findViewById(R.id.action_screenshot);
@@ -243,13 +246,13 @@
 
     /**
      * Updates a batch of flags to hide and show actions buttons for tablet/non tablet case.
-     * @param isSmallScreen True if the current display is a small screen.
      */
-    public void updateForSmallScreen(boolean isSmallScreen) {
+    private void updateForIsTablet() {
+        assert mDp != null;
         // Update flags to see if split button should be hidden.
-        updateSplitButtonHiddenFlags(FLAG_SMALL_SCREEN_HIDE_SPLIT, isSmallScreen);
+        updateSplitButtonHiddenFlags(FLAG_SMALL_SCREEN_HIDE_SPLIT, !mDp.isTablet);
         // Update flags to see if save app pair button should be hidden.
-        updateAppPairButtonHiddenFlags(FLAG_SMALL_SCREEN_HIDE_APP_PAIR, isSmallScreen);
+        updateAppPairButtonHiddenFlags(FLAG_SMALL_SCREEN_HIDE_APP_PAIR, !mDp.isTablet);
     }
 
     /**
@@ -274,7 +277,10 @@
             mScreenshotButtonHiddenFlags &= ~flag;
         }
         int desiredVisibility = mScreenshotButtonHiddenFlags == 0 ? VISIBLE : GONE;
-        mScreenshotButton.setVisibility(desiredVisibility);
+        if (mScreenshotButton.getVisibility() != desiredVisibility) {
+            mScreenshotButton.setVisibility(desiredVisibility);
+            mActionButtons.requestLayout();
+        }
     }
 
     /**
@@ -292,8 +298,10 @@
             mSplitButtonHiddenFlags &= ~flag;
         }
         int desiredVisibility = mSplitButtonHiddenFlags == 0 ? VISIBLE : GONE;
-        mSplitButton.setVisibility(desiredVisibility);
-        findViewById(R.id.action_split_space).setVisibility(desiredVisibility);
+        if (mSplitButton.getVisibility() != desiredVisibility) {
+            mSplitButton.setVisibility(desiredVisibility);
+            mActionButtons.requestLayout();
+        }
     }
 
     /**
@@ -315,7 +323,10 @@
             mAppPairButtonHiddenFlags &= ~flag;
         }
         int desiredVisibility = mAppPairButtonHiddenFlags == 0 ? VISIBLE : GONE;
-        mSaveAppPairButton.setVisibility(desiredVisibility);
+        if (mSaveAppPairButton.getVisibility() != desiredVisibility) {
+            mSaveAppPairButton.setVisibility(desiredVisibility);
+            mActionButtons.requestLayout();
+        }
     }
 
     public MultiProperty getContentAlpha() {
@@ -342,7 +353,7 @@
      * Returns the visibility of the overview actions buttons.
      */
     public @Visibility int getActionsButtonVisibility() {
-        return findViewById(R.id.action_buttons).getVisibility();
+        return mActionButtons.getVisibility();
     }
 
     /**
@@ -358,8 +369,7 @@
         if (mDp == null) {
             return;
         }
-        LayoutParams actionParams = (LayoutParams) findViewById(
-                R.id.action_buttons).getLayoutParams();
+        LayoutParams actionParams = (LayoutParams) mActionButtons.getLayoutParams();
         actionParams.setMargins(
                 actionParams.leftMargin, mDp.overviewActionsTopMarginPx,
                 actionParams.rightMargin, getBottomMargin());
@@ -386,6 +396,7 @@
         mDp = dp;
         mTaskSize.set(taskSize);
         updateVerticalMargin(DisplayController.getNavigationMode(getContext()));
+        updateForIsTablet();
 
         requestLayout();
 
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index 2aa16a9..791ef04 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -61,7 +61,6 @@
 import static com.android.quickstep.util.TaskGridNavHelper.DIRECTION_TAB;
 import static com.android.quickstep.util.TaskGridNavHelper.DIRECTION_UP;
 import static com.android.quickstep.views.ClearAllButton.DISMISS_ALPHA;
-import static com.android.window.flags.Flags.enableDesktopWindowingMode;
 import static com.android.quickstep.views.OverviewActionsView.HIDDEN_ACTIONS_IN_MENU;
 import static com.android.quickstep.views.OverviewActionsView.HIDDEN_DESKTOP;
 import static com.android.quickstep.views.OverviewActionsView.HIDDEN_NON_ZERO_ROTATION;
@@ -69,6 +68,7 @@
 import static com.android.quickstep.views.OverviewActionsView.HIDDEN_NO_TASKS;
 import static com.android.quickstep.views.OverviewActionsView.HIDDEN_SPLIT_SCREEN;
 import static com.android.quickstep.views.OverviewActionsView.HIDDEN_SPLIT_SELECT_ACTIVE;
+import static com.android.window.flags.Flags.enableDesktopWindowingMode;
 
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
@@ -129,7 +129,6 @@
 import androidx.core.graphics.ColorUtils;
 
 import com.android.internal.jank.Cuj;
-import com.android.launcher3.BaseActivity;
 import com.android.launcher3.BaseActivity.MultiWindowModeChangedListener;
 import com.android.launcher3.DeviceProfile;
 import com.android.launcher3.Insettable;
@@ -149,7 +148,7 @@
 import com.android.launcher3.model.data.ItemInfo;
 import com.android.launcher3.statehandlers.DepthController;
 import com.android.launcher3.statemanager.BaseState;
-import com.android.launcher3.statemanager.StatefulActivity;
+import com.android.launcher3.statemanager.StateManager;
 import com.android.launcher3.testing.TestLogging;
 import com.android.launcher3.testing.shared.TestProtocol;
 import com.android.launcher3.touch.OverScroll;
@@ -163,10 +162,11 @@
 import com.android.launcher3.util.SplitConfigurationOptions.SplitSelectSource;
 import com.android.launcher3.util.SplitConfigurationOptions.StagePosition;
 import com.android.launcher3.util.Themes;
+import com.android.launcher3.util.TraceHelper;
 import com.android.launcher3.util.TranslateEdgeEffect;
 import com.android.launcher3.util.VibratorWrapper;
 import com.android.launcher3.util.ViewPool;
-import com.android.quickstep.BaseActivityInterface;
+import com.android.quickstep.BaseContainerInterface;
 import com.android.quickstep.GestureState;
 import com.android.quickstep.OverviewCommandHelper;
 import com.android.quickstep.RecentsAnimationController;
@@ -226,8 +226,11 @@
 
 /**
  * A list of recent tasks.
+ * @param <CONTAINER_TYPE> : the container that should host recents view
+ * @param <STATE_TYPE> : the type of base state that will be used
  */
-public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_TYPE>,
+
+public abstract class RecentsView<CONTAINER_TYPE extends Context & RecentsViewContainer,
         STATE_TYPE extends BaseState<STATE_TYPE>> extends PagedView implements Insettable,
         TaskThumbnailCache.HighResLoadingState.HighResLoadingStateChangedCallback,
         TaskVisualsChangeListener {
@@ -443,7 +446,7 @@
     private static final float FOREGROUND_SCRIM_TINT = 0.32f;
 
     protected final RecentsOrientedState mOrientationState;
-    protected final BaseActivityInterface<STATE_TYPE, ACTIVITY_TYPE> mSizeStrategy;
+    protected final BaseContainerInterface<STATE_TYPE, CONTAINER_TYPE> mSizeStrategy;
     @Nullable
     protected RecentsAnimationController mRecentsAnimationController;
     @Nullable
@@ -480,7 +483,7 @@
     // The threshold at which we update the SystemUI flags when animating from the task into the app
     public static final float UPDATE_SYSUI_FLAGS_THRESHOLD = 0.85f;
 
-    protected final ACTIVITY_TYPE mActivity;
+    protected final CONTAINER_TYPE mContainer;
     private final float mFastFlingVelocity;
     private final int mScrollHapticMinGapMillis;
     private final RecentsModel mModel;
@@ -720,6 +723,7 @@
     private int mSplitHiddenTaskViewIndex = -1;
     @Nullable
     private FloatingTaskView mSecondFloatingTaskView;
+    private View mSplitDividerPlaceholderView;
 
     /**
      * The task to be removed and immediately re-added. Should not be added to task pool.
@@ -767,14 +771,14 @@
     private final RecentsFilterState mFilterState = new RecentsFilterState();
 
     public RecentsView(Context context, @Nullable AttributeSet attrs, int defStyleAttr,
-            BaseActivityInterface sizeStrategy) {
+            BaseContainerInterface sizeStrategy) {
         super(context, attrs, defStyleAttr);
         setEnableFreeScroll(true);
         mSizeStrategy = sizeStrategy;
-        mActivity = BaseActivity.fromContext(context);
+        mContainer = RecentsViewContainer.containerFromContext(context);
         mOrientationState = new RecentsOrientedState(
                 context, mSizeStrategy, this::animateRecentsRotationInPlace);
-        final int rotation = mActivity.getDisplay().getRotation();
+        final int rotation = mContainer.getDisplay().getRotation();
         mOrientationState.setRecentsRotation(rotation);
 
         mScrollHapticMinGapMillis = getResources()
@@ -826,7 +830,7 @@
                 R.string.task_overlay_factory_class);
 
         // Initialize quickstep specific cache params here, as this is constructed only once
-        mActivity.getViewCache().setCacheSize(R.layout.digital_wellbeing_toast, 5);
+        mContainer.getViewCache().setCacheSize(R.layout.digital_wellbeing_toast, 5);
 
         mTintingColor = getForegroundScrimDimColor(context);
 
@@ -834,9 +838,9 @@
         if (FeatureFlags.ENABLE_MULTI_INSTANCE.get()) {
             // invalidate the current list of tasks if filter changes with a fading in/out animation
             mFilterState.setOnFilterUpdatedListener(() -> {
-                Animator animatorFade = mActivity.getStateManager().createStateElementAnimation(
+                Animator animatorFade = getStateManager().createStateElementAnimation(
                         RecentsAtomicAnimationFactory.INDEX_RECENTS_FADE_ANIM, 1f, 0f);
-                Animator animatorAppear = mActivity.getStateManager().createStateElementAnimation(
+                Animator animatorAppear = getStateManager().createStateElementAnimation(
                         RecentsAtomicAnimationFactory.INDEX_RECENTS_FADE_ANIM, 0f, 1f);
                 animatorFade.addListener(new AnimatorListenerAdapter() {
                     @Override
@@ -1061,6 +1065,8 @@
             @Nullable DesktopRecentsTransitionController desktopRecentsTransitionController) {
         mActionsView = actionsView;
         mActionsView.updateHiddenFlags(HIDDEN_NO_TASKS, getTaskViewCount() == 0);
+        // Update flags for 1p/3p launchers
+        mActionsView.updateFor3pLauncher(!supportsAppPairs());
         mSplitSelectStateController = splitController;
         mDesktopRecentsTransitionController = desktopRecentsTransitionController;
     }
@@ -1086,13 +1092,13 @@
         super.onAttachedToWindow();
         updateTaskStackListenerState();
         mModel.getThumbnailCache().getHighResLoadingState().addCallback(this);
-        mActivity.addMultiWindowModeChangedListener(mMultiWindowModeChangedListener);
+        mContainer.addMultiWindowModeChangedListener(mMultiWindowModeChangedListener);
         TaskStackChangeListeners.getInstance().registerTaskStackListener(mTaskStackListener);
         mSyncTransactionApplier = new SurfaceTransactionApplier(this);
         runActionOnRemoteHandles(remoteTargetHandle -> remoteTargetHandle.getTransformParams()
                 .setSyncTransactionApplier(mSyncTransactionApplier));
         RecentsModel.INSTANCE.get(getContext()).addThumbnailChangeListener(this);
-        mIPipAnimationListener.setActivityAndRecentsView(mActivity, this);
+        mIPipAnimationListener.setActivityAndRecentsView(mContainer, this);
         SystemUiProxy.INSTANCE.get(getContext()).setPipAnimationListener(
                 mIPipAnimationListener);
         mOrientationState.initListeners();
@@ -1107,7 +1113,7 @@
         super.onDetachedFromWindow();
         updateTaskStackListenerState();
         mModel.getThumbnailCache().getHighResLoadingState().removeCallback(this);
-        mActivity.removeMultiWindowModeChangedListener(mMultiWindowModeChangedListener);
+        mContainer.removeMultiWindowModeChangedListener(mMultiWindowModeChangedListener);
         TaskStackChangeListeners.getInstance().unregisterTaskStackListener(mTaskStackListener);
         mSyncTransactionApplier = null;
         runActionOnRemoteHandles(remoteTargetHandle -> remoteTargetHandle.getTransformParams()
@@ -1247,20 +1253,27 @@
         if (taskView == null || !isTaskViewVisible(taskView)) {
             // TODO: Refine this animation.
             SurfaceTransactionApplier surfaceApplier =
-                    new SurfaceTransactionApplier(mActivity.getDragLayer());
+                    new SurfaceTransactionApplier(mContainer.getDragLayer());
             ValueAnimator appAnimator = ValueAnimator.ofFloat(0, 1);
             appAnimator.setDuration(RECENTS_LAUNCH_DURATION);
             appAnimator.setInterpolator(ACCELERATE_DECELERATE);
+            final Matrix matrix = new Matrix();
             appAnimator.addUpdateListener(valueAnimator -> {
                 float percent = valueAnimator.getAnimatedFraction();
                 SurfaceTransaction transaction = new SurfaceTransaction();
-                Matrix matrix = new Matrix();
-                matrix.postScale(percent, percent);
-                matrix.postTranslate(mActivity.getDeviceProfile().widthPx * (1 - percent) / 2,
-                        mActivity.getDeviceProfile().heightPx * (1 - percent) / 2);
-                transaction.forSurface(apps[apps.length - 1].leash)
-                        .setAlpha(percent)
-                        .setMatrix(matrix);
+                for (int i = apps.length - 1; i >= 0; --i) {
+                    RemoteAnimationTarget app = apps[i];
+
+                    float dx = mContainer.getDeviceProfile().widthPx * (1 - percent) / 2
+                            + app.screenSpaceBounds.left * percent;
+                    float dy = mContainer.getDeviceProfile().heightPx * (1 - percent) / 2
+                            + app.screenSpaceBounds.top * percent;
+                    matrix.setScale(percent, percent);
+                    matrix.postTranslate(dx, dy);
+                    transaction.forSurface(app.leash)
+                            .setAlpha(percent)
+                            .setMatrix(matrix);
+                }
                 surfaceApplier.scheduleApply(transaction);
             });
             appAnimator.addListener(new AnimatorListenerAdapter() {
@@ -1285,7 +1298,7 @@
             });
         } else {
             TaskViewUtils.composeRecentsLaunchAnimator(anim, taskView, apps, wallpaper, nonApps,
-                    true /* launcherClosing */, mActivity.getStateManager(), this,
+                    true /* launcherClosing */, getStateManager(), this,
                     getDepthController());
         }
         anim.start();
@@ -1445,6 +1458,7 @@
             TaskView taskView = requireTaskViewAt(i);
             taskView.setBorderEnabled(enabled);
         }
+        mClearAllButton.setBorderEnabled(enabled);
     }
 
     /**
@@ -1461,7 +1475,7 @@
     @Override
     protected void onPageBeginTransition() {
         super.onPageBeginTransition();
-        if (!mActivity.getDeviceProfile().isTablet) {
+        if (!mContainer.getDeviceProfile().isTablet) {
             mActionsView.updateDisabledFlags(OverviewActionsView.DISABLED_SCROLLING, true);
         }
         if (mOverviewStateEnabled) { // only when in overview
@@ -1474,7 +1488,7 @@
         super.onPageEndTransition();
         ActiveGestureLog.INSTANCE.addLog(
                 "onPageEndTransition: current page index updated", getNextPage());
-        if (isClearAllHidden() && !mActivity.getDeviceProfile().isTablet) {
+        if (isClearAllHidden() && !mContainer.getDeviceProfile().isTablet) {
             mActionsView.updateDisabledFlags(OverviewActionsView.DISABLED_SCROLLING, false);
         }
         if (getNextPage() > 0) {
@@ -1485,7 +1499,7 @@
 
     @Override
     protected boolean isSignificantMove(float absoluteDelta, int pageOrientedSize) {
-        DeviceProfile deviceProfile = mActivity.getDeviceProfile();
+        DeviceProfile deviceProfile = mContainer.getDeviceProfile();
         if (!deviceProfile.isTablet) {
             return super.isSignificantMove(absoluteDelta, pageOrientedSize);
         }
@@ -1495,6 +1509,15 @@
     }
 
     @Override
+    public boolean onInterceptTouchEvent(MotionEvent ev) {
+        boolean intercept = super.onInterceptTouchEvent(ev);
+        if (ev.getActionMasked() == MotionEvent.ACTION_DOWN) {
+            Log.d("b/318590728", "onInterceptTouchEvent: " + ev);
+        }
+        return intercept;
+    }
+
+    @Override
     public boolean onTouchEvent(MotionEvent ev) {
         super.onTouchEvent(ev);
 
@@ -1634,7 +1657,7 @@
      * required to move the running task in grid.
      */
     public void moveRunningTaskToFront() {
-        if (!mActivity.getDeviceProfile().isTablet) {
+        if (!mContainer.getDeviceProfile().isTablet) {
             return;
         }
 
@@ -2002,9 +2025,9 @@
         mInsets.set(insets);
 
         // Update DeviceProfile dependant state.
-        DeviceProfile dp = mActivity.getDeviceProfile();
+        DeviceProfile dp = mContainer.getDeviceProfile();
         setOverviewGridEnabled(
-                mActivity.getStateManager().getState().displayOverviewTasksAsGrid(dp));
+                getStateManager().getState().displayOverviewTasksAsGrid(dp));
         if (enableGridOnlyOverview()) {
             mActionsView.updateHiddenFlags(HIDDEN_ACTIONS_IN_MENU, dp.isTablet);
         }
@@ -2041,7 +2064,7 @@
         if (forceRecreateDragLayerControllers
                 || !getPagedOrientationHandler().equals(oldOrientationHandler)) {
             // Changed orientations, update controllers so they intercept accordingly.
-            mActivity.getDragLayer().recreateControllers();
+            mContainer.getDragLayer().recreateControllers();
             onOrientationChanged();
             resetTaskVisuals();
         }
@@ -2073,21 +2096,21 @@
 
     // Update task size and padding that are dependent on DeviceProfile and insets.
     private void updateSizeAndPadding() {
-        DeviceProfile dp = mActivity.getDeviceProfile();
+        DeviceProfile dp = mContainer.getDeviceProfile();
         getTaskSize(mLastComputedTaskSize);
         mTaskWidth = mLastComputedTaskSize.width();
         mTaskHeight = mLastComputedTaskSize.height();
-
         setPadding(mLastComputedTaskSize.left - mInsets.left,
                 mLastComputedTaskSize.top - dp.overviewTaskThumbnailTopMarginPx - mInsets.top,
                 dp.widthPx - mInsets.right - mLastComputedTaskSize.right,
                 dp.heightPx - mInsets.bottom - mLastComputedTaskSize.bottom);
 
-        mSizeStrategy.calculateGridSize(dp, mActivity, mLastComputedGridSize);
-        mSizeStrategy.calculateGridTaskSize(mActivity, dp, mLastComputedGridTaskSize,
+        mSizeStrategy.calculateGridSize(dp, mContainer, mLastComputedGridSize);
+        mSizeStrategy.calculateGridTaskSize(mContainer, dp, mLastComputedGridTaskSize,
                 getPagedOrientationHandler());
+
         if (enableGridOnlyOverview()) {
-            mSizeStrategy.calculateCarouselTaskSize(mActivity, dp, mLastComputedCarouselTaskSize,
+            mSizeStrategy.calculateCarouselTaskSize(mContainer, dp, mLastComputedCarouselTaskSize,
                     getPagedOrientationHandler());
         }
 
@@ -2121,7 +2144,7 @@
 
         float accumulatedTranslationX = 0;
         float translateXToMiddle = 0;
-        if (enableGridOnlyOverview() && mActivity.getDeviceProfile().isTablet) {
+        if (enableGridOnlyOverview() && mContainer.getDeviceProfile().isTablet) {
             translateXToMiddle = mIsRtl
                     ? mLastComputedCarouselTaskSize.right - mLastComputedTaskSize.right
                     : mLastComputedCarouselTaskSize.left - mLastComputedTaskSize.left;
@@ -2143,7 +2166,7 @@
     }
 
     public void getTaskSize(Rect outRect) {
-        mSizeStrategy.calculateTaskSize(mActivity, mActivity.getDeviceProfile(), outRect,
+        mSizeStrategy.calculateTaskSize(mContainer, mContainer.getDeviceProfile(), outRect,
                 getPagedOrientationHandler());
     }
 
@@ -2192,7 +2215,7 @@
 
     /** Gets the task size for modal state. */
     public void getModalTaskSize(Rect outRect) {
-        mSizeStrategy.calculateModalTaskSize(mActivity, mActivity.getDeviceProfile(), outRect,
+        mSizeStrategy.calculateModalTaskSize(mContainer, mContainer.getDeviceProfile(), outRect,
                 getPagedOrientationHandler());
     }
 
@@ -2258,7 +2281,7 @@
 
     @Override
     protected int getDestinationPage(int scaledScroll) {
-        if (!mActivity.getDeviceProfile().isTablet) {
+        if (!mContainer.getDeviceProfile().isTablet) {
             return super.getDestinationPage(scaledScroll);
         }
         if (!isPageScrollsInitialized()) {
@@ -2408,7 +2431,7 @@
     }
 
     public void startHome() {
-        startHome(mActivity.isStarted());
+        startHome(mContainer.isStarted());
     }
 
     public void startHome(boolean animated) {
@@ -2421,6 +2444,8 @@
     /** Returns whether user can start home based on state in {@link OverviewCommandHelper}. */
     protected abstract boolean canStartHomeSafely();
 
+    public abstract StateManager<STATE_TYPE> getStateManager();
+
     public void reset() {
         setCurrentTask(-1);
         mCurrentPageScrollDiff = 0;
@@ -2560,6 +2585,7 @@
      */
     public void onGestureAnimationStart(
             Task[] runningTasks, RotationTouchHelper rotationTouchHelper) {
+        Log.d(TAG, "onGestureAnimationStart");
         mActiveGestureRunningTasks = runningTasks;
         // This needs to be called before the other states are set since it can create the task view
         if (mOrientationState.setGestureActive(true)) {
@@ -2598,7 +2624,7 @@
         AnimatorSet pa = setRecentsChangedOrientation(true);
         pa.addListener(AnimatorListeners.forSuccessCallback(() -> {
             setLayoutRotation(newRotation, mOrientationState.getDisplayRotation());
-            mActivity.getDragLayer().recreateControllers();
+            mContainer.getDragLayer().recreateControllers();
             setRecentsChangedOrientation(false).start();
         }));
         pa.start();
@@ -2627,7 +2653,7 @@
         if (!shouldRotateMenuForFakeRotation) {
             return;
         }
-        TaskMenuView tv = (TaskMenuView) getTopOpenViewWithType(mActivity, TYPE_TASK_MENU);
+        TaskMenuView tv = (TaskMenuView) getTopOpenViewWithType(mContainer, TYPE_TASK_MENU);
         if (tv != null) {
             // Rotation is supported on phone (details at b/254198019#comment4)
             tv.onRotationChanged();
@@ -2648,7 +2674,7 @@
         }
 
         BaseState<?> endState = mSizeStrategy.stateFromGestureEndTarget(endTarget);
-        if (endState.displayOverviewTasksAsGrid(mActivity.getDeviceProfile())) {
+        if (endState.displayOverviewTasksAsGrid(mContainer.getDeviceProfile())) {
             TaskView runningTaskView = getRunningTaskView();
             float runningTaskPrimaryGridTranslation = 0;
             float runningTaskSecondaryGridTranslation = 0;
@@ -2911,7 +2937,7 @@
             return;
         }
 
-        DeviceProfile deviceProfile = mActivity.getDeviceProfile();
+        DeviceProfile deviceProfile = mContainer.getDeviceProfile();
         int taskTopMargin = deviceProfile.overviewTaskThumbnailTopMarginPx;
 
         int topRowWidth = 0;
@@ -3235,7 +3261,7 @@
         int secondaryTaskDimension = getPagedOrientationHandler().getSecondaryDimension(taskView);
         int verticalFactor = getPagedOrientationHandler().getSecondaryTranslationDirectionFactor();
 
-        ResourceProvider rp = DynamicResource.provider(mActivity);
+        ResourceProvider rp = DynamicResource.provider(mContainer);
         SpringProperty sp = new SpringProperty(SpringProperty.FLAG_CAN_SPRING_ON_START)
                 .setDampingRatio(rp.getFloat(R.dimen.dismiss_task_trans_y_damping_ratio))
                 .setStiffness(rp.getFloat(R.dimen.dismiss_task_trans_y_stiffness));
@@ -3263,10 +3289,10 @@
      */
     private void createInitialSplitSelectAnimation(PendingAnimation anim) {
         getPagedOrientationHandler().getInitialSplitPlaceholderBounds(mSplitPlaceholderSize,
-                mSplitPlaceholderInset, mActivity.getDeviceProfile(),
+                mSplitPlaceholderInset, mContainer.getDeviceProfile(),
                 mSplitSelectStateController.getActiveSplitStagePosition(), mTempRect);
         SplitAnimationTimings timings =
-                AnimUtils.getDeviceOverviewToSplitTimings(mActivity.getDeviceProfile().isTablet);
+                AnimUtils.getDeviceOverviewToSplitTimings(mContainer.getDeviceProfile().isTablet);
 
         RectF startingTaskRect = new RectF();
         safeRemoveDragLayerView(mSplitSelectStateController.getFirstFloatingTaskView());
@@ -3282,7 +3308,7 @@
                     timings.getIconFadeEndOffset()));
         }
 
-        FloatingTaskView firstFloatingTaskView = FloatingTaskView.getFloatingTaskView(mActivity,
+        FloatingTaskView firstFloatingTaskView = FloatingTaskView.getFloatingTaskView(mContainer,
                 splitAnimInitProps.getOriginalView(),
                 splitAnimInitProps.getOriginalBitmap(),
                 splitAnimInitProps.getIconDrawable(), startingTaskRect);
@@ -3294,13 +3320,13 @@
         // Allow user to click staged app to launch into fullscreen
         firstFloatingTaskView.setOnClickListener(view ->
                 mSplitSelectStateController.getSplitAnimationController().
-                        playAnimPlaceholderToFullscreen(mActivity, view,
+                        playAnimPlaceholderToFullscreen(mContainer, view,
                                 Optional.of(() -> resetFromSplitSelectionState())));
 
         // SplitInstructionsView: animate in
         safeRemoveDragLayerView(mSplitSelectStateController.getSplitInstructionsView());
         SplitInstructionsView splitInstructionsView =
-                SplitInstructionsView.getSplitInstructionsView(mActivity);
+                SplitInstructionsView.getSplitInstructionsView(mContainer);
         splitInstructionsView.setAlpha(0);
         anim.setViewAlpha(splitInstructionsView, 1, clampToProgress(LINEAR,
                 timings.getInstructionsContainerFadeInStartOffset(),
@@ -3426,7 +3452,7 @@
         boolean isClearAllHidden = isClearAllHidden();
         boolean snapToLastTask = false;
         boolean isLeftRightSplit =
-                mActivity.getDeviceProfile().isLeftRightSplit && isSplitSelectionActive();
+                mContainer.getDeviceProfile().isLeftRightSplit && isSplitSelectionActive();
         TaskView lastGridTaskView = showAsGrid ? getLastGridTaskView() : null;
         int currentPageScroll = getScrollForPage(mCurrentPage);
         int lastGridTaskScroll = getScrollForPage(indexOfChild(lastGridTaskView));
@@ -3471,7 +3497,7 @@
                     // and adjust accordingly to the new shortTotalCompensation after dismiss.
                     int newClearAllShortTotalWidthTranslation = 0;
                     if (longRowWidth < mLastComputedGridSize.width()) {
-                        DeviceProfile deviceProfile = mActivity.getDeviceProfile();
+                        DeviceProfile deviceProfile = mContainer.getDeviceProfile();
                         newClearAllShortTotalWidthTranslation =
                                 (mIsRtl
                                         ? mLastComputedTaskSize.right
@@ -3558,7 +3584,7 @@
         }
 
         SplitAnimationTimings splitTimings =
-                AnimUtils.getDeviceOverviewToSplitTimings(mActivity.getDeviceProfile().isTablet);
+                AnimUtils.getDeviceOverviewToSplitTimings(mContainer.getDeviceProfile().isTablet);
 
         int distanceFromDismissedTask = 0;
         for (int i = 0; i < count; i++) {
@@ -3767,7 +3793,7 @@
                             }
                             announceForAccessibility(
                                     getResources().getString(R.string.task_view_closed));
-                            mActivity.getStatsLogManager().logger()
+                            mContainer.getStatsLogManager().logger()
                                     .withItemInfo(dismissedTaskView.getItemInfo())
                                     .log(LAUNCHER_TASK_DISMISS_SWIPE_UP);
                         }
@@ -3933,7 +3959,7 @@
                         // Update various scroll-dependent UI.
                         dispatchScrollChanged();
                         updateActionsViewFocusedScroll();
-                        if (isClearAllHidden() && !mActivity.getDeviceProfile().isTablet) {
+                        if (isClearAllHidden() && !mContainer.getDeviceProfile().isTablet) {
                             mActionsView.updateDisabledFlags(OverviewActionsView.DISABLED_SCROLLING,
                                     false);
                         }
@@ -3962,15 +3988,9 @@
         // Update flags to see if actions bar should show buttons for a single task or a pair of
         // tasks.
         mActionsView.updateForGroupedTask(isCurrentSplit);
-        // Update flags to see if actions bar should show buttons for tablets or phones.
-        mActionsView.updateForSmallScreen(!mActivity.getDeviceProfile().isTablet);
-        // Update flags for 1p/3p launchers
-        mActionsView.updateFor3pLauncher(!supportsAppPairs());
 
-        if (enableDesktopWindowingMode()) {
-            boolean isCurrentDesktop = getCurrentPageTaskView() instanceof DesktopTaskView;
-            mActionsView.updateHiddenFlags(HIDDEN_DESKTOP, isCurrentDesktop);
-        }
+        boolean isCurrentDesktop = getCurrentPageTaskView() instanceof DesktopTaskView;
+        mActionsView.updateHiddenFlags(HIDDEN_DESKTOP, isCurrentDesktop);
     }
 
     /** Returns if app pairs are supported in this launcher. Overridden in subclasses. */
@@ -4161,7 +4181,7 @@
     @SuppressWarnings("unused")
     private void dismissAllTasks(View view) {
         runDismissAnimation(createAllTasksDismissAnimation(DISMISS_TASK_DURATION));
-        mActivity.getStatsLogManager().logger().log(LAUNCHER_TASK_CLEAR_ALL);
+        mContainer.getStatsLogManager().logger().log(LAUNCHER_TASK_CLEAR_ALL);
     }
 
     private void dismissCurrentTask() {
@@ -4290,7 +4310,8 @@
      * Updates {@link RecentsOrientedState}'s cached RecentsView rotation.
      */
     public void updateRecentsRotation() {
-        final int rotation = mActivity.getDisplay().getRotation();
+        final int rotation = TraceHelper.allowIpcs(
+                "RecentsView.updateRecentsRotation", () -> mContainer.getDisplay().getRotation());
         mOrientationState.setRecentsRotation(rotation);
     }
 
@@ -4404,14 +4425,14 @@
         } else {
             // Only update pivot when it is tablet and not in grid yet, so the pivot is correct
             // for non-current tasks when swiping up to overview
-            if (enableGridOnlyOverview() && mActivity.getDeviceProfile().isTablet
+            if (enableGridOnlyOverview() && mContainer.getDeviceProfile().isTablet
                     && !mOverviewGridEnabled) {
                 mTempRect.set(mLastComputedCarouselTaskSize);
             } else {
                 mTempRect.set(mLastComputedTaskSize);
             }
             getPagedViewOrientedState().getFullScreenScaleAndPivot(mTempRect,
-                    mActivity.getDeviceProfile(), mTempPointF);
+                    mContainer.getDeviceProfile(), mTempPointF);
         }
         setPivotX(mTempPointF.x);
         setPivotY(mTempPointF.y);
@@ -4511,7 +4532,7 @@
             TaskView taskView = (TaskView) child;
             outRect.offset(taskView.getPersistentTranslationX(),
                     taskView.getPersistentTranslationY());
-            outRect.top += mActivity.getDeviceProfile().overviewTaskThumbnailTopMarginPx;
+            outRect.top += mContainer.getDeviceProfile().overviewTaskThumbnailTopMarginPx;
 
             mTempMatrix.reset();
             float persistentScale = taskView.getPersistentScale();
@@ -4623,7 +4644,7 @@
         if (isTopShift) {
             distanceToOffscreen = -taskPosition.bottom;
         } else if (isBottomShift) {
-            distanceToOffscreen = mActivity.getDeviceProfile().heightPx - taskPosition.top;
+            distanceToOffscreen = mContainer.getDeviceProfile().heightPx - taskPosition.top;
         }
         return distanceToOffscreen * offsetProgress;
     }
@@ -4679,7 +4700,7 @@
      */
     public void initiateSplitSelect(TaskView taskView) {
         int defaultSplitPosition = getPagedOrientationHandler()
-                .getDefaultSplitPosition(mActivity.getDeviceProfile());
+                .getDefaultSplitPosition(mContainer.getDeviceProfile());
         initiateSplitSelect(taskView, defaultSplitPosition, LAUNCHER_OVERVIEW_ACTIONS_SPLIT);
     }
 
@@ -4692,9 +4713,7 @@
         mSplitSelectStateController.setAnimateCurrentTaskDismissal(
                 true /*animateCurrentTaskDismissal*/);
         mSplitHiddenTaskViewIndex = indexOfChild(taskView);
-        if (enableDesktopWindowingMode()) {
-            updateDesktopTaskVisibility(false /* visible */);
-        }
+        updateDesktopTaskVisibility(false /* visible */);
     }
 
     /**
@@ -4716,9 +4735,7 @@
         mSplitSelectStateController.setInitialTaskSelect(splitSelectSource.intent,
                 splitSelectSource.position.stagePosition, splitSelectSource.itemInfo,
                 splitSelectSource.splitEvent, splitSelectSource.alreadyRunningTaskId);
-        if (enableDesktopWindowingMode()) {
-            updateDesktopTaskVisibility(false /* visible */);
-        }
+        updateDesktopTaskVisibility(false /* visible */);
     }
 
     private void updateDesktopTaskVisibility(boolean visible) {
@@ -4748,7 +4765,7 @@
             TaskThumbnailView thumbnail = taskIdAttributeContainer.getThumbnailView();
             mSplitSelectStateController.getSplitAnimationController()
                     .addInitialSplitFromPair(taskIdAttributeContainer, builder,
-                            mActivity.getDeviceProfile(),
+                            mContainer.getDeviceProfile(),
                             mSplitHiddenTaskView.getWidth(), mSplitHiddenTaskView.getHeight(),
                             primaryTaskSelected);
             builder.addOnFrameCallback(() ->{
@@ -4816,17 +4833,20 @@
         Rect firstTaskStartingBounds = new Rect();
         Rect firstTaskEndingBounds = mTempRect;
 
-        boolean isTablet = mActivity.getDeviceProfile().isTablet;
+        boolean isTablet = mContainer.getDeviceProfile().isTablet;
         SplitAnimationTimings timings = AnimUtils.getDeviceSplitToConfirmTimings(isTablet);
         PendingAnimation pendingAnimation = new PendingAnimation(timings.getDuration());
 
         int halfDividerSize = getResources()
                 .getDimensionPixelSize(R.dimen.multi_window_task_divider_size) / 2;
         getPagedOrientationHandler().getFinalSplitPlaceholderBounds(halfDividerSize,
-                mActivity.getDeviceProfile(),
+                mContainer.getDeviceProfile(),
                 mSplitSelectStateController.getActiveSplitStagePosition(), firstTaskEndingBounds,
                 secondTaskEndingBounds);
 
+        mSplitDividerPlaceholderView = mSplitSelectStateController
+                .getSplitAnimationController().addDividerPlaceholderViewToAnim(pendingAnimation,
+                        mContainer, secondTaskEndingBounds, getContext());
         FloatingTaskView firstFloatingTaskView =
                 mSplitSelectStateController.getFirstFloatingTaskView();
         firstFloatingTaskView.getBoundsOnScreen(firstTaskStartingBounds);
@@ -4836,7 +4856,7 @@
 
         safeRemoveDragLayerView(mSecondFloatingTaskView);
 
-        mSecondFloatingTaskView = FloatingTaskView.getFloatingTaskView(mActivity, secondView,
+        mSecondFloatingTaskView = FloatingTaskView.getFloatingTaskView(mContainer, secondView,
                 thumbnail, drawable, secondTaskStartingBounds);
         mSecondFloatingTaskView.setAlpha(1);
         mSecondFloatingTaskView.addConfirmAnimation(pendingAnimation, secondTaskStartingBounds,
@@ -4881,10 +4901,11 @@
             safeRemoveDragLayerView(mSplitSelectStateController.getFirstFloatingTaskView());
             safeRemoveDragLayerView(mSecondFloatingTaskView);
             safeRemoveDragLayerView(mSplitSelectStateController.getSplitInstructionsView());
+            safeRemoveDragLayerView(mSplitDividerPlaceholderView);
             mSecondFloatingTaskView = null;
             mSplitSelectSource = null;
             mSplitSelectStateController.getSplitAnimationController()
-                    .removeSplitInstructionsView(mActivity);
+                    .removeSplitInstructionsView(mContainer);
         }
 
         if (mSecondSplitHiddenView != null) {
@@ -4905,7 +4926,7 @@
         if (mSplitHiddenTaskViewIndex == -1) {
             return;
         }
-        if (!mActivity.getDeviceProfile().isTablet) {
+        if (!mContainer.getDeviceProfile().isTablet) {
             int pageToSnapTo = mCurrentPage;
             if (mSplitHiddenTaskViewIndex <= pageToSnapTo) {
                 pageToSnapTo += 1;
@@ -4922,14 +4943,12 @@
             mSplitHiddenTaskView.setThumbnailVisibility(VISIBLE, INVALID_TASK_ID);
             mSplitHiddenTaskView = null;
         }
-        if (enableDesktopWindowingMode()) {
-            updateDesktopTaskVisibility(true /* visible */);
-        }
+        updateDesktopTaskVisibility(true /* visible */);
     }
 
     private void safeRemoveDragLayerView(@Nullable View viewToRemove) {
         if (viewToRemove != null) {
-            mActivity.getDragLayer().removeView(viewToRemove);
+            mContainer.getDragLayer().removeView(viewToRemove);
         }
     }
 
@@ -4938,11 +4957,11 @@
      * Note that the translation can be its primary or secondary dimension.
      */
     public float getSplitSelectTranslation() {
-        DeviceProfile deviceProfile = mActivity.getDeviceProfile();
+        DeviceProfile deviceProfile = mContainer.getDeviceProfile();
         RecentsPagedOrientationHandler orientationHandler = getPagedOrientationHandler();
         int splitPosition = getSplitSelectController().getActiveSplitStagePosition();
         int splitPlaceholderSize =
-                mActivity.getResources().getDimensionPixelSize(R.dimen.split_placeholder_size);
+                mContainer.getResources().getDimensionPixelSize(R.dimen.split_placeholder_size);
         int direction = orientationHandler.getSplitTranslationDirectionFactor(
                 splitPosition, deviceProfile);
 
@@ -4965,7 +4984,7 @@
 
     protected void onRotateInSplitSelectionState() {
         getPagedOrientationHandler().getInitialSplitPlaceholderBounds(mSplitPlaceholderSize,
-                mSplitPlaceholderInset, mActivity.getDeviceProfile(),
+                mSplitPlaceholderInset, mContainer.getDeviceProfile(),
                 mSplitSelectStateController.getActiveSplitStagePosition(), mTempRect);
         mTempRectF.set(mTempRect);
         FloatingTaskView firstFloatingTaskView =
@@ -4977,7 +4996,7 @@
         Pair<FloatProperty<RecentsView>, FloatProperty<RecentsView>> taskViewsFloat =
                 orientationHandler.getSplitSelectTaskOffset(
                         TASK_PRIMARY_SPLIT_TRANSLATION, TASK_SECONDARY_SPLIT_TRANSLATION,
-                        mActivity.getDeviceProfile());
+                        mContainer.getDeviceProfile());
         taskViewsFloat.first.set(this, getSplitSelectTranslation());
         taskViewsFloat.second.set(this, 0f);
 
@@ -5110,10 +5129,10 @@
      * Returns the scale up required on the view, so that it coves the screen completely
      */
     public float getMaxScaleForFullScreen() {
-        if (enableGridOnlyOverview() && mActivity.getDeviceProfile().isTablet
+        if (enableGridOnlyOverview() && mContainer.getDeviceProfile().isTablet
                 && !mOverviewGridEnabled) {
             if (mLastComputedCarouselTaskSize.isEmpty()) {
-                mSizeStrategy.calculateCarouselTaskSize(mActivity, mActivity.getDeviceProfile(),
+                mSizeStrategy.calculateCarouselTaskSize(mContainer, mContainer.getDeviceProfile(),
                         mLastComputedCarouselTaskSize, getPagedOrientationHandler());
             }
             mTempRect.set(mLastComputedCarouselTaskSize);
@@ -5124,7 +5143,7 @@
             mTempRect.set(mLastComputedTaskSize);
         }
         return getPagedViewOrientedState().getFullScreenScaleAndPivot(
-                mTempRect, mActivity.getDeviceProfile(), mTempPointF);
+                mTempRect, mContainer.getDeviceProfile(), mTempPointF);
     }
 
     public PendingAnimation createTaskLaunchAnimation(
@@ -5150,10 +5169,10 @@
             // Once we pass a certain threshold, update the sysui flags to match the target
             // tasks' flags
             if (animator.getAnimatedFraction() > UPDATE_SYSUI_FLAGS_THRESHOLD) {
-                mActivity.getSystemUiController().updateUiState(
+                mContainer.getSystemUiController().updateUiState(
                         UI_STATE_FULLSCREEN_TASK, targetSysUiFlags);
             } else {
-                mActivity.getSystemUiController().updateUiState(UI_STATE_FULLSCREEN_TASK, 0);
+                mContainer.getSystemUiController().updateUiState(UI_STATE_FULLSCREEN_TASK, 0);
             }
 
             // Passing the threshold from taskview to fullscreen app will vibrate
@@ -5175,7 +5194,7 @@
         DepthController depthController = getDepthController();
         if (depthController != null) {
             ObjectAnimator depthAnimator = ObjectAnimator.ofFloat(depthController.stateDepth,
-                    MULTI_PROPERTY_VALUE, BACKGROUND_APP.getDepth(mActivity));
+                    MULTI_PROPERTY_VALUE, BACKGROUND_APP.getDepth(mContainer));
             anim.play(depthAnimator);
         }
         anim.play(ObjectAnimator.ofFloat(this, TASK_THUMBNAIL_SPLASH_ALPHA, 0f, 1f));
@@ -5208,7 +5227,7 @@
                 }
                 Task task = tv.getTask();
                 if (task != null) {
-                    mActivity.getStatsLogManager().logger().withItemInfo(tv.getItemInfo())
+                    mContainer.getStatsLogManager().logger().withItemInfo(tv.getItemInfo())
                             .log(LAUNCHER_TASK_LAUNCH_SWIPE_DOWN);
                 }
             } else {
@@ -5335,7 +5354,7 @@
 
             TaskViewSimulator tvs = remoteTargetHandle.getTaskViewSimulator();
             tvs.setOrientationState(mOrientationState);
-            tvs.setDp(mActivity.getDeviceProfile());
+            tvs.setDp(mContainer.getDeviceProfile());
             tvs.recentsViewScale.value = 1;
         });
 
@@ -5367,6 +5386,10 @@
         finishRecentsAnimation(toRecents, true /* shouldPip */, onFinishComplete);
     }
 
+    /**
+     * NOTE: Whatever value gets passed through to the toRecents param may need to also be set on
+     * {@link #mRecentsAnimationController#setWillFinishToHome}.
+     */
     public void finishRecentsAnimation(boolean toRecents, boolean shouldPip,
             @Nullable Runnable onFinishComplete) {
         Log.d(TAG, "finishRecentsAnimation - mRecentsAnimationController: "
@@ -5386,7 +5409,7 @@
             // Notify the SysUI to use fade-in animation when entering PiP from live tile.
             final SystemUiProxy systemUiProxy = SystemUiProxy.INSTANCE.get(getContext());
             systemUiProxy.setPipAnimationTypeToAlpha();
-            systemUiProxy.setShelfHeight(true, mActivity.getDeviceProfile().hotseatBarSizePx);
+            systemUiProxy.setShelfHeight(true, mContainer.getDeviceProfile().hotseatBarSizePx);
             // Transaction to hide the task to avoid flicker for entering PiP from split-screen.
             // See also {@link AbsSwipeUpHandler#maybeFinishSwipeToHome}.
             PictureInPictureSurfaceTransaction tx =
@@ -5412,6 +5435,8 @@
      * Called when a running recents animation has finished or canceled.
      */
     public void onRecentsAnimationComplete() {
+        Log.d(TAG, "onRecentsAnimationComplete - mRecentsAnimationController: "
+                + mRecentsAnimationController);
         // At this point, the recents animation is not running and if the animation was canceled
         // by a display rotation then reset this state to show the screenshot
         setRunningTaskViewShowScreenshot(true);
@@ -5455,7 +5480,7 @@
 
     protected int getClearAllExtraPageSpacing() {
         return showAsGrid()
-                ? Math.max(mActivity.getDeviceProfile().overviewGridSideMargin - mPageSpacing, 0)
+                ? Math.max(mContainer.getDeviceProfile().overviewGridSideMargin - mPageSpacing, 0)
                 : 0;
     }
 
@@ -5904,7 +5929,7 @@
         return mTaskOverlayFactory;
     }
 
-    public BaseActivityInterface getSizeStrategy() {
+    public BaseContainerInterface getSizeStrategy() {
         return mSizeStrategy;
     }
 
@@ -5936,7 +5961,7 @@
             requireTaskViewAt(i).setColorTint(mColorTint, mTintingColor);
         }
 
-        Drawable scrimBg = mActivity.getScrimView().getBackground();
+        Drawable scrimBg = mContainer.getScrimView().getBackground();
         if (scrimBg != null) {
             if (tintAmount == 0f) {
                 scrimBg.setTintList(null);
@@ -5955,8 +5980,8 @@
     /** Returns {@code true} if the overview tasks are displayed as a grid. */
     public boolean showAsGrid() {
         return mOverviewGridEnabled || (mCurrentGestureEndTarget != null
-                && mSizeStrategy.stateFromGestureEndTarget(
-                mCurrentGestureEndTarget).displayOverviewTasksAsGrid(mActivity.getDeviceProfile()));
+                && mSizeStrategy.stateFromGestureEndTarget(mCurrentGestureEndTarget)
+                    .displayOverviewTasksAsGrid(mContainer.getDeviceProfile()));
     }
 
     private boolean showAsFullscreen() {
@@ -6122,7 +6147,7 @@
         }
     }
 
-    private static class PinnedStackAnimationListener<T extends BaseActivity> extends
+    private static class PinnedStackAnimationListener<T extends RecentsViewContainer> extends
             IPipAnimationListener.Stub {
         @Nullable
         private T mActivity;
@@ -6188,7 +6213,7 @@
     public void updateLocusId() {
         String locusId = "Overview";
 
-        if (mOverviewStateEnabled && mActivity.isStarted()) {
+        if (mOverviewStateEnabled && mContainer.isStarted()) {
             locusId += "|ENABLED";
         } else {
             locusId += "|DISABLED";
@@ -6196,7 +6221,28 @@
 
         final LocusId id = new LocusId(locusId);
         // 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));
+        UI_HELPER_EXECUTOR.post(() -> mContainer.setLocusContext(id, Bundle.EMPTY));
+    }
+
+    /**
+     * Moves the provided task into desktop mode, and invoke {@code successCallback} if succeeded.
+     */
+    public void moveTaskToDesktop(TaskIdAttributeContainer taskContainer,
+            Runnable successCallback) {
+        if (!enableDesktopWindowingMode()) {
+            return;
+        }
+        switchToScreenshot(() -> finishRecentsAnimation(/* toRecents= */true, /* shouldPip= */false,
+                () -> moveTaskToDesktopInternal(taskContainer, successCallback)));
+    }
+
+    private void moveTaskToDesktopInternal(TaskIdAttributeContainer taskContainer,
+            Runnable successCallback) {
+        if (mDesktopRecentsTransitionController == null) {
+            return;
+        }
+        mDesktopRecentsTransitionController.moveToDesktop(taskContainer.getTask().key.id);
+        successCallback.run();
     }
 
     public interface TaskLaunchListener {
diff --git a/quickstep/src/com/android/quickstep/views/SplitInstructionsView.java b/quickstep/src/com/android/quickstep/views/SplitInstructionsView.java
index 6a59ab4..a56d51e 100644
--- a/quickstep/src/com/android/quickstep/views/SplitInstructionsView.java
+++ b/quickstep/src/com/android/quickstep/views/SplitInstructionsView.java
@@ -16,10 +16,12 @@
 
 package com.android.quickstep.views;
 
+import static com.android.launcher3.LauncherState.NORMAL;
 import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_SPLIT_SELECTION_EXIT_CANCEL_BUTTON;
 
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
+import android.animation.AnimatorSet;
 import android.content.Context;
 import android.util.AttributeSet;
 import android.util.FloatProperty;
@@ -33,12 +35,15 @@
 import androidx.dynamicanimation.animation.SpringForce;
 
 import com.android.app.animation.Interpolators;
-import com.android.launcher3.LauncherState;
 import com.android.launcher3.R;
 import com.android.launcher3.Utilities;
 import com.android.launcher3.anim.PendingAnimation;
 import com.android.launcher3.config.FeatureFlags;
+import com.android.launcher3.statemanager.BaseState;
+import com.android.launcher3.statemanager.StateManager;
 import com.android.launcher3.statemanager.StatefulActivity;
+import com.android.launcher3.states.StateAnimationConfig;
+
 import com.android.quickstep.util.SplitSelectStateController;
 
 /**
@@ -51,8 +56,9 @@
 public class SplitInstructionsView extends LinearLayout {
     private static final int BOUNCE_DURATION = 250;
     private static final float BOUNCE_HEIGHT = 20;
+    private static final int DURATION_DEFAULT_SPLIT_DISMISS = 350;
 
-    private final StatefulActivity mLauncher;
+    private final RecentsViewContainer mContainer;
     public boolean mIsCurrentlyAnimating = false;
 
     public static final FloatProperty<SplitInstructionsView> UNFOLD =
@@ -91,13 +97,13 @@
 
     public SplitInstructionsView(Context context, AttributeSet attrs, int defStyleAttr) {
         super(context, attrs, defStyleAttr);
-        mLauncher = (StatefulActivity) context;
+        mContainer = RecentsViewContainer.containerFromContext(context);
     }
 
-    public static SplitInstructionsView getSplitInstructionsView(StatefulActivity launcher) {
-        ViewGroup dragLayer = launcher.getDragLayer();
+    public static SplitInstructionsView getSplitInstructionsView(RecentsViewContainer container) {
+        ViewGroup dragLayer = container.getDragLayer();
         final SplitInstructionsView splitInstructionsView =
-                (SplitInstructionsView) launcher.getLayoutInflater().inflate(
+                (SplitInstructionsView) container.getLayoutInflater().inflate(
                         R.layout.split_instructions_view,
                         dragLayer,
                         false
@@ -134,19 +140,34 @@
     }
 
     private void exitSplitSelection() {
-        SplitSelectStateController splitSelectController =
-                ((RecentsView) mLauncher.getOverviewPanel()).getSplitSelectController();
+        RecentsView recentsView = mContainer.getOverviewPanel();
+        SplitSelectStateController splitSelectController = recentsView.getSplitSelectController();
 
-        splitSelectController.getSplitAnimationController().playPlaceholderDismissAnim(mLauncher,
-                LAUNCHER_SPLIT_SELECTION_EXIT_CANCEL_BUTTON);
-        mLauncher.getStateManager().goToState(LauncherState.NORMAL);
+        StateManager stateManager = recentsView.getStateManager();
+        BaseState startState = stateManager.getState();
+        long duration = startState.getTransitionDuration(mContainer.asContext(), false);
+        if (duration == 0) {
+            // Case where we're in contextual on workspace (NORMAL), which by default has 0
+            // transition duration
+            duration = DURATION_DEFAULT_SPLIT_DISMISS;
+        }
+        StateAnimationConfig config = new StateAnimationConfig();
+        config.duration = duration;
+        AnimatorSet stateAnim = stateManager.createAtomicAnimation(
+                startState, NORMAL, config);
+        AnimatorSet dismissAnim = splitSelectController.getSplitAnimationController()
+                .createPlaceholderDismissAnim(mContainer,
+                        LAUNCHER_SPLIT_SELECTION_EXIT_CANCEL_BUTTON, duration);
+        stateAnim.play(dismissAnim);
+        stateManager.setCurrentAnimation(stateAnim, NORMAL);
+        stateAnim.start();
     }
 
     void ensureProperRotation() {
-        ((RecentsView) mLauncher.getOverviewPanel()).getPagedOrientationHandler()
+        ((RecentsView) mContainer.getOverviewPanel()).getPagedOrientationHandler()
                 .setSplitInstructionsParams(
                         this,
-                        mLauncher.getDeviceProfile(),
+                        mContainer.getDeviceProfile(),
                         getMeasuredHeight(),
                         getMeasuredWidth()
                 );
diff --git a/quickstep/src/com/android/quickstep/views/TaskMenuView.java b/quickstep/src/com/android/quickstep/views/TaskMenuView.java
index e86b7d8..fcbb45b 100644
--- a/quickstep/src/com/android/quickstep/views/TaskMenuView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskMenuView.java
@@ -46,7 +46,6 @@
 
 import com.android.app.animation.Interpolators;
 import com.android.launcher3.AbstractFloatingView;
-import com.android.launcher3.BaseDraggingActivity;
 import com.android.launcher3.DeviceProfile;
 import com.android.launcher3.R;
 import com.android.launcher3.anim.AnimationSuccessListener;
@@ -69,7 +68,7 @@
     private static final int REVEAL_OPEN_DURATION = enableOverviewIconMenu() ? 417 : 150;
     private static final int REVEAL_CLOSE_DURATION = enableOverviewIconMenu() ? 333 : 100;
 
-    private BaseDraggingActivity mActivity;
+    private RecentsViewContainer mContainer;
     private TextView mTaskName;
     @Nullable
     private AnimatorSet mOpenCloseAnimator;
@@ -89,7 +88,7 @@
     public TaskMenuView(Context context, AttributeSet attrs, int defStyleAttr) {
         super(context, attrs, defStyleAttr);
 
-        mActivity = BaseDraggingActivity.fromContext(context);
+        mContainer = RecentsViewContainer.containerFromContext(context);
         setClipToOutline(true);
     }
 
@@ -103,7 +102,7 @@
     @Override
     public boolean onControllerInterceptTouchEvent(MotionEvent ev) {
         if (ev.getAction() == MotionEvent.ACTION_DOWN) {
-            BaseDragLayer dl = mActivity.getDragLayer();
+            BaseDragLayer dl = mContainer.getDragLayer();
             if (!dl.isEventOverView(this, ev)) {
                 // TODO: log this once we have a new container type for it?
                 close(true);
@@ -140,9 +139,14 @@
 
     @Override
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-        int maxMenuHeight = calculateMaxHeight();
-        if (MeasureSpec.getSize(heightMeasureSpec) > maxMenuHeight) {
-            heightMeasureSpec = MeasureSpec.makeMeasureSpec(maxMenuHeight, MeasureSpec.AT_MOST);
+        if (!(enableOverviewIconMenu()
+                && ((RecentsView) mContainer.getOverviewPanel()).isOnGridBottomRow(mTaskView))) {
+            // TODO(b/326952853): Cap menu height for grid bottom row in a way that doesn't break
+            // additionalTranslationY.
+            int maxMenuHeight = calculateMaxHeight();
+            if (MeasureSpec.getSize(heightMeasureSpec) > maxMenuHeight) {
+                heightMeasureSpec = MeasureSpec.makeMeasureSpec(maxMenuHeight, MeasureSpec.AT_MOST);
+            }
         }
         super.onMeasure(widthMeasureSpec, heightMeasureSpec);
     }
@@ -161,10 +165,10 @@
 
     public static boolean showForTask(TaskIdAttributeContainer taskContainer,
             @Nullable Runnable onClosingStartCallback) {
-        BaseDraggingActivity activity = BaseDraggingActivity.fromContext(
+        RecentsViewContainer container = RecentsViewContainer.containerFromContext(
                 taskContainer.getTaskView().getContext());
-        final TaskMenuView taskMenuView = (TaskMenuView) activity.getLayoutInflater().inflate(
-                        R.layout.task_menu, activity.getDragLayer(), false);
+        final TaskMenuView taskMenuView = (TaskMenuView) container.getLayoutInflater().inflate(
+                        R.layout.task_menu, container.getDragLayer(), false);
         taskMenuView.setOnClosingStartCallback(onClosingStartCallback);
         return taskMenuView.populateAndShowForTask(taskContainer);
     }
@@ -177,7 +181,7 @@
         if (isAttachedToWindow()) {
             return false;
         }
-        mActivity.getDragLayer().addView(this);
+        mContainer.getDragLayer().addView(this);
         mTaskView = taskContainer.getTaskView();
         mTaskContainer = taskContainer;
         if (!populateAndLayoutMenu()) {
@@ -210,7 +214,7 @@
     }
 
     private void addMenuOption(SystemShortcut menuOption) {
-        LinearLayout menuOptionView = (LinearLayout) mActivity.getLayoutInflater().inflate(
+        LinearLayout menuOptionView = (LinearLayout) mContainer.getLayoutInflater().inflate(
                 R.layout.task_view_menu_option, this, false);
         if (enableOverviewIconMenu()) {
             ((GradientDrawable) menuOptionView.getBackground()).setCornerRadius(0);
@@ -219,7 +223,7 @@
                 menuOptionView.findViewById(R.id.icon), menuOptionView.findViewById(R.id.text));
         LayoutParams lp = (LayoutParams) menuOptionView.getLayoutParams();
         mTaskView.getPagedOrientationHandler().setLayoutParamsForTaskMenuOptionItem(lp,
-                menuOptionView, mActivity.getDeviceProfile());
+                menuOptionView, mContainer.getDeviceProfile());
         // Set an onClick listener on each menu option. The onClick method is responsible for
         // ending LiveTile mode on the thumbnail if needed.
         menuOptionView.setOnClickListener(menuOption::onClick);
@@ -227,19 +231,19 @@
     }
 
     private void orientAroundTaskView(TaskIdAttributeContainer taskContainer) {
-        RecentsView recentsView = mActivity.getOverviewPanel();
+        RecentsView recentsView = mContainer.getOverviewPanel();
         RecentsPagedOrientationHandler orientationHandler =
                 recentsView.getPagedOrientationHandler();
         measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
 
         // Get Position
-        DeviceProfile deviceProfile = mActivity.getDeviceProfile();
-        mActivity.getDragLayer().getDescendantRectRelativeToSelf(
+        DeviceProfile deviceProfile = mContainer.getDeviceProfile();
+        mContainer.getDragLayer().getDescendantRectRelativeToSelf(
                 enableOverviewIconMenu()
                         ? getIconView().findViewById(R.id.icon_view_menu_anchor)
                         : taskContainer.getThumbnailView(),
                 sTempRect);
-        Rect insets = mActivity.getDragLayer().getInsets();
+        Rect insets = mContainer.getDragLayer().getInsets();
         BaseDragLayer.LayoutParams params = (BaseDragLayer.LayoutParams) getLayoutParams();
         params.width = orientationHandler.getTaskMenuWidth(taskContainer.getThumbnailView(),
                 deviceProfile, taskContainer.getStagePosition());
@@ -320,12 +324,12 @@
             IconAppChipView iconAppChip = (IconAppChipView) mTaskContainer.getIconView().asView();
 
             float additionalTranslationY = 0;
-            if (((RecentsView) mActivity.getOverviewPanel()).isOnGridBottomRow(mTaskView)) {
+            if (((RecentsView) mContainer.getOverviewPanel()).isOnGridBottomRow(mTaskView)) {
                 // Animate menu up for enough room to display full menu when task on bottom row.
                 float menuBottom = getHeight() + mMenuTranslationYBeforeOpen;
                 float taskBottom = mTaskView.getHeight() + mTaskView.getPersistentTranslationY();
-                float taskbarTop = mActivity.getDeviceProfile().heightPx
-                        - mActivity.getDeviceProfile().getOverviewActionsClaimedSpaceBelow();
+                float taskbarTop = mContainer.getDeviceProfile().heightPx
+                        - mContainer.getDeviceProfile().getOverviewActionsClaimedSpaceBelow();
                 float midpoint = (taskBottom + taskbarTop) / 2f;
                 additionalTranslationY = -Math.max(menuBottom - midpoint, 0);
             }
@@ -340,11 +344,11 @@
             menuTranslationYAnim.setInterpolator(EMPHASIZED);
 
             float additionalTranslationX = 0;
-            if (mActivity.getDeviceProfile().isLandscape
+            if (mContainer.getDeviceProfile().isLandscape
                     && mTaskContainer.getStagePosition() == STAGE_POSITION_BOTTOM_OR_RIGHT) {
                 // Animate menu and icon when split task would display off the side of the screen.
                 additionalTranslationX = Math.max(
-                        getTranslationX() + getWidth() - (mActivity.getDeviceProfile().widthPx
+                        getTranslationX() + getWidth() - (mContainer.getDeviceProfile().widthPx
                                 - getResources().getDimensionPixelSize(
                                 R.dimen.task_menu_edge_padding) * 2), 0);
             }
@@ -405,7 +409,7 @@
     private void closeComplete() {
         testLogD(TEST_TAPL_OVERVIEW_ACTIONS_MENU_FAILURE, "TaskMenuView.java.closeComplete");
         mIsOpen = false;
-        mActivity.getDragLayer().removeView(this);
+        mContainer.getDragLayer().removeView(this);
         mRevealAnimator = null;
     }
 
@@ -428,7 +432,7 @@
     private int calculateMaxHeight() {
         float taskInsetMargin = getResources().getDimension(R.dimen.task_card_margin);
         return mTaskView.getPagedOrientationHandler().getTaskMenuHeight(taskInsetMargin,
-                mActivity.getDeviceProfile(), getTranslationX(), getTranslationY());
+                mContainer.getDeviceProfile(), getTranslationX(), getTranslationY());
     }
 
     private void setOnClosingStartCallback(Runnable onClosingStartCallback) {
diff --git a/quickstep/src/com/android/quickstep/views/TaskMenuViewWithArrow.kt b/quickstep/src/com/android/quickstep/views/TaskMenuViewWithArrow.kt
index 12b8b6f..c124f03 100644
--- a/quickstep/src/com/android/quickstep/views/TaskMenuViewWithArrow.kt
+++ b/quickstep/src/com/android/quickstep/views/TaskMenuViewWithArrow.kt
@@ -29,7 +29,6 @@
 import android.view.ViewGroup
 import android.widget.FrameLayout
 import android.widget.LinearLayout
-import com.android.launcher3.BaseDraggingActivity
 import com.android.launcher3.DeviceProfile
 import com.android.launcher3.InsettableFrameLayout
 import com.android.launcher3.R
@@ -40,24 +39,22 @@
 import com.android.quickstep.TaskOverlayFactory
 import com.android.quickstep.views.TaskView.TaskIdAttributeContainer
 
-class TaskMenuViewWithArrow<T : BaseDraggingActivity> : ArrowPopup<T> {
+class TaskMenuViewWithArrow<T> : ArrowPopup<T> where T : RecentsViewContainer, T : Context {
     companion object {
         const val TAG = "TaskMenuViewWithArrow"
 
-        fun showForTask(
+        fun <T> showForTask(
             taskContainer: TaskIdAttributeContainer,
             alignedOptionIndex: Int = 0
-        ): Boolean {
-            val activity =
-                BaseDraggingActivity.fromContext<BaseDraggingActivity>(
-                    taskContainer.taskView.context
-                )
+        ): Boolean where T : RecentsViewContainer, T : Context {
+            val container: RecentsViewContainer =
+                RecentsViewContainer.containerFromContext(taskContainer.taskView.context)
             val taskMenuViewWithArrow =
-                activity.layoutInflater.inflate(
+                container.layoutInflater.inflate(
                     R.layout.task_menu_with_arrow,
-                    activity.dragLayer,
+                    container.dragLayer,
                     false
-                ) as TaskMenuViewWithArrow<*>
+                ) as TaskMenuViewWithArrow<T>
 
             return taskMenuViewWithArrow.populateAndShowForTask(taskContainer, alignedOptionIndex)
         }
@@ -124,6 +121,25 @@
         optionLayout = requireViewById(R.id.menu_option_layout)
     }
 
+    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
+        val maxMenuHeight: Int = calculateMaxHeight()
+        val newHeightMeasureSpec =
+            if (MeasureSpec.getSize(heightMeasureSpec) > maxMenuHeight) {
+                MeasureSpec.makeMeasureSpec(maxMenuHeight, MeasureSpec.AT_MOST)
+            } else heightMeasureSpec
+        super.onMeasure(widthMeasureSpec, newHeightMeasureSpec)
+    }
+
+    private fun calculateMaxHeight(): Int {
+        val taskInsetMargin = resources.getDimension(R.dimen.task_card_margin)
+        return taskView.pagedOrientationHandler.getTaskMenuHeight(
+            taskInsetMargin,
+            mActivityContext.deviceProfile,
+            translationX,
+            translationY
+        )
+    }
+
     private fun populateAndShowForTask(
         taskContainer: TaskIdAttributeContainer,
         alignedOptionIndex: Int
diff --git a/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java b/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java
index 077247b..7e46739 100644
--- a/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java
@@ -48,7 +48,6 @@
 import androidx.annotation.RequiresApi;
 import androidx.core.graphics.ColorUtils;
 
-import com.android.launcher3.BaseActivity;
 import com.android.launcher3.DeviceProfile;
 import com.android.launcher3.Utilities;
 import com.android.launcher3.util.MainThreadInitializedObject;
@@ -122,7 +121,7 @@
                 }
             };
 
-    private final BaseActivity mActivity;
+    private final RecentsViewContainer mContainer;
     @Nullable
     private TaskOverlay mOverlay;
     private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
@@ -171,7 +170,7 @@
         mBackgroundPaint.setColor(Color.WHITE);
         mSplashBackgroundPaint.setColor(Color.WHITE);
         mClearPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
-        mActivity = BaseActivity.fromContext(context);
+        mContainer = RecentsViewContainer.containerFromContext(context);
         // Initialize with placeholder value. It is overridden later by TaskView
         mFullscreenParams = TEMP_PARAMS.get(context);
 
@@ -308,7 +307,7 @@
         RectF boundsInBitmapSpace = new RectF();
         boundsToBitmapSpace.mapRect(boundsInBitmapSpace, viewRect);
 
-        DeviceProfile dp = mActivity.getDeviceProfile();
+        DeviceProfile dp = mContainer.getDeviceProfile();
         int bottomInset = dp.isTablet
                 ? Math.round(bitmapRect.bottom - boundsInBitmapSpace.bottom) : 0;
         return Insets.of(0, 0, 0, bottomInset);
@@ -549,7 +548,7 @@
     }
 
     private void updateThumbnailMatrix() {
-        DeviceProfile dp = mActivity.getDeviceProfile();
+        DeviceProfile dp = mContainer.getDeviceProfile();
         mPreviewPositionHelper.setOrientationChanged(false);
         if (mBitmapShader != null && mThumbnailData != null) {
             mPreviewRect.set(0, 0, mThumbnailData.thumbnail.getWidth(),
diff --git a/quickstep/src/com/android/quickstep/views/TaskView.java b/quickstep/src/com/android/quickstep/views/TaskView.java
index 79bd107..ec57115 100644
--- a/quickstep/src/com/android/quickstep/views/TaskView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskView.java
@@ -87,7 +87,6 @@
 import com.android.launcher3.model.data.WorkspaceItemInfo;
 import com.android.launcher3.pm.UserCache;
 import com.android.launcher3.popup.SystemShortcut;
-import com.android.launcher3.statemanager.StatefulActivity;
 import com.android.launcher3.testing.TestLogging;
 import com.android.launcher3.testing.shared.TestProtocol;
 import com.android.launcher3.util.ActivityOptionsWrapper;
@@ -119,8 +118,6 @@
 import com.android.systemui.shared.system.ActivityManagerWrapper;
 import com.android.systemui.shared.system.QuickStepContract;
 
-import kotlin.Unit;
-
 import java.lang.annotation.Retention;
 import java.util.Arrays;
 import java.util.Collections;
@@ -129,6 +126,8 @@
 import java.util.function.Consumer;
 import java.util.stream.Stream;
 
+import kotlin.Unit;
+
 /**
  * A task in the Recents view.
  */
@@ -335,7 +334,7 @@
     private float mNonGridScale = 1;
     private float mDismissScale = 1;
     protected final FullscreenDrawParams mCurrentFullscreenParams;
-    protected final StatefulActivity mActivity;
+    protected final RecentsViewContainer mContainer;
 
     // Various causes of changing primary translation, which we aggregate to setTranslationX/Y().
     private float mDismissTranslationX;
@@ -417,13 +416,14 @@
             int defStyleRes, BorderAnimator focusBorderAnimator,
             BorderAnimator hoverBorderAnimator) {
         super(context, attrs, defStyleAttr, defStyleRes);
-        mActivity = StatefulActivity.fromContext(context);
+        mContainer = RecentsViewContainer.containerFromContext(context);
         setOnClickListener(this::onClick);
 
         mCurrentFullscreenParams = new FullscreenDrawParams(context);
-        mDigitalWellBeingToast = new DigitalWellBeingToast(mActivity, this);
+        mDigitalWellBeingToast = new DigitalWellBeingToast(mContainer, this);
 
-        boolean keyboardFocusHighlightEnabled = FeatureFlags.ENABLE_KEYBOARD_QUICK_SWITCH.get();
+        boolean keyboardFocusHighlightEnabled = FeatureFlags.ENABLE_KEYBOARD_QUICK_SWITCH.get()
+                || Flags.enableFocusOutline();
         boolean cursorHoverStatesEnabled = enableCursorHoverStates();
 
         setWillNotDraw(!keyboardFocusHighlightEnabled && !cursorHoverStatesEnabled);
@@ -486,7 +486,11 @@
         return getItemInfo(mTask);
     }
 
-    protected WorkspaceItemInfo getItemInfo(@Nullable Task task) {
+    /**
+     * Builds proto for logging
+     */
+    @VisibleForTesting
+    public WorkspaceItemInfo getItemInfo(@Nullable Task task) {
         WorkspaceItemInfo stubInfo = new WorkspaceItemInfo();
         stubInfo.itemType = LauncherSettings.Favorites.ITEM_TYPE_TASK;
         stubInfo.container = LauncherSettings.Favorites.CONTAINER_TASKSWITCHER;
@@ -612,7 +616,7 @@
         float viewHalfHeight = view.getHeight() / 2f;
         tempCenterCoords[0] = viewHalfWidth;
         tempCenterCoords[1] = viewHalfHeight;
-        getDescendantCoordRelativeToAncestor(view.asView(), mActivity.getDragLayer(),
+        getDescendantCoordRelativeToAncestor(view.asView(), mContainer.getDragLayer(),
                 tempCenterCoords, false);
         transformingTouchDelegate.setBounds(
                 (int) (tempCenterCoords[0] - viewHalfWidth),
@@ -645,6 +649,7 @@
      */
     public void bind(Task task, RecentsOrientedState orientedState) {
         cancelPendingLoadTasks();
+        testLogD(SUCCESSFUL_GESTURE_MISMATCH_EVENTS, "TaskView.bind: task=" + task);
         mTask = task;
         mTaskIdContainer[0] = mTask.key.id;
         mTaskIdAttributeContainer[0] = new TaskIdAttributeContainer(task, mSnapshotView, mIconView,
@@ -811,13 +816,19 @@
 
     private void onClick(View view) {
         if (getTask() == null) {
+            Log.d("b/310064698", "onClick - task is null");
             return;
         }
         if (confirmSecondSplitSelectApp()) {
+            Log.d("b/310064698", mTask + " - onClick - split select is active");
             return;
         }
-        launchTasks();
-        mActivity.getStatsLogManager().logger().withItemInfo(getItemInfo())
+        RunnableList callbackList = launchTasks();
+        Log.d("b/310064698", mTask + " - onClick - callbackList: " + callbackList);
+        if (callbackList != null) {
+            callbackList.add(() -> Log.d("b/310064698", mTask + " - onClick - launchCompleted"));
+        }
+        mContainer.getStatsLogManager().logger().withItemInfo(getItemInfo())
                 .log(LAUNCHER_TASK_LAUNCH_TAP);
     }
 
@@ -852,12 +863,14 @@
      */
     @Nullable
     public RunnableList launchTaskAnimated() {
+        testLogD(SUCCESSFUL_GESTURE_MISMATCH_EVENTS,
+                "TaskView.launchTaskAnimated: mTask=" + mTask);
         if (mTask != null) {
             testLogD(SUCCESSFUL_GESTURE_MISMATCH_EVENTS,
                     "TaskView.launchTaskAnimated: startActivityFromRecentsAsync");
             TestLogging.recordEvent(
                     TestProtocol.SEQUENCE_MAIN, "startActivityFromRecentsAsync", mTask);
-            ActivityOptionsWrapper opts =  mActivity.getActivityLaunchOptions(this, null);
+            ActivityOptionsWrapper opts =  mContainer.getActivityLaunchOptions(this, null);
             opts.options.setLaunchDisplayId(
                     getDisplay() == null ? DEFAULT_DISPLAY : getDisplay().getDisplayId());
             if (ActivityManagerWrapper.getInstance()
@@ -902,6 +915,7 @@
      * Starts the task associated with this view without any animation
      */
     public void launchTask(@NonNull Consumer<Boolean> callback, boolean isQuickswitch) {
+        testLogD(SUCCESSFUL_GESTURE_MISMATCH_EVENTS, "TaskView.launchTask: mTask=" + mTask);
         if (mTask != null) {
             testLogD(SUCCESSFUL_GESTURE_MISMATCH_EVENTS,
                     "TaskView.launchTask: startActivityFromRecentsAsync");
@@ -914,7 +928,7 @@
                 // We only listen for failures to launch in quickswitch because the during this
                 // gesture launcher is in the background state, vs other launches which are in
                 // the actual overview state
-                failureListener.register(mActivity, mTask.key.id, () -> {
+                failureListener.register(mContainer, mTask.key.id, () -> {
                     notifyTaskLaunchFailed(TAG);
                     RecentsView rv = getRecentsView();
                     if (rv != null) {
@@ -972,6 +986,9 @@
     public RunnableList launchTasks() {
         RecentsView recentsView = getRecentsView();
         RemoteTargetHandle[] remoteTargetHandles = recentsView.mRemoteTargetHandles;
+        testLogD(SUCCESSFUL_GESTURE_MISMATCH_EVENTS,
+                "TaskView.launchTasks: isRunningTask=" + isRunningTask() + ", "
+                        + "remoteTargetHandles == null?" + (remoteTargetHandles == null));
         if (isRunningTask() && remoteTargetHandles != null) {
             if (!mIsClickableAsLiveTile) {
                 Log.e(TAG, "TaskView is not clickable as a live tile; returning to home.");
@@ -999,7 +1016,7 @@
                 // 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.
                 testLogD(SUCCESSFUL_GESTURE_MISMATCH_EVENTS,
-                        "TaskView.java - launchTasks: recents animation is cancelled");
+                        "TaskView.launchTasks: recents animation is cancelled");
                 RunnableList runnableList = launchTaskAnimated();
                 if (runnableList == null) {
                     Log.e(TAG, "Recents animation cancelled and cannot launch task as non-live tile"
@@ -1014,14 +1031,14 @@
             TaskViewUtils.composeRecentsLaunchAnimator(
                     anim, this, targets.apps,
                     targets.wallpapers, targets.nonApps, true /* launcherClosing */,
-                    mActivity.getStateManager(), recentsView,
+                    recentsView.getStateManager(), recentsView,
                     recentsView.getDepthController());
             anim.addListener(new AnimatorListenerAdapter() {
                 @Override
                 public void onAnimationEnd(Animator animator) {
                     if (mTask != null && mTask.key.displayId != getRootViewDisplayId()) {
                         testLogD(SUCCESSFUL_GESTURE_MISMATCH_EVENTS,
-                                "TaskView.java - launchTasks: onAnimationEnd");
+                                "TaskView.launchTasks: onAnimationEnd");
                         launchTaskAnimated();
                     }
                     mIsClickableAsLiveTile = true;
@@ -1041,9 +1058,6 @@
             recentsView.onTaskLaunchedInLiveTileMode();
             return runnableList;
         } else {
-            testLogD(SUCCESSFUL_GESTURE_MISMATCH_EVENTS,
-                    "TaskView.java - launchTasks: isRunningTask=" + isRunningTask() + "||"
-                            + "remoteTargetHandles == null?" + (remoteTargetHandles == null));
             return launchTaskAnimated();
         }
     }
@@ -1128,12 +1142,12 @@
             return true;
         }
 
-        if (!mActivity.getDeviceProfile().isTablet
+        if (!mContainer.getDeviceProfile().isTablet
                 && !getRecentsView().isClearAllHidden()) {
             getRecentsView().snapToPage(getRecentsView().indexOfChild(this));
             return false;
         } else {
-            mActivity.getStatsLogManager().logger().withItemInfo(getItemInfo())
+            mContainer.getStatsLogManager().logger().withItemInfo(getItemInfo())
                     .log(LAUNCHER_TASK_ICON_TAP_OR_LONGPRESS);
             return showTaskMenuWithContainer(iconView);
         }
@@ -1142,7 +1156,7 @@
     protected boolean showTaskMenuWithContainer(TaskViewIcon iconView) {
         TaskIdAttributeContainer menuContainer =
                 mTaskIdAttributeContainer[iconView == mIconView ? 0 : 1];
-        DeviceProfile dp = mActivity.getDeviceProfile();
+        DeviceProfile dp = mContainer.getDeviceProfile();
         if (enableOverviewIconMenu() && iconView instanceof IconAppChipView) {
             ((IconAppChipView) iconView).revealAnim(/* isRevealing= */ true);
             return TaskMenuView.showForTask(menuContainer,
@@ -1196,7 +1210,7 @@
     }
 
     protected void setThumbnailOrientation(RecentsOrientedState orientationState) {
-        DeviceProfile deviceProfile = mActivity.getDeviceProfile();
+        DeviceProfile deviceProfile = mContainer.getDeviceProfile();
         int thumbnailTopMargin = deviceProfile.overviewTaskThumbnailTopMarginPx;
 
         // TODO(b/271468547), we should default to setting trasnlations only on the snapshot instead
@@ -1213,7 +1227,7 @@
      * Returns whether the task is part of overview grid and not being focused.
      */
     public boolean isGridTask() {
-        DeviceProfile deviceProfile = mActivity.getDeviceProfile();
+        DeviceProfile deviceProfile = mContainer.getDeviceProfile();
         return deviceProfile.isTablet && !isFocusedTask();
     }
 
@@ -1320,7 +1334,7 @@
     @Override
     protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
         super.onLayout(changed, left, top, right, bottom);
-        if (mActivity.getDeviceProfile().isTablet) {
+        if (mContainer.getDeviceProfile().isTablet) {
             setPivotX(getLayoutDirection() == LAYOUT_DIRECTION_RTL ? 0 : right - left);
             setPivotY(mSnapshotView.getTop());
         } else {
@@ -1677,10 +1691,10 @@
         mFullscreenProgress = progress;
         mIconView.setVisibility(progress < 1 ? VISIBLE : INVISIBLE);
         mSnapshotView.getTaskOverlay().setFullscreenProgress(progress);
-
+        RecentsView recentsView = mContainer.getOverviewPanel();
         // Animate icons and DWB banners in/out, except in QuickSwitch state, when tiles are
         // oversized and banner would look disproportionately large.
-        if (mActivity.getStateManager().getState() != BACKGROUND_APP) {
+        if (recentsView.getStateManager().getState() != BACKGROUND_APP) {
             setIconsAndBannersTransitionProgress(progress, true);
         }
 
@@ -1714,7 +1728,7 @@
         float boxTranslationY;
         int expectedWidth;
         int expectedHeight;
-        DeviceProfile deviceProfile = mActivity.getDeviceProfile();
+        DeviceProfile deviceProfile = mContainer.getDeviceProfile();
         final int thumbnailPadding = deviceProfile.overviewTaskThumbnailTopMarginPx;
         final Rect lastComputedTaskSize = getRecentsView().getLastComputedTaskSize();
         final int taskWidth = lastComputedTaskSize.width();
diff --git a/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/bubbles/animation/BubbleBarViewAnimatorTest.kt b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/bubbles/animation/BubbleBarViewAnimatorTest.kt
index c17aeaa..b478efa 100644
--- a/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/bubbles/animation/BubbleBarViewAnimatorTest.kt
+++ b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/bubbles/animation/BubbleBarViewAnimatorTest.kt
@@ -16,6 +16,9 @@
 
 package com.android.launcher3.taskbar.bubbles.animation
 
+import android.animation.Animator
+import android.animation.AnimatorListenerAdapter
+import android.animation.AnimatorSet
 import android.content.Context
 import android.graphics.Color
 import android.graphics.Path
@@ -24,6 +27,8 @@
 import android.view.View.INVISIBLE
 import android.view.View.VISIBLE
 import android.widget.FrameLayout
+import androidx.core.animation.AnimatorTestRule
+import androidx.core.animation.doOnEnd
 import androidx.core.graphics.drawable.toBitmap
 import androidx.dynamicanimation.animation.DynamicAnimation
 import androidx.test.core.app.ApplicationProvider
@@ -39,10 +44,14 @@
 import com.android.wm.shell.common.bubbles.BubbleInfo
 import com.android.wm.shell.shared.animation.PhysicsAnimatorTestUtils
 import com.google.common.truth.Truth.assertThat
+import java.util.concurrent.Semaphore
+import java.util.concurrent.TimeUnit
 import org.junit.Before
+import org.junit.ClassRule
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.mockito.kotlin.mock
+import org.mockito.kotlin.verify
 import org.mockito.kotlin.whenever
 
 @SmallTest
@@ -52,6 +61,10 @@
     private val context = ApplicationProvider.getApplicationContext<Context>()
     private val animatorScheduler = TestBubbleBarViewAnimatorScheduler()
 
+    companion object {
+        @JvmField @ClassRule val animatorTestRule = AnimatorTestRule()
+    }
+
     @Before
     fun setUp() {
         PhysicsAnimatorTestUtils.prepareForTest()
@@ -86,6 +99,15 @@
         val bubbleStashController = mock<BubbleStashController>()
         whenever(bubbleStashController.isStashed).thenReturn(true)
 
+        val semaphore = Semaphore(0)
+        val hideHandleAnimator = AnimatorSet()
+        hideHandleAnimator.duration = 0
+        whenever(bubbleStashController.buildHideHandleAnimationForNewBubble())
+            .thenReturn(hideHandleAnimator)
+        // add an end listener to the hide handle animation. we add it when the animation starts
+        // to ensure that it gets called after all other end listeners.
+        hideHandleAnimator.doOnStart { hideHandleAnimator.doOnEnd { semaphore.release() } }
+
         val animator =
             BubbleBarViewAnimator(bubbleBarView, bubbleStashController, animatorScheduler)
 
@@ -93,29 +115,44 @@
             animator.animateBubbleInForStashed(bubble)
         }
 
+        // wait for the stash handle animation to complete
+        assertThat(semaphore.tryAcquire(5, TimeUnit.SECONDS)).isTrue()
+        // stash handle animation finished. verify that the stash handle is now hidden
+        verify(bubbleStashController).setStashAlpha(0f)
+
         InstrumentationRegistry.getInstrumentation().waitForIdleSync()
 
         assertThat(overflowView.visibility).isEqualTo(INVISIBLE)
         assertThat(bubbleBarView.visibility).isEqualTo(VISIBLE)
         assertThat(bubbleView.visibility).isEqualTo(VISIBLE)
 
+        // wait for the show bubble animation to complete
         PhysicsAnimatorTestUtils.blockUntilAnimationsEnd(
             DynamicAnimation.ALPHA,
-            DynamicAnimation.TRANSLATION_Y
+            DynamicAnimation.TRANSLATION_Y,
+            DynamicAnimation.SCALE_Y,
         )
 
         assertThat(bubbleView.alpha).isEqualTo(1)
         assertThat(bubbleView.translationY).isEqualTo(-50)
+        assertThat(bubbleView.scaleY).isEqualTo(1)
 
+        val showHandleAnimator = AnimatorSet()
+        showHandleAnimator.duration = 0
+        whenever(bubbleStashController.buildShowHandleAnimationForNewBubble())
+            .thenReturn(showHandleAnimator)
+        var showHandleAnimationStarted = false
+        showHandleAnimator.doOnStart { showHandleAnimationStarted = true }
+
+        // execute the hide bubble animation
         assertThat(animatorScheduler.delayedBlock).isNotNull()
         InstrumentationRegistry.getInstrumentation().runOnMainSync(animatorScheduler.delayedBlock!!)
+        // finish the hide bubble animation
+        InstrumentationRegistry.getInstrumentation().runOnMainSync {
+            animatorTestRule.advanceTimeBy(250)
+        }
 
-        InstrumentationRegistry.getInstrumentation().waitForIdleSync()
-
-        PhysicsAnimatorTestUtils.blockUntilAnimationsEnd(
-            DynamicAnimation.ALPHA,
-            DynamicAnimation.TRANSLATION_Y
-        )
+        assertThat(showHandleAnimationStarted).isTrue()
 
         assertThat(bubbleView.alpha).isEqualTo(1)
         assertThat(bubbleView.visibility).isEqualTo(VISIBLE)
@@ -125,6 +162,16 @@
         assertThat(overflowView.visibility).isEqualTo(VISIBLE)
     }
 
+    private fun AnimatorSet.doOnStart(onStart: () -> Unit) {
+        addListener(
+            object : AnimatorListenerAdapter() {
+                override fun onAnimationStart(animator: Animator) {
+                    onStart()
+                }
+            }
+        )
+    }
+
     private class TestBubbleBarViewAnimatorScheduler : BubbleBarViewAnimator.Scheduler {
 
         var delayedBlock: (() -> Unit)? = null
diff --git a/quickstep/tests/src/com/android/launcher3/taskbar/navbutton/NavButtonLayoutFactoryTest.kt b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/navbutton/NavButtonLayoutFactoryTest.kt
similarity index 100%
rename from quickstep/tests/src/com/android/launcher3/taskbar/navbutton/NavButtonLayoutFactoryTest.kt
rename to quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/navbutton/NavButtonLayoutFactoryTest.kt
diff --git a/quickstep/tests/src/com/android/quickstep/orientation/LandscapePagedViewHandlerTest.kt b/quickstep/tests/multivalentTests/src/com/android/quickstep/orientation/LandscapePagedViewHandlerTest.kt
similarity index 100%
rename from quickstep/tests/src/com/android/quickstep/orientation/LandscapePagedViewHandlerTest.kt
rename to quickstep/tests/multivalentTests/src/com/android/quickstep/orientation/LandscapePagedViewHandlerTest.kt
diff --git a/quickstep/tests/src/com/android/quickstep/orientation/SeascapePagedViewHandlerTest.kt b/quickstep/tests/multivalentTests/src/com/android/quickstep/orientation/SeascapePagedViewHandlerTest.kt
similarity index 100%
rename from quickstep/tests/src/com/android/quickstep/orientation/SeascapePagedViewHandlerTest.kt
rename to quickstep/tests/multivalentTests/src/com/android/quickstep/orientation/SeascapePagedViewHandlerTest.kt
diff --git a/quickstep/tests/multivalentTests/src/com/android/quickstep/util/SplitSelectStateControllerTest.kt b/quickstep/tests/multivalentTests/src/com/android/quickstep/util/SplitSelectStateControllerTest.kt
index 18b1ea0..0de5f19 100644
--- a/quickstep/tests/multivalentTests/src/com/android/quickstep/util/SplitSelectStateControllerTest.kt
+++ b/quickstep/tests/multivalentTests/src/com/android/quickstep/util/SplitSelectStateControllerTest.kt
@@ -36,6 +36,8 @@
 import com.android.launcher3.util.SplitConfigurationOptions
 import com.android.quickstep.RecentsModel
 import com.android.quickstep.SystemUiProxy
+import com.android.quickstep.util.SplitSelectStateController.SplitFromDesktopController
+import com.android.quickstep.views.RecentsViewContainer
 import com.android.systemui.shared.recents.model.Task
 import com.android.wm.shell.common.split.SplitScreenConstants.SNAP_TO_50_50
 import java.util.function.Consumer
@@ -62,9 +64,10 @@
     private val statsLogger: StatsLogger = mock()
     private val stateManager: StateManager<LauncherState> = mock()
     private val handler: Handler = mock()
-    private val context: StatefulActivity<*> = mock()
+    private val context: RecentsViewContainer = mock()
     private val recentsModel: RecentsModel = mock()
     private val pendingIntent: PendingIntent = mock()
+    private val splitFromDesktopController: SplitFromDesktopController = mock()
 
     private lateinit var splitSelectStateController: SplitSelectStateController
 
@@ -607,6 +610,18 @@
         assertTrue(splitSelectStateController.isBothSplitAppsConfirmed)
     }
 
+    @Test
+    fun splitSelectStateControllerDestroyed_SplitFromDesktopControllerAlsoDestroyed() {
+        // Initiate split from desktop controller
+        splitSelectStateController.initSplitFromDesktopController(splitFromDesktopController)
+
+        // Simulate default controller being destroyed
+        splitSelectStateController.onDestroy()
+
+        // Verify desktop controller is also destroyed
+        verify(splitFromDesktopController).onDestroy()
+    }
+
     // Generate GroupTask with default userId.
     private fun generateGroupTask(
         task1ComponentName: ComponentName,
diff --git a/quickstep/tests/src/com/android/launcher3/model/WidgetsPredictionsRequesterTest.kt b/quickstep/tests/src/com/android/launcher3/model/WidgetsPredictionsRequesterTest.kt
new file mode 100644
index 0000000..5c7b4ab
--- /dev/null
+++ b/quickstep/tests/src/com/android/launcher3/model/WidgetsPredictionsRequesterTest.kt
@@ -0,0 +1,221 @@
+/*
+ * Copyright (C) 2024 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 android.app.prediction.AppTarget
+import android.app.prediction.AppTargetEvent
+import android.app.prediction.AppTargetId
+import android.appwidget.AppWidgetProviderInfo
+import android.content.ComponentName
+import android.content.Context
+import android.os.Process.myUserHandle
+import android.os.UserHandle
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import com.android.launcher3.DeviceProfile
+import com.android.launcher3.InvariantDeviceProfile
+import com.android.launcher3.LauncherAppState
+import com.android.launcher3.icons.IconCache
+import com.android.launcher3.model.WidgetPredictionsRequester.buildBundleForPredictionSession
+import com.android.launcher3.model.WidgetPredictionsRequester.filterPredictions
+import com.android.launcher3.model.WidgetPredictionsRequester.notOnUiSurfaceFilter
+import com.android.launcher3.util.ActivityContextWrapper
+import com.android.launcher3.util.PackageUserKey
+import com.android.launcher3.util.WidgetUtils.createAppWidgetProviderInfo
+import com.android.launcher3.widget.LauncherAppWidgetProviderInfo
+import com.google.common.truth.Truth.assertThat
+import java.util.function.Predicate
+import junit.framework.Assert.assertNotNull
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.MockitoAnnotations
+
+@RunWith(AndroidJUnit4::class)
+class WidgetsPredictionsRequesterTest {
+
+    private lateinit var mUserHandle: UserHandle
+    private lateinit var context: Context
+    private lateinit var deviceProfile: DeviceProfile
+    private lateinit var testInvariantProfile: InvariantDeviceProfile
+
+    private lateinit var widget1aInfo: AppWidgetProviderInfo
+    private lateinit var widget1bInfo: AppWidgetProviderInfo
+    private lateinit var widget2Info: AppWidgetProviderInfo
+
+    private lateinit var widgetItem1a: WidgetItem
+    private lateinit var widgetItem1b: WidgetItem
+    private lateinit var widgetItem2: WidgetItem
+
+    private lateinit var allWidgets: Map<PackageUserKey, List<WidgetItem>>
+
+    @Mock private lateinit var iconCache: IconCache
+
+    @Before
+    fun setUp() {
+        MockitoAnnotations.initMocks(this)
+        mUserHandle = myUserHandle()
+        context = ActivityContextWrapper(ApplicationProvider.getApplicationContext())
+        testInvariantProfile = LauncherAppState.getIDP(context)
+        deviceProfile = testInvariantProfile.getDeviceProfile(context).copy(context)
+
+        widget1aInfo =
+            createAppWidgetProviderInfo(
+                ComponentName.createRelative(APP_1_PACKAGE_NAME, APP_1_PROVIDER_A_CLASS_NAME)
+            )
+        widget1bInfo =
+            createAppWidgetProviderInfo(
+                ComponentName.createRelative(APP_1_PACKAGE_NAME, APP_1_PROVIDER_B_CLASS_NAME)
+            )
+        widgetItem1a = createWidgetItem(widget1aInfo)
+        widgetItem1b = createWidgetItem(widget1bInfo)
+
+        widget2Info =
+            createAppWidgetProviderInfo(
+                ComponentName.createRelative(APP_2_PACKAGE_NAME, APP_2_PROVIDER_1_CLASS_NAME)
+            )
+        widgetItem2 = createWidgetItem(widget2Info)
+
+        allWidgets =
+            mapOf(
+                PackageUserKey(APP_1_PACKAGE_NAME, mUserHandle) to
+                    listOf(widgetItem1a, widgetItem1b),
+                PackageUserKey(APP_2_PACKAGE_NAME, mUserHandle) to listOf(widgetItem2),
+            )
+    }
+
+    @Test
+    fun buildBundleForPredictionSession_includesAddedAppWidgets() {
+        val existingWidgets = arrayListOf(widget1aInfo, widget1bInfo, widget2Info)
+
+        val bundle = buildBundleForPredictionSession(existingWidgets, TEST_UI_SURFACE)
+        val addedWidgetsBundleExtra =
+            bundle.getParcelableArrayList(BUNDLE_KEY_ADDED_APP_WIDGETS, AppTarget::class.java)
+
+        assertNotNull(addedWidgetsBundleExtra)
+        assertThat(addedWidgetsBundleExtra)
+            .containsExactly(
+                buildExpectedAppTargetEvent(
+                    /*pkg=*/ APP_1_PACKAGE_NAME,
+                    /*providerClassName=*/ APP_1_PROVIDER_A_CLASS_NAME,
+                    /*user=*/ mUserHandle
+                ),
+                buildExpectedAppTargetEvent(
+                    /*pkg=*/ APP_1_PACKAGE_NAME,
+                    /*providerClassName=*/ APP_1_PROVIDER_B_CLASS_NAME,
+                    /*user=*/ mUserHandle
+                ),
+                buildExpectedAppTargetEvent(
+                    /*pkg=*/ APP_2_PACKAGE_NAME,
+                    /*providerClassName=*/ APP_2_PROVIDER_1_CLASS_NAME,
+                    /*user=*/ mUserHandle
+                )
+            )
+    }
+
+    @Test
+    fun filterPredictions_notOnUiSurfaceFilter_returnsOnlyEligiblePredictions() {
+        val widgetsAlreadyOnSurface = arrayListOf(widget1bInfo)
+        val filter: Predicate<WidgetItem> = notOnUiSurfaceFilter(widgetsAlreadyOnSurface)
+
+        val predictions =
+            listOf(
+                // already on surface
+                AppTarget(
+                    AppTargetId(APP_1_PACKAGE_NAME),
+                    APP_1_PACKAGE_NAME,
+                    APP_1_PROVIDER_B_CLASS_NAME,
+                    mUserHandle
+                ),
+                // eligible
+                AppTarget(
+                    AppTargetId(APP_2_PACKAGE_NAME),
+                    APP_2_PACKAGE_NAME,
+                    APP_2_PROVIDER_1_CLASS_NAME,
+                    mUserHandle
+                )
+            )
+
+        // only 2 was eligible
+        assertThat(filterPredictions(predictions, allWidgets, filter)).containsExactly(widgetItem2)
+    }
+
+    @Test
+    fun filterPredictions_appPredictions_returnsWidgetFromPackage() {
+        val widgetsAlreadyOnSurface = arrayListOf(widget1bInfo)
+        val filter: Predicate<WidgetItem> = notOnUiSurfaceFilter(widgetsAlreadyOnSurface)
+
+        val predictions =
+            listOf(
+                AppTarget(
+                    AppTargetId(APP_1_PACKAGE_NAME),
+                    APP_1_PACKAGE_NAME,
+                    "$APP_1_PACKAGE_NAME.SomeActivity",
+                    mUserHandle
+                ),
+                AppTarget(
+                    AppTargetId(APP_2_PACKAGE_NAME),
+                    APP_2_PACKAGE_NAME,
+                    "$APP_2_PACKAGE_NAME.SomeActivity2",
+                    mUserHandle
+                ),
+            )
+
+        assertThat(filterPredictions(predictions, allWidgets, filter))
+            .containsExactly(widgetItem1a, widgetItem2)
+    }
+
+    private fun createWidgetItem(
+        providerInfo: AppWidgetProviderInfo,
+    ): WidgetItem {
+        val widgetInfo = LauncherAppWidgetProviderInfo.fromProviderInfo(context, providerInfo)
+        return WidgetItem(widgetInfo, testInvariantProfile, iconCache, context)
+    }
+
+    companion object {
+        const val TEST_UI_SURFACE = "widgets_test"
+        const val BUNDLE_KEY_ADDED_APP_WIDGETS = "added_app_widgets"
+
+        const val APP_1_PACKAGE_NAME = "com.example.app1"
+        const val APP_1_PROVIDER_A_CLASS_NAME = "app1Provider1"
+        const val APP_1_PROVIDER_B_CLASS_NAME = "app1Provider2"
+
+        const val APP_2_PACKAGE_NAME = "com.example.app2"
+        const val APP_2_PROVIDER_1_CLASS_NAME = "app2Provider1"
+
+        const val TEST_PACKAGE = "pkg"
+
+        private fun buildExpectedAppTargetEvent(
+            pkg: String,
+            providerClassName: String,
+            userHandle: UserHandle
+        ): AppTargetEvent {
+            val appTarget =
+                AppTarget.Builder(
+                        /*id=*/ AppTargetId("widget:$pkg"),
+                        /*packageName=*/ pkg,
+                        /*user=*/ userHandle
+                    )
+                    .setClassName(providerClassName)
+                    .build()
+            return AppTargetEvent.Builder(appTarget, AppTargetEvent.ACTION_PIN)
+                .setLaunchLocation(TEST_UI_SURFACE)
+                .build()
+        }
+    }
+}
diff --git a/quickstep/tests/src/com/android/quickstep/AbstractQuickStepTest.java b/quickstep/tests/src/com/android/quickstep/AbstractQuickStepTest.java
index 6a48b77..44c23ba 100644
--- a/quickstep/tests/src/com/android/quickstep/AbstractQuickStepTest.java
+++ b/quickstep/tests/src/com/android/quickstep/AbstractQuickStepTest.java
@@ -23,9 +23,9 @@
 import androidx.test.uiautomator.By;
 import androidx.test.uiautomator.Until;
 
-import com.android.launcher3.Launcher;
 import com.android.launcher3.tapl.LaunchedAppState;
 import com.android.launcher3.ui.AbstractLauncherUiTest;
+import com.android.launcher3.uioverrides.QuickstepLauncher;
 import com.android.quickstep.views.RecentsView;
 
 import org.junit.rules.RuleChain;
@@ -34,7 +34,7 @@
 /**
  * Base class for all instrumentation tests that deal with Quickstep.
  */
-public abstract class AbstractQuickStepTest extends AbstractLauncherUiTest {
+public abstract class AbstractQuickStepTest extends AbstractLauncherUiTest<QuickstepLauncher> {
     public static final boolean ENABLE_SHELL_TRANSITIONS =
             SystemProperties.getBoolean("persist.wm.debug.shell_transit", true);
     @Override
@@ -46,7 +46,7 @@
     }
 
     @Override
-    protected void onLauncherActivityClose(Launcher launcher) {
+    protected void onLauncherActivityClose(QuickstepLauncher launcher) {
         RecentsView recentsView = launcher.getOverviewPanel();
         if (recentsView != null) {
             recentsView.finishRecentsAnimation(false /* toRecents */, null);
diff --git a/quickstep/tests/src/com/android/quickstep/DesktopSystemShortcutTest.kt b/quickstep/tests/src/com/android/quickstep/DesktopSystemShortcutTest.kt
new file mode 100644
index 0000000..7dabbca
--- /dev/null
+++ b/quickstep/tests/src/com/android/quickstep/DesktopSystemShortcutTest.kt
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2024 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 android.content.ComponentName
+import android.content.Intent
+import android.platform.test.flag.junit.SetFlagsRule
+import com.android.launcher3.AbstractFloatingView
+import com.android.launcher3.AbstractFloatingViewHelper
+import com.android.launcher3.Launcher
+import com.android.launcher3.logging.StatsLogManager
+import com.android.launcher3.logging.StatsLogManager.LauncherEvent
+import com.android.launcher3.model.data.WorkspaceItemInfo
+import com.android.launcher3.uioverrides.QuickstepLauncher
+import com.android.launcher3.util.SplitConfigurationOptions
+import com.android.quickstep.views.LauncherRecentsView
+import com.android.quickstep.views.TaskView
+import com.android.systemui.shared.recents.model.Task
+import com.android.systemui.shared.recents.model.Task.TaskKey
+import com.android.window.flags.Flags
+import com.google.common.truth.Truth.assertThat
+import org.junit.Rule
+import org.junit.Test
+import org.mockito.kotlin.any
+import org.mockito.kotlin.eq
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.verify
+import org.mockito.kotlin.whenever
+
+/** Test for DesktopSystemShortcut */
+class DesktopSystemShortcutTest {
+
+    @get:Rule val setFlagsRule = SetFlagsRule(SetFlagsRule.DefaultInitValueType.DEVICE_DEFAULT)
+
+    private val launcher: QuickstepLauncher = mock()
+    private val statsLogManager: StatsLogManager = mock()
+    private val statsLogger: StatsLogManager.StatsLogger = mock()
+    private val recentsView: LauncherRecentsView = mock()
+    private val taskView: TaskView = mock()
+    private val workspaceItemInfo: WorkspaceItemInfo = mock()
+    private val abstractFloatingViewHelper: AbstractFloatingViewHelper = mock()
+    private val factory: TaskShortcutFactory =
+        DesktopSystemShortcut.createFactory(abstractFloatingViewHelper)
+
+    @Test
+    fun createDesktopTaskShortcutFactory_featureOff() {
+        setFlagsRule.disableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
+
+        val task =
+            Task(TaskKey(1, 0, Intent(), ComponentName("", ""), 0, 2000)).apply {
+                isDockable = true
+            }
+        val taskContainer =
+            taskView.TaskIdAttributeContainer(
+                task,
+                null,
+                null,
+                SplitConfigurationOptions.STAGE_POSITION_UNDEFINED
+            )
+
+        val shortcuts = factory.getShortcuts(launcher, taskContainer)
+        assertThat(shortcuts).isNull()
+    }
+
+    @Test
+    fun createDesktopTaskShortcutFactory_undockable() {
+        setFlagsRule.enableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
+
+        val task =
+            Task(TaskKey(1, 0, Intent(), ComponentName("", ""), 0, 2000)).apply {
+                isDockable = false
+            }
+        val taskContainer =
+            taskView.TaskIdAttributeContainer(
+                task,
+                null,
+                null,
+                SplitConfigurationOptions.STAGE_POSITION_UNDEFINED
+            )
+
+        val shortcuts = factory.getShortcuts(launcher, taskContainer)
+        assertThat(shortcuts).isNull()
+    }
+
+    @Test
+    fun desktopSystemShortcutClicked() {
+        setFlagsRule.enableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE)
+
+        val task =
+            Task(TaskKey(1, 0, Intent(), ComponentName("", ""), 0, 2000)).apply {
+                isDockable = true
+            }
+        val taskContainer =
+            taskView.TaskIdAttributeContainer(
+                task,
+                null,
+                null,
+                SplitConfigurationOptions.STAGE_POSITION_UNDEFINED
+            )
+
+        whenever(launcher.getOverviewPanel<LauncherRecentsView>()).thenReturn(recentsView)
+        whenever(launcher.statsLogManager).thenReturn(statsLogManager)
+        whenever(statsLogManager.logger()).thenReturn(statsLogger)
+        whenever(statsLogger.withItemInfo(any())).thenReturn(statsLogger)
+        whenever(taskView.getItemInfo(task)).thenReturn(workspaceItemInfo)
+        whenever(recentsView.moveTaskToDesktop(any(), any())).thenAnswer {
+            val successCallback = it.getArgument<Runnable>(1)
+            successCallback.run()
+        }
+
+        val shortcuts = factory.getShortcuts(launcher, taskContainer)
+        assertThat(shortcuts).hasSize(1)
+        assertThat(shortcuts!!.first()).isInstanceOf(DesktopSystemShortcut::class.java)
+
+        val desktopShortcut = shortcuts.first() as DesktopSystemShortcut
+
+        desktopShortcut.onClick(taskView)
+
+        val allTypesExceptRebindSafe =
+            AbstractFloatingView.TYPE_ALL and AbstractFloatingView.TYPE_REBIND_SAFE.inv()
+        verify(abstractFloatingViewHelper).closeOpenViews(launcher, true, allTypesExceptRebindSafe)
+        verify(recentsView).moveTaskToDesktop(eq(taskContainer), any())
+        verify(statsLogger).withItemInfo(workspaceItemInfo)
+        verify(statsLogger).log(LauncherEvent.LAUNCHER_SYSTEM_SHORTCUT_DESKTOP_TAP)
+    }
+}
diff --git a/quickstep/tests/src/com/android/quickstep/TaplOverviewIconTest.java b/quickstep/tests/src/com/android/quickstep/TaplOverviewIconTest.java
index 3f3b9ed..fa10b61 100644
--- a/quickstep/tests/src/com/android/quickstep/TaplOverviewIconTest.java
+++ b/quickstep/tests/src/com/android/quickstep/TaplOverviewIconTest.java
@@ -27,6 +27,7 @@
 import com.android.launcher3.tapl.OverviewTask.OverviewSplitTask;
 import com.android.launcher3.tapl.OverviewTaskMenu;
 import com.android.launcher3.ui.AbstractLauncherUiTest;
+import com.android.launcher3.uioverrides.QuickstepLauncher;
 import com.android.launcher3.util.rule.TestStabilityRule;
 
 import org.junit.Test;
@@ -35,7 +36,7 @@
  * This test run in both Out of process (Oop) and in-process (Ipc).
  * Tests the app Icon in overview.
  */
-public class TaplOverviewIconTest extends AbstractLauncherUiTest {
+public class TaplOverviewIconTest extends AbstractLauncherUiTest<QuickstepLauncher> {
 
     private static final String CALCULATOR_APP_PACKAGE =
             resolveSystemApp(Intent.CATEGORY_APP_CALCULATOR);
diff --git a/quickstep/tests/src/com/android/quickstep/TaplPrivateSpaceTest.java b/quickstep/tests/src/com/android/quickstep/TaplPrivateSpaceTest.java
new file mode 100644
index 0000000..0c143b4
--- /dev/null
+++ b/quickstep/tests/src/com/android/quickstep/TaplPrivateSpaceTest.java
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2024 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.LauncherState.ALL_APPS;
+import static com.android.launcher3.LauncherState.NORMAL;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeTrue;
+
+import android.util.Log;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.LargeTest;
+
+import com.android.launcher3.tapl.LauncherInstrumentation;
+
+import org.junit.After;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.IOException;
+import java.util.Objects;
+
+@LargeTest
+@RunWith(AndroidJUnit4.class)
+public class TaplPrivateSpaceTest extends AbstractQuickStepTest {
+
+    private int mProfileUserId;
+    private boolean mPrivateProfileSetupSuccessful;
+    private static final String TAG = "TaplPrivateSpaceTest";
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        initialize(this);
+
+        createAndStartPrivateProfileUser();
+        assumeTrue("Private Profile Setup not successful, aborting",
+                mPrivateProfileSetupSuccessful);
+
+        mDevice.pressHome();
+        waitForLauncherCondition("Launcher didn't start", Objects::nonNull);
+        waitForStateTransitionToEnd("Launcher internal state didn't switch to Normal",
+                () -> NORMAL);
+        waitForResumed("Launcher internal state is still Background");
+        mLauncher.getWorkspace().switchToAllApps();
+        waitForStateTransitionToEnd("Launcher internal state didn't switch to All Apps",
+                () -> ALL_APPS);
+
+        // Wait for Private Space being available in Launcher.
+        waitForPrivateSpaceSetup();
+        // Wait for Launcher UI to be updated with Private Space Items.
+        waitForLauncherUIUpdate();
+    }
+
+    private void createAndStartPrivateProfileUser() {
+        String createUserOutput = executeShellCommand("pm create-user --profileOf 0 --user-type "
+                + "android.os.usertype.profile.PRIVATE LauncherPrivateProfile");
+        updatePrivateProfileSetupSuccessful("pm create-user", createUserOutput);
+        String[] tokens = createUserOutput.split("\\s+");
+        mProfileUserId = Integer.parseInt(tokens[tokens.length - 1]);
+        StringBuilder logStr = new StringBuilder().append("profileId: ").append(mProfileUserId);
+        for (String str : tokens) {
+            logStr.append(str).append("\n");
+        }
+        String startUserOutput = executeShellCommand("am start-user " + mProfileUserId);
+        updatePrivateProfileSetupSuccessful("am start-user", startUserOutput);
+    }
+
+    @After
+    public void removePrivateProfile() {
+        String output = executeShellCommand("pm remove-user " + mProfileUserId);
+        updateProfileRemovalSuccessful("pm remove-user", output);
+        waitForPrivateSpaceRemoval();
+    }
+
+    @Test
+    public void testPrivateSpaceContainerIsPresent() {
+        assumeTrue(mPrivateProfileSetupSuccessful);
+        // Scroll to the bottom of All Apps
+        executeOnLauncher(launcher -> launcher.getAppsView().resetAndScrollToPrivateSpaceHeader());
+        waitForResumed("Launcher internal state is still Background");
+
+        // Verify Unlocked View elements are present.
+        assertNotNull("Private Space Unlocked View not found, or is not correct",
+                mLauncher.getAllApps().getPrivateSpaceUnlockedView());
+    }
+
+    private void waitForPrivateSpaceSetup() {
+        waitForLauncherCondition("Private Profile not setup",
+                launcher -> launcher.getAppsView().hasPrivateProfile(),
+                LauncherInstrumentation.WAIT_TIME_MS);
+    }
+
+    private void waitForPrivateSpaceRemoval() {
+        waitForLauncherCondition("Private Profile not setup",
+                launcher -> !launcher.getAppsView().hasPrivateProfile(),
+                LauncherInstrumentation.WAIT_TIME_MS);
+    }
+
+    private void waitForLauncherUIUpdate() {
+        // Wait for model thread completion as it may be processing
+        // the install event from the SystemService
+        mLauncher.waitForModelQueueCleared();
+        // Wait for Launcher UI thread completion, as it may be processing updating the UI in
+        // response to the model update. Not that `waitForLauncherInitialized` is just a proxy
+        // method, we can use any method which touches Launcher UI thread,
+        mLauncher.waitForLauncherInitialized();
+    }
+
+    private void updatePrivateProfileSetupSuccessful(String cli, String output) {
+        Log.d(TAG, "updatePrivateProfileSetupSuccessful, cli=" + cli + " " + "output="
+                + output);
+        mPrivateProfileSetupSuccessful = output.startsWith("Success");
+    }
+
+    private void updateProfileRemovalSuccessful(String cli, String output) {
+        Log.d(TAG, "updateProfileRemovalSuccessful, cli=" + cli + " " + "output=" + output);
+        assertTrue(output, output.startsWith("Success"));
+    }
+
+    private String executeShellCommand(String command) {
+        try {
+            return mDevice.executeShellCommand(command);
+        } catch (IOException e) {
+            Log.e(TAG, "error running shell command", e);
+            throw new RuntimeException(e);
+        }
+    }
+}
diff --git a/quickstep/tests/src/com/android/quickstep/TaplStartLauncherViaGestureTests.java b/quickstep/tests/src/com/android/quickstep/TaplStartLauncherViaGestureTests.java
index b31f470..e4caa26 100644
--- a/quickstep/tests/src/com/android/quickstep/TaplStartLauncherViaGestureTests.java
+++ b/quickstep/tests/src/com/android/quickstep/TaplStartLauncherViaGestureTests.java
@@ -16,13 +16,9 @@
 
 package com.android.quickstep;
 
-import static com.android.launcher3.util.rule.TestStabilityRule.LOCAL;
-import static com.android.launcher3.util.rule.TestStabilityRule.PLATFORM_POSTSUBMIT;
-
 import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
-import com.android.launcher3.util.rule.TestStabilityRule.Stability;
 import com.android.quickstep.NavigationModeSwitchRule.NavigationModeSwitch;
 
 import org.junit.Before;
@@ -47,8 +43,6 @@
 
     @Test
     @NavigationModeSwitch
-    // Stress tests are long. We permanently demote them from presubmit to match the presubmit SLO.
-    @Stability(flavors = LOCAL | PLATFORM_POSTSUBMIT)
     public void testStressPressHome() {
         for (int i = 0; i < STRESS_REPEAT_COUNT; ++i) {
             // Destroy Launcher activity.
@@ -61,8 +55,6 @@
 
     @Test
     @NavigationModeSwitch
-    // Stress tests are long. We permanently demote them from presubmit to match the presubmit SLO.
-    @Stability(flavors = LOCAL | PLATFORM_POSTSUBMIT)
     public void testStressSwipeToOverview() {
         for (int i = 0; i < STRESS_REPEAT_COUNT; ++i) {
             // Destroy Launcher activity.
diff --git a/quickstep/tests/src/com/android/quickstep/TaplTestsPersistentTaskbar.java b/quickstep/tests/src/com/android/quickstep/TaplTestsPersistentTaskbar.java
index df73e09..a9ff161 100644
--- a/quickstep/tests/src/com/android/quickstep/TaplTestsPersistentTaskbar.java
+++ b/quickstep/tests/src/com/android/quickstep/TaplTestsPersistentTaskbar.java
@@ -15,6 +15,8 @@
  */
 package com.android.quickstep;
 
+import static com.android.launcher3.util.rule.TestStabilityRule.LOCAL;
+import static com.android.launcher3.util.rule.TestStabilityRule.PLATFORM_POSTSUBMIT;
 import static com.android.quickstep.TaskbarModeSwitchRule.Mode.PERSISTENT;
 
 import android.graphics.Rect;
@@ -23,6 +25,7 @@
 import androidx.test.runner.AndroidJUnit4;
 
 import com.android.launcher3.ui.PortraitLandscapeRunner.PortraitLandscape;
+import com.android.launcher3.util.rule.TestStabilityRule;
 import com.android.quickstep.NavigationModeSwitchRule.NavigationModeSwitch;
 import com.android.quickstep.TaskbarModeSwitchRule.TaskbarModeSwitch;
 
@@ -45,6 +48,7 @@
 
     @Test
     @NavigationModeSwitch(mode = NavigationModeSwitchRule.Mode.THREE_BUTTON)
+    @TestStabilityRule.Stability(flavors = LOCAL | PLATFORM_POSTSUBMIT)
     public void testThreeButtonsTaskbarBoundsAfterConfigChangeDuringIme() {
         Rect taskbarBoundsBefore = getTaskbar().getVisibleBounds();
         // Go home and to an IME activity (any configuration change would do, as long as it
diff --git a/quickstep/tests/src/com/android/quickstep/TaplTestsSplitscreen.java b/quickstep/tests/src/com/android/quickstep/TaplTestsSplitscreen.java
index ec8e00d..2a54057 100644
--- a/quickstep/tests/src/com/android/quickstep/TaplTestsSplitscreen.java
+++ b/quickstep/tests/src/com/android/quickstep/TaplTestsSplitscreen.java
@@ -117,18 +117,21 @@
     }
 
     @Test
-    public void testSaveAppPairMenuItemExistsOnSplitPair() throws Exception {
+    public void testSaveAppPairMenuItemOrActionExistsOnSplitPair() {
         assumeTrue("App pairs feature is currently not enabled, no test needed",
                 Flags.enableAppPairs());
 
         createAndLaunchASplitPair();
 
-        assertTrue("Save app pair menu item is missing",
-                mLauncher.goHome()
-                        .switchToOverview()
-                        .getCurrentTask()
-                        .tapMenu()
-                        .hasMenuItem("Save app pair"));
+        Overview overview = mLauncher.goHome().switchToOverview();
+        if (mLauncher.isGridOnlyOverviewEnabled() || !mLauncher.isTablet()) {
+            assertTrue("Save app pair menu item is missing",
+                    overview.getCurrentTask()
+                            .tapMenu()
+                            .hasMenuItem("Save app pair"));
+        } else {
+            overview.getOverviewActions().assertHasAction("Save app pair");
+        }
     }
 
     @Test
diff --git a/quickstep/tests/src/com/android/quickstep/TaskViewTest.java b/quickstep/tests/src/com/android/quickstep/TaskViewTest.java
index d744194..8eec903 100644
--- a/quickstep/tests/src/com/android/quickstep/TaskViewTest.java
+++ b/quickstep/tests/src/com/android/quickstep/TaskViewTest.java
@@ -35,6 +35,7 @@
 import androidx.test.filters.SmallTest;
 
 import com.android.launcher3.statemanager.StatefulActivity;
+import com.android.launcher3.uioverrides.QuickstepLauncher;
 import com.android.quickstep.util.BorderAnimator;
 import com.android.quickstep.views.TaskView;
 
@@ -47,7 +48,7 @@
 public class TaskViewTest {
 
     @Mock
-    private StatefulActivity mContext;
+    private QuickstepLauncher mContext;
     @Mock
     private Resources mResource;
     @Mock
diff --git a/res/color-night-v31/material_color_surface_container_high.xml b/res/color-night-v31/material_color_surface_container_high.xml
index 002b88e..edd36fc 100644
--- a/res/color-night-v31/material_color_surface_container_high.xml
+++ b/res/color-night-v31/material_color_surface_container_high.xml
@@ -15,5 +15,5 @@
   ~ limitations under the License.
   -->
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:color="@android:color/system_neutral1_500" android:lStar="12" />
+    <item android:color="@android:color/system_neutral1_500" android:lStar="17" />
 </selector>
\ No newline at end of file
diff --git a/res/color-night-v31/material_color_surface_container_highest.xml b/res/color-night-v31/material_color_surface_container_highest.xml
index 002b88e..e54f953 100644
--- a/res/color-night-v31/material_color_surface_container_highest.xml
+++ b/res/color-night-v31/material_color_surface_container_highest.xml
@@ -15,5 +15,5 @@
   ~ limitations under the License.
   -->
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:color="@android:color/system_neutral1_500" android:lStar="12" />
+    <item android:color="@android:color/system_neutral1_500" android:lStar="22" />
 </selector>
\ No newline at end of file
diff --git a/res/color-night-v31/material_color_surface_container_low.xml b/res/color-night-v31/material_color_surface_container_low.xml
index 002b88e..40f0d4c 100644
--- a/res/color-night-v31/material_color_surface_container_low.xml
+++ b/res/color-night-v31/material_color_surface_container_low.xml
@@ -15,5 +15,5 @@
   ~ limitations under the License.
   -->
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:color="@android:color/system_neutral1_500" android:lStar="12" />
+    <item android:color="@android:color/system_neutral1_500" android:lStar="10" />
 </selector>
\ No newline at end of file
diff --git a/res/color-night-v31/material_color_surface_container_lowest.xml b/res/color-night-v31/material_color_surface_container_lowest.xml
index 002b88e..24f559b 100644
--- a/res/color-night-v31/material_color_surface_container_lowest.xml
+++ b/res/color-night-v31/material_color_surface_container_lowest.xml
@@ -15,5 +15,5 @@
   ~ limitations under the License.
   -->
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:color="@android:color/system_neutral1_500" android:lStar="12" />
+    <item android:color="@android:color/system_neutral1_500" android:lStar="4" />
 </selector>
\ No newline at end of file
diff --git a/res/color-v31/material_color_surface_container_high.xml b/res/color-v31/material_color_surface_container_high.xml
index b031c08..a996d51 100644
--- a/res/color-v31/material_color_surface_container_high.xml
+++ b/res/color-v31/material_color_surface_container_high.xml
@@ -15,5 +15,5 @@
   ~ limitations under the License.
   -->
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:color="@android:color/system_neutral1_500" android:lStar="94" />
+    <item android:color="@android:color/system_neutral1_500" android:lStar="92" />
 </selector>
\ No newline at end of file
diff --git a/res/color-v31/material_color_surface_container_highest.xml b/res/color-v31/material_color_surface_container_highest.xml
index b031c08..e7a535a 100644
--- a/res/color-v31/material_color_surface_container_highest.xml
+++ b/res/color-v31/material_color_surface_container_highest.xml
@@ -15,5 +15,5 @@
   ~ limitations under the License.
   -->
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:color="@android:color/system_neutral1_500" android:lStar="94" />
+    <item android:color="@android:color/system_neutral1_500" android:lStar="90" />
 </selector>
\ No newline at end of file
diff --git a/res/color-v31/material_color_surface_container_low.xml b/res/color-v31/material_color_surface_container_low.xml
index b031c08..b8fe01e 100644
--- a/res/color-v31/material_color_surface_container_low.xml
+++ b/res/color-v31/material_color_surface_container_low.xml
@@ -15,5 +15,5 @@
   ~ limitations under the License.
   -->
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:color="@android:color/system_neutral1_500" android:lStar="94" />
+    <item android:color="@android:color/system_neutral1_500" android:lStar="96" />
 </selector>
\ No newline at end of file
diff --git a/res/color-v31/material_color_surface_container_lowest.xml b/res/color-v31/material_color_surface_container_lowest.xml
index 674fc73..25e8666 100644
--- a/res/color-v31/material_color_surface_container_lowest.xml
+++ b/res/color-v31/material_color_surface_container_lowest.xml
@@ -15,5 +15,5 @@
   ~ limitations under the License.
   -->
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:color="@android:color/system_neutral1_500" android:lStar="94" />
+    <item android:color="@android:color/system_neutral1_500" android:lStar="100" />
 </selector>
\ No newline at end of file
diff --git a/res/color/taskbar_background_dark.xml b/res/color/taskbar_background_dark.xml
new file mode 100644
index 0000000..0727b8a
--- /dev/null
+++ b/res/color/taskbar_background_dark.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2024 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.
+  -->
+<!-- Should be the same as in packages/apps/Launcher3/res/color-night-v31/taskbar_background.xml -->
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <!--  Want to use @android:color/system_neutral1_500, but that causes build errors  -->
+    <item android:color="#76777D" android:lStar="6" />
+</selector>
\ No newline at end of file
diff --git a/res/drawable/bg_ps_header.xml b/res/drawable/bg_ps_header.xml
index 526bb5a..da31445 100644
--- a/res/drawable/bg_ps_header.xml
+++ b/res/drawable/bg_ps_header.xml
@@ -14,9 +14,13 @@
   ~ 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">
-    <corners android:radius="@dimen/ps_container_corner_radius" />
-    <solid android:color="?attr/materialColorSurfaceContainerHigh" />
-</shape>
\ No newline at end of file
+<ripple xmlns:android="http://schemas.android.com/apk/res/android"
+    android:color="@color/accent_ripple_color">
+    <item>
+        <shape xmlns:android="http://schemas.android.com/apk/res/android"
+            android:shape="rectangle">
+            <corners android:radius="@dimen/ps_container_corner_radius" />
+            <solid android:color="?attr/materialColorSurfaceContainerHigh" />
+        </shape>
+    </item>
+</ripple>
diff --git a/res/drawable/ic_allapps_search.xml b/res/drawable/ic_allapps_search.xml
index 0c3ab78..53b4f91 100644
--- a/res/drawable/ic_allapps_search.xml
+++ b/res/drawable/ic_allapps_search.xml
@@ -18,8 +18,9 @@
     android:height="24dp"
     android:viewportHeight="24.0"
     android:viewportWidth="24.0"
-    android:autoMirrored="true">
+    android:autoMirrored="true"
+    android:tint="?attr/widgetPickerSearchTextColor">
     <path
-        android:fillColor="?attr/widgetPickerSearchTextColor"
+        android:fillColor="#FFFFFF"
         android:pathData="M15.5,14h-0.79l-0.28,-0.27C15.41,12.59 16,11.11 16,9.5 16,5.91 13.09,3 9.5,3S3,5.91 3,9.5 5.91,16 9.5,16c1.61,0 3.09,-0.59 4.23,-1.57l0.27,0.28v0.79l5,4.99L20.49,19l-4.99,-5zM9.5,14C7.01,14 5,11.99 5,9.5S7.01,5 9.5,5 14,7.01 14,9.5 11.99,14 9.5,14z" />
 </vector>
diff --git a/res/drawable/ps_lock_background.xml b/res/drawable/ps_lock_background.xml
index b81c23f..0be83db 100644
--- a/res/drawable/ps_lock_background.xml
+++ b/res/drawable/ps_lock_background.xml
@@ -15,13 +15,17 @@
   ~ limitations under the License.
   -->
 
-<inset xmlns:android="http://schemas.android.com/apk/res/android"
-    android:inset="4dp">
-    <shape android:shape="rectangle">
-        <corners android:radius="@dimen/ps_lock_corner_radius" />
-        <solid android:color="?attr/materialColorPrimaryFixedDim" />
-        <padding
-            android:left="@dimen/ps_lock_button_background_padding"
-            android:right="@dimen/ps_lock_button_background_padding" />
-    </shape>
-</inset>
\ No newline at end of file
+<ripple xmlns:android="http://schemas.android.com/apk/res/android"
+    android:color="@color/accent_ripple_color">
+    <item>
+        <inset android:inset="4dp">
+            <shape android:shape="rectangle">
+                <corners android:radius="@dimen/ps_lock_corner_radius" />
+                <solid android:color="?attr/materialColorPrimaryFixedDim" />
+                <padding
+                    android:left="@dimen/ps_lock_button_background_padding"
+                    android:right="@dimen/ps_lock_button_background_padding" />
+            </shape>
+        </inset>
+    </item>
+</ripple>
diff --git a/res/layout/develop_options_edit_text.xml b/res/layout/develop_options_edit_text.xml
new file mode 100644
index 0000000..5e44228
--- /dev/null
+++ b/res/layout/develop_options_edit_text.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  ~ Copyright (C) 2024 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.ExtendedEditText
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:minWidth="100dp"
+    android:inputType="numberSigned"
+    android:id="@+id/pref_edit_text"
+    android:selectAllOnFocus="true"
+    android:imeOptions="actionDone"
+    android:maxLines="1" />
\ No newline at end of file
diff --git a/res/layout/developer_options_top_bar.xml b/res/layout/developer_options_top_bar.xml
index 1b138ea..ca46311 100644
--- a/res/layout/developer_options_top_bar.xml
+++ b/res/layout/developer_options_top_bar.xml
@@ -11,16 +11,17 @@
         android:layout_weight="1"
         android:layout_height="wrap_content"
         android:layout_marginHorizontal="@dimen/developer_options_filter_margins"
+        android:background="@drawable/rounded_action_button"
+        android:layout_marginTop="4dp"
+        android:layout_marginLeft="16dp"
+        android:layout_marginRight="16dp"
+        android:padding="12dp"
+        android:drawableStart="@drawable/ic_allapps_search"
+        android:drawableTint="?android:attr/textColorSecondary"
+        android:drawablePadding="8dp"
         android:hint="@string/developer_options_filter_hint"
         android:inputType="text"
         android:maxLines="1"
         android:imeOptions="actionDone"
         />
-    <Button
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:gravity="center_vertical"
-        android:text="Apply"
-        android:visibility="invisible"
-        android:id="@+id/flag_apply_btn" />
 </LinearLayout>
\ No newline at end of file
diff --git a/res/layout/folder_app_pair.xml b/res/layout/folder_app_pair.xml
new file mode 100644
index 0000000..acecd46
--- /dev/null
+++ b/res/layout/folder_app_pair.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  ~ Copyright (C) 2024 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.apppairs.AppPairIcon
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:launcher="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical"
+    android:focusable="true"
+    launcher:iconDisplay="folder" >
+    <com.android.launcher3.apppairs.AppPairIconGraphic
+        android:id="@+id/app_pair_icon_graphic"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:focusable="false" />
+    <com.android.launcher3.BubbleTextView
+        style="@style/BaseIcon"
+        android:id="@+id/app_pair_icon_name"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:focusable="false"
+        android:layout_gravity="top"
+        android:textColor="?attr/folderTextColor"
+        launcher:iconDisplay="folder" />
+</com.android.launcher3.apppairs.AppPairIcon>
\ No newline at end of file
diff --git a/res/layout/widget_cell_content.xml b/res/layout/widget_cell_content.xml
index 106c5b7..12453a5 100644
--- a/res/layout/widget_cell_content.xml
+++ b/res/layout/widget_cell_content.xml
@@ -35,14 +35,6 @@
             android:layout_height="match_parent"
             android:importantForAccessibility="no"
             android:layout_gravity="fill"/>
-
-        <ImageView
-            android:id="@+id/widget_badge"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:importantForAccessibility="no"
-            android:layout_gravity="end|bottom"
-            android:layout_margin="@dimen/profile_badge_margin"/>
     </com.android.launcher3.widget.WidgetCellPreview>
 
     <FrameLayout
@@ -51,44 +43,45 @@
         <LinearLayout
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
+            android:layout_gravity="center_vertical"
             android:id="@+id/widget_text_container"
             android:orientation="vertical">
             <!-- The name of the widget. -->
-        <TextView
-            android:id="@+id/widget_name"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:ellipsize="end"
-            android:fadingEdge="horizontal"
-            android:layout_gravity="center_horizontal"
-            android:gravity="center_horizontal|center_vertical"
-            android:singleLine="true"
-            android:maxLines="1"
-            android:textColor="?android:attr/textColorPrimary"
-            android:drawablePadding="@dimen/widget_cell_app_icon_padding"
-            android:textSize="@dimen/widget_cell_font_size" />
-
-            <!-- The original dimensions of the widget -->
             <TextView
-                android:id="@+id/widget_dims"
-                android:layout_width="match_parent"
+                android:id="@+id/widget_name"
+                android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
-                android:gravity="center_horizontal"
-                android:textColor="?android:attr/textColorSecondary"
-                android:textSize="@dimen/widget_cell_font_size"
-                android:alpha="0.7" />
-
-            <TextView
-                android:id="@+id/widget_description"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:gravity="center_horizontal"
-                android:textSize="@dimen/widget_cell_font_size"
-                android:textColor="?android:attr/textColorSecondary"
-                android:maxLines="2"
                 android:ellipsize="end"
                 android:fadingEdge="horizontal"
-                android:alpha="0.7" />
+                android:layout_gravity="center_horizontal"
+                android:gravity="center_horizontal|center_vertical"
+                android:singleLine="true"
+                android:maxLines="1"
+                android:textColor="?android:attr/textColorPrimary"
+                android:drawablePadding="@dimen/widget_cell_app_icon_padding"
+                android:textSize="@dimen/widget_cell_font_size" />
+
+                <!-- The original dimensions of the widget -->
+                <TextView
+                    android:id="@+id/widget_dims"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:gravity="center_horizontal"
+                    android:textColor="?android:attr/textColorSecondary"
+                    android:textSize="@dimen/widget_cell_font_size"
+                    android:alpha="0.7" />
+
+                <TextView
+                    android:id="@+id/widget_description"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:gravity="center_horizontal"
+                    android:textSize="@dimen/widget_cell_font_size"
+                    android:textColor="?android:attr/textColorSecondary"
+                    android:maxLines="2"
+                    android:ellipsize="end"
+                    android:fadingEdge="horizontal"
+                    android:alpha="0.7" />
         </LinearLayout>
 
         <Button
@@ -97,8 +90,6 @@
             android:layout_height="@dimen/widget_cell_add_button_height"
             android:layout_gravity="center"
             android:minWidth="0dp"
-            android:paddingTop="@dimen/widget_cell_add_button_vertical_padding"
-            android:paddingBottom="@dimen/widget_cell_add_button_vertical_padding"
             android:paddingStart="@dimen/widget_cell_add_button_start_padding"
             android:paddingEnd="@dimen/widget_cell_add_button_end_padding"
             android:text="@string/widget_add_button_label"
@@ -106,7 +97,7 @@
             android:textSize="@dimen/widget_cell_font_size"
             android:gravity="center"
             android:visibility="gone"
-            android:drawableLeft="@drawable/ic_plus"
+            android:drawableStart="@drawable/ic_plus"
             android:drawablePadding="8dp"
             android:drawableTint="?attr/widgetPickerAddButtonTextColor"
             android:background="@drawable/widget_cell_add_button_background" />
diff --git a/res/layout/widget_recommendations.xml b/res/layout/widget_recommendations.xml
index 531db2e..5879b0f 100644
--- a/res/layout/widget_recommendations.xml
+++ b/res/layout/widget_recommendations.xml
@@ -33,6 +33,9 @@
         android:textColor="?attr/widgetPickerTitleColor"
         android:textFontWeight="500"
         android:textSize="16sp"
+        android:maxLines="1"
+        android:paddingHorizontal="8dp"
+        android:ellipsize="end"
         android:visibility="gone" />
     <!-- Shown when there are more than one pages -->
     <com.android.launcher3.pageindicators.PageIndicatorDots
diff --git a/res/values-af/strings.xml b/res/values-af/strings.xml
index 9718479..7c6aa83 100644
--- a/res/values-af/strings.xml
+++ b/res/values-af/strings.xml
@@ -33,6 +33,7 @@
     <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
     <string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"Hierdie apppaar word nie op hierdie toestel gesteun nie"</string>
     <string name="app_pair_needs_unfold" msgid="4588897528143807002">"Vou die toestel oop om hierdie apppaar te gebruik"</string>
+    <string name="app_pair_not_available" msgid="3556767440808032031">"Apppaar is nie beskikbaar nie"</string>
     <string name="long_press_widget_to_add" msgid="3587712543577675817">"Raak en hou om \'n legstuk te skuif."</string>
     <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Dubbeltik en hou om \'n legstuk te skuif of gebruik gepasmaakte handelinge."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -188,8 +189,7 @@
     <string name="developer_options_filter_hint" msgid="5896817443635989056">"Filter"</string>
     <string name="remote_action_failed" msgid="1383965239183576790">"Misluk: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
     <string name="private_space_label" msgid="2359721649407947001">"Privaat ruimte"</string>
-    <!-- no translation found for private_space_secondary_label (9203933341714508907) -->
-    <skip />
+    <string name="private_space_secondary_label" msgid="9203933341714508907">"Tik om op te stel of oop te maak"</string>
     <string name="ps_container_title" msgid="4391796149519594205">"Privaat"</string>
     <string name="ps_container_settings" msgid="6059734123353320479">"Privaat Ruimte-instellings"</string>
     <string name="ps_container_lock_unlock_button" msgid="7605602332253423755">"Sluit/ontsluit Privaat Ruimte"</string>
diff --git a/res/values-am/strings.xml b/res/values-am/strings.xml
index a19ea97..fe5b51a 100644
--- a/res/values-am/strings.xml
+++ b/res/values-am/strings.xml
@@ -33,6 +33,7 @@
     <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
     <string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"ይህ የመተግበሪያ ጥምረት በዚህ መሣሪያ ላይ አይደገፍም"</string>
     <string name="app_pair_needs_unfold" msgid="4588897528143807002">"ይህን የመተግበሪያ ጥምረት ለመጠቀም መሣሪያን ይዘርጉ"</string>
+    <string name="app_pair_not_available" msgid="3556767440808032031">"የመተግበሪያ ጥምረት አይገኝም"</string>
     <string name="long_press_widget_to_add" msgid="3587712543577675817">"ምግብርን ለማንቀሳቀስ ይንኩ እና ይያዙ።"</string>
     <string name="long_accessible_way_to_add" msgid="2733588281439571974">"ምግብርን ለማንቀሳቀስ ወይም ብጁ እርምጃዎችን ለመጠቀም ሁለቴ መታ ያድርጉ እና ይያዙ።"</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -188,8 +189,7 @@
     <string name="developer_options_filter_hint" msgid="5896817443635989056">"አጣራ"</string>
     <string name="remote_action_failed" msgid="1383965239183576790">"አልተሳካም፦ <xliff:g id="WHAT">%1$s</xliff:g>"</string>
     <string name="private_space_label" msgid="2359721649407947001">"የግል ቦታ"</string>
-    <!-- no translation found for private_space_secondary_label (9203933341714508907) -->
-    <skip />
+    <string name="private_space_secondary_label" msgid="9203933341714508907">"ለማዋቀር ወይም ለመክፈት መታ ያድርጉ"</string>
     <string name="ps_container_title" msgid="4391796149519594205">"የግል"</string>
     <string name="ps_container_settings" msgid="6059734123353320479">"የግል ቦታ ቅንብሮች"</string>
     <string name="ps_container_lock_unlock_button" msgid="7605602332253423755">"የግል ቦታን ቆልፍ/ክፈት"</string>
diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml
index dfd23da..6963bb7 100644
--- a/res/values-ar/strings.xml
+++ b/res/values-ar/strings.xml
@@ -29,10 +29,11 @@
     <string name="home_screen" msgid="5629429142036709174">"الشاشة الرئيسية"</string>
     <string name="recent_task_option_split_screen" msgid="6690461455618725183">"تقسيم الشاشة"</string>
     <string name="split_app_info_accessibility" msgid="5475288491241414932">"‏معلومات تطبيق %1$s"</string>
-    <string name="save_app_pair" msgid="5647523853662686243">"حفظ إعدادات ميزة \"استخدام تطبيقين في الوقت نفسه\""</string>
+    <string name="save_app_pair" msgid="5647523853662686243">"حفظ استخدام التطبيقين معًا"</string>
     <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | ‏<xliff:g id="APP2">%2$s</xliff:g>"</string>
     <string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"لا يمكن استخدام هذين التطبيقَين في الوقت نفسه على هذا الجهاز"</string>
     <string name="app_pair_needs_unfold" msgid="4588897528143807002">"افتح الجهاز لاستخدام هذين التطبيقَين في الوقت نفسه"</string>
+    <string name="app_pair_not_available" msgid="3556767440808032031">"ميزة \"استخدام تطبيقين في الوقت نفسه\" غير متوفّرة"</string>
     <string name="long_press_widget_to_add" msgid="3587712543577675817">"انقر مع الاستمرار لنقل أداة."</string>
     <string name="long_accessible_way_to_add" msgid="2733588281439571974">"انقر مرتين مع تثبيت إصبعك لنقل أداة أو استخدام الإجراءات المخصّصة."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -188,8 +189,7 @@
     <string name="developer_options_filter_hint" msgid="5896817443635989056">"فلتر"</string>
     <string name="remote_action_failed" msgid="1383965239183576790">"تعذَّر <xliff:g id="WHAT">%1$s</xliff:g>."</string>
     <string name="private_space_label" msgid="2359721649407947001">"مساحة خاصة"</string>
-    <!-- no translation found for private_space_secondary_label (9203933341714508907) -->
-    <skip />
+    <string name="private_space_secondary_label" msgid="9203933341714508907">"النقر للإعداد أو الفتح"</string>
     <string name="ps_container_title" msgid="4391796149519594205">"المساحة الخاصة"</string>
     <string name="ps_container_settings" msgid="6059734123353320479">"إعدادات المساحة الخاصة"</string>
     <string name="ps_container_lock_unlock_button" msgid="7605602332253423755">"قفل المساحة الخاصة أو فتح قفلها"</string>
diff --git a/res/values-as/strings.xml b/res/values-as/strings.xml
index 898b9d6..7872e45 100644
--- a/res/values-as/strings.xml
+++ b/res/values-as/strings.xml
@@ -33,6 +33,7 @@
     <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
     <string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"এই ডিভাইচটোত এই এপ্‌ পেয়াৰ কৰাৰ সুবিধাটো সমৰ্থিত নহয়"</string>
     <string name="app_pair_needs_unfold" msgid="4588897528143807002">"এই এপ্‌ পেয়াৰ কৰাৰ সুবিধাটো ব্যৱহাৰ কৰিবলৈ ডিভাইচটো আনফ’ল্ড কৰক"</string>
+    <string name="app_pair_not_available" msgid="3556767440808032031">"এপ্‌ পেয়াৰ কৰাৰ সুবিধাটো উপলব্ধ নহয়"</string>
     <string name="long_press_widget_to_add" msgid="3587712543577675817">"ৱিজেট স্থানান্তৰ কৰিবলৈ টিপি ধৰি ৰাখক।"</string>
     <string name="long_accessible_way_to_add" msgid="2733588281439571974">"কোনো ৱিজেট স্থানান্তৰ কৰিবলৈ দুবাৰ টিপি ধৰি ৰাখক অথবা কাষ্টম কাৰ্য ব্যৱহাৰ কৰক।"</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -188,8 +189,7 @@
     <string name="developer_options_filter_hint" msgid="5896817443635989056">"ফিল্টাৰ"</string>
     <string name="remote_action_failed" msgid="1383965239183576790">"বিফল: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
     <string name="private_space_label" msgid="2359721649407947001">"প্ৰাইভেট স্পে\'চ"</string>
-    <!-- no translation found for private_space_secondary_label (9203933341714508907) -->
-    <skip />
+    <string name="private_space_secondary_label" msgid="9203933341714508907">"ছেট আপ কৰিবলৈ টিপক অথবা খোলক"</string>
     <string name="ps_container_title" msgid="4391796149519594205">"ব্যক্তিগত"</string>
     <string name="ps_container_settings" msgid="6059734123353320479">"ব্যক্তিগত স্পে’চৰ ছেটিং"</string>
     <string name="ps_container_lock_unlock_button" msgid="7605602332253423755">"প্ৰাইভেট স্পে\'চ লক/আনলক কৰক"</string>
diff --git a/res/values-az/strings.xml b/res/values-az/strings.xml
index b714613..0f67a22 100644
--- a/res/values-az/strings.xml
+++ b/res/values-az/strings.xml
@@ -33,6 +33,7 @@
     <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
     <string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"Bu tətbiq cütü bu cihazda dəstəklənmir"</string>
     <string name="app_pair_needs_unfold" msgid="4588897528143807002">"Bu tətbiq cütündən istifadə üçün cihazı açın"</string>
+    <string name="app_pair_not_available" msgid="3556767440808032031">"Tətbiq cütü əlçatan deyil"</string>
     <string name="long_press_widget_to_add" msgid="3587712543577675817">"Vidceti daşımaq üçün toxunub saxlayın."</string>
     <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Vidceti daşımaq üçün iki dəfə toxunub saxlayın və ya fərdi əməliyyatlardan istifadə edin."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -188,8 +189,7 @@
     <string name="developer_options_filter_hint" msgid="5896817443635989056">"Filtr"</string>
     <string name="remote_action_failed" msgid="1383965239183576790">"Alınmadı: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
     <string name="private_space_label" msgid="2359721649407947001">"Şəxsi yer"</string>
-    <!-- no translation found for private_space_secondary_label (9203933341714508907) -->
-    <skip />
+    <string name="private_space_secondary_label" msgid="9203933341714508907">"Toxunaraq ayarlayın və ya açın"</string>
     <string name="ps_container_title" msgid="4391796149519594205">"Şəxsi"</string>
     <string name="ps_container_settings" msgid="6059734123353320479">"Şəxsi məkan ayarları"</string>
     <string name="ps_container_lock_unlock_button" msgid="7605602332253423755">"Şəxsi məkanı kilidləyin/kiliddən çıxarın"</string>
diff --git a/res/values-b+sr+Latn/strings.xml b/res/values-b+sr+Latn/strings.xml
index 6ff7970..59c4700 100644
--- a/res/values-b+sr+Latn/strings.xml
+++ b/res/values-b+sr+Latn/strings.xml
@@ -33,6 +33,7 @@
     <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
     <string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"Ovaj par aplikacija nije podržan na ovom uređaju"</string>
     <string name="app_pair_needs_unfold" msgid="4588897528143807002">"Otvorite uređaj da biste koristili ovaj par aplikacija"</string>
+    <string name="app_pair_not_available" msgid="3556767440808032031">"Par aplikacija nije dostupan"</string>
     <string name="long_press_widget_to_add" msgid="3587712543577675817">"Dodirnite i zadržite radi pomeranja vidžeta."</string>
     <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Dvaput dodirnite i zadržite da biste pomerali vidžet ili koristite prilagođene radnje."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d×%2$d"</string>
@@ -43,7 +44,7 @@
     <string name="add_to_home_screen" msgid="9168649446635919791">"Dodaj na početni ekran"</string>
     <string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"Dodali ste vidžet <xliff:g id="WIDGET_NAME">%1$s</xliff:g> na početni ekran"</string>
     <string name="suggested_widgets_header_title" msgid="1844314680798145222">"Predlozi"</string>
-    <string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"Osnovne aplikacije"</string>
+    <string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"Neophodne aplikacije"</string>
     <string name="news_widget_recommendation_category_label" msgid="6756167867113741310">"Novosti i časopisi"</string>
     <string name="social_and_entertainment_widget_recommendation_category_label" msgid="2923840997302308191">"Zona za opuštanje"</string>
     <string name="entertainment_widget_recommendation_category_label" msgid="3973107268630717874">"Zabava"</string>
@@ -87,7 +88,7 @@
     <string name="all_apps_button_work_label" msgid="7270707118948892488">"Lista poslovnih aplikacija"</string>
     <string name="remove_drop_target_label" msgid="7812859488053230776">"Ukloni"</string>
     <string name="uninstall_drop_target_label" msgid="4722034217958379417">"Deinstaliraj"</string>
-    <string name="app_info_drop_target_label" msgid="692894985365717661">"Infor. o aplikaciji"</string>
+    <string name="app_info_drop_target_label" msgid="692894985365717661">"Podaci o aplikaciji"</string>
     <string name="install_private_system_shortcut_label" msgid="1616889277073184841">"Instaliraj na privatni"</string>
     <string name="install_drop_target_label" msgid="2539096853673231757">"Instaliraj"</string>
     <string name="dismiss_prediction_label" msgid="3357562989568808658">"Ne predlaži aplikaciju"</string>
@@ -188,8 +189,7 @@
     <string name="developer_options_filter_hint" msgid="5896817443635989056">"Filter"</string>
     <string name="remote_action_failed" msgid="1383965239183576790">"Nije uspelo: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
     <string name="private_space_label" msgid="2359721649407947001">"Privatni prostor"</string>
-    <!-- no translation found for private_space_secondary_label (9203933341714508907) -->
-    <skip />
+    <string name="private_space_secondary_label" msgid="9203933341714508907">"Dodirnite da biste podesili ili otvorili"</string>
     <string name="ps_container_title" msgid="4391796149519594205">"Privatno"</string>
     <string name="ps_container_settings" msgid="6059734123353320479">"Podešavanja privatnog prostora"</string>
     <string name="ps_container_lock_unlock_button" msgid="7605602332253423755">"Zaključaj/otključaj privatni prostor"</string>
diff --git a/res/values-be/strings.xml b/res/values-be/strings.xml
index 22642d7..b6e30de 100644
--- a/res/values-be/strings.xml
+++ b/res/values-be/strings.xml
@@ -33,6 +33,8 @@
     <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
     <string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"Дадзенае спалучэнне праграм не падтрымліваецца на гэтай прыладзе"</string>
     <string name="app_pair_needs_unfold" msgid="4588897528143807002">"Каб выкарыстоўваць гэта спалучэнне праграм, раскладзіце прыладу"</string>
+    <!-- no translation found for app_pair_not_available (3556767440808032031) -->
+    <skip />
     <string name="long_press_widget_to_add" msgid="3587712543577675817">"Націсніце і ўтрымлівайце віджэт для перамяшчэння."</string>
     <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Дакраніцеся двойчы і ўтрымлівайце, каб перамясціць віджэт або выкарыстоўваць спецыяльныя дзеянні."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -188,8 +190,7 @@
     <string name="developer_options_filter_hint" msgid="5896817443635989056">"Фільтр"</string>
     <string name="remote_action_failed" msgid="1383965239183576790">"Не ўдалося: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
     <string name="private_space_label" msgid="2359721649407947001">"Прыватная вобласць"</string>
-    <!-- no translation found for private_space_secondary_label (9203933341714508907) -->
-    <skip />
+    <string name="private_space_secondary_label" msgid="9203933341714508907">"Націсніце, каб наладзіць або адкрыць"</string>
     <string name="ps_container_title" msgid="4391796149519594205">"Прыватная"</string>
     <string name="ps_container_settings" msgid="6059734123353320479">"Налады прыватнай вобласці"</string>
     <string name="ps_container_lock_unlock_button" msgid="7605602332253423755">"Заблакіраваць (разблакіраваць) прыватную вобласць"</string>
diff --git a/res/values-bg/strings.xml b/res/values-bg/strings.xml
index a9e4a26..b9b6b60 100644
--- a/res/values-bg/strings.xml
+++ b/res/values-bg/strings.xml
@@ -33,6 +33,8 @@
     <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
     <string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"Тази двойка приложения не се поддържа на устройството"</string>
     <string name="app_pair_needs_unfold" msgid="4588897528143807002">"Отворете устройството, за да използвате тази двойка приложения"</string>
+    <!-- no translation found for app_pair_not_available (3556767440808032031) -->
+    <skip />
     <string name="long_press_widget_to_add" msgid="3587712543577675817">"Докоснете и задръжте за преместване на приспособление"</string>
     <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Докоснете двукратно и задръжте за преместване на приспособление или използвайте персонал. действия."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -188,8 +190,7 @@
     <string name="developer_options_filter_hint" msgid="5896817443635989056">"Филтър"</string>
     <string name="remote_action_failed" msgid="1383965239183576790">"Неуспешно: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
     <string name="private_space_label" msgid="2359721649407947001">"Лично пространство"</string>
-    <!-- no translation found for private_space_secondary_label (9203933341714508907) -->
-    <skip />
+    <string name="private_space_secondary_label" msgid="9203933341714508907">"Докоснете за настройване или отваряне"</string>
     <string name="ps_container_title" msgid="4391796149519594205">"Лично"</string>
     <string name="ps_container_settings" msgid="6059734123353320479">"Настройки за личното пространство"</string>
     <string name="ps_container_lock_unlock_button" msgid="7605602332253423755">"Заключване/отключване на личното пространство"</string>
diff --git a/res/values-bn/strings.xml b/res/values-bn/strings.xml
index f20416b..64b0ba2 100644
--- a/res/values-bn/strings.xml
+++ b/res/values-bn/strings.xml
@@ -33,6 +33,8 @@
     <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
     <string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"এই ডিভাইসে এই অ্যাপ পেয়ারটি কাজ করে না"</string>
     <string name="app_pair_needs_unfold" msgid="4588897528143807002">"এই অ্যাপ পেয়ার ব্যবহার করতে ডিভাইস আনফোল্ড করুন"</string>
+    <!-- no translation found for app_pair_not_available (3556767440808032031) -->
+    <skip />
     <string name="long_press_widget_to_add" msgid="3587712543577675817">"কোনও উইজেট সরাতে সেটি টাচ করে ধরে রাখুন।"</string>
     <string name="long_accessible_way_to_add" msgid="2733588281439571974">"একটি উইজেট সরাতে বা কাস্টম অ্যাকশন ব্যবহার করতে ডবল ট্যাপ করে ধরে রাখুন।"</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -188,8 +190,7 @@
     <string name="developer_options_filter_hint" msgid="5896817443635989056">"ফিল্টার"</string>
     <string name="remote_action_failed" msgid="1383965239183576790">"কাজটি করা যায়নি: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
     <string name="private_space_label" msgid="2359721649407947001">"ব্যক্তিগত স্পেস"</string>
-    <!-- no translation found for private_space_secondary_label (9203933341714508907) -->
-    <skip />
+    <string name="private_space_secondary_label" msgid="9203933341714508907">"সেট-আপ করতে বা খুলতে ট্যাপ করুন"</string>
     <string name="ps_container_title" msgid="4391796149519594205">"ব্যক্তিগত"</string>
     <string name="ps_container_settings" msgid="6059734123353320479">"ব্যক্তিগত স্পেসের সেটিংস"</string>
     <string name="ps_container_lock_unlock_button" msgid="7605602332253423755">"ব্যক্তিগত স্পেস লক/আনলক করুন"</string>
diff --git a/res/values-bs/strings.xml b/res/values-bs/strings.xml
index 3e2ed4d..d0d4ce6 100644
--- a/res/values-bs/strings.xml
+++ b/res/values-bs/strings.xml
@@ -33,6 +33,7 @@
     <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
     <string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"Par aplikacija nije podržan na uređaju"</string>
     <string name="app_pair_needs_unfold" msgid="4588897528143807002">"Otklopite uređaj da koristite ovaj par aplikacija"</string>
+    <string name="app_pair_not_available" msgid="3556767440808032031">"Par aplikacija nije dostupan"</string>
     <string name="long_press_widget_to_add" msgid="3587712543577675817">"Dodirnite i zadržite da pomjerite vidžet."</string>
     <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Dvaput dodirnite i zadržite da pomjerite vidžet ili da koristite prilagođene radnje."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -188,8 +189,7 @@
     <string name="developer_options_filter_hint" msgid="5896817443635989056">"Filtrirajte"</string>
     <string name="remote_action_failed" msgid="1383965239183576790">"Nije uspjelo: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
     <string name="private_space_label" msgid="2359721649407947001">"Privatan prostor"</string>
-    <!-- no translation found for private_space_secondary_label (9203933341714508907) -->
-    <skip />
+    <string name="private_space_secondary_label" msgid="9203933341714508907">"Dodirnite da postavite ili otvorite"</string>
     <string name="ps_container_title" msgid="4391796149519594205">"Privatno"</string>
     <string name="ps_container_settings" msgid="6059734123353320479">"Postavke privatnog prostora"</string>
     <string name="ps_container_lock_unlock_button" msgid="7605602332253423755">"Zaključavanje/otključavanje privatnog prostora"</string>
diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml
index 4ffd4bb..5d54f2e 100644
--- a/res/values-ca/strings.xml
+++ b/res/values-ca/strings.xml
@@ -33,6 +33,8 @@
     <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
     <string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"Aquesta parella d\'aplicacions no s\'admet en aquest dispositiu"</string>
     <string name="app_pair_needs_unfold" msgid="4588897528143807002">"Desplega el dispositiu per utilitzar aquesta parella d\'aplicacions"</string>
+    <!-- no translation found for app_pair_not_available (3556767440808032031) -->
+    <skip />
     <string name="long_press_widget_to_add" msgid="3587712543577675817">"Fes doble toc i mantén premut per moure un widget."</string>
     <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Fes doble toc i mantén premut per moure un widget o per utilitzar accions personalitzades."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -118,7 +120,7 @@
     <string name="app_pair_name_format" msgid="8134106404716224054">"Parella d\'aplicacions: <xliff:g id="APP1">%1$s</xliff:g> i <xliff:g id="APP2">%2$s</xliff:g>"</string>
     <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Estil i fons de pantalla"</string>
     <string name="edit_home_screen" msgid="8947858375782098427">"Edita la pantalla d\'inici"</string>
-    <string name="settings_button_text" msgid="8873672322605444408">"Config. pantalla d\'inici"</string>
+    <string name="settings_button_text" msgid="8873672322605444408">"Configuració de la pantalla d\'inici"</string>
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Desactivada per l\'administrador"</string>
     <string name="allow_rotation_title" msgid="7222049633713050106">"Permet la rotació de la pantalla d\'inici"</string>
     <string name="allow_rotation_desc" msgid="8662546029078692509">"En girar el telèfon"</string>
@@ -188,14 +190,13 @@
     <string name="developer_options_filter_hint" msgid="5896817443635989056">"Filtra"</string>
     <string name="remote_action_failed" msgid="1383965239183576790">"Error: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
     <string name="private_space_label" msgid="2359721649407947001">"Espai privat"</string>
-    <!-- no translation found for private_space_secondary_label (9203933341714508907) -->
-    <skip />
+    <string name="private_space_secondary_label" msgid="9203933341714508907">"Toca per configurar o obrir"</string>
     <string name="ps_container_title" msgid="4391796149519594205">"Privat"</string>
     <string name="ps_container_settings" msgid="6059734123353320479">"Configuració d\'Espai privat"</string>
     <string name="ps_container_lock_unlock_button" msgid="7605602332253423755">"Bloqueja o desbloqueja Espai privat"</string>
     <string name="ps_container_lock_title" msgid="2640257399982364682">"Bloqueja"</string>
     <string name="ps_container_transition" msgid="8667331812048014412">"Canvia a Espai privat"</string>
-    <string name="ps_add_button_label" msgid="8611055839242385935">"Instal·la aplicacions"</string>
+    <string name="ps_add_button_label" msgid="8611055839242385935">"Instal·la apps"</string>
     <string name="ps_add_button_content_description" msgid="3254274107740952556">"Instal·la les aplicacions a Espai privat"</string>
     <string name="bubble_bar_overflow_description" msgid="7410995531938041192">"Menú addicional"</string>
 </resources>
diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml
index 61521ae..5d93636 100644
--- a/res/values-cs/strings.xml
+++ b/res/values-cs/strings.xml
@@ -33,6 +33,8 @@
     <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
     <string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"Tento pár aplikací není na tomto zařízení podporován"</string>
     <string name="app_pair_needs_unfold" msgid="4588897528143807002">"Pokud chcete použít tento pár aplikací, rozložte zařízení"</string>
+    <!-- no translation found for app_pair_not_available (3556767440808032031) -->
+    <skip />
     <string name="long_press_widget_to_add" msgid="3587712543577675817">"Widget přesunete klepnutím a podržením."</string>
     <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Dvojitým klepnutím a podržením přesunete widget, případně použijte vlastní akce."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -188,14 +190,13 @@
     <string name="developer_options_filter_hint" msgid="5896817443635989056">"Filtr"</string>
     <string name="remote_action_failed" msgid="1383965239183576790">"Selhalo: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
     <string name="private_space_label" msgid="2359721649407947001">"Soukromý prostor"</string>
-    <!-- no translation found for private_space_secondary_label (9203933341714508907) -->
-    <skip />
+    <string name="private_space_secondary_label" msgid="9203933341714508907">"Klepnutím nastavíte nebo otevřete"</string>
     <string name="ps_container_title" msgid="4391796149519594205">"Soukromé"</string>
     <string name="ps_container_settings" msgid="6059734123353320479">"Nastavení soukromého prostoru"</string>
     <string name="ps_container_lock_unlock_button" msgid="7605602332253423755">"Zamknout/odemknout soukromý prostor"</string>
     <string name="ps_container_lock_title" msgid="2640257399982364682">"Zamknout"</string>
     <string name="ps_container_transition" msgid="8667331812048014412">"Převádění soukromého prostoru"</string>
-    <string name="ps_add_button_label" msgid="8611055839242385935">"Instalace aplikací"</string>
+    <string name="ps_add_button_label" msgid="8611055839242385935">"Instalovat aplikace"</string>
     <string name="ps_add_button_content_description" msgid="3254274107740952556">"Instalovat aplikace do soukromého prostoru"</string>
     <string name="bubble_bar_overflow_description" msgid="7410995531938041192">"Rozbalovací nabídka"</string>
 </resources>
diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml
index f85a2a9..3260fb5 100644
--- a/res/values-da/strings.xml
+++ b/res/values-da/strings.xml
@@ -33,6 +33,8 @@
     <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
     <string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"Denne appsammenknytning understøttes ikke på enheden"</string>
     <string name="app_pair_needs_unfold" msgid="4588897528143807002">"Fold enheden ud for at bruge denne appsammenknytning"</string>
+    <!-- no translation found for app_pair_not_available (3556767440808032031) -->
+    <skip />
     <string name="long_press_widget_to_add" msgid="3587712543577675817">"Hold en widget nede for at flytte den."</string>
     <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Tryk to gange, og hold en widget nede for at flytte den eller bruge tilpassede handlinger."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -188,8 +190,7 @@
     <string name="developer_options_filter_hint" msgid="5896817443635989056">"Filter"</string>
     <string name="remote_action_failed" msgid="1383965239183576790">"Mislykket: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
     <string name="private_space_label" msgid="2359721649407947001">"Privat område"</string>
-    <!-- no translation found for private_space_secondary_label (9203933341714508907) -->
-    <skip />
+    <string name="private_space_secondary_label" msgid="9203933341714508907">"Tryk for at konfigurere eller åbne"</string>
     <string name="ps_container_title" msgid="4391796149519594205">"Privat"</string>
     <string name="ps_container_settings" msgid="6059734123353320479">"Indstillinger for privat rum"</string>
     <string name="ps_container_lock_unlock_button" msgid="7605602332253423755">"Lås/oplås det private område"</string>
diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml
index f6fd609..78e20b6 100644
--- a/res/values-de/strings.xml
+++ b/res/values-de/strings.xml
@@ -33,6 +33,8 @@
     <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
     <string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"Dieses App-Paar wird auf diesem Gerät nicht unterstützt"</string>
     <string name="app_pair_needs_unfold" msgid="4588897528143807002">"Gerät aufklappen, um dieses App-Paar zu verwenden"</string>
+    <!-- no translation found for app_pair_not_available (3556767440808032031) -->
+    <skip />
     <string name="long_press_widget_to_add" msgid="3587712543577675817">"Zum Verschieben des Widgets berühren und halten"</string>
     <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Doppeltippen und halten, um ein Widget zu bewegen oder benutzerdefinierte Aktionen zu nutzen."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -188,8 +190,7 @@
     <string name="developer_options_filter_hint" msgid="5896817443635989056">"Filter"</string>
     <string name="remote_action_failed" msgid="1383965239183576790">"Fehler: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
     <string name="private_space_label" msgid="2359721649407947001">"Privates Profil"</string>
-    <!-- no translation found for private_space_secondary_label (9203933341714508907) -->
-    <skip />
+    <string name="private_space_secondary_label" msgid="9203933341714508907">"Zum Einrichten oder Öffnen tippen"</string>
     <string name="ps_container_title" msgid="4391796149519594205">"Privat"</string>
     <string name="ps_container_settings" msgid="6059734123353320479">"Einstellungen für privaten Bereich"</string>
     <string name="ps_container_lock_unlock_button" msgid="7605602332253423755">"Privaten Bereich sperren/entsperren"</string>
diff --git a/res/values-el/strings.xml b/res/values-el/strings.xml
index 04e42b2..f2d8a15 100644
--- a/res/values-el/strings.xml
+++ b/res/values-el/strings.xml
@@ -33,6 +33,8 @@
     <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
     <string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"Αυτό το ζεύγος εφαρμογών δεν υποστηρίζεται σε αυτή τη συσκευή"</string>
     <string name="app_pair_needs_unfold" msgid="4588897528143807002">"Ξεδιπλώστε τη συσκευή για να χρησιμοποιήσετε αυτό το ζεύγος εφαρμογών"</string>
+    <!-- no translation found for app_pair_not_available (3556767440808032031) -->
+    <skip />
     <string name="long_press_widget_to_add" msgid="3587712543577675817">"Πατήστε παρατετ. για μετακίνηση γραφ. στοιχείου."</string>
     <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Πατήστε δύο φορές παρατεταμένα για μετακίνηση γραφικού στοιχείου ή χρήση προσαρμοσμένων ενεργειών."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -188,8 +190,7 @@
     <string name="developer_options_filter_hint" msgid="5896817443635989056">"Φίλτρο"</string>
     <string name="remote_action_failed" msgid="1383965239183576790">"Αποτυχία: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
     <string name="private_space_label" msgid="2359721649407947001">"Ιδιωτικός χώρος"</string>
-    <!-- no translation found for private_space_secondary_label (9203933341714508907) -->
-    <skip />
+    <string name="private_space_secondary_label" msgid="9203933341714508907">"Πάτημα για ρύθμιση ή άνοιγμα"</string>
     <string name="ps_container_title" msgid="4391796149519594205">"Ιδιωτικό"</string>
     <string name="ps_container_settings" msgid="6059734123353320479">"Ρυθμίσεις Ιδιωτικού χώρου"</string>
     <string name="ps_container_lock_unlock_button" msgid="7605602332253423755">"Κλείδωμα/Ξεκλείδωμα Ιδιωτικού χώρου"</string>
diff --git a/res/values-en-rAU/strings.xml b/res/values-en-rAU/strings.xml
index 6a7fbb7..7061889 100644
--- a/res/values-en-rAU/strings.xml
+++ b/res/values-en-rAU/strings.xml
@@ -33,6 +33,8 @@
     <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
     <string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"This app pair isn\'t supported on this device"</string>
     <string name="app_pair_needs_unfold" msgid="4588897528143807002">"Unfold device to use this app pair"</string>
+    <!-- no translation found for app_pair_not_available (3556767440808032031) -->
+    <skip />
     <string name="long_press_widget_to_add" msgid="3587712543577675817">"Touch and hold to move a widget."</string>
     <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Double-tap &amp; hold to move a widget or use custom actions."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
diff --git a/res/values-en-rCA/strings.xml b/res/values-en-rCA/strings.xml
index 53c0074..ec69ea8 100644
--- a/res/values-en-rCA/strings.xml
+++ b/res/values-en-rCA/strings.xml
@@ -33,6 +33,7 @@
     <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
     <string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"This app pair isn\'t supported on this device"</string>
     <string name="app_pair_needs_unfold" msgid="4588897528143807002">"Unfold device to use this app pair"</string>
+    <string name="app_pair_not_available" msgid="3556767440808032031">"App pair isn\'t available"</string>
     <string name="long_press_widget_to_add" msgid="3587712543577675817">"Touch and hold to move a widget."</string>
     <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Double-tap and hold to move a widget or use custom actions."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
diff --git a/res/values-en-rGB/strings.xml b/res/values-en-rGB/strings.xml
index 6a7fbb7..7061889 100644
--- a/res/values-en-rGB/strings.xml
+++ b/res/values-en-rGB/strings.xml
@@ -33,6 +33,8 @@
     <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
     <string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"This app pair isn\'t supported on this device"</string>
     <string name="app_pair_needs_unfold" msgid="4588897528143807002">"Unfold device to use this app pair"</string>
+    <!-- no translation found for app_pair_not_available (3556767440808032031) -->
+    <skip />
     <string name="long_press_widget_to_add" msgid="3587712543577675817">"Touch and hold to move a widget."</string>
     <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Double-tap &amp; hold to move a widget or use custom actions."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
diff --git a/res/values-en-rIN/strings.xml b/res/values-en-rIN/strings.xml
index 6a7fbb7..7061889 100644
--- a/res/values-en-rIN/strings.xml
+++ b/res/values-en-rIN/strings.xml
@@ -33,6 +33,8 @@
     <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
     <string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"This app pair isn\'t supported on this device"</string>
     <string name="app_pair_needs_unfold" msgid="4588897528143807002">"Unfold device to use this app pair"</string>
+    <!-- no translation found for app_pair_not_available (3556767440808032031) -->
+    <skip />
     <string name="long_press_widget_to_add" msgid="3587712543577675817">"Touch and hold to move a widget."</string>
     <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Double-tap &amp; hold to move a widget or use custom actions."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
diff --git a/res/values-en-rXC/strings.xml b/res/values-en-rXC/strings.xml
index f95149f..476ffda 100644
--- a/res/values-en-rXC/strings.xml
+++ b/res/values-en-rXC/strings.xml
@@ -33,6 +33,7 @@
     <string name="app_pair_default_title" msgid="4045241727446873529">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‏‏‎‎‎‎‎‏‎‎‎‏‏‏‎‎‏‎‏‎‏‏‏‏‎‏‎‏‏‎‎‏‎‎‎‏‏‎‎‎‎‏‏‏‎‏‏‏‏‎‏‎‏‏‎‏‏‏‎‎‏‎‎‏‎‎‏‏‎<xliff:g id="APP1">%1$s</xliff:g>‎‏‎‎‏‏‏‎ | ‎‏‎‎‏‏‎<xliff:g id="APP2">%2$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
     <string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‎‏‏‏‏‏‏‎‏‎‏‎‎‏‎‎‏‏‏‎‎‎‏‏‎‎‏‎‏‏‎‏‏‎‏‎‏‏‏‏‎‎‏‏‎‏‎‎‎‎‏‎‎‏‏‎‎‎‎‎‎‎This app pair isn\'t supported on this device‎‏‎‎‏‎"</string>
     <string name="app_pair_needs_unfold" msgid="4588897528143807002">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‏‏‏‏‏‏‎‏‎‏‏‏‏‎‎‎‎‏‎‎‏‏‏‏‏‏‏‎‏‎‎‏‎‎‎‏‏‏‎‏‎‏‏‏‎‎‎‎‎‎‎‏‎‎‎‎‏‏‎‏‎‎Unfold device to use this app pair‎‏‎‎‏‎"</string>
+    <string name="app_pair_not_available" msgid="3556767440808032031">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‏‎‎‎‏‎‏‎‏‏‏‎‎‎‎‏‎‏‏‎‏‎‎‏‎‎‏‎‎‏‎‎‏‎‎‏‎‎‎‎‎‏‎‎‏‏‎‏‏‎‏‏‏‎‎‎‏‏‏‏‏‎App pair isn\'t available‎‏‎‎‏‎"</string>
     <string name="long_press_widget_to_add" msgid="3587712543577675817">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‏‎‎‎‏‏‏‎‎‏‎‏‎‎‎‎‏‏‏‎‏‏‎‎‎‏‏‎‎‏‏‎‎‎‏‎‎‎‎‏‎‏‎‎‏‎‎‎‏‏‎‎‎‎‎‏‎‏‎‎‏‎Touch &amp; hold to move a widget.‎‏‎‎‏‎"</string>
     <string name="long_accessible_way_to_add" msgid="2733588281439571974">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‎‎‏‎‏‏‏‏‎‏‏‏‏‏‎‏‎‏‎‎‎‎‎‎‎‏‏‏‏‎‎‎‎‏‏‎‏‎‏‏‎‎‎‎‎‎‏‎‏‎‎‎‎‎‎‎‎‎‏‏‎‎Double-tap &amp; hold to move a widget or use custom actions.‎‏‎‎‏‎"</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‎‎‎‎‎‏‏‏‎‎‏‏‎‏‎‎‏‏‏‏‏‏‎‎‏‏‎‎‏‏‎‏‎‎‎‎‎‎‏‎‏‎‎‎‏‎‎‎‎‎‏‎‎‎‏‎‏‏‏‏‏‎%1$d × %2$d‎‏‎‎‏‎"</string>
diff --git a/res/values-es-rUS/strings.xml b/res/values-es-rUS/strings.xml
index c377990..012609e 100644
--- a/res/values-es-rUS/strings.xml
+++ b/res/values-es-rUS/strings.xml
@@ -33,6 +33,8 @@
     <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
     <string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"No se admite esta vinculación de apps en este dispositivo"</string>
     <string name="app_pair_needs_unfold" msgid="4588897528143807002">"Abre el dispositivo para usar esta vinculación de apps"</string>
+    <!-- no translation found for app_pair_not_available (3556767440808032031) -->
+    <skip />
     <string name="long_press_widget_to_add" msgid="3587712543577675817">"Mantén presionado para mover un widget."</string>
     <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Presiona dos veces y mantén presionado para mover un widget o usar acciones personalizadas."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -188,8 +190,7 @@
     <string name="developer_options_filter_hint" msgid="5896817443635989056">"Filtro"</string>
     <string name="remote_action_failed" msgid="1383965239183576790">"Error: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
     <string name="private_space_label" msgid="2359721649407947001">"Espacio privado"</string>
-    <!-- no translation found for private_space_secondary_label (9203933341714508907) -->
-    <skip />
+    <string name="private_space_secondary_label" msgid="9203933341714508907">"Presiona para configurar o abrir"</string>
     <string name="ps_container_title" msgid="4391796149519594205">"Privado"</string>
     <string name="ps_container_settings" msgid="6059734123353320479">"Configuración de Espacio privado"</string>
     <string name="ps_container_lock_unlock_button" msgid="7605602332253423755">"Bloquear o desbloquear Espacio privado"</string>
diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml
index 5c950b1..0b0cb41 100644
--- a/res/values-es/strings.xml
+++ b/res/values-es/strings.xml
@@ -33,6 +33,8 @@
     <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
     <string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"El dispositivo no admite esta aplicación emparejada"</string>
     <string name="app_pair_needs_unfold" msgid="4588897528143807002">"Despliega el dispositivo para usar esta aplicación emparejada"</string>
+    <!-- no translation found for app_pair_not_available (3556767440808032031) -->
+    <skip />
     <string name="long_press_widget_to_add" msgid="3587712543577675817">"Mantén pulsado un widget para moverlo"</string>
     <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Toca dos veces y mantén pulsado un widget para moverlo o usar acciones personalizadas."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -188,14 +190,13 @@
     <string name="developer_options_filter_hint" msgid="5896817443635989056">"Filtro"</string>
     <string name="remote_action_failed" msgid="1383965239183576790">"Se ha producido un error: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
     <string name="private_space_label" msgid="2359721649407947001">"Espacio privado"</string>
-    <!-- no translation found for private_space_secondary_label (9203933341714508907) -->
-    <skip />
+    <string name="private_space_secondary_label" msgid="9203933341714508907">"Toca para configurarlo o abrirlo"</string>
     <string name="ps_container_title" msgid="4391796149519594205">"Privado"</string>
     <string name="ps_container_settings" msgid="6059734123353320479">"Ajustes del espacio privado"</string>
     <string name="ps_container_lock_unlock_button" msgid="7605602332253423755">"Bloquear/Desbloquear espacio privado"</string>
     <string name="ps_container_lock_title" msgid="2640257399982364682">"Bloquear"</string>
     <string name="ps_container_transition" msgid="8667331812048014412">"Cambiar a espacio privado"</string>
-    <string name="ps_add_button_label" msgid="8611055839242385935">"Descargar aplicaciones"</string>
+    <string name="ps_add_button_label" msgid="8611055839242385935">"Descarg. apps"</string>
     <string name="ps_add_button_content_description" msgid="3254274107740952556">"Descargar aplicaciones en el espacio privado"</string>
     <string name="bubble_bar_overflow_description" msgid="7410995531938041192">"Desplegable"</string>
 </resources>
diff --git a/res/values-et/strings.xml b/res/values-et/strings.xml
index 610c243..212b672 100644
--- a/res/values-et/strings.xml
+++ b/res/values-et/strings.xml
@@ -33,6 +33,8 @@
     <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
     <string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"See rakendusepaar ei ole selles seadmes toetatud"</string>
     <string name="app_pair_needs_unfold" msgid="4588897528143807002">"Selle rakendusepaari kasutamiseks voltige seade lahti"</string>
+    <!-- no translation found for app_pair_not_available (3556767440808032031) -->
+    <skip />
     <string name="long_press_widget_to_add" msgid="3587712543577675817">"Vidina teisaldamiseks puudutage ja hoidke all."</string>
     <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Vidina teisaldamiseks või kohandatud toimingute kasutamiseks topeltpuudutage ja hoidke all."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -188,8 +190,7 @@
     <string name="developer_options_filter_hint" msgid="5896817443635989056">"Filter"</string>
     <string name="remote_action_failed" msgid="1383965239183576790">"Nurjus: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
     <string name="private_space_label" msgid="2359721649407947001">"Privaatne ruum"</string>
-    <!-- no translation found for private_space_secondary_label (9203933341714508907) -->
-    <skip />
+    <string name="private_space_secondary_label" msgid="9203933341714508907">"Seadistamiseks või avamiseks puudutage"</string>
     <string name="ps_container_title" msgid="4391796149519594205">"Privaatne"</string>
     <string name="ps_container_settings" msgid="6059734123353320479">"Privaatse ruumi seaded"</string>
     <string name="ps_container_lock_unlock_button" msgid="7605602332253423755">"Privaatse ruumi lukustamine/avamine"</string>
diff --git a/res/values-eu/strings.xml b/res/values-eu/strings.xml
index 1d25061..8ffbea6 100644
--- a/res/values-eu/strings.xml
+++ b/res/values-eu/strings.xml
@@ -33,6 +33,8 @@
     <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
     <string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"Aplikazio pare hori ez da onartzen gailu honetan"</string>
     <string name="app_pair_needs_unfold" msgid="4588897528143807002">"Zabaldu gailua aplikazio pare hau erabiltzeko"</string>
+    <!-- no translation found for app_pair_not_available (3556767440808032031) -->
+    <skip />
     <string name="long_press_widget_to_add" msgid="3587712543577675817">"Eduki sakatuta widget bat mugitzeko."</string>
     <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Sakatu birritan eta eduki sakatuta widget bat mugitzeko edo ekintza pertsonalizatuak erabiltzeko."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -118,7 +120,7 @@
     <string name="app_pair_name_format" msgid="8134106404716224054">"Aplikazio parea: <xliff:g id="APP1">%1$s</xliff:g> eta <xliff:g id="APP2">%2$s</xliff:g>"</string>
     <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"Horma-papera eta estiloa"</string>
     <string name="edit_home_screen" msgid="8947858375782098427">"Editatu orri nagusia"</string>
-    <string name="settings_button_text" msgid="8873672322605444408">"Orri nagusiaren ezarpenak"</string>
+    <string name="settings_button_text" msgid="8873672322605444408">"Orri nagusiko ezarpenak"</string>
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Administratzaileak desgaitu du"</string>
     <string name="allow_rotation_title" msgid="7222049633713050106">"Eman orri nagusia biratzeko baimena"</string>
     <string name="allow_rotation_desc" msgid="8662546029078692509">"Telefonoa biratzean"</string>
@@ -188,14 +190,13 @@
     <string name="developer_options_filter_hint" msgid="5896817443635989056">"Iragazi"</string>
     <string name="remote_action_failed" msgid="1383965239183576790">"Huts egin du: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
     <string name="private_space_label" msgid="2359721649407947001">"Eremu pribatua"</string>
-    <!-- no translation found for private_space_secondary_label (9203933341714508907) -->
-    <skip />
+    <string name="private_space_secondary_label" msgid="9203933341714508907">"Sakatu konfiguratzeko edo irekitzeko"</string>
     <string name="ps_container_title" msgid="4391796149519594205">"Pribatua"</string>
     <string name="ps_container_settings" msgid="6059734123353320479">"Eremu pribatuaren ezarpenak"</string>
     <string name="ps_container_lock_unlock_button" msgid="7605602332253423755">"Blokeatu/Desblokeatu eremu pribatua"</string>
     <string name="ps_container_lock_title" msgid="2640257399982364682">"Blokeatu"</string>
     <string name="ps_container_transition" msgid="8667331812048014412">"Eremu pribaturako trantsizioa"</string>
-    <string name="ps_add_button_label" msgid="8611055839242385935">"Aplikazioak instalatu"</string>
+    <string name="ps_add_button_label" msgid="8611055839242385935">"Instalatu aplikazioak"</string>
     <string name="ps_add_button_content_description" msgid="3254274107740952556">"Instalatu aplikazioak eremu pribatuan"</string>
     <string name="bubble_bar_overflow_description" msgid="7410995531938041192">"Luzapena"</string>
 </resources>
diff --git a/res/values-fa/strings.xml b/res/values-fa/strings.xml
index dc48d82..848ebee 100644
--- a/res/values-fa/strings.xml
+++ b/res/values-fa/strings.xml
@@ -33,6 +33,7 @@
     <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
     <string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"از این جفت برنامه در این دستگاه پشتیبانی نمی‌شود"</string>
     <string name="app_pair_needs_unfold" msgid="4588897528143807002">"برای استفاده از این جفت برنامه، دستگاه را باز کنید"</string>
+    <string name="app_pair_not_available" msgid="3556767440808032031">"جفت برنامه دردسترس نیست"</string>
     <string name="long_press_widget_to_add" msgid="3587712543577675817">"برای جابه‌جا کردن ابزارک، لمس کنید و نگه دارید."</string>
     <string name="long_accessible_way_to_add" msgid="2733588281439571974">"برای جابه‌جا کردن ابزارک یا استفاده از کنش‌های سفارشی، دوضربه بزنید و نگه دارید."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -188,8 +189,7 @@
     <string name="developer_options_filter_hint" msgid="5896817443635989056">"فیلتر"</string>
     <string name="remote_action_failed" msgid="1383965239183576790">"ناموفق بود: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
     <string name="private_space_label" msgid="2359721649407947001">"فضای خصوصی"</string>
-    <!-- no translation found for private_space_secondary_label (9203933341714508907) -->
-    <skip />
+    <string name="private_space_secondary_label" msgid="9203933341714508907">"برای راه‌اندازی یا باز کردن، ضربه بزنید"</string>
     <string name="ps_container_title" msgid="4391796149519594205">"خصوصی"</string>
     <string name="ps_container_settings" msgid="6059734123353320479">"تنظیمات «فضای خصوصی»"</string>
     <string name="ps_container_lock_unlock_button" msgid="7605602332253423755">"قفل/ باز کردن «فضای خصوصی»"</string>
diff --git a/res/values-fi/strings.xml b/res/values-fi/strings.xml
index 820f7eb..e55c32f 100644
--- a/res/values-fi/strings.xml
+++ b/res/values-fi/strings.xml
@@ -33,6 +33,8 @@
     <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
     <string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"Sovellusparia ei tueta tällä laitteella"</string>
     <string name="app_pair_needs_unfold" msgid="4588897528143807002">"Avaa taitettu laite, niin voit käyttää sovellusparia"</string>
+    <!-- no translation found for app_pair_not_available (3556767440808032031) -->
+    <skip />
     <string name="long_press_widget_to_add" msgid="3587712543577675817">"Kosketa pitkään, niin voit siirtää widgetiä."</string>
     <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Kaksoisnapauta ja paina pitkään, niin voit siirtää widgetiä tai käyttää muokattuja toimintoja."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -188,8 +190,7 @@
     <string name="developer_options_filter_hint" msgid="5896817443635989056">"Suodatin"</string>
     <string name="remote_action_failed" msgid="1383965239183576790">"Epäonnistui: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
     <string name="private_space_label" msgid="2359721649407947001">"Yksityinen tila"</string>
-    <!-- no translation found for private_space_secondary_label (9203933341714508907) -->
-    <skip />
+    <string name="private_space_secondary_label" msgid="9203933341714508907">"Ota käyttöön tai avaa napauttamalla"</string>
     <string name="ps_container_title" msgid="4391796149519594205">"Yksityinen"</string>
     <string name="ps_container_settings" msgid="6059734123353320479">"Yksityisen tilan asetukset"</string>
     <string name="ps_container_lock_unlock_button" msgid="7605602332253423755">"Lukitse yksityinen tila / avaa sen lukitus"</string>
diff --git a/res/values-fr-rCA/strings.xml b/res/values-fr-rCA/strings.xml
index d47e63e..7578aea 100644
--- a/res/values-fr-rCA/strings.xml
+++ b/res/values-fr-rCA/strings.xml
@@ -33,6 +33,8 @@
     <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
     <string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"Cette paire d\'applications n\'est pas prise en charge sur cet appareil"</string>
     <string name="app_pair_needs_unfold" msgid="4588897528143807002">"Déplier l\'appareil pour utiliser cette paire d\'applications"</string>
+    <!-- no translation found for app_pair_not_available (3556767440808032031) -->
+    <skip />
     <string name="long_press_widget_to_add" msgid="3587712543577675817">"Maintenez le doigt sur un widget pour le déplacer."</string>
     <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Touchez 2x un widget et maintenez le doigt dessus pour le déplacer ou utiliser des actions personnalisées."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -188,8 +190,7 @@
     <string name="developer_options_filter_hint" msgid="5896817443635989056">"Filtrer"</string>
     <string name="remote_action_failed" msgid="1383965239183576790">"Échec : <xliff:g id="WHAT">%1$s</xliff:g>"</string>
     <string name="private_space_label" msgid="2359721649407947001">"Espace privé"</string>
-    <!-- no translation found for private_space_secondary_label (9203933341714508907) -->
-    <skip />
+    <string name="private_space_secondary_label" msgid="9203933341714508907">"Toucher pour configurer ou ouvrir"</string>
     <string name="ps_container_title" msgid="4391796149519594205">"Privé"</string>
     <string name="ps_container_settings" msgid="6059734123353320479">"Paramètres de l\'Espace privé"</string>
     <string name="ps_container_lock_unlock_button" msgid="7605602332253423755">"Verrouiller/Déverrouiller l\'Espace privé"</string>
diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml
index 54ad858..435d3d3 100644
--- a/res/values-fr/strings.xml
+++ b/res/values-fr/strings.xml
@@ -33,6 +33,8 @@
     <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
     <string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"Cette paire d\'applications n\'est pas prise en charge sur cet appareil"</string>
     <string name="app_pair_needs_unfold" msgid="4588897528143807002">"Dépliez l\'appareil pour utiliser cette paire d\'applications"</string>
+    <!-- no translation found for app_pair_not_available (3556767440808032031) -->
+    <skip />
     <string name="long_press_widget_to_add" msgid="3587712543577675817">"Appuyez de manière prolongée sur un widget pour le déplacer."</string>
     <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Appuyez deux fois et maintenez la pression pour déplacer widget ou utiliser actions personnalisées."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d x %2$d"</string>
@@ -123,8 +125,8 @@
     <string name="allow_rotation_title" msgid="7222049633713050106">"Autoriser la rotation de l\'écran d\'accueil"</string>
     <string name="allow_rotation_desc" msgid="8662546029078692509">"Lorsque vous faites pivoter le téléphone"</string>
     <string name="notification_dots_title" msgid="9062440428204120317">"Pastilles de notification"</string>
-    <string name="notification_dots_desc_on" msgid="1679848116452218908">"Activé"</string>
-    <string name="notification_dots_desc_off" msgid="1760796511504341095">"Désactivé"</string>
+    <string name="notification_dots_desc_on" msgid="1679848116452218908">"Activées"</string>
+    <string name="notification_dots_desc_off" msgid="1760796511504341095">"Désactivées"</string>
     <string name="title_missing_notification_access" msgid="7503287056163941064">"Accès aux notifications requis"</string>
     <string name="msg_missing_notification_access" msgid="281113995110910548">"Pour afficher les pastilles de notification, activez les notifications de l\'application <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="title_change_settings" msgid="1376365968844349552">"Modifier les paramètres"</string>
@@ -188,14 +190,13 @@
     <string name="developer_options_filter_hint" msgid="5896817443635989056">"Filtre"</string>
     <string name="remote_action_failed" msgid="1383965239183576790">"Échec : <xliff:g id="WHAT">%1$s</xliff:g>"</string>
     <string name="private_space_label" msgid="2359721649407947001">"Espace privé"</string>
-    <!-- no translation found for private_space_secondary_label (9203933341714508907) -->
-    <skip />
+    <string name="private_space_secondary_label" msgid="9203933341714508907">"Appuyer pour ouvrir ou configurer"</string>
     <string name="ps_container_title" msgid="4391796149519594205">"Privé"</string>
     <string name="ps_container_settings" msgid="6059734123353320479">"Paramètres d\'Espace privé"</string>
     <string name="ps_container_lock_unlock_button" msgid="7605602332253423755">"Verrouiller/Déverrouiller Espace privé"</string>
     <string name="ps_container_lock_title" msgid="2640257399982364682">"Verrouiller"</string>
     <string name="ps_container_transition" msgid="8667331812048014412">"Transition vers Espace privé"</string>
-    <string name="ps_add_button_label" msgid="8611055839242385935">"Installer des applis"</string>
+    <string name="ps_add_button_label" msgid="8611055839242385935">"Installer applis"</string>
     <string name="ps_add_button_content_description" msgid="3254274107740952556">"Installer des applis dans l\'espace privé"</string>
     <string name="bubble_bar_overflow_description" msgid="7410995531938041192">"Dépassement"</string>
 </resources>
diff --git a/res/values-gl/strings.xml b/res/values-gl/strings.xml
index 0a7c96c..180a786 100644
--- a/res/values-gl/strings.xml
+++ b/res/values-gl/strings.xml
@@ -29,10 +29,12 @@
     <string name="home_screen" msgid="5629429142036709174">"Inicio"</string>
     <string name="recent_task_option_split_screen" msgid="6690461455618725183">"Pantalla dividida"</string>
     <string name="split_app_info_accessibility" msgid="5475288491241414932">"Información da aplicación para %1$s"</string>
-    <string name="save_app_pair" msgid="5647523853662686243">"Gardar parella de aplicacións"</string>
+    <string name="save_app_pair" msgid="5647523853662686243">"Gardar parella de apps"</string>
     <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
     <string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"O dispositivo non admite este emparellamento de aplicacións"</string>
     <string name="app_pair_needs_unfold" msgid="4588897528143807002">"Desprega o dispositivo para usar este emparellamento de aplicacións"</string>
+    <!-- no translation found for app_pair_not_available (3556767440808032031) -->
+    <skip />
     <string name="long_press_widget_to_add" msgid="3587712543577675817">"Mantén premido un widget para movelo."</string>
     <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Toca dúas veces un widget e manteno premido para movelo ou utiliza accións personalizadas."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -188,14 +190,13 @@
     <string name="developer_options_filter_hint" msgid="5896817443635989056">"Filtra"</string>
     <string name="remote_action_failed" msgid="1383965239183576790">"Erro: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
     <string name="private_space_label" msgid="2359721649407947001">"Espazo privado"</string>
-    <!-- no translation found for private_space_secondary_label (9203933341714508907) -->
-    <skip />
+    <string name="private_space_secondary_label" msgid="9203933341714508907">"Toca para configuralo ou abrilo"</string>
     <string name="ps_container_title" msgid="4391796149519594205">"Privado"</string>
     <string name="ps_container_settings" msgid="6059734123353320479">"Configuración do espazo privado"</string>
     <string name="ps_container_lock_unlock_button" msgid="7605602332253423755">"Bloquear ou desbloquear o espazo privado"</string>
     <string name="ps_container_lock_title" msgid="2640257399982364682">"Bloquear"</string>
     <string name="ps_container_transition" msgid="8667331812048014412">"Transición ao espazo privado"</string>
-    <string name="ps_add_button_label" msgid="8611055839242385935">"Instalar as aplicacións"</string>
+    <string name="ps_add_button_label" msgid="8611055839242385935">"Instalar apps"</string>
     <string name="ps_add_button_content_description" msgid="3254274107740952556">"Instalar as aplicacións no espazo privado"</string>
     <string name="bubble_bar_overflow_description" msgid="7410995531938041192">"Menú adicional"</string>
 </resources>
diff --git a/res/values-gu/strings.xml b/res/values-gu/strings.xml
index c3be263..931c38a 100644
--- a/res/values-gu/strings.xml
+++ b/res/values-gu/strings.xml
@@ -33,6 +33,7 @@
     <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
     <string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"આ ડિવાઇસ પર, આ ઍપની જોડીને સપોર્ટ આપવામાં આવતો નથી"</string>
     <string name="app_pair_needs_unfold" msgid="4588897528143807002">"આ ઍપની જોડીનો ઉપયોગ કરવા માટે, ડિવાઇસને અનફોલ્ડ કરો"</string>
+    <string name="app_pair_not_available" msgid="3556767440808032031">"ઍપની જોડી ઉપલબ્ધ નથી"</string>
     <string name="long_press_widget_to_add" msgid="3587712543577675817">"વિજેટ ખસેડવા ટચ કરીને થોડી વાર દબાવી રાખો."</string>
     <string name="long_accessible_way_to_add" msgid="2733588281439571974">"વિજેટ ખસેડવા બે વાર ટૅપ કરીને દબાવી રાખો અથવા કસ્ટમ ક્રિયાઓનો ઉપયોગ કરો."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -188,8 +189,7 @@
     <string name="developer_options_filter_hint" msgid="5896817443635989056">"ફિલ્ટર કરો"</string>
     <string name="remote_action_failed" msgid="1383965239183576790">"નિષ્ફળ: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
     <string name="private_space_label" msgid="2359721649407947001">"ખાનગી સ્પેસ"</string>
-    <!-- no translation found for private_space_secondary_label (9203933341714508907) -->
-    <skip />
+    <string name="private_space_secondary_label" msgid="9203933341714508907">"સેટઅપ કરવા કે ખોલવા માટે ટૅપ કરો"</string>
     <string name="ps_container_title" msgid="4391796149519594205">"ખાનગી"</string>
     <string name="ps_container_settings" msgid="6059734123353320479">"ખાનગી સ્પેસના સેટિંગ"</string>
     <string name="ps_container_lock_unlock_button" msgid="7605602332253423755">"ખાનગી સ્પેસને લૉક/અનલૉક કરો"</string>
diff --git a/res/values-hi/strings.xml b/res/values-hi/strings.xml
index 7b6a9f9..6d83820 100644
--- a/res/values-hi/strings.xml
+++ b/res/values-hi/strings.xml
@@ -33,6 +33,7 @@
     <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
     <string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"साथ में इस्तेमाल किए जा सकने वाले ये ऐप्लिकेशन, इस डिवाइस पर काम नहीं कर सकते"</string>
     <string name="app_pair_needs_unfold" msgid="4588897528143807002">"साथ में इस्तेमाल किए जा सकने वाले ये ऐप्लिकेशन इस्तेमाल करने के लिए डिवाइस को अनफ़ोल्ड करें"</string>
+    <string name="app_pair_not_available" msgid="3556767440808032031">"साथ में इस्तेमाल किए जा सकने वाले ऐप्लिकेशन की सुविधा उपलब्ध नहीं है"</string>
     <string name="long_press_widget_to_add" msgid="3587712543577675817">"किसी विजेट को एक से दूसरी जगह ले जाने के लिए, उसे दबाकर रखें."</string>
     <string name="long_accessible_way_to_add" msgid="2733588281439571974">"किसी विजेट को एक से दूसरी जगह ले जाने के लिए, उस पर दो बार टैप करके दबाकर रखें या पसंद के मुताबिक कार्रवाइयां इस्तेमाल करें."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -188,8 +189,7 @@
     <string name="developer_options_filter_hint" msgid="5896817443635989056">"फ़िल्टर"</string>
     <string name="remote_action_failed" msgid="1383965239183576790">"पूरा नहीं हुआ: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
     <string name="private_space_label" msgid="2359721649407947001">"प्राइवेट स्पेस"</string>
-    <!-- no translation found for private_space_secondary_label (9203933341714508907) -->
-    <skip />
+    <string name="private_space_secondary_label" msgid="9203933341714508907">"सेट अप करने या खोलने के लिए टैप करें"</string>
     <string name="ps_container_title" msgid="4391796149519594205">"निजी"</string>
     <string name="ps_container_settings" msgid="6059734123353320479">"प्राइवेट स्पेस सेटिंग"</string>
     <string name="ps_container_lock_unlock_button" msgid="7605602332253423755">"प्राइवेट स्पेस को लॉक करें/अनलॉक करें"</string>
diff --git a/res/values-hr/strings.xml b/res/values-hr/strings.xml
index 89f95f0..e860ea9 100644
--- a/res/values-hr/strings.xml
+++ b/res/values-hr/strings.xml
@@ -33,6 +33,7 @@
     <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
     <string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"Taj par aplikacija nije podržan na ovom uređaju"</string>
     <string name="app_pair_needs_unfold" msgid="4588897528143807002">"Otvorite uređaj da biste upotrebljavali ovaj par aplikacija"</string>
+    <string name="app_pair_not_available" msgid="3556767440808032031">"Par aplikacija nije dostupan"</string>
     <string name="long_press_widget_to_add" msgid="3587712543577675817">"Dodirnite i zadržite da biste premjestili widget."</string>
     <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Dvaput dodirnite i zadržite pritisak da biste premjestili widget ili upotrijebite prilagođene radnje"</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -188,14 +189,13 @@
     <string name="developer_options_filter_hint" msgid="5896817443635989056">"Filtrirajte"</string>
     <string name="remote_action_failed" msgid="1383965239183576790">"Nije uspjelo: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
     <string name="private_space_label" msgid="2359721649407947001">"Privatni prostor"</string>
-    <!-- no translation found for private_space_secondary_label (9203933341714508907) -->
-    <skip />
+    <string name="private_space_secondary_label" msgid="9203933341714508907">"Dodirnite da biste postavili ili otvorili"</string>
     <string name="ps_container_title" msgid="4391796149519594205">"Privatno"</string>
     <string name="ps_container_settings" msgid="6059734123353320479">"Postavke privatnog prostora"</string>
     <string name="ps_container_lock_unlock_button" msgid="7605602332253423755">"Zaključavanje/otključavanje privatnog prostora"</string>
     <string name="ps_container_lock_title" msgid="2640257399982364682">"Zaključavanje"</string>
     <string name="ps_container_transition" msgid="8667331812048014412">"Prelazak na privatni prostor"</string>
-    <string name="ps_add_button_label" msgid="8611055839242385935">"Instaliranje aplikacija"</string>
+    <string name="ps_add_button_label" msgid="8611055839242385935">"Instalirajte aplikacije"</string>
     <string name="ps_add_button_content_description" msgid="3254274107740952556">"Instaliranje aplikacija u privatni prostor"</string>
     <string name="bubble_bar_overflow_description" msgid="7410995531938041192">"Dodatni izbornik"</string>
 </resources>
diff --git a/res/values-hu/strings.xml b/res/values-hu/strings.xml
index 626a79e..69031fe 100644
--- a/res/values-hu/strings.xml
+++ b/res/values-hu/strings.xml
@@ -33,6 +33,8 @@
     <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
     <string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"Ezt az alkalmazáspárt nem támogatja az eszköz"</string>
     <string name="app_pair_needs_unfold" msgid="4588897528143807002">"Hajtsa ki az eszközt az alkalmazáspár használatához"</string>
+    <!-- no translation found for app_pair_not_available (3556767440808032031) -->
+    <skip />
     <string name="long_press_widget_to_add" msgid="3587712543577675817">"Tartsa lenyomva a modult az áthelyezéshez."</string>
     <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Modul áthelyezéséhez koppintson duplán, tartsa nyomva az ujját, vagy használjon egyéni műveleteket."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -194,7 +196,7 @@
     <string name="ps_container_lock_unlock_button" msgid="7605602332253423755">"Privát terület zárolása/zárolásának feloldása"</string>
     <string name="ps_container_lock_title" msgid="2640257399982364682">"Zárolás"</string>
     <string name="ps_container_transition" msgid="8667331812048014412">"Átállás privát területre…"</string>
-    <string name="ps_add_button_label" msgid="8611055839242385935">"Alkalmazástelepítés"</string>
+    <string name="ps_add_button_label" msgid="8611055839242385935">"App telepítése"</string>
     <string name="ps_add_button_content_description" msgid="3254274107740952556">"Alkalmazások telepítése magánterületre"</string>
     <string name="bubble_bar_overflow_description" msgid="7410995531938041192">"Túlcsordulás"</string>
 </resources>
diff --git a/res/values-hy/strings.xml b/res/values-hy/strings.xml
index bdb473b..8d78f1c 100644
--- a/res/values-hy/strings.xml
+++ b/res/values-hy/strings.xml
@@ -33,6 +33,8 @@
     <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
     <string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"Հավելվածների զույգը չի աջակցվում այս սարքում"</string>
     <string name="app_pair_needs_unfold" msgid="4588897528143807002">"Բացեք սարքը՝ այս հավելվածների զույգն օգտագործելու համար"</string>
+    <!-- no translation found for app_pair_not_available (3556767440808032031) -->
+    <skip />
     <string name="long_press_widget_to_add" msgid="3587712543577675817">"Հպեք և պահեք՝ վիջեթ տեղափոխելու համար։"</string>
     <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Կրկնակի հպեք և պահեք՝ վիջեթ տեղափոխելու համար, կամ օգտվեք հատուկ գործողություններից։"</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -188,13 +190,12 @@
     <string name="developer_options_filter_hint" msgid="5896817443635989056">"Զտեք"</string>
     <string name="remote_action_failed" msgid="1383965239183576790">"Չհաջողվեց կատարել գործողությունը (<xliff:g id="WHAT">%1$s</xliff:g>)"</string>
     <string name="private_space_label" msgid="2359721649407947001">"Անձնական տարածք"</string>
-    <!-- no translation found for private_space_secondary_label (9203933341714508907) -->
-    <skip />
-    <string name="ps_container_title" msgid="4391796149519594205">"Անձնական"</string>
+    <string name="private_space_secondary_label" msgid="9203933341714508907">"Հպեք կարգավորելու կամ բացելու համար"</string>
+    <string name="ps_container_title" msgid="4391796149519594205">"Մասնավոր"</string>
     <string name="ps_container_settings" msgid="6059734123353320479">"Անձնական տարածքի կարգավորումներ"</string>
-    <string name="ps_container_lock_unlock_button" msgid="7605602332253423755">"Կողպել/ապակողպել անձնական տարածքը"</string>
+    <string name="ps_container_lock_unlock_button" msgid="7605602332253423755">"Կողպել/ապակողպել մասնավոր տարածքը"</string>
     <string name="ps_container_lock_title" msgid="2640257399982364682">"Կողպում"</string>
-    <string name="ps_container_transition" msgid="8667331812048014412">"Անցում անձնական տարածք"</string>
+    <string name="ps_container_transition" msgid="8667331812048014412">"Անցում մասնավոր տարածք"</string>
     <string name="ps_add_button_label" msgid="8611055839242385935">"Հավելվածների տեղադրում"</string>
     <string name="ps_add_button_content_description" msgid="3254274107740952556">"Հավելվածների տեղադրում անձնական տարածքում"</string>
     <string name="bubble_bar_overflow_description" msgid="7410995531938041192">"Լրացուցիչ ընտրացանկ"</string>
diff --git a/res/values-in/strings.xml b/res/values-in/strings.xml
index b80f233..092995c 100644
--- a/res/values-in/strings.xml
+++ b/res/values-in/strings.xml
@@ -32,7 +32,8 @@
     <string name="save_app_pair" msgid="5647523853662686243">"Simpan pasangan aplikasi"</string>
     <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
     <string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"Pasangan aplikasi ini tidak didukung di perangkat ini"</string>
-    <string name="app_pair_needs_unfold" msgid="4588897528143807002">"Buka perangkat untuk menggunakan pasangan aplikasi ini"</string>
+    <string name="app_pair_needs_unfold" msgid="4588897528143807002">"Bentangkan perangkat untuk menggunakan pasangan aplikasi ini"</string>
+    <string name="app_pair_not_available" msgid="3556767440808032031">"Pasangan aplikasi tidak tersedia"</string>
     <string name="long_press_widget_to_add" msgid="3587712543577675817">"Sentuh lama untuk memindahkan widget."</string>
     <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Ketuk dua kali &amp; tahan untuk memindahkan widget atau gunakan tindakan khusus."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -188,14 +189,13 @@
     <string name="developer_options_filter_hint" msgid="5896817443635989056">"Filter"</string>
     <string name="remote_action_failed" msgid="1383965239183576790">"Gagal: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
     <string name="private_space_label" msgid="2359721649407947001">"Ruang pribadi"</string>
-    <!-- no translation found for private_space_secondary_label (9203933341714508907) -->
-    <skip />
+    <string name="private_space_secondary_label" msgid="9203933341714508907">"Ketuk untuk menyiapkan atau membuka"</string>
     <string name="ps_container_title" msgid="4391796149519594205">"Pribadi"</string>
     <string name="ps_container_settings" msgid="6059734123353320479">"Setelan Ruang Pribadi"</string>
     <string name="ps_container_lock_unlock_button" msgid="7605602332253423755">"Kunci/Buka Kunci Ruang Pribadi"</string>
     <string name="ps_container_lock_title" msgid="2640257399982364682">"Kunci"</string>
     <string name="ps_container_transition" msgid="8667331812048014412">"Ruang Pribadi Bertransisi"</string>
-    <string name="ps_add_button_label" msgid="8611055839242385935">"Menginstal aplikasi"</string>
+    <string name="ps_add_button_label" msgid="8611055839242385935">"Instal aplikasi"</string>
     <string name="ps_add_button_content_description" msgid="3254274107740952556">"Instal aplikasi ke Ruang Pribadi"</string>
     <string name="bubble_bar_overflow_description" msgid="7410995531938041192">"Menu tambahan"</string>
 </resources>
diff --git a/res/values-is/strings.xml b/res/values-is/strings.xml
index 1287322..73a7d64 100644
--- a/res/values-is/strings.xml
+++ b/res/values-is/strings.xml
@@ -33,6 +33,7 @@
     <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
     <string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"Þetta forritapar er ekki stutt í þessu tæki"</string>
     <string name="app_pair_needs_unfold" msgid="4588897528143807002">"Opnaðu tæki til að nota þetta forritapar"</string>
+    <string name="app_pair_not_available" msgid="3556767440808032031">"Forritapar er ekki í boði"</string>
     <string name="long_press_widget_to_add" msgid="3587712543577675817">"Haltu fingri á græju til að færa hana."</string>
     <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Ýttu tvisvar og haltu fingri á græju til að færa hana eða notaðu sérsniðnar aðgerðir."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -188,14 +189,13 @@
     <string name="developer_options_filter_hint" msgid="5896817443635989056">"Sía"</string>
     <string name="remote_action_failed" msgid="1383965239183576790">"Mistókst: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
     <string name="private_space_label" msgid="2359721649407947001">"Einkarými"</string>
-    <!-- no translation found for private_space_secondary_label (9203933341714508907) -->
-    <skip />
+    <string name="private_space_secondary_label" msgid="9203933341714508907">"Ýttu til að setja upp eða opna"</string>
     <string name="ps_container_title" msgid="4391796149519594205">"Lokað"</string>
     <string name="ps_container_settings" msgid="6059734123353320479">"Stillingar einkarýmis"</string>
-    <string name="ps_container_lock_unlock_button" msgid="7605602332253423755">"Læsaeinkarými/taka einkarými úr lás"</string>
+    <string name="ps_container_lock_unlock_button" msgid="7605602332253423755">"Læsa leynirými/taka leynirými úr lás"</string>
     <string name="ps_container_lock_title" msgid="2640257399982364682">"Læsa"</string>
     <string name="ps_container_transition" msgid="8667331812048014412">"Einkarými að breytast"</string>
     <string name="ps_add_button_label" msgid="8611055839242385935">"Setja upp forrit"</string>
-    <string name="ps_add_button_content_description" msgid="3254274107740952556">"Setja upp forrit í einkarými"</string>
+    <string name="ps_add_button_content_description" msgid="3254274107740952556">"Setja upp forrit í leynirými"</string>
     <string name="bubble_bar_overflow_description" msgid="7410995531938041192">"Yfirflæði"</string>
 </resources>
diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml
index 4805748..8cffb25 100644
--- a/res/values-it/strings.xml
+++ b/res/values-it/strings.xml
@@ -33,6 +33,8 @@
     <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
     <string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"Questa coppia di app non è supportata su questo dispositivo"</string>
     <string name="app_pair_needs_unfold" msgid="4588897528143807002">"Apri il dispositivo per usare questa coppia di app"</string>
+    <!-- no translation found for app_pair_not_available (3556767440808032031) -->
+    <skip />
     <string name="long_press_widget_to_add" msgid="3587712543577675817">"Tocca e tieni premuto per spostare un widget."</string>
     <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Tocca due volte e tieni premuto per spostare un widget o per usare le azioni personalizzate."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -188,8 +190,7 @@
     <string name="developer_options_filter_hint" msgid="5896817443635989056">"Filtra"</string>
     <string name="remote_action_failed" msgid="1383965239183576790">"Operazione non riuscita: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
     <string name="private_space_label" msgid="2359721649407947001">"Spazio privato"</string>
-    <!-- no translation found for private_space_secondary_label (9203933341714508907) -->
-    <skip />
+    <string name="private_space_secondary_label" msgid="9203933341714508907">"Tocca per configurare o aprire"</string>
     <string name="ps_container_title" msgid="4391796149519594205">"Privato"</string>
     <string name="ps_container_settings" msgid="6059734123353320479">"Impostazioni dello Spazio privato"</string>
     <string name="ps_container_lock_unlock_button" msgid="7605602332253423755">"Blocca/sblocca Spazio privato"</string>
diff --git a/res/values-iw/strings.xml b/res/values-iw/strings.xml
index 2f10ef3..0d67af5 100644
--- a/res/values-iw/strings.xml
+++ b/res/values-iw/strings.xml
@@ -33,6 +33,8 @@
     <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
     <string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"צמד האפליקציות הזה לא נתמך במכשיר הזה"</string>
     <string name="app_pair_needs_unfold" msgid="4588897528143807002">"צריך לפתוח את המכשיר כדי להשתמש בצמד האפליקציות הזה"</string>
+    <!-- no translation found for app_pair_not_available (3556767440808032031) -->
+    <skip />
     <string name="long_press_widget_to_add" msgid="3587712543577675817">"להעברת ווידג\'ט למקום אחר לוחצים עליו לחיצה ארוכה."</string>
     <string name="long_accessible_way_to_add" msgid="2733588281439571974">"כדי להעביר ווידג\'ט למקום אחר או להשתמש בפעולות מותאמות אישית, יש ללחוץ פעמיים ולא להרפות."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -188,8 +190,7 @@
     <string name="developer_options_filter_hint" msgid="5896817443635989056">"סינון"</string>
     <string name="remote_action_failed" msgid="1383965239183576790">"הפעולה נכשלה: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
     <string name="private_space_label" msgid="2359721649407947001">"מרחב פרטי"</string>
-    <!-- no translation found for private_space_secondary_label (9203933341714508907) -->
-    <skip />
+    <string name="private_space_secondary_label" msgid="9203933341714508907">"אפשר להקיש כדי להגדיר או לפתוח"</string>
     <string name="ps_container_title" msgid="4391796149519594205">"פרטי"</string>
     <string name="ps_container_settings" msgid="6059734123353320479">"הגדרות המרחב הפרטי"</string>
     <string name="ps_container_lock_unlock_button" msgid="7605602332253423755">"נעילה או ביטול הנעילה של המרחב הפרטי"</string>
diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml
index 3112a55..50f5ddf 100644
--- a/res/values-ja/strings.xml
+++ b/res/values-ja/strings.xml
@@ -33,6 +33,8 @@
     <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
     <string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"このデバイスは、このアプリのペア設定に対応していません"</string>
     <string name="app_pair_needs_unfold" msgid="4588897528143807002">"このアプリのペア設定を使用するには、デバイスを開いてください"</string>
+    <!-- no translation found for app_pair_not_available (3556767440808032031) -->
+    <skip />
     <string name="long_press_widget_to_add" msgid="3587712543577675817">"長押ししてウィジェットを移動させます。"</string>
     <string name="long_accessible_way_to_add" msgid="2733588281439571974">"ウィジェットをダブルタップして長押ししながら移動するか、カスタム操作を使用してください。"</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$dx%2$d"</string>
@@ -128,7 +130,7 @@
     <string name="title_missing_notification_access" msgid="7503287056163941064">"通知へのアクセス権限が必要"</string>
     <string name="msg_missing_notification_access" msgid="281113995110910548">"通知ドットを表示するには、「<xliff:g id="NAME">%1$s</xliff:g>」のアプリ通知を ON にしてください"</string>
     <string name="title_change_settings" msgid="1376365968844349552">"設定を変更"</string>
-    <string name="notification_dots_service_title" msgid="4284221181793592871">"通知ドットの表示"</string>
+    <string name="notification_dots_service_title" msgid="4284221181793592871">"通知ドットを表示"</string>
     <string name="developer_options_title" msgid="700788437593726194">"開発者向けオプション"</string>
     <string name="auto_add_shortcuts_label" msgid="4926805029653694105">"ホーム画面にアプリのアイコンを追加"</string>
     <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"新しいアプリをダウンロードしたときに自動で追加します"</string>
@@ -188,8 +190,7 @@
     <string name="developer_options_filter_hint" msgid="5896817443635989056">"フィルタ"</string>
     <string name="remote_action_failed" msgid="1383965239183576790">"失敗: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
     <string name="private_space_label" msgid="2359721649407947001">"プライベート スペース"</string>
-    <!-- no translation found for private_space_secondary_label (9203933341714508907) -->
-    <skip />
+    <string name="private_space_secondary_label" msgid="9203933341714508907">"設定したり開いたりするにはタップしてください"</string>
     <string name="ps_container_title" msgid="4391796149519594205">"プライベート"</string>
     <string name="ps_container_settings" msgid="6059734123353320479">"プライベート スペースの設定"</string>
     <string name="ps_container_lock_unlock_button" msgid="7605602332253423755">"プライベート スペースをロック / ロック解除する"</string>
diff --git a/res/values-ka/strings.xml b/res/values-ka/strings.xml
index ea5c207..a3c3d87 100644
--- a/res/values-ka/strings.xml
+++ b/res/values-ka/strings.xml
@@ -33,6 +33,8 @@
     <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
     <string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"ამ მოწყობილობაზე აღნიშნული აპთა წყვილი არ არის მხარდაჭერილი"</string>
     <string name="app_pair_needs_unfold" msgid="4588897528143807002">"გაშალეთ მოწყობილობა ამ აპთა წყვილის გამოსაყენებლად"</string>
+    <!-- no translation found for app_pair_not_available (3556767440808032031) -->
+    <skip />
     <string name="long_press_widget_to_add" msgid="3587712543577675817">"შეხებით აირჩიეთ და გეჭიროთ ვიჯეტის გადასაადგილებლად."</string>
     <string name="long_accessible_way_to_add" msgid="2733588281439571974">"ორმაგი შეხებით აირჩიეთ და გეჭიროთ ვიჯეტის გადასაადგილებლად ან მორგებული მოქმედებების გამოსაყენებლად."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -188,8 +190,7 @@
     <string name="developer_options_filter_hint" msgid="5896817443635989056">"ფილტრი"</string>
     <string name="remote_action_failed" msgid="1383965239183576790">"ვერ მოხერხდა: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
     <string name="private_space_label" msgid="2359721649407947001">"პირადი სივრცე"</string>
-    <!-- no translation found for private_space_secondary_label (9203933341714508907) -->
-    <skip />
+    <string name="private_space_secondary_label" msgid="9203933341714508907">"დასაყენებლად ან გასახსნელად შეეხეთ"</string>
     <string name="ps_container_title" msgid="4391796149519594205">"პირადი"</string>
     <string name="ps_container_settings" msgid="6059734123353320479">"პირადი სივრცის პარამეტრები"</string>
     <string name="ps_container_lock_unlock_button" msgid="7605602332253423755">"პირადი სივრცის ჩაკეტვა/განბლოკვა"</string>
diff --git a/res/values-kk/strings.xml b/res/values-kk/strings.xml
index 56895cb..ff030e8 100644
--- a/res/values-kk/strings.xml
+++ b/res/values-kk/strings.xml
@@ -33,6 +33,8 @@
     <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
     <string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"Бұл құрылғы қолданбаларды жұптау функциясын қолдамайды."</string>
     <string name="app_pair_needs_unfold" msgid="4588897528143807002">"Қолданбаларды жұптау функциясын пайдалану үшін құрылғыны ашыңыз."</string>
+    <!-- no translation found for app_pair_not_available (3556767440808032031) -->
+    <skip />
     <string name="long_press_widget_to_add" msgid="3587712543577675817">"Виджетті жылжыту үшін басып тұрыңыз."</string>
     <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Виджетті жылжыту үшін екі рет түртіңіз де, ұстап тұрыңыз немесе арнаулы әрекеттерді пайдаланыңыз."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -188,8 +190,7 @@
     <string name="developer_options_filter_hint" msgid="5896817443635989056">"Сүзгі"</string>
     <string name="remote_action_failed" msgid="1383965239183576790">"Қате шықты: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
     <string name="private_space_label" msgid="2359721649407947001">"Жеке бөлме"</string>
-    <!-- no translation found for private_space_secondary_label (9203933341714508907) -->
-    <skip />
+    <string name="private_space_secondary_label" msgid="9203933341714508907">"Реттеу немесе ашу үшін түртіңіз"</string>
     <string name="ps_container_title" msgid="4391796149519594205">"Жеке"</string>
     <string name="ps_container_settings" msgid="6059734123353320479">"Жеке бөлме параметрлері"</string>
     <string name="ps_container_lock_unlock_button" msgid="7605602332253423755">"Жеке бөлмені құлыптау/оның құлпын ашу"</string>
diff --git a/res/values-km/strings.xml b/res/values-km/strings.xml
index f955b54..243f9f4 100644
--- a/res/values-km/strings.xml
+++ b/res/values-km/strings.xml
@@ -33,6 +33,7 @@
     <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
     <string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"មិនអាចប្រើគូកម្មវិធីនេះនៅលើឧបករណ៍នេះបានទេ"</string>
     <string name="app_pair_needs_unfold" msgid="4588897528143807002">"លាឧបករណ៍ ដើម្បីប្រើគូកម្មវិធីនេះ"</string>
+    <string name="app_pair_not_available" msgid="3556767440808032031">"មិនអាចប្រើគូកម្មវិធីបានទេ"</string>
     <string name="long_press_widget_to_add" msgid="3587712543577675817">"ចុចឱ្យជាប់​ដើម្បីផ្លាស់ទី​ធាតុក្រាហ្វិក​។"</string>
     <string name="long_accessible_way_to_add" msgid="2733588281439571974">"ចុចពីរដង រួចសង្កត់ឱ្យជាប់ ដើម្បីផ្លាស់ទី​ធាតុក្រាហ្វិក ឬប្រើ​សកម្មភាព​តាមបំណង​។"</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -188,8 +189,7 @@
     <string name="developer_options_filter_hint" msgid="5896817443635989056">"តម្រង"</string>
     <string name="remote_action_failed" msgid="1383965239183576790">"បានបរាជ័យ៖ <xliff:g id="WHAT">%1$s</xliff:g>"</string>
     <string name="private_space_label" msgid="2359721649407947001">"បន្ទប់​ឯកជន"</string>
-    <!-- no translation found for private_space_secondary_label (9203933341714508907) -->
-    <skip />
+    <string name="private_space_secondary_label" msgid="9203933341714508907">"ចុចដើម្បីរៀបចំ ឬបើក"</string>
     <string name="ps_container_title" msgid="4391796149519594205">"ឯកជន"</string>
     <string name="ps_container_settings" msgid="6059734123353320479">"ការកំណត់ Private Space"</string>
     <string name="ps_container_lock_unlock_button" msgid="7605602332253423755">"ចាក់សោ/ដោះសោ Private Space"</string>
diff --git a/res/values-kn/strings.xml b/res/values-kn/strings.xml
index 3fd334a..62864cb 100644
--- a/res/values-kn/strings.xml
+++ b/res/values-kn/strings.xml
@@ -33,6 +33,8 @@
     <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
     <string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"ಈ ಆ್ಯಪ್ ಜೋಡಿಯು ಈ ಸಾಧನದಲ್ಲಿ ಬೆಂಬಲಿತವಾಗಿಲ್ಲ"</string>
     <string name="app_pair_needs_unfold" msgid="4588897528143807002">"ಈ ಆ್ಯಪ್ ಜೋಡಿಯನ್ನು ಬಳಸಲು ಸಾಧನವನ್ನು ಅನ್‌ಫೋಲ್ಡ್ ಮಾಡಿ"</string>
+    <!-- no translation found for app_pair_not_available (3556767440808032031) -->
+    <skip />
     <string name="long_press_widget_to_add" msgid="3587712543577675817">"ವಿಜೆಟ್ ಸರಿಸಲು ಸ್ಪರ್ಶಿಸಿ ಮತ್ತು ಹಿಡಿದುಕೊಳ್ಳಿ."</string>
     <string name="long_accessible_way_to_add" msgid="2733588281439571974">"ವಿಜೆಟ್ ಸರಿಸಲು ಅಥವಾ ಕಸ್ಟಮ್ ಕ್ರಿಯೆಗಳನ್ನು ಬಳಸಲು ಡಬಲ್-ಟ್ಯಾಪ್ ಮಾಡಿ ಮತ್ತು ಹಿಡಿದುಕೊಳ್ಳಿ."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -188,8 +190,7 @@
     <string name="developer_options_filter_hint" msgid="5896817443635989056">"ಫಿಲ್ಟರ್‌"</string>
     <string name="remote_action_failed" msgid="1383965239183576790">"ವಿಫಲವಾಗಿದೆ: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
     <string name="private_space_label" msgid="2359721649407947001">"ಖಾಸಗಿ ಸ್ಪೇಸ್"</string>
-    <!-- no translation found for private_space_secondary_label (9203933341714508907) -->
-    <skip />
+    <string name="private_space_secondary_label" msgid="9203933341714508907">"ಸೆಟಪ್ ಮಾಡಲು ಅಥವಾ ತೆರೆಯಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
     <string name="ps_container_title" msgid="4391796149519594205">"ಖಾಸಗಿ"</string>
     <string name="ps_container_settings" msgid="6059734123353320479">"ಖಾಸಗಿ ಸ್ಪೇಸ್ ಸೆಟ್ಟಿಂಗ್‌ಗಳು"</string>
     <string name="ps_container_lock_unlock_button" msgid="7605602332253423755">"ಖಾಸಗಿ ಸ್ಪೇಸ್ ಅನ್ನು ಲಾಕ್/ಅನ್‌ಲಾಕ್ ಮಾಡಿ"</string>
diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml
index 4814ede..f97acf1 100644
--- a/res/values-ko/strings.xml
+++ b/res/values-ko/strings.xml
@@ -33,6 +33,8 @@
     <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
     <string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"이 앱 페어링은 이 기기에서 지원되지 않습니다"</string>
     <string name="app_pair_needs_unfold" msgid="4588897528143807002">"이 앱 페어링을 사용하려면 기기를 펼치세요"</string>
+    <!-- no translation found for app_pair_not_available (3556767440808032031) -->
+    <skip />
     <string name="long_press_widget_to_add" msgid="3587712543577675817">"길게 터치하여 위젯을 이동하세요."</string>
     <string name="long_accessible_way_to_add" msgid="2733588281439571974">"두 번 탭한 다음 길게 터치하여 위젯을 이동하거나 맞춤 작업을 사용하세요."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d×%2$d"</string>
@@ -188,8 +190,7 @@
     <string name="developer_options_filter_hint" msgid="5896817443635989056">"필터"</string>
     <string name="remote_action_failed" msgid="1383965239183576790">"실패: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
     <string name="private_space_label" msgid="2359721649407947001">"비공개 스페이스"</string>
-    <!-- no translation found for private_space_secondary_label (9203933341714508907) -->
-    <skip />
+    <string name="private_space_secondary_label" msgid="9203933341714508907">"탭하여 설정 또는 열기"</string>
     <string name="ps_container_title" msgid="4391796149519594205">"비공개"</string>
     <string name="ps_container_settings" msgid="6059734123353320479">"비공개 스페이스 설정"</string>
     <string name="ps_container_lock_unlock_button" msgid="7605602332253423755">"비공개 스페이스 잠금/잠금 해제"</string>
diff --git a/res/values-ky/strings.xml b/res/values-ky/strings.xml
index 8d59747..f908299 100644
--- a/res/values-ky/strings.xml
+++ b/res/values-ky/strings.xml
@@ -33,6 +33,7 @@
     <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
     <string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"Бул эки колдонмону бул түзмөктө бир маалда пайдаланууга болбойт"</string>
     <string name="app_pair_needs_unfold" msgid="4588897528143807002">"Бул эки колдонмону бир маалда пайдалануу үчүн түзмөктү ачыңыз"</string>
+    <string name="app_pair_not_available" msgid="3556767440808032031">"Эки колдонмону бир маалда пайдаланууга болбойт"</string>
     <string name="long_press_widget_to_add" msgid="3587712543577675817">"Виджетти кое бербей басып туруп жылдырыңыз."</string>
     <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Виджетти жылдыруу үчүн эки жолу таптап, кармап туруңуз же ыңгайлаштырылган аракеттерди колдонуңуз."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -187,11 +188,11 @@
     <string name="work_apps_enable_btn_text" msgid="1736198302467317371">"Улантуу"</string>
     <string name="developer_options_filter_hint" msgid="5896817443635989056">"Чыпкалоо"</string>
     <string name="remote_action_failed" msgid="1383965239183576790">"Аткарылган жок: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
-    <string name="private_space_label" msgid="2359721649407947001">"Жеке чөйрө"</string>
+    <string name="private_space_label" msgid="2359721649407947001">"Жеке мейкиндик"</string>
     <string name="private_space_secondary_label" msgid="9203933341714508907">"Тууралоо же ачуу үчүн таптап коюңуз"</string>
     <string name="ps_container_title" msgid="4391796149519594205">"Жеке"</string>
-    <string name="ps_container_settings" msgid="6059734123353320479">"Жеке чөйрөнүн параметрлери"</string>
-    <string name="ps_container_lock_unlock_button" msgid="7605602332253423755">"Жеке чөйрөнү кулпулоо/кулпусун ачуу"</string>
+    <string name="ps_container_settings" msgid="6059734123353320479">"Жеке мейкиндиктин параметрлери"</string>
+    <string name="ps_container_lock_unlock_button" msgid="7605602332253423755">"Жеке мейкиндикти кулпулоо/кулпусун ачуу"</string>
     <string name="ps_container_lock_title" msgid="2640257399982364682">"Кулпулоо"</string>
     <string name="ps_container_transition" msgid="8667331812048014412">"Жеке чөйрөгө өтүү"</string>
     <string name="ps_add_button_label" msgid="8611055839242385935">"Колдонмолорду орнотуу"</string>
diff --git a/res/values-lo/strings.xml b/res/values-lo/strings.xml
index 5c0d6a8..c215bc8 100644
--- a/res/values-lo/strings.xml
+++ b/res/values-lo/strings.xml
@@ -33,6 +33,7 @@
     <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
     <string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"ການຈັບຄູ່ແອັບນີ້ບໍ່ຮອງຮັບຢູ່ອຸປະກອນນີ້"</string>
     <string name="app_pair_needs_unfold" msgid="4588897528143807002">"ກາງອຸປະກອນອອກເພື່ອໃຊ້ການຈັບຄູ່ແອັບນີ້"</string>
+    <string name="app_pair_not_available" msgid="3556767440808032031">"ການຈັບຄູ່ແອັບບໍ່ມີໃຫ້"</string>
     <string name="long_press_widget_to_add" msgid="3587712543577675817">"ແຕະຄ້າງໄວ້ເພື່ອຍ້າຍວິດເຈັດ."</string>
     <string name="long_accessible_way_to_add" msgid="2733588281439571974">"ແຕະສອງເທື່ອຄ້າງໄວ້ເພື່ອຍ້າຍວິດເຈັດ ຫຼື ໃຊ້ຄຳສັ່ງກຳນົດເອງ."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -188,8 +189,7 @@
     <string name="developer_options_filter_hint" msgid="5896817443635989056">"ກັ່ນຕອງ"</string>
     <string name="remote_action_failed" msgid="1383965239183576790">"ບໍ່ສຳເລັດ: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
     <string name="private_space_label" msgid="2359721649407947001">"ພື້ນທີ່ສ່ວນຕົວ"</string>
-    <!-- no translation found for private_space_secondary_label (9203933341714508907) -->
-    <skip />
+    <string name="private_space_secondary_label" msgid="9203933341714508907">"ແຕະເພື່ອຕັ້ງຄ່າ ຫຼື ເປີດ"</string>
     <string name="ps_container_title" msgid="4391796149519594205">"ສ່ວນຕົວ"</string>
     <string name="ps_container_settings" msgid="6059734123353320479">"ການຕັ້ງຄ່າພື້ນທີ່ສ່ວນຕົວ"</string>
     <string name="ps_container_lock_unlock_button" msgid="7605602332253423755">"ລັອກ/ປົດລັອກພື້ນທີ່ສ່ວນຕົວ"</string>
diff --git a/res/values-lt/strings.xml b/res/values-lt/strings.xml
index abcbb25..1dcb559 100644
--- a/res/values-lt/strings.xml
+++ b/res/values-lt/strings.xml
@@ -33,6 +33,8 @@
     <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
     <string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"Ši programų pora šiame įrenginyje nepalaikoma"</string>
     <string name="app_pair_needs_unfold" msgid="4588897528143807002">"Atlenkite įrenginį, kad galėtumėte naudoti šią programų porą."</string>
+    <!-- no translation found for app_pair_not_available (3556767440808032031) -->
+    <skip />
     <string name="long_press_widget_to_add" msgid="3587712543577675817">"Dukart pal. ir palaik., kad perkeltumėte valdiklį."</string>
     <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Dukart palieskite ir palaikykite, kad perkeltumėte valdiklį ar naudotumėte tinkintus veiksmus."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -188,8 +190,7 @@
     <string name="developer_options_filter_hint" msgid="5896817443635989056">"Filtruoti"</string>
     <string name="remote_action_failed" msgid="1383965239183576790">"Nepavyko: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
     <string name="private_space_label" msgid="2359721649407947001">"Privati erdvė"</string>
-    <!-- no translation found for private_space_secondary_label (9203933341714508907) -->
-    <skip />
+    <string name="private_space_secondary_label" msgid="9203933341714508907">"Palieskite, kad nustatytumėte arba atidarytumėte"</string>
     <string name="ps_container_title" msgid="4391796149519594205">"Privatus"</string>
     <string name="ps_container_settings" msgid="6059734123353320479">"Privačios erdvės nustatymai"</string>
     <string name="ps_container_lock_unlock_button" msgid="7605602332253423755">"Užrakinti ir (arba) atrakinti privačią erdvę"</string>
diff --git a/res/values-lv/strings.xml b/res/values-lv/strings.xml
index b400b03..e2b1031 100644
--- a/res/values-lv/strings.xml
+++ b/res/values-lv/strings.xml
@@ -33,6 +33,8 @@
     <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
     <string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"Šis lietotņu pāris netiek atbalstīts šajā ierīcē"</string>
     <string name="app_pair_needs_unfold" msgid="4588897528143807002">"Atveriet ierīci, lai izmantotu šo lietotņu pāri"</string>
+    <!-- no translation found for app_pair_not_available (3556767440808032031) -->
+    <skip />
     <string name="long_press_widget_to_add" msgid="3587712543577675817">"Lai pārvietotu logrīku, pieskarieties un turiet."</string>
     <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Lai pārvietotu logrīku, uz tā veiciet dubultskārienu un turiet. Varat arī veikt pielāgotas darbības."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -188,8 +190,7 @@
     <string name="developer_options_filter_hint" msgid="5896817443635989056">"Filtrs"</string>
     <string name="remote_action_failed" msgid="1383965239183576790">"Neizdevās: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
     <string name="private_space_label" msgid="2359721649407947001">"Privātā telpa"</string>
-    <!-- no translation found for private_space_secondary_label (9203933341714508907) -->
-    <skip />
+    <string name="private_space_secondary_label" msgid="9203933341714508907">"Pieskarieties, lai iestatītu vai atvērtu"</string>
     <string name="ps_container_title" msgid="4391796149519594205">"Privātā mape"</string>
     <string name="ps_container_settings" msgid="6059734123353320479">"Privātās mapes iestatījumi"</string>
     <string name="ps_container_lock_unlock_button" msgid="7605602332253423755">"Bloķēt/atbloķēt privāto mapi"</string>
diff --git a/res/values-mk/strings.xml b/res/values-mk/strings.xml
index 6e09073..0accd7f 100644
--- a/res/values-mk/strings.xml
+++ b/res/values-mk/strings.xml
@@ -33,6 +33,8 @@
     <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
     <string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"Паров апликации не е поддржан на уредов"</string>
     <string name="app_pair_needs_unfold" msgid="4588897528143807002">"Отворете го уредот за да го користите паров апликации"</string>
+    <!-- no translation found for app_pair_not_available (3556767440808032031) -->
+    <skip />
     <string name="long_press_widget_to_add" msgid="3587712543577675817">"Допрете и задржете за да преместите виџет."</string>
     <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Допрете двапати и задржете за да преместите виџет или користете приспособени дејства."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -188,14 +190,13 @@
     <string name="developer_options_filter_hint" msgid="5896817443635989056">"Филтер"</string>
     <string name="remote_action_failed" msgid="1383965239183576790">"Не успеа: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
     <string name="private_space_label" msgid="2359721649407947001">"Приватен простор"</string>
-    <!-- no translation found for private_space_secondary_label (9203933341714508907) -->
-    <skip />
+    <string name="private_space_secondary_label" msgid="9203933341714508907">"Допрете за да поставите или отворите"</string>
     <string name="ps_container_title" msgid="4391796149519594205">"Приватен"</string>
     <string name="ps_container_settings" msgid="6059734123353320479">"Поставки за „Приватен простор“"</string>
     <string name="ps_container_lock_unlock_button" msgid="7605602332253423755">"Заклучување/отклучување на „Приватен простор“"</string>
     <string name="ps_container_lock_title" msgid="2640257399982364682">"Брава"</string>
     <string name="ps_container_transition" msgid="8667331812048014412">"Префрлање на „Приватен простор“"</string>
-    <string name="ps_add_button_label" msgid="8611055839242385935">"Инсталирање апликации"</string>
+    <string name="ps_add_button_label" msgid="8611055839242385935">"Инсталирајте апликации"</string>
     <string name="ps_add_button_content_description" msgid="3254274107740952556">"Инсталирање апликации во „Приватен простор“"</string>
     <string name="bubble_bar_overflow_description" msgid="7410995531938041192">"Проширено балонче"</string>
 </resources>
diff --git a/res/values-ml/strings.xml b/res/values-ml/strings.xml
index 26bd635..e3b6e6b 100644
--- a/res/values-ml/strings.xml
+++ b/res/values-ml/strings.xml
@@ -33,6 +33,7 @@
     <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
     <string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"ഈ ഉപകരണത്തിൽ ഈ ആപ്പ് ജോടിക്ക് പിന്തുണയില്ല"</string>
     <string name="app_pair_needs_unfold" msgid="4588897528143807002">"ഈ ആപ്പ് ജോടി ഉപയോഗിക്കാൻ ഉപകരണം അൺഫോൾഡ് ചെയ്യുക"</string>
+    <string name="app_pair_not_available" msgid="3556767440808032031">"ആപ്പ് ജോടി ലഭ്യമല്ല"</string>
     <string name="long_press_widget_to_add" msgid="3587712543577675817">"വിജറ്റ് നീക്കാൻ സ്‌പർശിച്ച് പിടിക്കുക."</string>
     <string name="long_accessible_way_to_add" msgid="2733588281439571974">"വിജറ്റ് നീക്കാൻ ഡബിൾ ടാപ്പ് ചെയ്യൂ, ഹോൾഡ് ചെയ്യൂ അല്ലെങ്കിൽ ഇഷ്‌ടാനുസൃത പ്രവർത്തനങ്ങൾ ഉപയോഗിക്കൂ."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -188,8 +189,7 @@
     <string name="developer_options_filter_hint" msgid="5896817443635989056">"ഫിൽട്ടർ ചെയ്യുക"</string>
     <string name="remote_action_failed" msgid="1383965239183576790">"പരാജയപ്പെട്ടു: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
     <string name="private_space_label" msgid="2359721649407947001">"സ്വകാര്യ സ്പേസ്"</string>
-    <!-- no translation found for private_space_secondary_label (9203933341714508907) -->
-    <skip />
+    <string name="private_space_secondary_label" msgid="9203933341714508907">"സജ്ജീകരിക്കാനോ തുറക്കാനോ ടാപ്പ് ചെയ്യുക"</string>
     <string name="ps_container_title" msgid="4391796149519594205">"സ്വകാര്യം"</string>
     <string name="ps_container_settings" msgid="6059734123353320479">"സ്വകാര്യ സ്‌പേസ് ക്രമീകരണം"</string>
     <string name="ps_container_lock_unlock_button" msgid="7605602332253423755">"സ്വകാര്യ സ്‌പേസ് ലോക്ക് ചെയ്യുക/അൺലോക്ക് ചെയ്യുക"</string>
diff --git a/res/values-mn/strings.xml b/res/values-mn/strings.xml
index 5e86120..cc4af0e 100644
--- a/res/values-mn/strings.xml
+++ b/res/values-mn/strings.xml
@@ -33,6 +33,8 @@
     <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
     <string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"Энэ апп хослуулалтыг уг төхөөрөмж дээр дэмждэггүй"</string>
     <string name="app_pair_needs_unfold" msgid="4588897528143807002">"Энэ апп хослуулалтыг ашиглахын тулд төхөөрөмжийг дэлгэнэ үү"</string>
+    <!-- no translation found for app_pair_not_available (3556767440808032031) -->
+    <skip />
     <string name="long_press_widget_to_add" msgid="3587712543577675817">"Виджетийг зөөх бол хүрээд, удаан дарна уу."</string>
     <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Виджетийг зөөх эсвэл захиалгат үйлдлийг ашиглахын тулд хоёр товшоод, удаан дарна уу."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -188,8 +190,7 @@
     <string name="developer_options_filter_hint" msgid="5896817443635989056">"Шүүлтүүр"</string>
     <string name="remote_action_failed" msgid="1383965239183576790">"Амжилтгүй болсон: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
     <string name="private_space_label" msgid="2359721649407947001">"Хувийн орон зай"</string>
-    <!-- no translation found for private_space_secondary_label (9203933341714508907) -->
-    <skip />
+    <string name="private_space_secondary_label" msgid="9203933341714508907">"Тохируулах эсвэл нээхийн тулд товших"</string>
     <string name="ps_container_title" msgid="4391796149519594205">"Хувийн"</string>
     <string name="ps_container_settings" msgid="6059734123353320479">"Private Space-н тохиргоо"</string>
     <string name="ps_container_lock_unlock_button" msgid="7605602332253423755">"Private Space-г түгжих/түгжээг тайлах"</string>
diff --git a/res/values-mr/strings.xml b/res/values-mr/strings.xml
index 9ec42c1..5eec969 100644
--- a/res/values-mr/strings.xml
+++ b/res/values-mr/strings.xml
@@ -33,6 +33,8 @@
     <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
     <string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"या ॲपची जोडीला या डिव्हाइसवर सपोर्ट नाही"</string>
     <string name="app_pair_needs_unfold" msgid="4588897528143807002">"ही ॲपची जोडी वापरण्यासाठी डिव्हाइस अनफोल्ड करा"</string>
+    <!-- no translation found for app_pair_not_available (3556767440808032031) -->
+    <skip />
     <string name="long_press_widget_to_add" msgid="3587712543577675817">"विजेट हलवण्यासाठी स्पर्श करा आणि धरून ठेवा."</string>
     <string name="long_accessible_way_to_add" msgid="2733588281439571974">"विजेट हलवण्यासाठी किंवा कस्टम कृती वापरण्यासाठी दोनदा टॅप करा आणि धरून ठेवा."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -188,8 +190,7 @@
     <string name="developer_options_filter_hint" msgid="5896817443635989056">"फिल्टर"</string>
     <string name="remote_action_failed" msgid="1383965239183576790">"हे करता आले नाही: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
     <string name="private_space_label" msgid="2359721649407947001">"खाजगी स्पेस"</string>
-    <!-- no translation found for private_space_secondary_label (9203933341714508907) -->
-    <skip />
+    <string name="private_space_secondary_label" msgid="9203933341714508907">"सेट करण्यासाठी किंवा उघडण्यासाठी टॅप करा"</string>
     <string name="ps_container_title" msgid="4391796149519594205">"खाजगी"</string>
     <string name="ps_container_settings" msgid="6059734123353320479">"खाजगी स्पेस ची सेटिंग्ज"</string>
     <string name="ps_container_lock_unlock_button" msgid="7605602332253423755">"खाजगी स्पेस लॉक/अनलॉक करा"</string>
diff --git a/res/values-ms/strings.xml b/res/values-ms/strings.xml
index 63f500a..68a9238 100644
--- a/res/values-ms/strings.xml
+++ b/res/values-ms/strings.xml
@@ -33,6 +33,7 @@
     <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
     <string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"Gandingan apl ini tidak disokong pada peranti ini"</string>
     <string name="app_pair_needs_unfold" msgid="4588897528143807002">"Buka lipatan peranti untuk menggunakan gandingan apl ini"</string>
+    <string name="app_pair_not_available" msgid="3556767440808032031">"Gandingan apl tidak tersedia"</string>
     <string name="long_press_widget_to_add" msgid="3587712543577675817">"Sentuh &amp; tahan untuk menggerakkan widget."</string>
     <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Ketik dua kali &amp; tahan untuk menggerakkan widget atau menggunakan tindakan tersuai."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -188,8 +189,7 @@
     <string name="developer_options_filter_hint" msgid="5896817443635989056">"Tapis"</string>
     <string name="remote_action_failed" msgid="1383965239183576790">"Gagal: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
     <string name="private_space_label" msgid="2359721649407947001">"Ruang privasi"</string>
-    <!-- no translation found for private_space_secondary_label (9203933341714508907) -->
-    <skip />
+    <string name="private_space_secondary_label" msgid="9203933341714508907">"Ketik untuk menyediakan atau membuka"</string>
     <string name="ps_container_title" msgid="4391796149519594205">"Peribadi"</string>
     <string name="ps_container_settings" msgid="6059734123353320479">"Tetapan Ruang Peribadi"</string>
     <string name="ps_container_lock_unlock_button" msgid="7605602332253423755">"Kunci/Buka kunci Ruang Peribadi"</string>
diff --git a/res/values-my/strings.xml b/res/values-my/strings.xml
index 93b61f8..6a06d0d 100644
--- a/res/values-my/strings.xml
+++ b/res/values-my/strings.xml
@@ -33,6 +33,8 @@
     <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
     <string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"ဤအက်ပ်တွဲချိတ်ခြင်းကို ဤစက်တွင် ပံ့ပိုးမထားပါ"</string>
     <string name="app_pair_needs_unfold" msgid="4588897528143807002">"ဤအက်ပ်တွဲချိတ်ခြင်းကို သုံးရန် စက်ကိုဖြန့်ပါ"</string>
+    <!-- no translation found for app_pair_not_available (3556767440808032031) -->
+    <skip />
     <string name="long_press_widget_to_add" msgid="3587712543577675817">"ဝိဂျက်ကို ရွှေ့ရန် တို့ပြီး ဖိထားပါ။"</string>
     <string name="long_accessible_way_to_add" msgid="2733588281439571974">"ဝိဂျက်ကို ရွှေ့ရန် (သို့) စိတ်ကြိုက်လုပ်ဆောင်ချက်များကို သုံးရန် နှစ်ချက်တို့ပြီး ဖိထားပါ။"</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -188,14 +190,13 @@
     <string name="developer_options_filter_hint" msgid="5896817443635989056">"စစ်ထုတ်ရန်"</string>
     <string name="remote_action_failed" msgid="1383965239183576790">"မအောင်မြင်ပါ− <xliff:g id="WHAT">%1$s</xliff:g>"</string>
     <string name="private_space_label" msgid="2359721649407947001">"သီးသန့်ချတ်ခန်း"</string>
-    <!-- no translation found for private_space_secondary_label (9203933341714508907) -->
-    <skip />
+    <string name="private_space_secondary_label" msgid="9203933341714508907">"စနစ်ထည့်သွင်းရန် (သို့) ဖွင့်ရန် တို့ပါ"</string>
     <string name="ps_container_title" msgid="4391796149519594205">"သီးသန့်"</string>
     <string name="ps_container_settings" msgid="6059734123353320479">"သီးသန့်ချတ်ခန်း ဆက်တင်များ"</string>
     <string name="ps_container_lock_unlock_button" msgid="7605602332253423755">"သီးသန့်ချတ်ခန်း လော့ခ်ချ/ဖွင့်ရန်"</string>
     <string name="ps_container_lock_title" msgid="2640257399982364682">"လော့ခ်ချခြင်း"</string>
     <string name="ps_container_transition" msgid="8667331812048014412">"သီးသန့်ချတ်ခန်း အပြောင်းအလဲ"</string>
-    <string name="ps_add_button_label" msgid="8611055839242385935">"အက်ပ်များ ထည့်သွင်းခြင်း"</string>
+    <string name="ps_add_button_label" msgid="8611055839242385935">"အက်ပ်ထည့်ခြင်း"</string>
     <string name="ps_add_button_content_description" msgid="3254274107740952556">"‘သီးသန့်နေရာ’ တွင် အက်ပ်များ ထည့်သွင်းနိုင်သည်"</string>
     <string name="bubble_bar_overflow_description" msgid="7410995531938041192">"မီနူးအပို"</string>
 </resources>
diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml
index 4a352f5..5a19b9b 100644
--- a/res/values-nb/strings.xml
+++ b/res/values-nb/strings.xml
@@ -33,6 +33,8 @@
     <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
     <string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"Denne apptilkoblingen støttes ikke på denne enheten"</string>
     <string name="app_pair_needs_unfold" msgid="4588897528143807002">"Åpne enheten for å bruke denne apptilkoblingen"</string>
+    <!-- no translation found for app_pair_not_available (3556767440808032031) -->
+    <skip />
     <string name="long_press_widget_to_add" msgid="3587712543577675817">"Trykk og hold for å flytte en modul."</string>
     <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Dobbelttrykk og hold inne for å flytte en modul eller bruke tilpassede handlinger."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -188,8 +190,7 @@
     <string name="developer_options_filter_hint" msgid="5896817443635989056">"Filter"</string>
     <string name="remote_action_failed" msgid="1383965239183576790">"Mislyktes: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
     <string name="private_space_label" msgid="2359721649407947001">"Privat område"</string>
-    <!-- no translation found for private_space_secondary_label (9203933341714508907) -->
-    <skip />
+    <string name="private_space_secondary_label" msgid="9203933341714508907">"Trykk for å konfigurere eller åpne"</string>
     <string name="ps_container_title" msgid="4391796149519594205">"Privat"</string>
     <string name="ps_container_settings" msgid="6059734123353320479">"Innstillinger for Private Space"</string>
     <string name="ps_container_lock_unlock_button" msgid="7605602332253423755">"Lås / lås opp Private Space"</string>
diff --git a/res/values-ne/strings.xml b/res/values-ne/strings.xml
index 0f5e1a5..8e06879 100644
--- a/res/values-ne/strings.xml
+++ b/res/values-ne/strings.xml
@@ -33,6 +33,7 @@
     <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
     <string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"यस डिभाइसमा यो एप पेयर प्रयोग गर्न मिल्दैन"</string>
     <string name="app_pair_needs_unfold" msgid="4588897528143807002">"यो एप पेयर प्रयोग गर्न डिभाइस अनफोल्ड गर्नुहोस्"</string>
+    <string name="app_pair_not_available" msgid="3556767440808032031">"एप पेयर उपलब्ध छैन"</string>
     <string name="long_press_widget_to_add" msgid="3587712543577675817">"कुनै विजेट सार्न डबल ट्याप गरेर छोइराख्नुहोस्।"</string>
     <string name="long_accessible_way_to_add" msgid="2733588281439571974">"कुनै विजेट सार्न वा आफ्नो रोजाइका कारबाही प्रयोग गर्न डबल ट्याप गरेर छोइराख्नुहोस्।"</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -83,25 +84,25 @@
     <string name="hotseat_out_of_space" msgid="7448809638125333693">"मन पर्ने ट्रे अब कुनै ठाँउ छैन"</string>
     <string name="all_apps_button_label" msgid="8130441508702294465">"एपको सूची"</string>
     <string name="all_apps_search_results" msgid="5889367432531296759">"खोज परिणामहरू"</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_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>
     <string name="install_private_system_shortcut_label" msgid="1616889277073184841">"निजी प्रोफाइलमा इन्स्टल गर्नुहोस्"</string>
     <string name="install_drop_target_label" msgid="2539096853673231757">"स्थापना गर्नुहोस्"</string>
-    <string name="dismiss_prediction_label" msgid="3357562989568808658">"एप सिफारिस नगरियोस्"</string>
+    <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="5136500343007704955">"होम स्क्रिनका सेटिङ र सर्टकटहरू रिड गरियोस्"</string>
+    <string name="permlab_read_settings" msgid="5136500343007704955">"होम स्क्रिनका सेटिङ र सर्टकटहरू रिड गर्नुहोस्"</string>
     <string name="permdesc_read_settings" msgid="4208061150510996676">"एपलाई होम स्क्रिनबाट सेटिङ र सर्टकटहरू रिड गर्ने अनुमति दिन्छ।"</string>
-    <string name="permlab_write_settings" msgid="4820028712156303762">"होम स्क्रिनका सेटिङ र सर्टकटहरू राइट गरियोस्"</string>
+    <string name="permlab_write_settings" msgid="4820028712156303762">"होम स्क्रिनका सेटिङ र सर्टकटहरू राइट गर्नुहोस्"</string>
     <string name="permdesc_write_settings" msgid="726859348127868466">"एपलाई होम स्क्रिनबाट सेटिङ र सर्टकट बदल्ने अनुमति दिन्छ"</string>
     <string name="gadget_error_text" msgid="740356548025791839">"विजेट लोड गर्न सकिएन"</string>
     <string name="gadget_setup_text" msgid="8348374825537681407">"विजेटका सेटिङ"</string>
     <string name="gadget_complete_setup_text" msgid="309040266978007925">"सेटअप पूरा गर्न ट्याप गर्नुहोस्"</string>
-    <string name="uninstall_system_app_text" msgid="4172046090762920660">"यो प्रणाली एप हो र यसलाई स्थापना रद्द गर्न सकिँदैन।"</string>
+    <string name="uninstall_system_app_text" msgid="4172046090762920660">"यो सिस्टम एप हो र यसलाई स्थापना रद्द गर्न सकिँदैन।"</string>
     <string name="folder_hint_text" msgid="5174843001373488816">"नाम सम्पादन गर्नुहोस्"</string>
     <string name="disabled_app_label" msgid="6673129024321402780">"असक्षम पारिएको <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
     <string name="dotted_app_label" msgid="1865617679843363410">"{count,plural, =1{{app_name} सँग सम्बन्धित # सूचना छ}other{{app_name} सँग सम्बन्धित # वटा सूचना छन्}}"</string>
@@ -130,7 +131,7 @@
     <string name="title_change_settings" msgid="1376365968844349552">"सेटिङहरू बदल्नुहोस्"</string>
     <string name="notification_dots_service_title" msgid="4284221181793592871">"नोटिफिकेसन डट देखाउनुहोस्"</string>
     <string name="developer_options_title" msgid="700788437593726194">"विकासकर्ताका लागि उपलब्ध विकल्पहरू"</string>
-    <string name="auto_add_shortcuts_label" msgid="4926805029653694105">"एपका आइकनहरू होम स्क्रिनमा राखियोस्"</string>
+    <string name="auto_add_shortcuts_label" msgid="4926805029653694105">"एपका आइकनहरू होम स्क्रिनमा राख्नुहोस्"</string>
     <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"नयाँ एपका लागि"</string>
     <string name="package_state_unknown" msgid="7592128424511031410">"अज्ञात"</string>
     <string name="abandoned_clean_this" msgid="7610119707847920412">"हटाउनुहोस्"</string>
@@ -188,8 +189,7 @@
     <string name="developer_options_filter_hint" msgid="5896817443635989056">"फिल्टर"</string>
     <string name="remote_action_failed" msgid="1383965239183576790">"कार्य पूरा गर्न सकिएन: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
     <string name="private_space_label" msgid="2359721649407947001">"निजी स्पेस"</string>
-    <!-- no translation found for private_space_secondary_label (9203933341714508907) -->
-    <skip />
+    <string name="private_space_secondary_label" msgid="9203933341714508907">"सेटअप गर्न वा खोल्न ट्याप गर्नुहोस्"</string>
     <string name="ps_container_title" msgid="4391796149519594205">"निजी"</string>
     <string name="ps_container_settings" msgid="6059734123353320479">"निजी स्पेससम्बन्धी सेटिङ"</string>
     <string name="ps_container_lock_unlock_button" msgid="7605602332253423755">"निजी स्पेस लक/अनलक गर्नुहोस्"</string>
diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml
index ace1d8e..d64e6c3 100644
--- a/res/values-nl/strings.xml
+++ b/res/values-nl/strings.xml
@@ -33,6 +33,8 @@
     <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
     <string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"Dit app-paar wordt niet ondersteund op dit apparaat"</string>
     <string name="app_pair_needs_unfold" msgid="4588897528143807002">"Vouw het apparaat open om dit app-paar te gebruiken"</string>
+    <!-- no translation found for app_pair_not_available (3556767440808032031) -->
+    <skip />
     <string name="long_press_widget_to_add" msgid="3587712543577675817">"Tik en houd vast om een widget te verplaatsen."</string>
     <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Dubbeltik en houd vast om een widget te verplaatsen of aangepaste acties te gebruiken."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -177,7 +179,7 @@
     <string name="work_profile_toggle_label" msgid="3081029915775481146">"Werkprofiel"</string>
     <string name="work_profile_edu_work_apps" msgid="7895468576497746520">"Werk-apps hebben badges en zijn zichtbaar voor je IT-beheerder"</string>
     <string name="work_profile_edu_accept" msgid="6069788082535149071">"OK"</string>
-    <string name="work_apps_paused_title" msgid="3040901117349444598">"Werk-apps zijn onderbroken"</string>
+    <string name="work_apps_paused_title" msgid="3040901117349444598">"Werk-apps zijn gepauzeerd"</string>
     <string name="work_apps_paused_info_body" msgid="1687828929959237477">"Je krijgt geen meldingen van je werk-apps"</string>
     <string name="work_apps_paused_body" msgid="261634750995824906">"Je werk-apps kunnen je geen meldingen sturen, je batterij niet gebruiken en geen toegang krijgen tot je locatie"</string>
     <string name="work_apps_paused_telephony_unavailable_body" msgid="8358872357502756790">"Je krijgt geen telefoongesprekken, tekstberichten of meldingen van je werk-apps"</string>
@@ -188,8 +190,7 @@
     <string name="developer_options_filter_hint" msgid="5896817443635989056">"Filteren"</string>
     <string name="remote_action_failed" msgid="1383965239183576790">"Mislukt: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
     <string name="private_space_label" msgid="2359721649407947001">"Privéruimte"</string>
-    <!-- no translation found for private_space_secondary_label (9203933341714508907) -->
-    <skip />
+    <string name="private_space_secondary_label" msgid="9203933341714508907">"Tik om in te stellen of te openen"</string>
     <string name="ps_container_title" msgid="4391796149519594205">"Privé"</string>
     <string name="ps_container_settings" msgid="6059734123353320479">"Instellingen voor privéruimte"</string>
     <string name="ps_container_lock_unlock_button" msgid="7605602332253423755">"Privéruimte vergrendelen/ontgrendelen"</string>
diff --git a/res/values-or/strings.xml b/res/values-or/strings.xml
index 2c03967..9cecf07 100644
--- a/res/values-or/strings.xml
+++ b/res/values-or/strings.xml
@@ -33,6 +33,7 @@
     <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
     <string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"ଏହି ଆପ ପେୟାର ଏ ଡିଭାଇସରେ ସମର୍ଥିତ ନୁହେଁ"</string>
     <string name="app_pair_needs_unfold" msgid="4588897528143807002">"ଏହି ଆପ ପେୟାରକୁ ବ୍ୟବହାର କରିବା ପାଇଁ ଡିଭାଇସକୁ ଅନଫୋଲ୍ଡ କରନ୍ତୁ"</string>
+    <string name="app_pair_not_available" msgid="3556767440808032031">"ଆପ ପେୟାର ଉପଲବ୍ଧ ନାହିଁ"</string>
     <string name="long_press_widget_to_add" msgid="3587712543577675817">"ଏକ ୱିଜେଟକୁ ମୁଭ୍ କରିବା ପାଇଁ ସ୍ପର୍ଶ କରି ଧରି ରଖନ୍ତୁ।"</string>
     <string name="long_accessible_way_to_add" msgid="2733588281439571974">"ଏକ ୱିଜେଟକୁ ମୁଭ୍ କରିବା ପାଇଁ ଦୁଇଥର-ଟାପ୍ କରି ଧରି ରଖନ୍ତୁ କିମ୍ବା କଷ୍ଟମ୍ କାର୍ଯ୍ୟଗୁଡ଼ିକୁ ବ୍ୟବହାର କରନ୍ତୁ।"</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -188,8 +189,7 @@
     <string name="developer_options_filter_hint" msgid="5896817443635989056">"ଫିଲ୍ଟର୍"</string>
     <string name="remote_action_failed" msgid="1383965239183576790">"ବିଫଳ ହୋଇଛି: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
     <string name="private_space_label" msgid="2359721649407947001">"ପ୍ରାଇଭେଟ ସ୍ପେସ"</string>
-    <!-- no translation found for private_space_secondary_label (9203933341714508907) -->
-    <skip />
+    <string name="private_space_secondary_label" msgid="9203933341714508907">"ସେଟ ଅପ କରିବା କିମ୍ବା ଖୋଲିବାକୁ ଟାପ କରନ୍ତୁ"</string>
     <string name="ps_container_title" msgid="4391796149519594205">"ପ୍ରାଇଭେଟ"</string>
     <string name="ps_container_settings" msgid="6059734123353320479">"ପ୍ରାଇଭେଟ ସ୍ପେସ ସେଟିଂସ"</string>
     <string name="ps_container_lock_unlock_button" msgid="7605602332253423755">"ପ୍ରାଇଭେଟ ସ୍ପେସକୁ ଲକ/ଅନଲକ କରନ୍ତୁ"</string>
diff --git a/res/values-pa/strings.xml b/res/values-pa/strings.xml
index 321d6c0..17f16f1 100644
--- a/res/values-pa/strings.xml
+++ b/res/values-pa/strings.xml
@@ -33,6 +33,8 @@
     <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
     <string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"ਇਸ ਐਪ ਜੋੜਾਬੱਧ ਦਾ ਇਸ ਡੀਵਾਈਸ \'ਤੇ ਸਮਰਥਨ ਨਹੀਂ ਕੀਤਾ ਜਾਂਦਾ"</string>
     <string name="app_pair_needs_unfold" msgid="4588897528143807002">"ਇਸ ਐਪ ਜੋੜਾਬੱਧ ਨੂੰ ਵਰਤਣ ਲਈ ਡੀਵਾਈਸ ਨੂੰ ਅਣਫੋਲਡ ਕਰੋ"</string>
+    <!-- no translation found for app_pair_not_available (3556767440808032031) -->
+    <skip />
     <string name="long_press_widget_to_add" msgid="3587712543577675817">"ਕਿਸੇ ਵਿਜੇਟ ਨੂੰ ਲਿਜਾਉਣ ਲਈ ਸਪਰਸ਼ ਕਰਕੇ ਰੱਖੋ।"</string>
     <string name="long_accessible_way_to_add" msgid="2733588281439571974">"ਵਿਜੇਟ ਲਿਜਾਉਣ ਲਈ ਜਾਂ ਵਿਉਂਂਤੀਆਂ ਕਾਰਵਾਈਆਂ ਵਰਤਣ ਲਈ ਦੋ ਵਾਰ ਟੈਪ ਕਰਕੇ ਦਬਾ ਕੇ ਰੱਖੋ।"</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -188,8 +190,7 @@
     <string name="developer_options_filter_hint" msgid="5896817443635989056">"ਫਿਲਟਰ"</string>
     <string name="remote_action_failed" msgid="1383965239183576790">"ਇਹ ਕਾਰਵਾਈ ਅਸਫਲ ਹੋਈ: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
     <string name="private_space_label" msgid="2359721649407947001">"ਨਿੱਜੀ ਸਪੇਸ"</string>
-    <!-- no translation found for private_space_secondary_label (9203933341714508907) -->
-    <skip />
+    <string name="private_space_secondary_label" msgid="9203933341714508907">"ਸੈੱਟਅੱਪ ਕਰਨ ਜਾਂ ਖੋਲ੍ਹਣ ਲਈ ਟੈਪ ਕਰੋ"</string>
     <string name="ps_container_title" msgid="4391796149519594205">"ਨਿੱਜੀ"</string>
     <string name="ps_container_settings" msgid="6059734123353320479">"ਨਿੱਜੀ ਸਪੇਸ ਸੰਬੰਧੀ ਸੈਟਿੰਗਾਂ"</string>
     <string name="ps_container_lock_unlock_button" msgid="7605602332253423755">"ਨਿੱਜੀ ਸਪੇਸ ਨੂੰ ਲਾਕ/ਅਣਲਾਕ ਕਰੋ"</string>
diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml
index 7cc4f1f..18642d7 100644
--- a/res/values-pl/strings.xml
+++ b/res/values-pl/strings.xml
@@ -33,6 +33,7 @@
     <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
     <string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"Ta para aplikacji nie jest obsługiwana na tym urządzeniu"</string>
     <string name="app_pair_needs_unfold" msgid="4588897528143807002">"Otwórz urządzenie, aby użyć tej pary aplikacji"</string>
+    <string name="app_pair_not_available" msgid="3556767440808032031">"Para aplikacji jest niedostępna"</string>
     <string name="long_press_widget_to_add" msgid="3587712543577675817">"Naciśnij i przytrzymaj, aby przenieść widżet."</string>
     <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Naciśnij dwukrotnie i przytrzymaj, aby przenieść widżet lub użyć działań niestandardowych."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -128,7 +129,7 @@
     <string name="title_missing_notification_access" msgid="7503287056163941064">"Wymagany jest dostęp do powiadomień"</string>
     <string name="msg_missing_notification_access" msgid="281113995110910548">"Aby pokazywać kropki powiadomień, włącz powiadomienia aplikacji <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="title_change_settings" msgid="1376365968844349552">"Zmień ustawienia"</string>
-    <string name="notification_dots_service_title" msgid="4284221181793592871">"Pokaż kropki powiadomień"</string>
+    <string name="notification_dots_service_title" msgid="4284221181793592871">"Pokazuj kropki powiadomień"</string>
     <string name="developer_options_title" msgid="700788437593726194">"Opcje programisty"</string>
     <string name="auto_add_shortcuts_label" msgid="4926805029653694105">"Dodawaj ikony aplikacji do ekranu głównego"</string>
     <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"W przypadku nowych aplikacji"</string>
@@ -188,14 +189,13 @@
     <string name="developer_options_filter_hint" msgid="5896817443635989056">"Filtruj"</string>
     <string name="remote_action_failed" msgid="1383965239183576790">"Niepowodzenie: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
     <string name="private_space_label" msgid="2359721649407947001">"Obszar prywatny"</string>
-    <!-- no translation found for private_space_secondary_label (9203933341714508907) -->
-    <skip />
+    <string name="private_space_secondary_label" msgid="9203933341714508907">"Kliknij, aby skonfigurować lub otworzyć"</string>
     <string name="ps_container_title" msgid="4391796149519594205">"Prywatne"</string>
     <string name="ps_container_settings" msgid="6059734123353320479">"Ustawienia obszaru prywatnego"</string>
     <string name="ps_container_lock_unlock_button" msgid="7605602332253423755">"Zablokuj/odblokuj obszar prywatny"</string>
     <string name="ps_container_lock_title" msgid="2640257399982364682">"Zablokuj"</string>
     <string name="ps_container_transition" msgid="8667331812048014412">"Przenoszenie obszaru prywatnego"</string>
-    <string name="ps_add_button_label" msgid="8611055839242385935">"Instalowanie aplikacji"</string>
+    <string name="ps_add_button_label" msgid="8611055839242385935">"Instaluj aplikacje"</string>
     <string name="ps_add_button_content_description" msgid="3254274107740952556">"Zainstaluj aplikacje w przestrzeni prywatnej"</string>
     <string name="bubble_bar_overflow_description" msgid="7410995531938041192">"Rozwiń menu"</string>
 </resources>
diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml
index 25a6562..fc70150 100644
--- a/res/values-pt-rPT/strings.xml
+++ b/res/values-pt-rPT/strings.xml
@@ -33,6 +33,7 @@
     <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
     <string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"Este par de apps não é suportado neste dispositivo"</string>
     <string name="app_pair_needs_unfold" msgid="4588897528143807002">"Abra o dispositivo para usar este par de apps"</string>
+    <string name="app_pair_not_available" msgid="3556767440808032031">"O par de apps não está disponível"</string>
     <string name="long_press_widget_to_add" msgid="3587712543577675817">"Toque sem soltar para mover um widget."</string>
     <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Toque duas vezes sem soltar para mover um widget ou utilizar ações personalizadas."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -192,7 +193,7 @@
     <string name="ps_container_title" msgid="4391796149519594205">"Privado"</string>
     <string name="ps_container_settings" msgid="6059734123353320479">"Definições do espaço privado"</string>
     <string name="ps_container_lock_unlock_button" msgid="7605602332253423755">"Bloquear/desbloquear espaço privado"</string>
-    <string name="ps_container_lock_title" msgid="2640257399982364682">"Fechadura"</string>
+    <string name="ps_container_lock_title" msgid="2640257399982364682">"Bloquear"</string>
     <string name="ps_container_transition" msgid="8667331812048014412">"Transição do espaço privado"</string>
     <string name="ps_add_button_label" msgid="8611055839242385935">"Instalar apps"</string>
     <string name="ps_add_button_content_description" msgid="3254274107740952556">"Instale apps no espaço privado"</string>
diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml
index 07fe3db..0391efe 100644
--- a/res/values-pt/strings.xml
+++ b/res/values-pt/strings.xml
@@ -33,6 +33,8 @@
     <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
     <string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"Este Par de apps não está disponível no dispositivo"</string>
     <string name="app_pair_needs_unfold" msgid="4588897528143807002">"Abra o dispositivo para usar este Par de apps"</string>
+    <!-- no translation found for app_pair_not_available (3556767440808032031) -->
+    <skip />
     <string name="long_press_widget_to_add" msgid="3587712543577675817">"Toque e pressione para mover um widget."</string>
     <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Toque duas vezes e mantenha a tela pressionada para mover um widget ou usar ações personalizadas."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -188,8 +190,7 @@
     <string name="developer_options_filter_hint" msgid="5896817443635989056">"Filtrar"</string>
     <string name="remote_action_failed" msgid="1383965239183576790">"Falha: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
     <string name="private_space_label" msgid="2359721649407947001">"Espaço particular"</string>
-    <!-- no translation found for private_space_secondary_label (9203933341714508907) -->
-    <skip />
+    <string name="private_space_secondary_label" msgid="9203933341714508907">"Toque para configurar ou abrir"</string>
     <string name="ps_container_title" msgid="4391796149519594205">"Particular"</string>
     <string name="ps_container_settings" msgid="6059734123353320479">"Configurações do Espaço particular"</string>
     <string name="ps_container_lock_unlock_button" msgid="7605602332253423755">"Bloquear/desbloquear o Espaço particular"</string>
diff --git a/res/values-ro/strings.xml b/res/values-ro/strings.xml
index 30b2ea6..07f3cf4 100644
--- a/res/values-ro/strings.xml
+++ b/res/values-ro/strings.xml
@@ -33,6 +33,8 @@
     <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
     <string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"Perechea de aplicații nu este acceptată pe acest dispozitiv"</string>
     <string name="app_pair_needs_unfold" msgid="4588897528143807002">"Deschide dispozitivul ca să folosești această pereche de aplicații"</string>
+    <!-- no translation found for app_pair_not_available (3556767440808032031) -->
+    <skip />
     <string name="long_press_widget_to_add" msgid="3587712543577675817">"Atinge și ține apăsat pentru a muta un widget."</string>
     <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Atinge de două ori și ține apăsat pentru a muta un widget sau folosește acțiuni personalizate."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -188,8 +190,7 @@
     <string name="developer_options_filter_hint" msgid="5896817443635989056">"Filtru"</string>
     <string name="remote_action_failed" msgid="1383965239183576790">"Eșuare: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
     <string name="private_space_label" msgid="2359721649407947001">"Spațiu privat"</string>
-    <!-- no translation found for private_space_secondary_label (9203933341714508907) -->
-    <skip />
+    <string name="private_space_secondary_label" msgid="9203933341714508907">"Atinge pentru a configura sau a deschide"</string>
     <string name="ps_container_title" msgid="4391796149519594205">"Privat"</string>
     <string name="ps_container_settings" msgid="6059734123353320479">"Setări spațiu privat"</string>
     <string name="ps_container_lock_unlock_button" msgid="7605602332253423755">"Blochează / deblochează spațiul privat"</string>
diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml
index a96e2e1..ee1caef 100644
--- a/res/values-ru/strings.xml
+++ b/res/values-ru/strings.xml
@@ -33,6 +33,7 @@
     <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
     <string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"Одновременно использовать эти два приложения на устройстве нельзя."</string>
     <string name="app_pair_needs_unfold" msgid="4588897528143807002">"Чтобы одновременно использовать эти два приложения, разложите устройство."</string>
+    <string name="app_pair_not_available" msgid="3556767440808032031">"Одновременное использование двух приложений недоступно"</string>
     <string name="long_press_widget_to_add" msgid="3587712543577675817">"Чтобы переместить виджет, нажмите на него и удерживайте"</string>
     <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Чтобы использовать специальные действия или перенести виджет, нажмите на него дважды и удерживайте."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d x %2$d"</string>
@@ -188,8 +189,7 @@
     <string name="developer_options_filter_hint" msgid="5896817443635989056">"Фильтр"</string>
     <string name="remote_action_failed" msgid="1383965239183576790">"Не удалось выполнить действие (<xliff:g id="WHAT">%1$s</xliff:g>)."</string>
     <string name="private_space_label" msgid="2359721649407947001">"Личное пространство"</string>
-    <!-- no translation found for private_space_secondary_label (9203933341714508907) -->
-    <skip />
+    <string name="private_space_secondary_label" msgid="9203933341714508907">"Нажмите, чтобы настроить или открыть"</string>
     <string name="ps_container_title" msgid="4391796149519594205">"Доступно только вам"</string>
     <string name="ps_container_settings" msgid="6059734123353320479">"Настройки личного пространства"</string>
     <string name="ps_container_lock_unlock_button" msgid="7605602332253423755">"Блокировка и разблокировка личного пространства"</string>
diff --git a/res/values-si/strings.xml b/res/values-si/strings.xml
index 53aee23..25cc880 100644
--- a/res/values-si/strings.xml
+++ b/res/values-si/strings.xml
@@ -33,6 +33,8 @@
     <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
     <string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"මෙම යෙදුම් යුගලය මෙම උපාංගයෙහි සහාය නොදක්වයි"</string>
     <string name="app_pair_needs_unfold" msgid="4588897528143807002">"මෙම යෙදුම් යුගලය භාවිතා කිරීමට උපාංගය දිගහරින්න"</string>
+    <!-- no translation found for app_pair_not_available (3556767440808032031) -->
+    <skip />
     <string name="long_press_widget_to_add" msgid="3587712543577675817">"විජට් එකක් ගෙන යාමට ස්පර්ශ කර අල්ලා ගෙන සිටින්න."</string>
     <string name="long_accessible_way_to_add" msgid="2733588281439571974">"විජට් එකක් ගෙන යාමට හෝ අභිරුචි ක්‍රියා භාවිත කිරීමට දෙවරක් තට්ටු කර අල්ලා ගෙන සිටින්න."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -188,8 +190,7 @@
     <string name="developer_options_filter_hint" msgid="5896817443635989056">"පෙරහන"</string>
     <string name="remote_action_failed" msgid="1383965239183576790">"අසාර්ථකයි: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
     <string name="private_space_label" msgid="2359721649407947001">"පෞද්ගලික ඉඩ"</string>
-    <!-- no translation found for private_space_secondary_label (9203933341714508907) -->
-    <skip />
+    <string name="private_space_secondary_label" msgid="9203933341714508907">"පිහිටුවීමට හෝ විවෘත කිරීමට තට්ටු කරන්න"</string>
     <string name="ps_container_title" msgid="4391796149519594205">"පෞද්ගලික"</string>
     <string name="ps_container_settings" msgid="6059734123353320479">"පෞද්ගලික අවකාශ සැකසීම්"</string>
     <string name="ps_container_lock_unlock_button" msgid="7605602332253423755">"පෞද්ගලික අවකාශය අගුළු දමන්න/අගුළු හරින්න"</string>
diff --git a/res/values-sk/strings.xml b/res/values-sk/strings.xml
index e058442..cf87cf8 100644
--- a/res/values-sk/strings.xml
+++ b/res/values-sk/strings.xml
@@ -33,6 +33,7 @@
     <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
     <string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"Tento pár aplikácií nie je v tomto zariadení podporovaný"</string>
     <string name="app_pair_needs_unfold" msgid="4588897528143807002">"Ak chcete používať tento pár aplikácií, rozložte zariadenie"</string>
+    <string name="app_pair_not_available" msgid="3556767440808032031">"Pár aplikácií nie je k dispozícii"</string>
     <string name="long_press_widget_to_add" msgid="3587712543577675817">"Pridržaním presuňte miniaplikáciu."</string>
     <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Dvojitým klepnutím a pridržaním presuňte miniaplikáciu alebo použite vlastné akcie."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -188,12 +189,11 @@
     <string name="developer_options_filter_hint" msgid="5896817443635989056">"Filtrujte"</string>
     <string name="remote_action_failed" msgid="1383965239183576790">"Zlyhalo: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
     <string name="private_space_label" msgid="2359721649407947001">"Súkromný priestor"</string>
-    <!-- no translation found for private_space_secondary_label (9203933341714508907) -->
-    <skip />
+    <string name="private_space_secondary_label" msgid="9203933341714508907">"Klepnutím nastavte alebo otvorte"</string>
     <string name="ps_container_title" msgid="4391796149519594205">"Súkromné"</string>
     <string name="ps_container_settings" msgid="6059734123353320479">"Nastavenia súkromného priestoru"</string>
     <string name="ps_container_lock_unlock_button" msgid="7605602332253423755">"Súkromný priestor zamykania a odomykania"</string>
-    <string name="ps_container_lock_title" msgid="2640257399982364682">"Uzamknutie"</string>
+    <string name="ps_container_lock_title" msgid="2640257399982364682">"Uzamknúť"</string>
     <string name="ps_container_transition" msgid="8667331812048014412">"Prechod súkromného priestoru"</string>
     <string name="ps_add_button_label" msgid="8611055839242385935">"Inštalovať aplikácie"</string>
     <string name="ps_add_button_content_description" msgid="3254274107740952556">"Inštalácia aplikácií v súkromnom priestore"</string>
diff --git a/res/values-sl/strings.xml b/res/values-sl/strings.xml
index 8b67004..8693ea2 100644
--- a/res/values-sl/strings.xml
+++ b/res/values-sl/strings.xml
@@ -33,6 +33,7 @@
     <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
     <string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"Ta par aplikacij ni podprt v tej napravi"</string>
     <string name="app_pair_needs_unfold" msgid="4588897528143807002">"Razprite napravo, če želite uporabljati ta par aplikacij"</string>
+    <string name="app_pair_not_available" msgid="3556767440808032031">"Par aplikacij ni na voljo"</string>
     <string name="long_press_widget_to_add" msgid="3587712543577675817">"Pridržite pripomoček, da ga premaknete."</string>
     <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Dvakrat se dotaknite pripomočka in ga pridržite, da ga premaknete, ali pa uporabite dejanja po meri."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
diff --git a/res/values-sq/strings.xml b/res/values-sq/strings.xml
index 062a5e1..7643c4a 100644
--- a/res/values-sq/strings.xml
+++ b/res/values-sq/strings.xml
@@ -33,6 +33,8 @@
     <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
     <string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"Ky çift aplikacionesh nuk mbështetet në këtë pajisje"</string>
     <string name="app_pair_needs_unfold" msgid="4588897528143807002">"Shpalose pajisjen për të përdorur këtë çift aplikacionesh"</string>
+    <!-- no translation found for app_pair_not_available (3556767440808032031) -->
+    <skip />
     <string name="long_press_widget_to_add" msgid="3587712543577675817">"Prek dhe mbaj shtypur një miniaplikacion për ta zhvendosur."</string>
     <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Trokit dy herë dhe mbaje shtypur një miniapliikacion për ta zhvendosur atë ose për të përdorur veprimet e personalizuara."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -188,8 +190,7 @@
     <string name="developer_options_filter_hint" msgid="5896817443635989056">"Filtro"</string>
     <string name="remote_action_failed" msgid="1383965239183576790">"Dështoi: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
     <string name="private_space_label" msgid="2359721649407947001">"Hapësira private"</string>
-    <!-- no translation found for private_space_secondary_label (9203933341714508907) -->
-    <skip />
+    <string name="private_space_secondary_label" msgid="9203933341714508907">"Trokit për të konfiguruar ose për të hapur"</string>
     <string name="ps_container_title" msgid="4391796149519594205">"Private"</string>
     <string name="ps_container_settings" msgid="6059734123353320479">"Cilësimet e \"Hapësirës private\""</string>
     <string name="ps_container_lock_unlock_button" msgid="7605602332253423755">"Kyç/Shkyç \"Hapësirën private\""</string>
diff --git a/res/values-sr/strings.xml b/res/values-sr/strings.xml
index 6b3a1ea..9535dc0 100644
--- a/res/values-sr/strings.xml
+++ b/res/values-sr/strings.xml
@@ -33,6 +33,7 @@
     <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
     <string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"Овај пар апликација није подржан на овом уређају"</string>
     <string name="app_pair_needs_unfold" msgid="4588897528143807002">"Отворите уређај да бисте користили овај пар апликација"</string>
+    <string name="app_pair_not_available" msgid="3556767440808032031">"Пар апликација није доступан"</string>
     <string name="long_press_widget_to_add" msgid="3587712543577675817">"Додирните и задржите ради померања виџета."</string>
     <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Двапут додирните и задржите да бисте померали виџет или користите прилагођене радње."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d×%2$d"</string>
@@ -43,7 +44,7 @@
     <string name="add_to_home_screen" msgid="9168649446635919791">"Додај на почетни екран"</string>
     <string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"Додали сте виџет <xliff:g id="WIDGET_NAME">%1$s</xliff:g> на почетни екран"</string>
     <string name="suggested_widgets_header_title" msgid="1844314680798145222">"Предлози"</string>
-    <string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"Основне апликације"</string>
+    <string name="productivity_widget_recommendation_category_label" msgid="3811812719618323750">"Неопходне апликације"</string>
     <string name="news_widget_recommendation_category_label" msgid="6756167867113741310">"Новости и часописи"</string>
     <string name="social_and_entertainment_widget_recommendation_category_label" msgid="2923840997302308191">"Зона за опуштање"</string>
     <string name="entertainment_widget_recommendation_category_label" msgid="3973107268630717874">"Забава"</string>
@@ -87,7 +88,7 @@
     <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>
+    <string name="app_info_drop_target_label" msgid="692894985365717661">"Подаци о апликацији"</string>
     <string name="install_private_system_shortcut_label" msgid="1616889277073184841">"Инсталирај на приватни"</string>
     <string name="install_drop_target_label" msgid="2539096853673231757">"Инсталирај"</string>
     <string name="dismiss_prediction_label" msgid="3357562989568808658">"Не предлажи апликацију"</string>
@@ -188,8 +189,7 @@
     <string name="developer_options_filter_hint" msgid="5896817443635989056">"Филтер"</string>
     <string name="remote_action_failed" msgid="1383965239183576790">"Није успело: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
     <string name="private_space_label" msgid="2359721649407947001">"Приватни простор"</string>
-    <!-- no translation found for private_space_secondary_label (9203933341714508907) -->
-    <skip />
+    <string name="private_space_secondary_label" msgid="9203933341714508907">"Додирните да бисте подесили или отворили"</string>
     <string name="ps_container_title" msgid="4391796149519594205">"Приватно"</string>
     <string name="ps_container_settings" msgid="6059734123353320479">"Подешавања приватног простора"</string>
     <string name="ps_container_lock_unlock_button" msgid="7605602332253423755">"Закључај/откључај приватни простор"</string>
diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml
index 94a9ff0..fd34dee 100644
--- a/res/values-sv/strings.xml
+++ b/res/values-sv/strings.xml
@@ -33,6 +33,8 @@
     <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
     <string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"De här apparna som ska användas tillsammans stöds inte på den här enheten"</string>
     <string name="app_pair_needs_unfold" msgid="4588897528143807002">"Vik upp enheten för att använda de här apparna som ska användas tillsammans"</string>
+    <!-- no translation found for app_pair_not_available (3556767440808032031) -->
+    <skip />
     <string name="long_press_widget_to_add" msgid="3587712543577675817">"Tryck länge för att flytta en widget."</string>
     <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Tryck snabbt två gånger och håll kvar för att flytta en widget eller använda anpassade åtgärder."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -188,8 +190,7 @@
     <string name="developer_options_filter_hint" msgid="5896817443635989056">"Filter"</string>
     <string name="remote_action_failed" msgid="1383965239183576790">"Misslyckades: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
     <string name="private_space_label" msgid="2359721649407947001">"Privat rum"</string>
-    <!-- no translation found for private_space_secondary_label (9203933341714508907) -->
-    <skip />
+    <string name="private_space_secondary_label" msgid="9203933341714508907">"Tryck för att ställa in eller öppna"</string>
     <string name="ps_container_title" msgid="4391796149519594205">"Privat"</string>
     <string name="ps_container_settings" msgid="6059734123353320479">"Inställningar för privat rum"</string>
     <string name="ps_container_lock_unlock_button" msgid="7605602332253423755">"Lås eller lås upp ditt privata rum"</string>
diff --git a/res/values-sw/strings.xml b/res/values-sw/strings.xml
index 069894b..8d74b83 100644
--- a/res/values-sw/strings.xml
+++ b/res/values-sw/strings.xml
@@ -33,6 +33,7 @@
     <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
     <string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"Jozi hii ya programu haitumiki kwenye kifaa hiki"</string>
     <string name="app_pair_needs_unfold" msgid="4588897528143807002">"Fungua kifaa ili utumie jozi hii ya programu"</string>
+    <string name="app_pair_not_available" msgid="3556767440808032031">"Kipengele cha jozi ya programu hakipatikani"</string>
     <string name="long_press_widget_to_add" msgid="3587712543577675817">"Gusa na ushikilie ili usogeze wijeti."</string>
     <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Gusa mara mbili na ushikilie ili usogeze wijeti au utumie vitendo maalum."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -188,8 +189,7 @@
     <string name="developer_options_filter_hint" msgid="5896817443635989056">"Kichujio"</string>
     <string name="remote_action_failed" msgid="1383965239183576790">"Hitilafu: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
     <string name="private_space_label" msgid="2359721649407947001">"Nafasi ya faragha"</string>
-    <!-- no translation found for private_space_secondary_label (9203933341714508907) -->
-    <skip />
+    <string name="private_space_secondary_label" msgid="9203933341714508907">"Gusa ili uweke mipangilio au ufungue"</string>
     <string name="ps_container_title" msgid="4391796149519594205">"Faragha"</string>
     <string name="ps_container_settings" msgid="6059734123353320479">"Mipangilio ya Nafasi ya Faragha"</string>
     <string name="ps_container_lock_unlock_button" msgid="7605602332253423755">"Funga/Fungua Nafasi ya Faragha"</string>
diff --git a/res/values-ta/strings.xml b/res/values-ta/strings.xml
index 043b654..6baa6b1 100644
--- a/res/values-ta/strings.xml
+++ b/res/values-ta/strings.xml
@@ -33,6 +33,8 @@
     <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
     <string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"இந்தச் சாதனத்தில் இந்த ஆப்ஸ் ஜோடி ஆதரிக்கப்படவில்லை"</string>
     <string name="app_pair_needs_unfold" msgid="4588897528143807002">"இந்த ஆப்ஸ் ஜோடியைப் பயன்படுத்த சாதனத்தை விரியுங்கள்"</string>
+    <!-- no translation found for app_pair_not_available (3556767440808032031) -->
+    <skip />
     <string name="long_press_widget_to_add" msgid="3587712543577675817">"விட்ஜெட்டை நகர்த்தத் தொட்டுப் பிடிக்கவும்."</string>
     <string name="long_accessible_way_to_add" msgid="2733588281439571974">"விட்ஜெட்டை நகர்த்த இருமுறை தட்டிப் பிடிக்கவும் அல்லது பிரத்தியேகச் செயல்களைப் பயன்படுத்தவும்."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -188,8 +190,7 @@
     <string name="developer_options_filter_hint" msgid="5896817443635989056">"வடிப்பான்"</string>
     <string name="remote_action_failed" msgid="1383965239183576790">"தோல்வி: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
     <string name="private_space_label" msgid="2359721649407947001">"தனிப்பட்ட சேமிப்பிடம்"</string>
-    <!-- no translation found for private_space_secondary_label (9203933341714508907) -->
-    <skip />
+    <string name="private_space_secondary_label" msgid="9203933341714508907">"அமைக்கவோ திறக்கவோ தட்டுங்கள்"</string>
     <string name="ps_container_title" msgid="4391796149519594205">"தனிப்பட்டது"</string>
     <string name="ps_container_settings" msgid="6059734123353320479">"தனிப்பட்ட சேமிப்பிட அமைப்புகள்"</string>
     <string name="ps_container_lock_unlock_button" msgid="7605602332253423755">"தனிப்பட்ட சேமிப்பிடத்தை லாக்/அன்லாக் செய்யும்"</string>
diff --git a/res/values-te/strings.xml b/res/values-te/strings.xml
index ef1cc44..daa90fa 100644
--- a/res/values-te/strings.xml
+++ b/res/values-te/strings.xml
@@ -33,6 +33,7 @@
     <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
     <string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"ఈ పరికరంలో ఈ యాప్ పెయిర్ సపోర్ట్ చేయదు"</string>
     <string name="app_pair_needs_unfold" msgid="4588897528143807002">"ఈ యాప్ పెయిర్‌ను ఉపయోగించడానికి పరికరాన్ని అన్‌ఫోల్డ్ చేయండి"</string>
+    <string name="app_pair_not_available" msgid="3556767440808032031">"యాప్ పెయిర్ అందుబాటులో లేదు"</string>
     <string name="long_press_widget_to_add" msgid="3587712543577675817">"విడ్జెట్‌ను తరలించడానికి తాకి &amp; నొక్కి ఉంచండి."</string>
     <string name="long_accessible_way_to_add" msgid="2733588281439571974">"విడ్జెట్‌ను తరలించడానికి లేదా అనుకూల చర్యలను ఉపయోగించడానికి రెండుసార్లు నొక్కండి &amp; హోల్డ్ చేయి."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -188,8 +189,7 @@
     <string name="developer_options_filter_hint" msgid="5896817443635989056">"ఫిల్టర్ చేయి"</string>
     <string name="remote_action_failed" msgid="1383965239183576790">"విఫలమైంది: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
     <string name="private_space_label" msgid="2359721649407947001">"ప్రైవేట్ స్పేస్"</string>
-    <!-- no translation found for private_space_secondary_label (9203933341714508907) -->
-    <skip />
+    <string name="private_space_secondary_label" msgid="9203933341714508907">"సెటప్ చేయడానికి లేదా తెరవడానికి ట్యాప్ చేయండి"</string>
     <string name="ps_container_title" msgid="4391796149519594205">"ప్రైవేట్"</string>
     <string name="ps_container_settings" msgid="6059734123353320479">"ప్రైవేట్ స్పేస్ సెట్టింగ్‌లు"</string>
     <string name="ps_container_lock_unlock_button" msgid="7605602332253423755">"ప్రైవేట్ స్పేస్‌ను లాక్/అన్‌లాక్ చేయండి"</string>
diff --git a/res/values-th/strings.xml b/res/values-th/strings.xml
index 37e2c21..efcd36f 100644
--- a/res/values-th/strings.xml
+++ b/res/values-th/strings.xml
@@ -33,6 +33,7 @@
     <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
     <string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"ไม่รองรับคู่แอปนี้ในอุปกรณ์เครื่องนี้"</string>
     <string name="app_pair_needs_unfold" msgid="4588897528143807002">"กางอุปกรณ์เพื่อใช้คู่แอปนี้"</string>
+    <string name="app_pair_not_available" msgid="3556767440808032031">"การจับคู่อุปกรณ์ไม่พร้อมให้บริการ"</string>
     <string name="long_press_widget_to_add" msgid="3587712543577675817">"แตะค้างไว้เพื่อย้ายวิดเจ็ต"</string>
     <string name="long_accessible_way_to_add" msgid="2733588281439571974">"แตะสองครั้งค้างไว้เพื่อย้ายวิดเจ็ตหรือใช้การดำเนินการที่กำหนดเอง"</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -116,7 +117,7 @@
     <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="app_pair_name_format" msgid="8134106404716224054">"คู่แอป: <xliff:g id="APP1">%1$s</xliff:g> และ <xliff:g id="APP2">%2$s</xliff:g>"</string>
-    <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"วอลเปเปอร์และรูปแบบ"</string>
+    <string name="styles_wallpaper_button_text" msgid="8216961355289236794">"วอลเปเปอร์และสไตล์"</string>
     <string name="edit_home_screen" msgid="8947858375782098427">"แก้ไขหน้าจอหลัก"</string>
     <string name="settings_button_text" msgid="8873672322605444408">"การตั้งค่าหน้าจอหลัก"</string>
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"ปิดใช้โดยผู้ดูแลระบบ"</string>
@@ -188,8 +189,7 @@
     <string name="developer_options_filter_hint" msgid="5896817443635989056">"ตัวกรอง"</string>
     <string name="remote_action_failed" msgid="1383965239183576790">"ไม่สำเร็จ: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
     <string name="private_space_label" msgid="2359721649407947001">"พื้นที่ส่วนตัว"</string>
-    <!-- no translation found for private_space_secondary_label (9203933341714508907) -->
-    <skip />
+    <string name="private_space_secondary_label" msgid="9203933341714508907">"แตะเพื่อตั้งค่าหรือเปิด"</string>
     <string name="ps_container_title" msgid="4391796149519594205">"ส่วนตัว"</string>
     <string name="ps_container_settings" msgid="6059734123353320479">"การตั้งค่าพื้นที่ส่วนตัว"</string>
     <string name="ps_container_lock_unlock_button" msgid="7605602332253423755">"ล็อก/ปลดล็อกพื้นที่ส่วนตัว"</string>
diff --git a/res/values-tl/strings.xml b/res/values-tl/strings.xml
index 33dbecf..27c2dd8 100644
--- a/res/values-tl/strings.xml
+++ b/res/values-tl/strings.xml
@@ -29,10 +29,11 @@
     <string name="home_screen" msgid="5629429142036709174">"Home"</string>
     <string name="recent_task_option_split_screen" msgid="6690461455618725183">"Split screen"</string>
     <string name="split_app_info_accessibility" msgid="5475288491241414932">"Impormasyon ng app para sa %1$s"</string>
-    <string name="save_app_pair" msgid="5647523853662686243">"I-save ang pares ng app"</string>
+    <string name="save_app_pair" msgid="5647523853662686243">"I-save ang app pair"</string>
     <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
     <string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"Hindi sinusuportahan sa device na ito ang pares ng app na ito"</string>
     <string name="app_pair_needs_unfold" msgid="4588897528143807002">"I-unfold ang device para magamit ang pares ng app na ito"</string>
+    <string name="app_pair_not_available" msgid="3556767440808032031">"Hindi available ang pares ng app"</string>
     <string name="long_press_widget_to_add" msgid="3587712543577675817">"Pindutin nang matagal para ilipat ang widget."</string>
     <string name="long_accessible_way_to_add" msgid="2733588281439571974">"I-double tap at pindutin nang matagal para ilipat ang widget o gumamit ng mga custom na pagkilos."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -188,8 +189,7 @@
     <string name="developer_options_filter_hint" msgid="5896817443635989056">"Filter"</string>
     <string name="remote_action_failed" msgid="1383965239183576790">"Hindi nagawa: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
     <string name="private_space_label" msgid="2359721649407947001">"Pribadong space"</string>
-    <!-- no translation found for private_space_secondary_label (9203933341714508907) -->
-    <skip />
+    <string name="private_space_secondary_label" msgid="9203933341714508907">"I-tap para i-set up o buksan"</string>
     <string name="ps_container_title" msgid="4391796149519594205">"Pribado"</string>
     <string name="ps_container_settings" msgid="6059734123353320479">"Mga Setting ng Pribadong Space"</string>
     <string name="ps_container_lock_unlock_button" msgid="7605602332253423755">"I-lock/I-unlock ang Pribadong Space"</string>
diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml
index f299b2c..b4743d6 100644
--- a/res/values-tr/strings.xml
+++ b/res/values-tr/strings.xml
@@ -33,6 +33,8 @@
     <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
     <string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"Bu uygulama çifti bu cihazda desteklenmiyor"</string>
     <string name="app_pair_needs_unfold" msgid="4588897528143807002">"Bu uygulama çiftini kullanmak için katlanmış durumda olan cihazı açın"</string>
+    <!-- no translation found for app_pair_not_available (3556767440808032031) -->
+    <skip />
     <string name="long_press_widget_to_add" msgid="3587712543577675817">"Widget\'ı taşımak için dokunup basılı tutun."</string>
     <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Widget\'ı taşımak veya özel işlemleri kullanmak için iki kez dokunup basılı tutun."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -188,8 +190,7 @@
     <string name="developer_options_filter_hint" msgid="5896817443635989056">"Filtre"</string>
     <string name="remote_action_failed" msgid="1383965239183576790">"Başarısız: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
     <string name="private_space_label" msgid="2359721649407947001">"Gizli alan"</string>
-    <!-- no translation found for private_space_secondary_label (9203933341714508907) -->
-    <skip />
+    <string name="private_space_secondary_label" msgid="9203933341714508907">"Kurmak veya açmak için dokunun"</string>
     <string name="ps_container_title" msgid="4391796149519594205">"Gizli"</string>
     <string name="ps_container_settings" msgid="6059734123353320479">"Gizli Alan Ayarları"</string>
     <string name="ps_container_lock_unlock_button" msgid="7605602332253423755">"Gizli Alanı Kilitleyin/Kilidini Açın"</string>
diff --git a/res/values-uk/strings.xml b/res/values-uk/strings.xml
index c1703f3..d09e51b 100644
--- a/res/values-uk/strings.xml
+++ b/res/values-uk/strings.xml
@@ -33,6 +33,8 @@
     <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
     <string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"Ці два додатки не можна одночасно використовувати на цьому пристрої"</string>
     <string name="app_pair_needs_unfold" msgid="4588897528143807002">"Розкладіть пристрій, щоб одночасно використовувати ці два додатки"</string>
+    <!-- no translation found for app_pair_not_available (3556767440808032031) -->
+    <skip />
     <string name="long_press_widget_to_add" msgid="3587712543577675817">"Натисніть і втримуйте, щоб перемістити віджет."</string>
     <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Двічі натисніть і втримуйте віджет, щоб перемістити його або виконати інші дії."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -188,8 +190,7 @@
     <string name="developer_options_filter_hint" msgid="5896817443635989056">"Фільтр"</string>
     <string name="remote_action_failed" msgid="1383965239183576790">"Не вдалося <xliff:g id="WHAT">%1$s</xliff:g>"</string>
     <string name="private_space_label" msgid="2359721649407947001">"Приватний простір"</string>
-    <!-- no translation found for private_space_secondary_label (9203933341714508907) -->
-    <skip />
+    <string name="private_space_secondary_label" msgid="9203933341714508907">"Натисніть, щоб налаштувати або відкрити"</string>
     <string name="ps_container_title" msgid="4391796149519594205">"Приватні"</string>
     <string name="ps_container_settings" msgid="6059734123353320479">"Налаштування приватного простору"</string>
     <string name="ps_container_lock_unlock_button" msgid="7605602332253423755">"Заблокувати/розблокувати приватний простір"</string>
diff --git a/res/values-ur/strings.xml b/res/values-ur/strings.xml
index 3169e03..50334a0 100644
--- a/res/values-ur/strings.xml
+++ b/res/values-ur/strings.xml
@@ -33,6 +33,7 @@
     <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
     <string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"ایپس کا یہ جوڑا اس آلے پر تعاون یافتہ نہیں ہے"</string>
     <string name="app_pair_needs_unfold" msgid="4588897528143807002">"ایپس کے اس جوڑے کا استعمال کرنے کیلئے آلے کو اَن فولڈ کریں"</string>
+    <string name="app_pair_not_available" msgid="3556767440808032031">"ایپ کا جوڑا دستیاب نہیں ہے"</string>
     <string name="long_press_widget_to_add" msgid="3587712543577675817">"ویجیٹ منتقل کرنے کے لیے ٹچ کریں اور پکڑ کر رکھیں۔"</string>
     <string name="long_accessible_way_to_add" msgid="2733588281439571974">"ویجیٹ کو منتقل کرنے یا حسب ضرورت کارروائیاں استعمال کرنے کے لیے دوبار تھپتھپائیں اور پکڑ کر رکھیں۔"</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -188,8 +189,7 @@
     <string name="developer_options_filter_hint" msgid="5896817443635989056">"فلٹر"</string>
     <string name="remote_action_failed" msgid="1383965239183576790">"ناکام ہو گيا: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
     <string name="private_space_label" msgid="2359721649407947001">"نجی اسپیس"</string>
-    <!-- no translation found for private_space_secondary_label (9203933341714508907) -->
-    <skip />
+    <string name="private_space_secondary_label" msgid="9203933341714508907">"سیٹ اپ کرنے یا کھولنے کے لیے تھپتھپائیں"</string>
     <string name="ps_container_title" msgid="4391796149519594205">"نجی"</string>
     <string name="ps_container_settings" msgid="6059734123353320479">"نجی اسپیس کی ترتیبات"</string>
     <string name="ps_container_lock_unlock_button" msgid="7605602332253423755">"نجی اسپیس کو مقفل کریں/غیر مقفل کریں"</string>
diff --git a/res/values-uz/strings.xml b/res/values-uz/strings.xml
index b80f4cd..795a495 100644
--- a/res/values-uz/strings.xml
+++ b/res/values-uz/strings.xml
@@ -33,6 +33,8 @@
     <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
     <string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"Bu ilova jufti ushbu qurilmada ishlamaydi"</string>
     <string name="app_pair_needs_unfold" msgid="4588897528143807002">"Bu ilova juftidan foydalanish uchun qurilmani oching"</string>
+    <!-- no translation found for app_pair_not_available (3556767440808032031) -->
+    <skip />
     <string name="long_press_widget_to_add" msgid="3587712543577675817">"Vidjetni bosib turgan holatda suring."</string>
     <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Ikki marta bosib va bosib turgan holatda vidjetni tanlang yoki maxsus amaldan foydalaning."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -188,8 +190,7 @@
     <string name="developer_options_filter_hint" msgid="5896817443635989056">"Saralash"</string>
     <string name="remote_action_failed" msgid="1383965239183576790">"Xato: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
     <string name="private_space_label" msgid="2359721649407947001">"Shaxsiy xona"</string>
-    <!-- no translation found for private_space_secondary_label (9203933341714508907) -->
-    <skip />
+    <string name="private_space_secondary_label" msgid="9203933341714508907">"Sozlash yoki ochish uchun bosing"</string>
     <string name="ps_container_title" msgid="4391796149519594205">"Yopiq"</string>
     <string name="ps_container_settings" msgid="6059734123353320479">"Shaxsiy xona sozlamalari"</string>
     <string name="ps_container_lock_unlock_button" msgid="7605602332253423755">"Shaxsiy xonani ochish/qulflash"</string>
diff --git a/res/values-vi/strings.xml b/res/values-vi/strings.xml
index a3e26d0..99bf064 100644
--- a/res/values-vi/strings.xml
+++ b/res/values-vi/strings.xml
@@ -33,6 +33,8 @@
     <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
     <string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"Cặp ứng dụng này không hoạt động được trên thiết bị này"</string>
     <string name="app_pair_needs_unfold" msgid="4588897528143807002">"Hãy mở thiết bị để dùng cặp ứng dụng này"</string>
+    <!-- no translation found for app_pair_not_available (3556767440808032031) -->
+    <skip />
     <string name="long_press_widget_to_add" msgid="3587712543577675817">"Chạm và giữ để di chuyển một tiện ích."</string>
     <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Nhấn đúp và giữ để di chuyển một tiện ích hoặc sử dụng các thao tác tùy chỉnh."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -188,8 +190,7 @@
     <string name="developer_options_filter_hint" msgid="5896817443635989056">"Bộ lọc"</string>
     <string name="remote_action_failed" msgid="1383965239183576790">"Không thực hiện được thao tác: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
     <string name="private_space_label" msgid="2359721649407947001">"Không gian riêng tư"</string>
-    <!-- no translation found for private_space_secondary_label (9203933341714508907) -->
-    <skip />
+    <string name="private_space_secondary_label" msgid="9203933341714508907">"Nhấn để thiết lập hoặc mở"</string>
     <string name="ps_container_title" msgid="4391796149519594205">"Riêng tư"</string>
     <string name="ps_container_settings" msgid="6059734123353320479">"Cài đặt không gian riêng tư"</string>
     <string name="ps_container_lock_unlock_button" msgid="7605602332253423755">"Khoá/mở khoá không gian riêng tư"</string>
diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml
index c8e524d..2b4abe1 100644
--- a/res/values-zh-rCN/strings.xml
+++ b/res/values-zh-rCN/strings.xml
@@ -29,10 +29,12 @@
     <string name="home_screen" msgid="5629429142036709174">"主屏幕"</string>
     <string name="recent_task_option_split_screen" msgid="6690461455618725183">"分屏"</string>
     <string name="split_app_info_accessibility" msgid="5475288491241414932">"%1$s 的应用信息"</string>
-    <string name="save_app_pair" msgid="5647523853662686243">"保存应用对"</string>
+    <string name="save_app_pair" msgid="5647523853662686243">"保存应用组合"</string>
     <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
     <string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"在该设备上无法使用此应用对"</string>
-    <string name="app_pair_needs_unfold" msgid="4588897528143807002">"展开设备即可使用此应用对"</string>
+    <string name="app_pair_needs_unfold" msgid="4588897528143807002">"展开设备即可使用此应用组合"</string>
+    <!-- no translation found for app_pair_not_available (3556767440808032031) -->
+    <skip />
     <string name="long_press_widget_to_add" msgid="3587712543577675817">"轻触并按住即可移动微件。"</string>
     <string name="long_accessible_way_to_add" msgid="2733588281439571974">"点按两次并按住微件即可移动该微件或使用自定义操作。"</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -188,8 +190,7 @@
     <string name="developer_options_filter_hint" msgid="5896817443635989056">"过滤器"</string>
     <string name="remote_action_failed" msgid="1383965239183576790">"失败:<xliff:g id="WHAT">%1$s</xliff:g>"</string>
     <string name="private_space_label" msgid="2359721649407947001">"私密空间"</string>
-    <!-- no translation found for private_space_secondary_label (9203933341714508907) -->
-    <skip />
+    <string name="private_space_secondary_label" msgid="9203933341714508907">"点按即可设置或打开"</string>
     <string name="ps_container_title" msgid="4391796149519594205">"私密"</string>
     <string name="ps_container_settings" msgid="6059734123353320479">"私密空间设置"</string>
     <string name="ps_container_lock_unlock_button" msgid="7605602332253423755">"锁定/解锁私密空间"</string>
diff --git a/res/values-zh-rHK/strings.xml b/res/values-zh-rHK/strings.xml
index 46669eb..a48ca7e 100644
--- a/res/values-zh-rHK/strings.xml
+++ b/res/values-zh-rHK/strings.xml
@@ -33,6 +33,8 @@
     <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
     <string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"此裝置不支援此應用程式配對"</string>
     <string name="app_pair_needs_unfold" msgid="4588897528143807002">"打開裝置即可使用此應用程式配對"</string>
+    <!-- no translation found for app_pair_not_available (3556767440808032031) -->
+    <skip />
     <string name="long_press_widget_to_add" msgid="3587712543577675817">"輕觸並按住即可移動小工具。"</string>
     <string name="long_accessible_way_to_add" msgid="2733588281439571974">"㩒兩下之後㩒住,就可以郁小工具或者用自訂操作。"</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -188,8 +190,7 @@
     <string name="developer_options_filter_hint" msgid="5896817443635989056">"篩選器"</string>
     <string name="remote_action_failed" msgid="1383965239183576790">"操作失敗:<xliff:g id="WHAT">%1$s</xliff:g>"</string>
     <string name="private_space_label" msgid="2359721649407947001">"私人空間"</string>
-    <!-- no translation found for private_space_secondary_label (9203933341714508907) -->
-    <skip />
+    <string name="private_space_secondary_label" msgid="9203933341714508907">"輕按即可設定或開啟"</string>
     <string name="ps_container_title" msgid="4391796149519594205">"私人"</string>
     <string name="ps_container_settings" msgid="6059734123353320479">"「私人空間」設定"</string>
     <string name="ps_container_lock_unlock_button" msgid="7605602332253423755">"鎖定/解鎖「私人空間」"</string>
diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml
index 8fddcc4..66e504c 100644
--- a/res/values-zh-rTW/strings.xml
+++ b/res/values-zh-rTW/strings.xml
@@ -33,6 +33,8 @@
     <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
     <string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"這部裝置不支援這組應用程式配對"</string>
     <string name="app_pair_needs_unfold" msgid="4588897528143807002">"展開裝置即可使用這組應用程式配對"</string>
+    <!-- no translation found for app_pair_not_available (3556767440808032031) -->
+    <skip />
     <string name="long_press_widget_to_add" msgid="3587712543577675817">"按住即可移動小工具。"</string>
     <string name="long_accessible_way_to_add" msgid="2733588281439571974">"輕觸兩下並按住即可移動小工具或使用自訂操作。"</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -188,8 +190,7 @@
     <string name="developer_options_filter_hint" msgid="5896817443635989056">"篩選器"</string>
     <string name="remote_action_failed" msgid="1383965239183576790">"失敗:<xliff:g id="WHAT">%1$s</xliff:g>"</string>
     <string name="private_space_label" msgid="2359721649407947001">"私人空間"</string>
-    <!-- no translation found for private_space_secondary_label (9203933341714508907) -->
-    <skip />
+    <string name="private_space_secondary_label" msgid="9203933341714508907">"輕觸即可設定或開啟"</string>
     <string name="ps_container_title" msgid="4391796149519594205">"私人"</string>
     <string name="ps_container_settings" msgid="6059734123353320479">"私人空間設定"</string>
     <string name="ps_container_lock_unlock_button" msgid="7605602332253423755">"鎖定/取消鎖定私人空間"</string>
diff --git a/res/values-zu/strings.xml b/res/values-zu/strings.xml
index 308e6e0..9a90e1e 100644
--- a/res/values-zu/strings.xml
+++ b/res/values-zu/strings.xml
@@ -33,6 +33,8 @@
     <string name="app_pair_default_title" msgid="4045241727446873529">"<xliff:g id="APP1">%1$s</xliff:g> | <xliff:g id="APP2">%2$s</xliff:g>"</string>
     <string name="app_pair_unlaunchable_at_screen_size" msgid="3446551575502685376">"Lokhu kubhanqwa kwe-app akusekelwa kule divayisi"</string>
     <string name="app_pair_needs_unfold" msgid="4588897528143807002">"Vula idivayisi ukuze usebenzise lokhu kubhanqwa kwe-app"</string>
+    <!-- no translation found for app_pair_not_available (3556767440808032031) -->
+    <skip />
     <string name="long_press_widget_to_add" msgid="3587712543577675817">"Thinta uphinde ubambe ukuze uhambise iwijethi."</string>
     <string name="long_accessible_way_to_add" msgid="2733588281439571974">"Thepha kabili uphinde ubambe ukuze uhambise iwijethi noma usebenzise izindlela ezingokwezifiso."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
@@ -188,8 +190,7 @@
     <string name="developer_options_filter_hint" msgid="5896817443635989056">"Hlunga"</string>
     <string name="remote_action_failed" msgid="1383965239183576790">"Yehlulekile: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
     <string name="private_space_label" msgid="2359721649407947001">"Isikhala esiyimfihlo"</string>
-    <!-- no translation found for private_space_secondary_label (9203933341714508907) -->
-    <skip />
+    <string name="private_space_secondary_label" msgid="9203933341714508907">"Thepha ukuze usethe noma uvule"</string>
     <string name="ps_container_title" msgid="4391796149519594205">"Okuyimfihlo"</string>
     <string name="ps_container_settings" msgid="6059734123353320479">"Amasethingi Esikhala Esiyimfihlo"</string>
     <string name="ps_container_lock_unlock_button" msgid="7605602332253423755">"Khiya/Vula Isikhala Esiyimfihlo"</string>
diff --git a/res/values/attrs.xml b/res/values/attrs.xml
index ffc8bd0..b3a25c0 100644
--- a/res/values/attrs.xml
+++ b/res/values/attrs.xml
@@ -52,6 +52,7 @@
     <attr name="folderIconBorderColor" format="color" />
     <attr name="folderTextColor" format="color" />
     <attr name="folderHintTextColor" format="color" />
+    <attr name="appPairSurfaceInFolder" format="color" />
     <attr name="isFolderDarkText" format="boolean" />
     <attr name="workspaceAccentColor" format="color" />
     <attr name="workspaceSurfaceColor" format="color" />
diff --git a/res/values/config.xml b/res/values/config.xml
index 048d6cc..f820e76 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -17,38 +17,23 @@
     <!-- Miscellaneous -->
     <bool name="config_largeHeap">false</bool>
 
-    <integer name="extracted_color_gradient_alpha">153</integer>
-
     <!-- A string pointer to the original app name string. This allows derived projects to
      easily override the app name without providing all translations -->
     <string name="derived_app_name" translatable="false">@string/app_name</string>
 
-    <!-- String representing the intent for search on the apps market. To specify a query, add
-    q=<query> to the data to the intent -->
-    <string name="market_search_intent" translatable="false">market://search?c=apps</string>
-
     <!-- String representing the intent to delete a package.-->
     <string name="delete_package_intent" translatable="false">#Intent;action=android.intent.action.DELETE;launchFlags=0x10800000;end</string>
 
     <!-- String representing the fragment class for settings activity.-->
     <string name="settings_fragment_name" translatable="false">com.android.launcher3.settings.SettingsActivity$LauncherSettingsFragment</string>
 
-    <!-- DragController -->
-    <item type="id" name="drag_event_parity" />
-
     <!-- AllApps & Launcher transitions -->
-    <!-- The duration of the animation from search hint to text entry -->
-    <integer name="config_searchHintAnimationDuration">50</integer>
-
     <!-- The duration of the PagedView page snap animation -->
     <integer name="config_pageSnapAnimationDuration">750</integer>
 
     <!-- The duration of the PagedView page snap animation -->
     <integer name="config_keyboardTaskFocusSnapAnimationDuration">750</integer>
 
-    <!-- View tag key used to store SpringAnimation data. -->
-    <item type="id" name="spring_animation_tag" />
-
     <!-- View tag key used to determine if we should fade in the child views.. -->
     <string name="popup_container_iterate_children" translatable="false">popup_container_iterate_children</string>
 
@@ -91,71 +76,28 @@
     <string name="taskbar_model_callbacks_factory_class" translatable="false"></string>
     <string name="taskbar_view_callbacks_factory_class" translatable="false"></string>
     <string name="launcher_restore_event_logger_class" translatable="false"></string>
-
-    <!-- View ID to use for QSB widget -->
-    <item type="id" name="qsb_widget" />
-
-    <!-- View ID used by cell layout to jail its content -->
-    <item type="id" name="cell_layout_jail_id" />
-
-    <!-- View IDs to store item highlight information -->
-    <item type="id" name="view_unhighlight_background" />
-
-    <!-- view ID used to restore work tab state -->
-    <item type="id" name="work_tab_state_id" />
-
-    <!-- Menu id for feature flags -->
-    <item type="id" name="menu_apply_flags" />
+    <!--  Used for determining category of a widget presented in widget recommendations. -->
+    <string name="widget_recommendation_category_provider_class" translatable="false"></string>
+    <string name="api_wrapper_class" translatable="false"></string>
 
     <!-- Default packages -->
     <string name="wallpaper_picker_package" translatable="false"></string>
     <string name="local_colors_extraction_class" translatable="false"></string>
     <string name="search_session_manager_class" translatable="false"></string>
 
-    <!-- Accessibility actions -->
-    <item type="id" name="action_remove" />
-    <item type="id" name="action_uninstall" />
-    <item type="id" name="action_reconfigure" />
-    <item type="id" name="action_add_to_workspace" />
-    <item type="id" name="action_move" />
-    <item type="id" name="action_move_to_workspace" />
-    <item type="id" name="action_move_screen_backwards" />
-    <item type="id" name="action_move_screen_forwards" />
-    <item type="id" name="action_resize" />
-    <item type="id" name="action_deep_shortcuts" />
-    <item type="id" name="action_remote_action_shortcut" />
-    <item type="id" name="action_dismiss_prediction" />
-    <item type="id" name="action_pin_prediction"/>
-
-    <!-- QSB IDs. DO not change -->
-    <item type="id" name="search_container_workspace" />
-    <item type="id" name="search_container_all_apps" />
-    <item type="id" name="search_container_hotseat" />
 
     <!-- Scalable Grid configuration -->
     <!-- This is a float because it is converted to dp later in DeviceProfile -->
     <dimen name="hotseat_bar_bottom_space_default">48</dimen>
     <dimen name="hotseat_qsb_space_default">0</dimen>
 
-    <!-- Recents -->
-    <item type="id" name="overview_panel"/>
-
     <!-- Whether to enable background preloading of task thumbnails. -->
     <bool name="config_enableTaskSnapshotPreloading">true</bool>
 
     <!-- Configuration resources -->
-    <item name="all_apps_spring_damping_ratio" type="dimen" format="float">0.75</item>
-    <item name="all_apps_spring_stiffness" type="dimen" format="float">600</item>
-
     <item name="dismiss_task_trans_y_damping_ratio" type="dimen" format="float">0.73</item>
     <item name="dismiss_task_trans_y_stiffness" type="dimen" format="float">800</item>
 
-    <item name="dismiss_task_trans_x_damping_ratio" type="dimen" format="float">0.73</item>
-    <item name="dismiss_task_trans_x_stiffness" type="dimen" format="float">800</item>
-
-    <item name="horizontal_spring_damping_ratio" type="dimen" format="float">0.8</item>
-    <item name="horizontal_spring_stiffness" type="dimen" format="float">250</item>
-
     <item name="swipe_up_rect_scale_damping_ratio" type="dimen" format="float">0.75</item>
     <item name="swipe_up_rect_scale_stiffness" type="dimen" format="float">200</item>
     <item name="swipe_up_rect_scale_higher_stiffness" type="dimen" format="float">400</item>
@@ -217,9 +159,6 @@
     <!-- Widget component names to be included in fitness category of widget suggestions. -->
     <string-array name="fitness_recommendations"></string-array>
 
-    <!-- Name of the class used to generate colors from the wallpaper colors. Must be implementing the LauncherAppWidgetHostView.ColorGenerator interface. -->
-    <string name="color_generator_class" translatable="false"/>
-
     <!-- Swipe back to home related -->
     <dimen name="swipe_back_window_scale_x_margin">10dp</dimen>
     <dimen name="swipe_back_window_corner_radius">40dp</dimen>
@@ -275,9 +214,6 @@
     <!--  Used for custom widgets  -->
     <array name="custom_widget_providers"/>
 
-    <!--  Used for determining category of a widget presented in widget recommendations. -->
-    <string name="widget_recommendation_category_provider_class" translatable="false"></string>
-
     <!-- Embed parameters -->
     <dimen name="activity_split_ratio"  format="float">0.5</dimen>
     <integer name="min_width_split">720</integer>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index dcb1c28..a056e81 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -183,7 +183,6 @@
     <dimen name="widget_cell_add_button_height">48dp</dimen>
     <dimen name="widget_cell_add_button_start_padding">8dp</dimen>
     <dimen name="widget_cell_add_button_end_padding">16dp</dimen>
-    <dimen name="widget_cell_add_button_vertical_padding">10dp</dimen>
 
     <dimen name="widget_tabs_button_horizontal_padding">4dp</dimen>
     <dimen name="widget_tabs_horizontal_padding">16dp</dimen>
@@ -277,7 +276,6 @@
 
     <!-- Sizes for managed profile badges -->
     <dimen name="profile_badge_size">24dp</dimen>
-    <dimen name="profile_badge_margin">5dp</dimen>
     <dimen name="profile_badge_minimum_top">2dp</dimen>
 
     <!-- Shadows and outlines -->
@@ -449,6 +447,8 @@
     <dimen name="split_instructions_bottom_margin_phone_landscape">24dp</dimen>
     <dimen name="split_instructions_bottom_margin_phone_portrait">60dp</dimen>
     <dimen name="split_instructions_start_margin_cancel">8dp</dimen>
+    <dimen name="split_divider_handle_region_width">96dp</dimen>
+    <dimen name="split_divider_handle_region_height">48dp</dimen>
 
     <dimen name="focus_outline_radius">16dp</dimen>
     <dimen name="focus_inner_outline_radius">14dp</dimen>
@@ -498,6 +498,7 @@
     <dimen name="ps_button_width">40dp</dimen>
     <dimen name="ps_lock_button_width">89dp</dimen>
     <dimen name="ps_app_divider_padding">16dp</dimen>
+    <dimen name="ps_extra_bottom_padding">16dp</dimen>
     <dimen name="ps_lock_corner_radius">20dp</dimen>
     <dimen name="ps_lock_icon_size">20dp</dimen>
     <dimen name="ps_lock_icon_margin_top">10dp</dimen>
diff --git a/res/values/id.xml b/res/values/id.xml
index 59813ad..7bb9396 100644
--- a/res/values/id.xml
+++ b/res/values/id.xml
@@ -23,6 +23,40 @@
     <item type="id" name="split_topLeft_appInfo" />
     <item type="id" name="split_bottomRight_appInfo" />
 
+    <!-- Accessibility actions -->
+    <item type="id" name="action_remove" />
+    <item type="id" name="action_uninstall" />
+    <item type="id" name="action_reconfigure" />
+    <item type="id" name="action_add_to_workspace" />
+    <item type="id" name="action_move" />
+    <item type="id" name="action_move_to_workspace" />
+    <item type="id" name="action_move_screen_backwards" />
+    <item type="id" name="action_move_screen_forwards" />
+    <item type="id" name="action_resize" />
+    <item type="id" name="action_deep_shortcuts" />
+    <item type="id" name="action_remote_action_shortcut" />
+    <item type="id" name="action_dismiss_prediction" />
+    <item type="id" name="action_pin_prediction"/>
+
+    <!-- QSB IDs. DO not change -->
+    <item type="id" name="search_container_workspace" />
+    <item type="id" name="search_container_all_apps" />
+    <item type="id" name="search_container_hotseat" />
+
+    <!-- View ID to use for QSB widget -->
+    <item type="id" name="qsb_widget" />
+
+    <!-- View ID used by cell layout to jail its content -->
+    <item type="id" name="cell_layout_jail_id" />
+
+    <!-- View IDs to store item highlight information -->
+    <item type="id" name="view_unhighlight_background" />
+
+    <!-- view ID used to restore work tab state -->
+    <item type="id" name="work_tab_state_id" />
+
+    <!-- Menu id for feature flags -->
+    <item type="id" name="menu_apply_flags" />
 
     <!--  Do not change, must be kept in sync with sysui navbar button IDs for tests!  -->
     <item type="id" name="home" />
@@ -53,4 +87,13 @@
     <item type="id" name="ps_settings_button" />
     <item type="id" name="ps_transition_image" />
 
+    <!-- Recents -->
+    <item type="id" name="overview_panel"/>
+
+    <!-- DragController -->
+    <item type="id" name="drag_event_parity" />
+
+    <!-- View tag key used to store SpringAnimation data. -->
+    <item type="id" name="spring_animation_tag" />
+
 </resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index c442195..e1c7d64 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -50,6 +50,8 @@
     <string name="app_pair_unlaunchable_at_screen_size">This app pair isn\'t supported on this device</string>
     <!-- Displayed when an app pair can't launch at this screen size, but user can unfold device to restore functionality [CHAR_LIMIT=none] -->
     <string name="app_pair_needs_unfold">Unfold device to use this app pair</string>
+    <!-- Displayed when user selects a shortcut for an app pair that is currently not available [CHAR_LIMIT=none]-->
+    <string name="app_pair_not_available">App pair isn\'t available</string>
 
     <!-- Widgets -->
     <!-- Message to tell the user to press and hold on a widget to add it [CHAR_LIMIT=50] -->
diff --git a/res/values/styles.xml b/res/values/styles.xml
index e35d241..00b962e 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -61,6 +61,7 @@
         <item name="isFolderDarkText">true</item>
         <item name="folderTextColor">@color/folder_text_color_light</item>
         <item name="folderHintTextColor">@color/folder_hint_text_color_light</item>
+        <item name="appPairSurfaceInFolder">@color/material_color_surface_container_lowest</item>
         <item name="loadingIconColor">#CCFFFFFF</item>
         <item name="iconOnlyShortcutColor">?android:attr/textColorSecondary</item>
         <item name="eduHalfSheetBGColor">?android:attr/colorAccent</item>
@@ -172,6 +173,7 @@
         <item name="isFolderDarkText">false</item>
         <item name="folderTextColor">@color/folder_text_color_dark</item>
         <item name="folderHintTextColor">@color/folder_hint_text_color_dark</item>
+        <item name="appPairSurfaceInFolder">@color/material_color_surface_container_lowest</item>
         <item name="isMainColorDark">true</item>
         <item name="loadingIconColor">#99FFFFFF</item>
         <item name="iconOnlyShortcutColor">#B3FFFFFF</item>
diff --git a/src/com/android/launcher3/AbstractFloatingView.java b/src/com/android/launcher3/AbstractFloatingView.java
index e7b88dc..4ccf3db 100644
--- a/src/com/android/launcher3/AbstractFloatingView.java
+++ b/src/com/android/launcher3/AbstractFloatingView.java
@@ -278,18 +278,7 @@
 
     public static void closeOpenViews(ActivityContext activity, boolean animate,
             @FloatingViewType int type) {
-        BaseDragLayer dragLayer = activity.getDragLayer();
-        // Iterate in reverse order. AbstractFloatingView is added later to the dragLayer,
-        // and will be one of the last views.
-        for (int i = dragLayer.getChildCount() - 1; i >= 0; i--) {
-            View child = dragLayer.getChildAt(i);
-            if (child instanceof AbstractFloatingView) {
-                AbstractFloatingView abs = (AbstractFloatingView) child;
-                if (abs.isOfType(type)) {
-                    abs.close(animate);
-                }
-            }
-        }
+        new AbstractFloatingViewHelper().closeOpenViews(activity, animate, type);
     }
 
     public static void closeAllOpenViews(ActivityContext activity, boolean animate) {
diff --git a/src/com/android/launcher3/AbstractFloatingViewHelper.kt b/src/com/android/launcher3/AbstractFloatingViewHelper.kt
new file mode 100644
index 0000000..0bfbc6e
--- /dev/null
+++ b/src/com/android/launcher3/AbstractFloatingViewHelper.kt
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2024 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
+
+import com.android.launcher3.AbstractFloatingView.FloatingViewType
+import com.android.launcher3.views.ActivityContext
+
+/**
+ * Helper class for manaing AbstractFloatingViews which shows a floating UI on top of the launcher
+ * UI.
+ */
+class AbstractFloatingViewHelper {
+    fun closeOpenViews(activity: ActivityContext, animate: Boolean, @FloatingViewType type: Int) {
+        val dragLayer = activity.getDragLayer()
+        // Iterate in reverse order. AbstractFloatingView is added later to the dragLayer,
+        // and will be one of the last views.
+        for (i in dragLayer.getChildCount() - 1 downTo 0) {
+            val child = dragLayer.getChildAt(i)
+            if (child is AbstractFloatingView && child.isOfType(type)) {
+                child.close(animate)
+            }
+        }
+    }
+}
diff --git a/src/com/android/launcher3/AppWidgetResizeFrame.java b/src/com/android/launcher3/AppWidgetResizeFrame.java
index 4a277f0..b46d7e2 100644
--- a/src/com/android/launcher3/AppWidgetResizeFrame.java
+++ b/src/com/android/launcher3/AppWidgetResizeFrame.java
@@ -46,6 +46,7 @@
 import com.android.launcher3.views.ArrowTipView;
 import com.android.launcher3.widget.LauncherAppWidgetHostView;
 import com.android.launcher3.widget.LauncherAppWidgetProviderInfo;
+import com.android.launcher3.widget.PendingAppWidgetHostView;
 import com.android.launcher3.widget.util.WidgetSizes;
 
 import java.util.ArrayList;
@@ -200,6 +201,10 @@
     }
 
     public static void showForWidget(LauncherAppWidgetHostView widget, CellLayout cellLayout) {
+        // If widget is not added to view hierarchy, we cannot show resize frame at correct location
+        if (widget.getParent() == null) {
+            return;
+        }
         Launcher launcher = Launcher.getLauncher(cellLayout.getContext());
         AbstractFloatingView.closeAllOpenViews(launcher);
 
@@ -470,8 +475,11 @@
             mLastDirectionVector[1] = mDirectionVector[1];
         }
 
-        if (mCellLayout.createAreaForResize(cellX, cellY, spanX, spanY, mWidgetView,
-                mDirectionVector, onDismiss)) {
+        // We don't want to evaluate resize if a widget was pending config activity and was already
+        // occupying a space on the screen. This otherwise will cause reorder algorithm evaluate a
+        // different location for the widget and cause a jump.
+        if (!(mWidgetView instanceof PendingAppWidgetHostView) && mCellLayout.createAreaForResize(
+                cellX, cellY, spanX, spanY, mWidgetView, mDirectionVector, onDismiss)) {
             if (mStateAnnouncer != null && (lp.cellHSpan != spanX || lp.cellVSpan != spanY) ) {
                 mStateAnnouncer.announce(
                         mLauncher.getString(R.string.widget_resized, spanX, spanY));
diff --git a/src/com/android/launcher3/AutoInstallsLayout.java b/src/com/android/launcher3/AutoInstallsLayout.java
index c7cdfa8..cf86528 100644
--- a/src/com/android/launcher3/AutoInstallsLayout.java
+++ b/src/com/android/launcher3/AutoInstallsLayout.java
@@ -52,7 +52,7 @@
 import com.android.launcher3.pm.UserCache;
 import com.android.launcher3.qsb.QsbContainerView;
 import com.android.launcher3.shortcuts.ShortcutKey;
-import com.android.launcher3.uioverrides.ApiWrapper;
+import com.android.launcher3.util.ApiWrapper;
 import com.android.launcher3.util.IntArray;
 import com.android.launcher3.util.Partner;
 import com.android.launcher3.util.Thunk;
@@ -203,7 +203,7 @@
         mIdp = LauncherAppState.getIDP(context);
         mRowCount = mIdp.numRows;
         mColumnCount = mIdp.numColumns;
-        mActivityOverride = ApiWrapper.getActivityOverrides(context);
+        mActivityOverride = ApiWrapper.INSTANCE.get(context).getActivityOverrides();
     }
 
     /**
diff --git a/src/com/android/launcher3/BaseDraggingActivity.java b/src/com/android/launcher3/BaseDraggingActivity.java
index 1c2ed43..cf93a79 100644
--- a/src/com/android/launcher3/BaseDraggingActivity.java
+++ b/src/com/android/launcher3/BaseDraggingActivity.java
@@ -111,8 +111,6 @@
         return false;
     }
 
-    public abstract <T extends View> T getOverviewPanel();
-
     public abstract View getRootView();
 
     public void returnToHomescreen() {
diff --git a/src/com/android/launcher3/BubbleTextView.java b/src/com/android/launcher3/BubbleTextView.java
index 4c8ed15..83236d1 100644
--- a/src/com/android/launcher3/BubbleTextView.java
+++ b/src/com/android/launcher3/BubbleTextView.java
@@ -912,7 +912,7 @@
     @Nullable
     public PreloadIconDrawable applyProgressLevel() {
         if (!(getTag() instanceof ItemInfoWithIcon)
-                || !((ItemInfoWithIcon) getTag()).isActiveArchive()) {
+                || ((ItemInfoWithIcon) getTag()).isInactiveArchive()) {
             return null;
         }
 
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index 3ddc7aa..6cb33a8 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -63,13 +63,13 @@
 import com.android.launcher3.responsive.ResponsiveSpec.Companion.ResponsiveSpecType;
 import com.android.launcher3.responsive.ResponsiveSpec.DimensionType;
 import com.android.launcher3.responsive.ResponsiveSpecsProvider;
-import com.android.launcher3.uioverrides.ApiWrapper;
 import com.android.launcher3.util.CellContentDimensions;
 import com.android.launcher3.util.DisplayController;
 import com.android.launcher3.util.DisplayController.Info;
 import com.android.launcher3.util.IconSizeSteps;
 import com.android.launcher3.util.ResourceHelper;
 import com.android.launcher3.util.WindowBounds;
+import com.android.launcher3.util.window.WindowManagerProxy;
 
 import java.io.PrintWriter;
 import java.util.Locale;
@@ -350,7 +350,8 @@
         isTablet = info.isTablet(windowBounds);
         isPhone = !isTablet;
         isTwoPanels = isTablet && isMultiDisplay;
-        isTaskbarPresent = isTablet && ApiWrapper.TASKBAR_DRAWN_IN_PROCESS;
+        isTaskbarPresent = isTablet
+                && WindowManagerProxy.INSTANCE.get(context).isTaskbarDrawnInProcess();
 
         // Some more constants.
         context = getContext(context, info, isVerticalBarLayout() || (isTablet && isLandscape)
diff --git a/src/com/android/launcher3/InvariantDeviceProfile.java b/src/com/android/launcher3/InvariantDeviceProfile.java
index 2e0f676..bc36336 100644
--- a/src/com/android/launcher3/InvariantDeviceProfile.java
+++ b/src/com/android/launcher3/InvariantDeviceProfile.java
@@ -359,6 +359,15 @@
         return displayOption.grid.name;
     }
 
+    /**
+     * @deprecated This is a temporary solution because on the backup and restore case we modify the
+     * IDP, this resets it. b/332974074
+     */
+    @Deprecated
+    public void reset(Context context) {
+        initGrid(context, getCurrentGridName(context));
+    }
+
     @VisibleForTesting
     public static String getDefaultGridName(Context context) {
         return new InvariantDeviceProfile().initGrid(context, null);
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index cfa8967..d2d5ba9 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -680,7 +680,7 @@
 
             @Override
             public void onBackCancelled() {
-                mStateManager.getState().onBackCancelled(Launcher.this);
+                Launcher.this.onBackCancelled();
             }
         };
     }
@@ -1551,7 +1551,13 @@
             LauncherAppWidgetInfo launcherInfo,
             CellPos presenterPos) {
         CellLayout cellLayout = getCellLayout(launcherInfo.container, presenterPos.screenId);
-        if (mStateManager.getState() == NORMAL) {
+        // We should wait until launcher is not animating to show resize frame so that
+        // {@link View#hasIdentityMatrix()} returns true (no scale effect) from CellLayout and
+        // Workspace (they are widget's parent view). Otherwise widget's
+        // {@link View#getLocationInWindow(int[])} will set skewed location, causing resize
+        // frame not showing at skewed location in
+        // {@link AppWidgetResizeFrame#snapToWidget(boolean)}.
+        if (mStateManager.getState() == NORMAL && !mStateManager.isInTransition()) {
             AppWidgetResizeFrame.showForWidget(launcherHostView, cellLayout);
         } else {
             mStateManager.addStateListener(new StateManager.StateListener<LauncherState>() {
@@ -1647,7 +1653,7 @@
         } else if (Intent.ACTION_ALL_APPS.equals(intent.getAction())) {
             showAllAppsFromIntent(alreadyOnHome);
         } else if (INTENT_ACTION_ALL_APPS_TOGGLE.equals(intent.getAction())) {
-            toggleAllAppsFromIntent(alreadyOnHome);
+            toggleAllAppsSearch(alreadyOnHome);
         } else if (Intent.ACTION_SHOW_WORK_APPS.equals(intent.getAction())) {
             showAllAppsWithSelectedTabFromIntent(alreadyOnHome,
                     ActivityAllAppsContainerView.AdapterHolder.WORK);
@@ -1661,7 +1667,12 @@
         // Overridden
     }
 
-    protected void toggleAllAppsFromIntent(boolean alreadyOnHome) {
+    /** Toggles Launcher All Apps with keyboard ready for search. */
+    public void toggleAllAppsSearch() {
+        toggleAllAppsSearch(/* alreadyOnHome= */ true);
+    }
+
+    protected void toggleAllAppsSearch(boolean alreadyOnHome) {
         if (getStateManager().isInStableState(ALL_APPS)) {
             getStateManager().goToState(NORMAL, alreadyOnHome);
         } else {
@@ -2086,6 +2097,10 @@
         mStateManager.getState().onBackInvoked(this);
     }
 
+    protected void onBackCancelled() {
+        mStateManager.getState().onBackCancelled(this);
+    }
+
     protected void onScreenOnChanged(boolean isOn) {
         // Reset AllApps to its initial state only if we are not in the middle of
         // processing a multi-step drop
@@ -2878,8 +2893,8 @@
      * Returns {@code true} if there are visible tasks with windowing mode set to
      * {@link android.app.WindowConfiguration#WINDOWING_MODE_FREEFORM}
      */
-    public boolean areFreeformTasksVisible() {
-        return false; // Base launcher does not track freeform tasks
+    public boolean areDesktopTasksVisible() {
+        return false; // Base launcher does not track desktop tasks
     }
 
     // Getters and Setters
diff --git a/src/com/android/launcher3/LauncherAppState.java b/src/com/android/launcher3/LauncherAppState.java
index 60a6be6..50a597d 100644
--- a/src/com/android/launcher3/LauncherAppState.java
+++ b/src/com/android/launcher3/LauncherAppState.java
@@ -110,7 +110,7 @@
         mOnTerminateCallback.add(() ->
                 mContext.getSystemService(LauncherApps.class).unregisterCallback(callbacks));
 
-        if (Utilities.enableSupportForArchiving()) {
+        if (Flags.enableSupportForArchiving()) {
             ArchiveCompatibilityParams params = new ArchiveCompatibilityParams();
             params.setEnableUnarchivalConfirmation(false);
             launcherApps.setArchiveCompatibility(params);
diff --git a/src/com/android/launcher3/LauncherPrefs.kt b/src/com/android/launcher3/LauncherPrefs.kt
index 27e084c..875c407 100644
--- a/src/com/android/launcher3/LauncherPrefs.kt
+++ b/src/com/android/launcher3/LauncherPrefs.kt
@@ -20,7 +20,6 @@
 import android.content.SharedPreferences
 import android.content.SharedPreferences.OnSharedPreferenceChangeListener
 import android.util.Log
-import android.view.ViewConfiguration
 import androidx.annotation.VisibleForTesting
 import com.android.launcher3.BuildConfig.WIDGET_ON_FIRST_SCREEN
 import com.android.launcher3.LauncherFiles.DEVICE_PREFERENCES_KEY
@@ -298,64 +297,7 @@
         @JvmField
         val ICON_STATE =
             nonRestorableItem("pref_icon_shape_path", "", EncryptionType.MOVE_TO_DEVICE_PROTECTED)
-        @JvmField
-        val ALL_APPS_OVERVIEW_THRESHOLD =
-            nonRestorableItem(
-                "pref_all_apps_overview_threshold",
-                180,
-                EncryptionType.MOVE_TO_DEVICE_PROTECTED
-            )
-        @JvmField
-        val LONG_PRESS_NAV_HANDLE_SLOP_PERCENTAGE =
-            nonRestorableItem("LPNH_SLOP_PERCENTAGE", 100, EncryptionType.MOVE_TO_DEVICE_PROTECTED)
-        @JvmField
-        val LONG_PRESS_NAV_HANDLE_EXTRA_TOUCH_WIDTH_DP =
-            nonRestorableItem(
-                "LPNH_EXTRA_TOUCH_WIDTH_DP",
-                0,
-                EncryptionType.MOVE_TO_DEVICE_PROTECTED
-            )
-        @JvmField
-        val LONG_PRESS_NAV_HANDLE_TIMEOUT_MS =
-            nonRestorableItem(
-                "LPNH_TIMEOUT_MS",
-                ViewConfiguration.getLongPressTimeout(),
-                EncryptionType.MOVE_TO_DEVICE_PROTECTED
-            )
-        @JvmField
-        val LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_START_SCALE_PERCENT =
-            nonRestorableItem(
-                "LPNH_HAPTIC_HINT_START_SCALE_PERCENT",
-                0,
-                EncryptionType.MOVE_TO_DEVICE_PROTECTED
-            )
-        @JvmField
-        val LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_END_SCALE_PERCENT =
-            nonRestorableItem(
-                "LPNH_HAPTIC_HINT_END_SCALE_PERCENT",
-                100,
-                EncryptionType.MOVE_TO_DEVICE_PROTECTED
-            )
-        @JvmField
-        val LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_SCALE_EXPONENT =
-            nonRestorableItem(
-                "LPNH_HAPTIC_HINT_SCALE_EXPONENT",
-                1,
-                EncryptionType.MOVE_TO_DEVICE_PROTECTED
-            )
-        @JvmField
-        val LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_ITERATIONS =
-            nonRestorableItem(
-                "LPNH_HAPTIC_HINT_ITERATIONS",
-                50,
-                EncryptionType.MOVE_TO_DEVICE_PROTECTED
-            )
-        @JvmField
-        val LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_DELAY =
-            nonRestorableItem("LPNH_HAPTIC_HINT_DELAY", 0, EncryptionType.MOVE_TO_DEVICE_PROTECTED)
-        @JvmField
-        val PRIVATE_SPACE_APPS =
-            nonRestorableItem("pref_private_space_apps", 0, EncryptionType.MOVE_TO_DEVICE_PROTECTED)
+
         @JvmField
         val ENABLE_TWOLINE_ALLAPPS_TOGGLE = backedUpItem("pref_enable_two_line_toggle", false)
         @JvmField
diff --git a/src/com/android/launcher3/Utilities.java b/src/com/android/launcher3/Utilities.java
index d44438f..2b886e4 100644
--- a/src/com/android/launcher3/Utilities.java
+++ b/src/com/android/launcher3/Utilities.java
@@ -830,10 +830,4 @@
                 // No-Op
         }
     }
-
-    /** Encapsulates two flag checks into a single one. */
-    public static boolean enableSupportForArchiving() {
-        return Flags.enableSupportForArchiving()
-                || getSystemProperty("pm.archiving.enabled", "false").equals("true");
-    }
 }
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index ce3c55a..0fc3211 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -16,8 +16,9 @@
 
 package com.android.launcher3;
 
+import static com.android.launcher3.BubbleTextView.DISPLAY_FOLDER;
 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.LauncherSettings.Favorites.CONTAINER_HOTSEAT_PREDICTION;
 import static com.android.launcher3.LauncherState.ALL_APPS;
 import static com.android.launcher3.LauncherState.EDIT_MODE;
 import static com.android.launcher3.LauncherState.FLAG_MULTI_PAGE;
@@ -73,6 +74,7 @@
 import com.android.launcher3.accessibility.AccessibleDragListenerAdapter;
 import com.android.launcher3.accessibility.WorkspaceAccessibilityHelper;
 import com.android.launcher3.anim.PendingAnimation;
+import com.android.launcher3.apppairs.AppPairIcon;
 import com.android.launcher3.celllayout.CellInfo;
 import com.android.launcher3.celllayout.CellLayoutLayoutParams;
 import com.android.launcher3.celllayout.CellPosMapper;
@@ -241,6 +243,8 @@
     public static final int REORDER_TIMEOUT = 650;
     protected final Alarm mReorderAlarm = new Alarm();
     private PreviewBackground mFolderCreateBg;
+    /** The underlying view that we are dragging something over. */
+    private View mDragOverView = null;
     private FolderIcon mDragOverFolderIcon = null;
     private boolean mCreateUserFolderOnDrop = false;
     private boolean mAddToExistingFolderOnDrop = false;
@@ -1873,12 +1877,9 @@
             return false;
         }
 
-        boolean aboveShortcut = (dropOverView.getTag() instanceof WorkspaceItemInfo
-                && ((WorkspaceItemInfo) dropOverView.getTag()).container
-                != LauncherSettings.Favorites.CONTAINER_HOTSEAT_PREDICTION);
-        boolean willBecomeShortcut =
-                (info.itemType == ITEM_TYPE_APPLICATION ||
-                        info.itemType == LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT);
+        boolean aboveShortcut = Folder.willAccept(dropOverView.getTag())
+                && ((ItemInfo) dropOverView.getTag()).container != CONTAINER_HOTSEAT_PREDICTION;
+        boolean willBecomeShortcut = Folder.willAcceptItemType(info.itemType);
 
         return (aboveShortcut && willBecomeShortcut);
     }
@@ -1925,12 +1926,12 @@
         mCreateUserFolderOnDrop = false;
         final int screenId = getCellLayoutId(target);
 
-        boolean aboveShortcut = (v.getTag() instanceof WorkspaceItemInfo);
-        boolean willBecomeShortcut = (newView.getTag() instanceof WorkspaceItemInfo);
+        boolean aboveShortcut = Folder.willAccept(v.getTag());
+        boolean willBecomeShortcut = Folder.willAccept(newView.getTag());
 
         if (aboveShortcut && willBecomeShortcut) {
-            WorkspaceItemInfo sourceInfo = (WorkspaceItemInfo) newView.getTag();
-            WorkspaceItemInfo destInfo = (WorkspaceItemInfo) v.getTag();
+            ItemInfo sourceInfo = (ItemInfo) newView.getTag();
+            ItemInfo destInfo = (ItemInfo) v.getTag();
             // if the drag started here, we need to remove it from the workspace
             if (!external) {
                 getParentCellLayoutForView(mDragInfo.cell).removeView(mDragInfo.cell);
@@ -2384,6 +2385,11 @@
         if (mFolderCreateBg != null) {
             mFolderCreateBg.animateToRest();
         }
+
+        if (mDragOverView instanceof AppPairIcon api) {
+            api.getIconDrawableArea().onTemporaryContainerChange(null);
+            mDragOverView = null;
+        }
     }
 
     private void cleanupAddToFolder() {
@@ -2659,32 +2665,36 @@
             return;
         }
 
-        final View dragOverView = mDragTargetLayout.getChildAt(mTargetCell[0], mTargetCell[1]);
+        mDragOverView = mDragTargetLayout.getChildAt(mTargetCell[0], mTargetCell[1]);
         ItemInfo info = dragObject.dragInfo;
-        boolean userFolderPending = willCreateUserFolder(info, dragOverView, false);
+        boolean userFolderPending = willCreateUserFolder(info, mDragOverView, false);
         if (mDragMode == DRAG_MODE_NONE && userFolderPending) {
 
             mFolderCreateBg = new PreviewBackground();
             mFolderCreateBg.setup(mLauncher, mLauncher, null,
-                    dragOverView.getMeasuredWidth(), dragOverView.getPaddingTop());
+                    mDragOverView.getMeasuredWidth(), mDragOverView.getPaddingTop());
 
             // The full preview background should appear behind the icon
             mFolderCreateBg.isClipping = false;
 
+            if (mDragOverView instanceof AppPairIcon api) {
+                api.getIconDrawableArea().onTemporaryContainerChange(DISPLAY_FOLDER);
+            }
+
             mFolderCreateBg.animateToAccept(mDragTargetLayout, mTargetCell[0], mTargetCell[1]);
             mDragTargetLayout.clearDragOutlines();
             setDragMode(DRAG_MODE_CREATE_FOLDER);
 
             if (dragObject.stateAnnouncer != null) {
                 dragObject.stateAnnouncer.announce(WorkspaceAccessibilityHelper
-                        .getDescriptionForDropOver(dragOverView, getContext()));
+                        .getDescriptionForDropOver(mDragOverView, getContext()));
             }
             return;
         }
 
-        boolean willAddToFolder = willAddToExistingUserFolder(info, dragOverView);
+        boolean willAddToFolder = willAddToExistingUserFolder(info, mDragOverView);
         if (willAddToFolder && mDragMode == DRAG_MODE_NONE) {
-            mDragOverFolderIcon = ((FolderIcon) dragOverView);
+            mDragOverFolderIcon = ((FolderIcon) mDragOverView);
             mDragOverFolderIcon.onDragEnter(info);
             if (mDragTargetLayout != null) {
                 mDragTargetLayout.clearDragOutlines();
@@ -2693,7 +2703,7 @@
 
             if (dragObject.stateAnnouncer != null) {
                 dragObject.stateAnnouncer.announce(WorkspaceAccessibilityHelper
-                        .getDescriptionForDropOver(dragOverView, getContext()));
+                        .getDescriptionForDropOver(mDragOverView, getContext()));
             }
             return;
         }
@@ -3314,7 +3324,7 @@
                     }
                 } else if (child instanceof FolderIcon) {
                     FolderInfo folderInfo = (FolderInfo) info;
-                    List<WorkspaceItemInfo> matches = folderInfo.getContents().stream()
+                    List<ItemInfo> matches = folderInfo.getContents().stream()
                             .filter(matcher)
                             .collect(Collectors.toList());
                     if (!matches.isEmpty()) {
@@ -3381,7 +3391,7 @@
                 FolderInfo fi = (FolderInfo) info;
                 if (fi.anyMatch(matcher)) {
                     FolderDotInfo folderDotInfo = new FolderDotInfo();
-                    for (WorkspaceItemInfo si : fi.getContents()) {
+                    for (ItemInfo si : fi.getContents()) {
                         folderDotInfo.addDotInfo(mLauncher.getDotInfoForItem(si));
                     }
                     ((FolderIcon) v).setDotInfo(folderDotInfo);
diff --git a/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java b/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java
index bb25b6d..9792300 100644
--- a/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java
+++ b/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java
@@ -423,11 +423,16 @@
                     widgetInfo.bindOptions = widgetInfo.getDefaultSizeOptions(mContext);
                 }
                 Workspace<?> workspace = mContext.getWorkspace();
-                workspace.post(
-                        () -> workspace.snapToPage(workspace.getPageIndexForScreenId(screenId))
-                );
-                mContext.addPendingItem(info, LauncherSettings.Favorites.CONTAINER_DESKTOP,
-                        screenId, coordinates, info.spanX, info.spanY);
+                workspace.post(() -> {
+                    workspace.snapToPage(workspace.getPageIndexForScreenId(screenId));
+                    workspace.setOnPageTransitionEndCallback(() -> {
+                        mContext.addPendingItem(info, LauncherSettings.Favorites.CONTAINER_DESKTOP,
+                                screenId, coordinates, info.spanX, info.spanY);
+                        if (finishCallback != null) {
+                            finishCallback.accept(/* success= */ true);
+                        }
+                    });
+                });
             } else if (item instanceof WorkspaceItemInfo) {
                 WorkspaceItemInfo info = ((WorkspaceItemInfo) item).clone();
                 mContext.getModelWriter().addItemToDatabase(info,
diff --git a/src/com/android/launcher3/accessibility/WorkspaceAccessibilityHelper.java b/src/com/android/launcher3/accessibility/WorkspaceAccessibilityHelper.java
index 52073cc..84d6a6f 100644
--- a/src/com/android/launcher3/accessibility/WorkspaceAccessibilityHelper.java
+++ b/src/com/android/launcher3/accessibility/WorkspaceAccessibilityHelper.java
@@ -23,6 +23,7 @@
 import com.android.launcher3.CellLayout;
 import com.android.launcher3.R;
 import com.android.launcher3.accessibility.BaseAccessibilityDelegate.DragType;
+import com.android.launcher3.folder.Folder;
 import com.android.launcher3.model.data.AppInfo;
 import com.android.launcher3.model.data.FolderInfo;
 import com.android.launcher3.model.data.ItemInfo;
@@ -117,7 +118,7 @@
             return mContext.getString(R.string.item_moved);
         } else {
             ItemInfo info = (ItemInfo) child.getTag();
-            if (info instanceof AppInfo || info instanceof WorkspaceItemInfo) {
+            if (Folder.willAccept(info)) {
                 return mContext.getString(R.string.folder_created);
 
             } else if (info instanceof FolderInfo) {
@@ -148,8 +149,8 @@
             if (TextUtils.isEmpty(info.title)) {
                 // Find the first item in the folder.
                 FolderInfo folder = (FolderInfo) info;
-                WorkspaceItemInfo firstItem = null;
-                for (WorkspaceItemInfo shortcut : folder.getContents()) {
+                ItemInfo firstItem = null;
+                for (ItemInfo shortcut : folder.getContents()) {
                     if (firstItem == null || firstItem.rank > shortcut.rank) {
                         firstItem = shortcut;
                     }
diff --git a/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java b/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java
index 4b65b73..c255eb5 100644
--- a/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java
@@ -18,6 +18,7 @@
 import static com.android.launcher3.Flags.enableExpandingPauseWorkButton;
 import static com.android.launcher3.allapps.ActivityAllAppsContainerView.AdapterHolder.MAIN;
 import static com.android.launcher3.allapps.ActivityAllAppsContainerView.AdapterHolder.SEARCH;
+import static com.android.launcher3.allapps.BaseAllAppsAdapter.VIEW_TYPE_PRIVATE_SPACE_HEADER;
 import static com.android.launcher3.allapps.BaseAllAppsAdapter.VIEW_TYPE_WORK_DISABLED_CARD;
 import static com.android.launcher3.allapps.BaseAllAppsAdapter.VIEW_TYPE_WORK_EDU_CARD;
 import static com.android.launcher3.config.FeatureFlags.ALL_APPS_GONE_VISIBILITY;
@@ -85,6 +86,7 @@
 import com.android.launcher3.pm.UserCache;
 import com.android.launcher3.recyclerview.AllAppsRecyclerViewPool;
 import com.android.launcher3.util.ItemInfoMatcher;
+import com.android.launcher3.util.Preconditions;
 import com.android.launcher3.util.Themes;
 import com.android.launcher3.views.ActivityContext;
 import com.android.launcher3.views.BaseDragLayer;
@@ -96,6 +98,7 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
+import java.util.Optional;
 import java.util.function.Predicate;
 import java.util.stream.Stream;
 
@@ -156,6 +159,7 @@
             };
     private final Paint mNavBarScrimPaint;
     private final int mHeaderProtectionColor;
+    private final int mPrivateSpaceBottomExtraSpace;
     private final Path mTmpPath = new Path();
     private final RectF mTmpRectF = new RectF();
     protected AllAppsPagedView mViewPager;
@@ -218,6 +222,8 @@
                 this,
                 mActivityContext.getStatsLogManager(),
                 UserCache.INSTANCE.get(mActivityContext));
+        mPrivateSpaceBottomExtraSpace = context.getResources().getDimensionPixelSize(
+                R.dimen.ps_extra_bottom_padding);
         mAH = Arrays.asList(null, null, null);
         mNavBarScrimPaint = new Paint();
         mNavBarScrimPaint.setColor(Themes.getNavBarScrimColor(mActivityContext));
@@ -511,7 +517,7 @@
             switchToTab(ActivityAllAppsContainerView.AdapterHolder.MAIN);
             // Scroll to bottom
             if (mPrivateProfileManager != null) {
-                mPrivateProfileManager.scrollForViewToBeVisibleInContainer(
+                mPrivateProfileManager.scrollForHeaderToBeVisibleInContainer(
                         getActiveAppsRecyclerView(),
                         getPersonalAppList().getAdapterItems(),
                         mPrivateProfileManager.getPsHeaderHeight(),
@@ -1366,6 +1372,18 @@
         invalidateHeader();
     }
 
+    /**
+     * Set {@link Animator.AnimatorListener} on {@link mAllAppsTransitionController} to observe
+     * animation of backing out of all apps search view to all apps view.
+     */
+    public void setAllAppsSearchBackAnimatorListener(Animator.AnimatorListener listener) {
+        Preconditions.assertNotNull(mAllAppsTransitionController);
+        if (mAllAppsTransitionController == null) {
+            return;
+        }
+        mAllAppsTransitionController.setAllAppsSearchBackAnimationListener(listener);
+    }
+
     public void setScrimView(ScrimView scrimView) {
         mScrimView = scrimView;
     }
@@ -1564,6 +1582,14 @@
                 int bottomOffset = 0;
                 if (isWork() && mWorkManager.getWorkModeSwitch() != null) {
                     bottomOffset = mInsets.bottom + mWorkManager.getWorkModeSwitch().getHeight();
+                } else if (isMain() && mPrivateProfileManager != null) {
+                    Optional<AdapterItem> privateSpaceHeaderItem = mAppsList.getAdapterItems()
+                            .stream()
+                            .filter(item -> item.viewType == VIEW_TYPE_PRIVATE_SPACE_HEADER)
+                            .findFirst();
+                    if (privateSpaceHeaderItem.isPresent()) {
+                        bottomOffset = mPrivateSpaceBottomExtraSpace;
+                    }
                 }
                 if (isSearchBarFloating()) {
                     bottomOffset += mSearchContainer.getHeight();
@@ -1580,5 +1606,9 @@
         private boolean isSearch() {
             return mType == SEARCH;
         }
+
+        private boolean isMain() {
+            return mType == MAIN;
+        }
     }
 }
diff --git a/src/com/android/launcher3/allapps/AllAppsTransitionController.java b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
index 63f6227..564daf1 100644
--- a/src/com/android/launcher3/allapps/AllAppsTransitionController.java
+++ b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
@@ -44,6 +44,7 @@
 import android.view.animation.Interpolator;
 
 import androidx.annotation.FloatRange;
+import androidx.annotation.Nullable;
 
 import com.android.app.animation.Interpolators;
 import com.android.launcher3.DeviceProfile;
@@ -167,6 +168,8 @@
     private final AnimatedFloat mAllAppScale = new AnimatedFloat(this::onScaleProgressChanged);
     private final int mNavScrimFlag;
 
+    @Nullable private Animator.AnimatorListener mAllAppsSearchBackAnimationListener;
+
     private boolean mIsVerticalLayout;
 
     // Animation in this class is controlled by a single variable {@link mProgress}.
@@ -280,8 +283,7 @@
             return;
         }
 
-        float deceleratedProgress =
-                Interpolators.PREDICTIVE_BACK_DECELERATED_EASE.getInterpolation(backProgress);
+        float deceleratedProgress = Interpolators.BACK_GESTURE.getInterpolation(backProgress);
         float scaleProgress = ScrollableLayoutManager.PREDICTIVE_BACK_MIN_SCALE
                 + (1 - ScrollableLayoutManager.PREDICTIVE_BACK_MIN_SCALE)
                 * (1 - deceleratedProgress);
@@ -312,11 +314,25 @@
         }
     }
 
-    /** Animate all apps view to 1f scale. */
+    /** Set {@link Animator.AnimatorListener} for scaling all apps scale to 1 animation. */
+    public void setAllAppsSearchBackAnimationListener(Animator.AnimatorListener listener) {
+        mAllAppsSearchBackAnimationListener = listener;
+    }
+
+    /**
+     * Animate all apps view to 1f scale. This is called when backing (exiting) from all apps
+     * search view to all apps view.
+     */
     public void animateAllAppsToNoScale() {
-        mAllAppScale.animateToValue(1f)
-                .setDuration(REVERT_SWIPE_ALL_APPS_TO_HOME_ANIMATION_DURATION_MS)
-                .start();
+        if (mAllAppScale.isAnimating()) {
+            return;
+        }
+        Animator animator = mAllAppScale.animateToValue(1f)
+                .setDuration(REVERT_SWIPE_ALL_APPS_TO_HOME_ANIMATION_DURATION_MS);
+        if (mAllAppsSearchBackAnimationListener != null) {
+            animator.addListener(mAllAppsSearchBackAnimationListener);
+        }
+        animator.start();
     }
 
     /**
diff --git a/src/com/android/launcher3/allapps/BaseAllAppsAdapter.java b/src/com/android/launcher3/allapps/BaseAllAppsAdapter.java
index 2190e1a..3ba1eed 100644
--- a/src/com/android/launcher3/allapps/BaseAllAppsAdapter.java
+++ b/src/com/android/launcher3/allapps/BaseAllAppsAdapter.java
@@ -21,6 +21,7 @@
 import static com.android.launcher3.allapps.SectionDecorationInfo.ROUND_TOP_LEFT;
 import static com.android.launcher3.allapps.SectionDecorationInfo.ROUND_TOP_RIGHT;
 import static com.android.launcher3.allapps.UserProfileManager.STATE_DISABLED;
+import static com.android.launcher3.allapps.UserProfileManager.STATE_ENABLED;
 
 import android.content.Context;
 import android.view.LayoutInflater;
@@ -40,7 +41,6 @@
 import com.android.launcher3.LauncherPrefs;
 import com.android.launcher3.R;
 import com.android.launcher3.allapps.search.SearchAdapterProvider;
-import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.model.data.AppInfo;
 import com.android.launcher3.views.ActivityContext;
 
@@ -262,6 +262,17 @@
                 icon.reset();
                 icon.applyFromApplicationInfo(adapterItem.itemInfo);
                 icon.setOnFocusChangeListener(mIconFocusListener);
+                PrivateProfileManager privateProfileManager = mApps.getPrivateProfileManager();
+                // Set the alpha of the private space icon to 0 upon expanding the header so the
+                // alpha can animate -> 1.
+                if (icon.getAlpha() == 0 || icon.getAlpha() == 1) {
+                    icon.setAlpha(privateProfileManager != null
+                            && privateProfileManager.isPrivateSpaceItem(adapterItem)
+                            && privateProfileManager.getAnimationScrolling()
+                            && privateProfileManager.getAnimate()
+                            && privateProfileManager.getCurrentState() == STATE_ENABLED
+                            ? 0 : 1);
+                }
                 break;
             }
             case VIEW_TYPE_EMPTY_SEARCH: {
diff --git a/src/com/android/launcher3/allapps/PrivateProfileManager.java b/src/com/android/launcher3/allapps/PrivateProfileManager.java
index eb967bc..1def8a3 100644
--- a/src/com/android/launcher3/allapps/PrivateProfileManager.java
+++ b/src/com/android/launcher3/allapps/PrivateProfileManager.java
@@ -40,6 +40,7 @@
 import android.animation.AnimatorListenerAdapter;
 import android.animation.AnimatorSet;
 import android.animation.LayoutTransition;
+import android.animation.ObjectAnimator;
 import android.animation.ValueAnimator;
 import android.content.Context;
 import android.content.Intent;
@@ -52,6 +53,7 @@
 import android.widget.RelativeLayout;
 import android.widget.TextView;
 
+import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.annotation.VisibleForTesting;
 import androidx.recyclerview.widget.LinearSmoothScroller;
@@ -70,7 +72,7 @@
 import com.android.launcher3.model.data.AppInfo;
 import com.android.launcher3.model.data.PrivateSpaceInstallAppButtonInfo;
 import com.android.launcher3.pm.UserCache;
-import com.android.launcher3.uioverrides.ApiWrapper;
+import com.android.launcher3.util.ApiWrapper;
 import com.android.launcher3.util.Preconditions;
 import com.android.launcher3.util.SettingsCache;
 import com.android.launcher3.views.ActivityContext;
@@ -91,13 +93,27 @@
     private static final int SETTINGS_OPACITY_DURATION = 160;
     private final ActivityAllAppsContainerView<?> mAllApps;
     private final Predicate<UserHandle> mPrivateProfileMatcher;
+    private final int mPsHeaderHeight;
+    private final RecyclerView.OnScrollListener mOnIdleScrollListener =
+            new RecyclerView.OnScrollListener() {
+        @Override
+        public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
+            super.onScrollStateChanged(recyclerView, newState);
+            if (newState == RecyclerView.SCROLL_STATE_IDLE) {
+                mAnimationScrolling = false;
+            }
+        }
+    };
     private Set<String> mPreInstalledSystemPackages = new HashSet<>();
     private Intent mAppInstallerIntent = new Intent();
     private PrivateAppsSectionDecorator mPrivateAppsSectionDecorator;
     private boolean mPrivateSpaceSettingsAvailable;
     private boolean mIsAnimationRunning;
-    private int mHeaderHeight;
     private boolean mAnimate;
+    private boolean mAnimationScrolling;
+    private Runnable mOnPSHeaderAdded;
+    @Nullable
+    private RelativeLayout mPSHeader;
 
     public PrivateProfileManager(UserManager userManager,
             ActivityAllAppsContainerView<?> allApps,
@@ -106,7 +122,11 @@
         super(userManager, statsLogManager, userCache);
         mAllApps = allApps;
         mPrivateProfileMatcher = (user) -> userCache.getUserInfo(user).isPrivate();
-        UI_HELPER_EXECUTOR.post(this::initializeInBackgroundThread);
+
+        Context appContext = allApps.getContext().getApplicationContext();
+        UI_HELPER_EXECUTOR.post(() -> initializeInBackgroundThread(appContext));
+        mPsHeaderHeight = mAllApps.getContext().getResources().getDimensionPixelSize(
+                R.dimen.ps_header_height);
     }
 
     /** Adds Private Space Header to the layout. */
@@ -169,29 +189,36 @@
     /** Whether private profile should be hidden on Launcher. */
     public boolean isPrivateSpaceHidden() {
         return getCurrentState() == STATE_DISABLED && SettingsCache.INSTANCE
-                    .get(mAllApps.mActivityContext).getValue(PRIVATE_SPACE_HIDE_WHEN_LOCKED_URI, 0);
+                    .get(mAllApps.getContext()).getValue(PRIVATE_SPACE_HIDE_WHEN_LOCKED_URI, 0);
     }
 
-    /** Resets the current state of Private Profile, w.r.t. to Launcher. */
+    /**
+     * Resets the current state of Private Profile, w.r.t. to Launcher. The decorator should only
+     * be applied upon expand before animating. When collapsing, reset() will remove the decorator
+     * when animation is not running.
+     */
     public void reset() {
         int previousState = getCurrentState();
         boolean isEnabled = !mAllApps.getAppsStore()
                 .hasModelFlag(FLAG_PRIVATE_PROFILE_QUIET_MODE_ENABLED);
         int updatedState = isEnabled ? STATE_ENABLED : STATE_DISABLED;
         setCurrentState(updatedState);
-        resetPrivateSpaceDecorator(updatedState);
+        if (mPSHeader != null) {
+            mPSHeader.setAlpha(1);
+        }
         if (transitioningFromLockedToUnlocked(previousState, updatedState)) {
             postUnlock();
         } else if (transitioningFromUnlockedToLocked(previousState, updatedState)){
             executeLock();
         }
+        resetPrivateSpaceDecorator(updatedState);
     }
 
     /** Opens the Private Space Settings Page. */
     public void openPrivateSpaceSettings() {
         if (mPrivateSpaceSettingsAvailable) {
-            mAllApps.getContext()
-                    .startActivity(ApiWrapper.getPrivateSpaceSettingsIntent(mAllApps.getContext()));
+            mAllApps.getContext().startActivity(
+                    ApiWrapper.INSTANCE.get(mAllApps.getContext()).getPrivateSpaceSettingsIntent());
         }
     }
 
@@ -214,33 +241,17 @@
      * This case should still be ok, as locking the Private Space container and unlocking it,
      * reloads the values, fixing the incorrect UI.
      */
-    private void initializeInBackgroundThread() {
+    private void initializeInBackgroundThread(Context appContext) {
         Preconditions.assertNonUiThread();
-        setPreInstalledSystemPackages();
-        setAppInstallerIntent();
-        initializePrivateSpaceSettingsState();
-    }
-
-    private void initializePrivateSpaceSettingsState() {
-        Preconditions.assertNonUiThread();
-        Intent psSettingsIntent = ApiWrapper.getPrivateSpaceSettingsIntent(mAllApps.getContext());
-        setPrivateSpaceSettingsAvailable(psSettingsIntent != null);
-    }
-
-    private void setPreInstalledSystemPackages() {
-        Preconditions.assertNonUiThread();
-        if (getProfileUser() != null) {
-            mPreInstalledSystemPackages = new HashSet<>(ApiWrapper
-                    .getPreInstalledSystemPackages(mAllApps.getContext(), getProfileUser()));
+        ApiWrapper apiWrapper = ApiWrapper.INSTANCE.get(appContext);
+        UserHandle profileUser = getProfileUser();
+        if (profileUser != null) {
+            mPreInstalledSystemPackages = new HashSet<>(
+                    apiWrapper.getPreInstalledSystemPackages(profileUser));
+            mAppInstallerIntent = apiWrapper
+                    .getAppMarketActivityIntent(BuildConfig.APPLICATION_ID, profileUser);
         }
-    }
-
-    private void setAppInstallerIntent() {
-        Preconditions.assertNonUiThread();
-        if (getProfileUser() != null) {
-            mAppInstallerIntent = ApiWrapper.getAppMarketActivityIntent(mAllApps.getContext(),
-                    BuildConfig.APPLICATION_ID, getProfileUser());
-        }
+        setPrivateSpaceSettingsAvailable(apiWrapper.getPrivateSpaceSettingsIntent() != null);
     }
 
     @VisibleForTesting
@@ -263,7 +274,7 @@
             mainAdapterHolder.mRecyclerView.addItemDecoration(mPrivateAppsSectionDecorator);
         } else {
             // Remove Private Space Decorator from the Recycler view.
-            if (mPrivateAppsSectionDecorator != null) {
+            if (mPrivateAppsSectionDecorator != null && !mIsAnimationRunning) {
                 mainAdapterHolder.mRecyclerView.removeItemDecoration(mPrivateAppsSectionDecorator);
             }
         }
@@ -289,10 +300,13 @@
 
     /** Collapses the private space before the app list has been updated. */
     void executeLock() {
-        MAIN_EXECUTOR.execute(this::collapsePrivateSpace);
+        MAIN_EXECUTOR.execute(() -> updatePrivateStateAnimator(false));
     }
 
     void setAnimationRunning(boolean isAnimationRunning) {
+        if (!isAnimationRunning) {
+            mAnimate = false;
+        }
         mIsAnimationRunning = isAnimationRunning;
     }
 
@@ -325,8 +339,13 @@
 
     /** Add Private Space Header view elements based upon {@link UserProfileState} */
     public void addPrivateSpaceHeaderViewElements(RelativeLayout parent) {
+        mPSHeader = parent;
+        if (mOnPSHeaderAdded != null) {
+            MAIN_EXECUTOR.execute(mOnPSHeaderAdded);
+            mOnPSHeaderAdded = null;
+        }
         // Set the transition duration for the settings and lock button to animate.
-        ViewGroup settingAndLockGroup = parent.findViewById(R.id.settingsAndLockGroup);
+        ViewGroup settingAndLockGroup = mPSHeader.findViewById(R.id.settingsAndLockGroup);
         if (mAnimate) {
             enableLayoutTransition(settingAndLockGroup);
         } else {
@@ -335,16 +354,15 @@
         }
 
         //Add quietMode image and action for lock/unlock button
-        ViewGroup lockButton =
-                parent.findViewById(R.id.ps_lock_unlock_button);
+        ViewGroup lockButton = mPSHeader.findViewById(R.id.ps_lock_unlock_button);
         assert lockButton != null;
         addLockButton(lockButton);
 
         //Trigger lock/unlock action from header.
-        addHeaderOnClickListener(parent);
+        addHeaderOnClickListener(mPSHeader);
 
         //Add image and action for private space settings button
-        ImageButton settingsButton = parent.findViewById(R.id.ps_settings_button);
+        ImageButton settingsButton = mPSHeader.findViewById(R.id.ps_settings_button);
         assert settingsButton != null;
         addPrivateSpaceSettingsButton(settingsButton);
 
@@ -352,7 +370,6 @@
         ImageView transitionView = parent.findViewById(R.id.ps_transition_image);
         assert transitionView != null;
         addTransitionImage(transitionView);
-        mHeaderHeight = parent.getHeight();
     }
 
     /**
@@ -379,8 +396,10 @@
     private void addHeaderOnClickListener(RelativeLayout header) {
         if (getCurrentState() == STATE_DISABLED) {
             header.setOnClickListener(view -> lockingAction(/* lock */ false));
+            header.setClickable(true);
         } else {
             header.setOnClickListener(null);
+            header.setClickable(false);
         }
     }
 
@@ -436,16 +455,18 @@
                 smoothScroller.setTargetPosition(i);
                 RecyclerView.LayoutManager layoutManager = allAppsRecyclerView.getLayoutManager();
                 if (layoutManager != null) {
-                    layoutManager.startSmoothScroll(smoothScroller);
+                    startAnimationScroll(allAppsRecyclerView, layoutManager, smoothScroller);
+                    currentItem.decorationInfo = null;
                 }
                 break;
             }
             // Make the private space apps gone to "collapse".
-            if (currentItem.decorationInfo != null) {
+            if (isPrivateSpaceItem(currentItem)) {
                 RecyclerView.ViewHolder viewHolder =
                         allAppsRecyclerView.findViewHolderForAdapterPosition(i);
                 if (viewHolder != null) {
                     viewHolder.itemView.setVisibility(GONE);
+                    currentItem.decorationInfo = null;
                 }
             }
         }
@@ -455,7 +476,7 @@
      * Upon expanding, only scroll to the item position in the adapter that allows the header to be
      * visible.
      */
-    public int scrollForViewToBeVisibleInContainer(
+    public int scrollForHeaderToBeVisibleInContainer(
             AllAppsRecyclerView allAppsRecyclerView,
             List<BaseAllAppsAdapter.AdapterItem> appListAdapterItems,
             int psHeaderHeight,
@@ -495,7 +516,7 @@
             smoothScroller.setTargetPosition(itemToScrollTo);
             RecyclerView.LayoutManager layoutManager = allAppsRecyclerView.getLayoutManager();
             if (layoutManager != null) {
-                layoutManager.startSmoothScroll(smoothScroller);
+                startAnimationScroll(allAppsRecyclerView, layoutManager, smoothScroller);
             }
         }
         return itemToScrollTo;
@@ -531,27 +552,56 @@
         return collapseAnim;
     }
 
+    private ValueAnimator animateAlphaOfIcons(boolean isExpanding) {
+        float from = isExpanding ? 0 : 1;
+        float to = isExpanding ? 1 : 0;
+        AllAppsRecyclerView allAppsRecyclerView = mAllApps.getActiveRecyclerView();
+        List<BaseAllAppsAdapter.AdapterItem> allAppsAdapterItems =
+                mAllApps.getActiveRecyclerView().getApps().getAdapterItems();
+        ValueAnimator alphaAnim = ObjectAnimator.ofFloat(from, to);
+        alphaAnim.setDuration(EXPAND_COLLAPSE_DURATION);
+        alphaAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+            @Override
+            public void onAnimationUpdate(ValueAnimator valueAnimator) {
+                float newAlpha = (float) valueAnimator.getAnimatedValue();
+                for (int i = 0; i < allAppsAdapterItems.size(); i++) {
+                    BaseAllAppsAdapter.AdapterItem currentItem = allAppsAdapterItems.get(i);
+                    if (isPrivateSpaceItem(currentItem) &&
+                            currentItem.viewType != VIEW_TYPE_PRIVATE_SPACE_HEADER) {
+                        RecyclerView.ViewHolder viewHolder =
+                                allAppsRecyclerView.findViewHolderForAdapterPosition(i);
+                        if (viewHolder != null) {
+                            viewHolder.itemView.setAlpha(newAlpha);
+                        }
+                    }
+                }
+            }
+        });
+        return alphaAnim;
+    }
+
     /**
      * Using PropertySetter{@link PropertySetter}, we can update the view's attributes within an
      * animation. At the moment, collapsing, setting alpha changes, and animating the text is done
      * here.
      */
-    private void updatePrivateStateAnimator(boolean expand, @Nullable ViewGroup psHeader) {
-        if (psHeader == null) {
+    private void updatePrivateStateAnimator(boolean expand) {
+        if (mPSHeader == null) {
+            mOnPSHeaderAdded = () -> updatePrivateStateAnimator(expand);
+            setAnimationRunning(false);
             return;
         }
-        ViewGroup settingsAndLockGroup = psHeader.findViewById(R.id.settingsAndLockGroup);
-        ViewGroup lockButton = psHeader.findViewById(R.id.ps_lock_unlock_button);
+        ViewGroup settingsAndLockGroup = mPSHeader.findViewById(R.id.settingsAndLockGroup);
+        ViewGroup lockButton = mPSHeader.findViewById(R.id.ps_lock_unlock_button);
         if (settingsAndLockGroup.getLayoutTransition() == null) {
             // Set a new transition if the current ViewGroup does not already contain one as each
             // transition should only happen once when applied.
             enableLayoutTransition(settingsAndLockGroup);
         }
-
-        PropertySetter setter = new AnimatedPropertySetter();
-        ImageButton settingsButton = psHeader.findViewById(R.id.ps_settings_button);
-        updateSettingsGearAlpha(settingsButton, expand, setter);
-        AnimatorSet animatorSet = setter.buildAnim();
+        PropertySetter headerSetter = new AnimatedPropertySetter();
+        ImageButton settingsButton = mPSHeader.findViewById(R.id.ps_settings_button);
+        updateSettingsGearAlpha(settingsButton, expand, headerSetter);
+        AnimatorSet animatorSet = headerSetter.buildAnim();
         animatorSet.addListener(new AnimatorListenerAdapter() {
             @Override
             public void onAnimationStart(Animator animation) {
@@ -562,22 +612,50 @@
         });
         animatorSet.addListener(forEndCallback(() -> {
             setAnimationRunning(false);
-            mAnimate = false;
             if (!expand) {
                 // Call onAppsUpdated() because it may be canceled when this animation occurs.
                 mAllApps.getPersonalAppList().onAppsUpdated();
+                if (isPrivateSpaceHidden()) {
+                    // TODO (b/325455879): Figure out if we can avoid this.
+                    mAllApps.getActiveRecyclerView().getAdapter().notifyDataSetChanged();
+                }
             }
         }));
-        // Play the collapsing together of the stateAnimator to avoid being unable to scroll to the
-        // header. Otherwise the smooth scrolling will scroll higher when played with the state
-        // animator.
-        if (!expand) {
-            animatorSet.playTogether(animateCollapseAnimation());
+        if (expand) {
+            animatorSet.playTogether(animateAlphaOfIcons(true));
+        } else {
+            if (isPrivateSpaceHidden()) {
+                animatorSet.playSequentially(animateAlphaOfIcons(false),
+                        animateCollapseAnimation(), fadeOutHeaderAlpha());
+            } else {
+                animatorSet.playSequentially(animateAlphaOfIcons(false),
+                        animateCollapseAnimation());
+            }
         }
         animatorSet.setDuration(EXPAND_COLLAPSE_DURATION);
         animatorSet.start();
     }
 
+    /** Fades out the private space container. */
+    private ValueAnimator fadeOutHeaderAlpha() {
+        if (mPSHeader == null) {
+            return new ValueAnimator();
+        }
+        float from = 1;
+        float to = 0;
+        ValueAnimator alphaAnim = ObjectAnimator.ofFloat(from, to);
+        alphaAnim.setDuration(EXPAND_COLLAPSE_DURATION);
+        alphaAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+            @Override
+            public void onAnimationUpdate(ValueAnimator valueAnimator) {
+                if (mPSHeader != null) {
+                    mPSHeader.setAlpha((float) valueAnimator.getAnimatedValue());
+                }
+            }
+        });
+        return alphaAnim;
+    }
+
     /** Animates the layout changes when the text of the button becomes visible/gone. */
     private void enableLayoutTransition(ViewGroup settingsAndLockGroup) {
         LayoutTransition settingsAndLockTransition = new LayoutTransition();
@@ -617,10 +695,9 @@
             // Animate the text and settings icon.
             DeviceProfile deviceProfile =
                     ActivityContext.lookupContext(mAllApps.getContext()).getDeviceProfile();
-            scrollForViewToBeVisibleInContainer(mainAdapterHolder.mRecyclerView, adapterItems,
+            scrollForHeaderToBeVisibleInContainer(mainAdapterHolder.mRecyclerView, adapterItems,
                     getPsHeaderHeight(), deviceProfile.allAppsCellHeightPx);
-            ViewGroup psHeader = getPsHeader(mainAdapterHolder.mRecyclerView, adapterItems);
-            updatePrivateStateAnimator(true, psHeader);
+            updatePrivateStateAnimator(true);
         }
     }
 
@@ -635,36 +712,28 @@
         });
     }
 
-    private void collapsePrivateSpace() {
-        AllAppsRecyclerView allAppsRecyclerView = mAllApps.getActiveRecyclerView();
-        AlphabeticalAppsList<?> appList = allAppsRecyclerView.getApps();
-        if (appList == null) {
-            return;
-        }
-        ViewGroup psHeader = getPsHeader(allAppsRecyclerView, appList.getAdapterItems());
-        assert psHeader != null;
-        updatePrivateStateAnimator(false, psHeader);
+    /** Starts the smooth scroll with the provided smoothScroller and add idle listener. */
+    private void startAnimationScroll(AllAppsRecyclerView allAppsRecyclerView,
+            RecyclerView.LayoutManager layoutManager, RecyclerView.SmoothScroller smoothScroller) {
+        mAnimationScrolling = true;
+        layoutManager.startSmoothScroll(smoothScroller);
+        allAppsRecyclerView.removeOnScrollListener(mOnIdleScrollListener);
+        allAppsRecyclerView.addOnScrollListener(mOnIdleScrollListener);
+    }
+
+    boolean getAnimate() {
+        return mAnimate;
+    }
+
+    boolean getAnimationScrolling() {
+        return mAnimationScrolling;
     }
 
     int getPsHeaderHeight() {
-        return mHeaderHeight;
+        return mPsHeaderHeight;
     }
 
-    /** Get the private space header from the adapter items. */
-    @Nullable
-    private ViewGroup getPsHeader(AllAppsRecyclerView allAppsRecyclerView,
-            List<BaseAllAppsAdapter.AdapterItem> adapterItems){
-        ViewGroup psHeader = null;
-        for (int i = 0; i < adapterItems.size(); i++) {
-            BaseAllAppsAdapter.AdapterItem currentItem = adapterItems.get(i);
-            if (currentItem.viewType == VIEW_TYPE_PRIVATE_SPACE_HEADER) {
-                RecyclerView.ViewHolder viewHolder =
-                        allAppsRecyclerView.findViewHolderForAdapterPosition(i);
-                if (viewHolder != null) {
-                    psHeader = (ViewGroup) viewHolder.itemView;
-                }
-            }
-        }
-        return psHeader;
+    boolean isPrivateSpaceItem(BaseAllAppsAdapter.AdapterItem item) {
+        return item.decorationInfo != null;
     }
 }
diff --git a/src/com/android/launcher3/apppairs/AppPairIcon.java b/src/com/android/launcher3/apppairs/AppPairIcon.java
index 9010f82..0e955ad 100644
--- a/src/com/android/launcher3/apppairs/AppPairIcon.java
+++ b/src/com/android/launcher3/apppairs/AppPairIcon.java
@@ -30,11 +30,13 @@
 
 import com.android.launcher3.BubbleTextView;
 import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.LauncherAppState;
 import com.android.launcher3.R;
 import com.android.launcher3.Reorderable;
 import com.android.launcher3.dragndrop.DraggableView;
+import com.android.launcher3.icons.IconCache;
 import com.android.launcher3.model.data.AppPairInfo;
-import com.android.launcher3.model.data.WorkspaceItemInfo;
+import com.android.launcher3.model.data.ItemInfo;
 import com.android.launcher3.util.MultiTranslateDelegate;
 import com.android.launcher3.views.ActivityContext;
 
@@ -108,22 +110,42 @@
         // For some reason, app icons have setIncludeFontPadding(false) inside folders, so we set it
         // here to match that.
         icon.mAppPairName.setIncludeFontPadding(container != DISPLAY_FOLDER);
-        icon.mAppPairName.applyLabel(appPairInfo);
+        // Set title text and accessibility title text.
+        icon.updateTitleAndA11yTitle();
 
-        // Set up accessibility
-        icon.setContentDescription(icon.getAccessibilityTitle(appPairInfo));
         icon.setAccessibilityDelegate(activity.getAccessibilityDelegate());
 
         return icon;
     }
 
     /**
-     * Returns a formatted accessibility title for app pairs.
+     * Updates the title and a11y title of the app pair. Called on creation and when packages
+     * change, to reflect app name changes or user language changes.
      */
-    public String getAccessibilityTitle(AppPairInfo appPairInfo) {
-        CharSequence app1 = appPairInfo.getFirstApp().title;
-        CharSequence app2 = appPairInfo.getSecondApp().title;
-        return getContext().getString(R.string.app_pair_name_format, app1, app2);
+    public void updateTitleAndA11yTitle() {
+        updateTitleAndTextView();
+        updateAccessibilityTitle();
+    }
+
+    /**
+     * Updates AppPairInfo with a formatted app pair title, and sets it on the BubbleTextView.
+     */
+    public void updateTitleAndTextView() {
+        CharSequence newTitle = getInfo().generateTitle(getContext());
+        mAppPairName.setText(newTitle);
+    }
+
+    /**
+     * Updates the accessibility title with a formatted string template.
+     */
+    public void updateAccessibilityTitle() {
+        CharSequence app1 = getInfo().getFirstApp().title;
+        CharSequence app2 = getInfo().getSecondApp().title;
+        String a11yTitle = getContext().getString(R.string.app_pair_name_format, app1, app2);
+        setContentDescription(
+                getInfo().shouldDrawAsDisabled(getContext())
+                        ? getContext().getString(R.string.disabled_app_label, a11yTitle)
+                        : a11yTitle);
     }
 
     // Required for DraggableView
@@ -179,13 +201,26 @@
         return mIconGraphic;
     }
 
+    public int getContainer() {
+        return mContainer;
+    }
+
+    /**
+     * Ensures that both app icons in the pair are loaded in high resolution.
+     */
+    public void verifyHighRes() {
+        IconCache iconCache = LauncherAppState.getInstance(getContext()).getIconCache();
+        getInfo().fetchHiResIconsIfNeeded(iconCache);
+    }
+
     /**
      * Called when WorkspaceItemInfos get updated, and the app pair icon may need to be redrawn.
      */
-    public void maybeRedrawForWorkspaceUpdate(Predicate<WorkspaceItemInfo> itemCheck) {
+    public void maybeRedrawForWorkspaceUpdate(Predicate<ItemInfo> itemCheck) {
         // If either of the app pair icons return true on the predicate (i.e. in the list of
         // updated apps), redraw the icon graphic (icon background and both icons).
         if (getInfo().anyMatch(itemCheck)) {
+            updateTitleAndA11yTitle();
             mIconGraphic.redraw();
         }
     }
diff --git a/src/com/android/launcher3/apppairs/AppPairIconDrawable.java b/src/com/android/launcher3/apppairs/AppPairIconDrawable.java
index c0ac11a..db83d91 100644
--- a/src/com/android/launcher3/apppairs/AppPairIconDrawable.java
+++ b/src/com/android/launcher3/apppairs/AppPairIconDrawable.java
@@ -32,7 +32,7 @@
  * A composed Drawable consisting of the two app pair icons and the background behind them (looks
  * like two rectangles).
  */
-class AppPairIconDrawable extends Drawable {
+public class AppPairIconDrawable extends Drawable {
     private final Paint mBackgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
     private final AppPairIconDrawingParams mP;
     private final FastBitmapDrawable mIcon1;
@@ -102,6 +102,7 @@
         }
 
         mIcon2.draw(canvas);
+        canvas.restore();
     }
 
     /**
@@ -205,4 +206,14 @@
     public void setColorFilter(ColorFilter colorFilter) {
         mBackgroundPaint.setColorFilter(colorFilter);
     }
+
+    @Override
+    public int getIntrinsicWidth() {
+        return mP.getIconSize();
+    }
+
+    @Override
+    public int getIntrinsicHeight() {
+        return mP.getIconSize();
+    }
 }
diff --git a/src/com/android/launcher3/apppairs/AppPairIconDrawingParams.kt b/src/com/android/launcher3/apppairs/AppPairIconDrawingParams.kt
index 62e5771..45dc013 100644
--- a/src/com/android/launcher3/apppairs/AppPairIconDrawingParams.kt
+++ b/src/com/android/launcher3/apppairs/AppPairIconDrawingParams.kt
@@ -20,6 +20,7 @@
 import com.android.launcher3.BubbleTextView.DISPLAY_FOLDER
 import com.android.launcher3.DeviceProfile
 import com.android.launcher3.R
+import com.android.launcher3.util.Themes
 import com.android.launcher3.views.ActivityContext
 
 class AppPairIconDrawingParams(val context: Context, container: Int) {
@@ -62,7 +63,7 @@
     // The app pair icon appears differently in portrait and landscape.
     var isLeftRightSplit: Boolean = true
     // The background paint color (based on container).
-    val bgColor: Int
+    var bgColor: Int = 0
 
     init {
         val activity: ActivityContext = ActivityContext.lookupContext(context)
@@ -77,22 +78,21 @@
         innerPadding = iconSize * INNER_PADDING_SCALE
         memberIconSize = iconSize * MEMBER_ICON_SCALE
         updateOrientation(dp)
-        if (container == DISPLAY_FOLDER) {
-            val ta =
-                context.theme.obtainStyledAttributes(
-                    intArrayOf(R.attr.materialColorSurfaceContainerLowest)
-                )
-            bgColor = ta.getColor(0, 0)
-            ta.recycle()
-        } else {
-            val ta = context.theme.obtainStyledAttributes(R.styleable.FolderIconPreview)
-            bgColor = ta.getColor(R.styleable.FolderIconPreview_folderPreviewColor, 0)
-            ta.recycle()
-        }
+        updateBgColor(container)
     }
 
     /** Checks the device orientation and updates isLeftRightSplit accordingly. */
     fun updateOrientation(dp: DeviceProfile) {
         isLeftRightSplit = dp.isLeftRightSplit
     }
+
+    fun updateBgColor(container: Int) {
+        if (container == DISPLAY_FOLDER) {
+            bgColor = Themes.getAttrColor(context, R.attr.appPairSurfaceInFolder)
+        } else {
+            val ta = context.theme.obtainStyledAttributes(R.styleable.FolderIconPreview)
+            bgColor = ta.getColor(R.styleable.FolderIconPreview_folderPreviewColor, 0)
+            ta.recycle()
+        }
+    }
 }
diff --git a/src/com/android/launcher3/apppairs/AppPairIconGraphic.kt b/src/com/android/launcher3/apppairs/AppPairIconGraphic.kt
index a3a1cfc..7809102 100644
--- a/src/com/android/launcher3/apppairs/AppPairIconGraphic.kt
+++ b/src/com/android/launcher3/apppairs/AppPairIconGraphic.kt
@@ -19,7 +19,6 @@
 import android.content.Context
 import android.graphics.Canvas
 import android.graphics.Rect
-import android.graphics.drawable.Drawable
 import android.util.AttributeSet
 import android.view.Gravity
 import android.widget.FrameLayout
@@ -27,7 +26,6 @@
 import com.android.launcher3.DeviceProfile
 import com.android.launcher3.DeviceProfile.OnDeviceProfileChangeListener
 import com.android.launcher3.icons.BitmapInfo
-import com.android.launcher3.icons.FastBitmapDrawable.getDisabledColorFilter
 import com.android.launcher3.model.data.AppPairInfo
 import com.android.launcher3.util.Themes
 import com.android.launcher3.views.ActivityContext
@@ -44,15 +42,12 @@
     private val TAG = "AppPairIconGraphic"
 
     companion object {
-        /**
-         * Composes a drawable for this icon, consisting of a background and 2 app icons. The app
-         * pair will draw as "disabled" if either of the following is true:
-         * 1) One of the member WorkspaceItemInfos is disabled (i.e. the app software itself is
-         *    paused or can't be launched for some other reason).
-         * 2) One of the member apps can't be launched due to screen size requirements.
-         */
+        /** Composes a drawable for this icon, consisting of a background and 2 app icons. */
         @JvmStatic
-        fun composeDrawable(appPairInfo: AppPairInfo, p: AppPairIconDrawingParams): Drawable {
+        fun composeDrawable(
+            appPairInfo: AppPairInfo,
+            p: AppPairIconDrawingParams
+        ): AppPairIconDrawable {
             // Generate new icons, using themed flag if needed.
             val flags = if (Themes.isThemedIconEnabled(p.context)) BitmapInfo.FLAG_THEMED else 0
             val appIcon1 = appPairInfo.getFirstApp().newIcon(p.context, flags)
@@ -60,28 +55,17 @@
             appIcon1.setBounds(0, 0, p.memberIconSize.toInt(), p.memberIconSize.toInt())
             appIcon2.setBounds(0, 0, p.memberIconSize.toInt(), p.memberIconSize.toInt())
 
-            val shouldDrawAsDisabled =
-                appPairInfo.isDisabled || !appPairInfo.isLaunchable(p.context)
-
-            // Set disabled status on icons.
-            appIcon1.setIsDisabled(shouldDrawAsDisabled)
-            appIcon2.setIsDisabled(shouldDrawAsDisabled)
-
             // Create icon drawable.
             val fullIconDrawable = AppPairIconDrawable(p, appIcon1, appIcon2)
             fullIconDrawable.setBounds(0, 0, p.iconSize, p.iconSize)
 
-            // Set disabled color filter on background paint.
-            fullIconDrawable.colorFilter =
-                if (shouldDrawAsDisabled) getDisabledColorFilter() else null
-
             return fullIconDrawable
         }
     }
 
     private lateinit var parentIcon: AppPairIcon
     private lateinit var drawParams: AppPairIconDrawingParams
-    private lateinit var drawable: Drawable
+    lateinit var drawable: AppPairIconDrawable
 
     fun init(icon: AppPairIcon, container: Int) {
         parentIcon = icon
@@ -116,10 +100,13 @@
         redraw()
     }
 
-    /** Updates the icon drawable and redraws it */
-    fun redraw() {
-        drawable = composeDrawable(parentIcon.info, drawParams)
-        invalidate()
+    /**
+     * When the icon is temporary moved to a different colored surface, update the background color.
+     * Calling this method with [null] reverts the icon back to its default color.
+     */
+    fun onTemporaryContainerChange(newContainer: Int?) {
+        drawParams.updateBgColor(newContainer ?: parentIcon.container)
+        redraw()
     }
 
     /**
@@ -136,6 +123,12 @@
         )
     }
 
+    /** Updates the icon drawable and redraws it */
+    fun redraw() {
+        drawable = composeDrawable(parentIcon.info, drawParams)
+        invalidate()
+    }
+
     override fun dispatchDraw(canvas: Canvas) {
         super.dispatchDraw(canvas)
         drawable.draw(canvas)
diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java
index 1c34c72..830e552 100644
--- a/src/com/android/launcher3/config/FeatureFlags.java
+++ b/src/com/android/launcher3/config/FeatureFlags.java
@@ -17,32 +17,16 @@
 package com.android.launcher3.config;
 
 import static com.android.launcher3.BuildConfig.WIDGET_ON_FIRST_SCREEN;
-import static com.android.launcher3.LauncherPrefs.LONG_PRESS_NAV_HANDLE_EXTRA_TOUCH_WIDTH_DP;
-import static com.android.launcher3.LauncherPrefs.LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_DELAY;
-import static com.android.launcher3.LauncherPrefs.LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_END_SCALE_PERCENT;
-import static com.android.launcher3.LauncherPrefs.LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_ITERATIONS;
-import static com.android.launcher3.LauncherPrefs.LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_SCALE_EXPONENT;
-import static com.android.launcher3.LauncherPrefs.LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_START_SCALE_PERCENT;
-import static com.android.launcher3.LauncherPrefs.LONG_PRESS_NAV_HANDLE_SLOP_PERCENTAGE;
-import static com.android.launcher3.LauncherPrefs.LONG_PRESS_NAV_HANDLE_TIMEOUT_MS;
-import static com.android.launcher3.config.FeatureFlags.FlagState.DISABLED;
-import static com.android.launcher3.config.FeatureFlags.FlagState.ENABLED;
-import static com.android.launcher3.config.FeatureFlags.FlagState.TEAMFOOD;
-import static com.android.launcher3.uioverrides.flags.FlagsFactory.getDebugFlag;
-import static com.android.launcher3.uioverrides.flags.FlagsFactory.getReleaseFlag;
+import static com.android.launcher3.config.FeatureFlags.BooleanFlag.DISABLED;
+import static com.android.launcher3.config.FeatureFlags.BooleanFlag.ENABLED;
 import static com.android.wm.shell.Flags.enableTaskbarNavbarUnification;
 
 import android.content.res.Resources;
-import android.view.ViewConfiguration;
 
 import androidx.annotation.VisibleForTesting;
 
 import com.android.launcher3.BuildConfig;
 import com.android.launcher3.Flags;
-import com.android.launcher3.uioverrides.flags.FlagsFactory;
-
-import java.util.function.Predicate;
-import java.util.function.ToIntFunction;
 
 /**
  * Defines a set of flags used to control various launcher behaviors.
@@ -51,11 +35,6 @@
  */
 public final class FeatureFlags {
 
-    @VisibleForTesting
-    public static Predicate<BooleanFlag> sBooleanReader = f -> f.mCurrentValue;
-    @VisibleForTesting
-    public static ToIntFunction<IntFlag> sIntReader = f -> f.mCurrentValue;
-
     private FeatureFlags() { }
 
     /**
@@ -131,34 +110,6 @@
             getDebugFlag(275132633, "ENABLE_ALL_APPS_FROM_OVERVIEW", DISABLED,
                     "Allow entering All Apps from Overview (e.g. long swipe up from app)");
 
-    public static final BooleanFlag CUSTOM_LPNH_THRESHOLDS =
-            getReleaseFlag(301680992, "CUSTOM_LPNH_THRESHOLDS", DISABLED,
-                    "Add dev options to customize the LPNH trigger slop and milliseconds");
-
-    public static final BooleanFlag ANIMATE_LPNH =
-            getReleaseFlag(308693847, "ANIMATE_LPNH", TEAMFOOD,
-                    "Animates navbar when long pressing");
-
-    public static final BooleanFlag SHRINK_NAV_HANDLE_ON_PRESS =
-            getReleaseFlag(314158312, "SHRINK_NAV_HANDLE_ON_PRESS", DISABLED,
-                    "Shrinks navbar when long pressing if ANIMATE_LPNH is enabled");
-
-    public static final IntFlag LPNH_SLOP_PERCENTAGE =
-            FlagsFactory.getIntFlag(301680992, "LPNH_SLOP_PERCENTAGE", 100,
-                    "Controls touch slop percentage for lpnh",
-                    LONG_PRESS_NAV_HANDLE_SLOP_PERCENTAGE);
-
-    public static final IntFlag LPNH_EXTRA_TOUCH_WIDTH_DP =
-            FlagsFactory.getIntFlag(301680992, "LPNH_EXTRA_TOUCH_WIDTH_DP", 0,
-                    "Controls extra dp on the nav bar sides to trigger LPNH."
-                            + " Can be negative for a smaller touch region.",
-                    LONG_PRESS_NAV_HANDLE_EXTRA_TOUCH_WIDTH_DP);
-
-    public static final IntFlag LPNH_TIMEOUT_MS =
-            FlagsFactory.getIntFlag(301680992, "LPNH_TIMEOUT_MS",
-                    ViewConfiguration.getLongPressTimeout(),
-                    "Controls lpnh timeout in milliseconds", LONG_PRESS_NAV_HANDLE_TIMEOUT_MS);
-
     public static final BooleanFlag ENABLE_SHOW_KEYBOARD_OPTION_IN_ALL_APPS = getReleaseFlag(
             270394468, "ENABLE_SHOW_KEYBOARD_OPTION_IN_ALL_APPS", ENABLED,
             "Enable option to show keyboard when going to all-apps");
@@ -222,7 +173,7 @@
 
     // TODO(Block 14): Cleanup flags
     public static final BooleanFlag NOTIFY_CRASHES = getDebugFlag(270393108, "NOTIFY_CRASHES",
-            TEAMFOOD, "Sends a notification whenever launcher encounters an uncaught exception.");
+            DISABLED, "Sends a notification whenever launcher encounters an uncaught exception.");
 
     public static final boolean ENABLE_TASKBAR_NAVBAR_UNIFICATION =
             enableTaskbarNavbarUnification() && !isPhone();
@@ -289,53 +240,10 @@
             "INJECT_FALLBACK_APP_CORPUS_RESULTS", DISABLED,
             "Inject fallback app corpus result when AiAi fails to return it.");
 
-    public static final BooleanFlag ENABLE_LONG_PRESS_NAV_HANDLE =
-            getReleaseFlag(299682306, "ENABLE_LONG_PRESS_NAV_HANDLE", ENABLED,
-                    "Enables long pressing on the bottom bar nav handle to trigger events.");
-
-    public static final BooleanFlag ENABLE_SEARCH_HAPTIC_HINT =
-            getReleaseFlag(314005131, "ENABLE_SEARCH_HAPTIC_HINT", ENABLED,
-                    "Enables haptic hint while long pressing on the bottom bar nav handle.");
-
-    public static final BooleanFlag ENABLE_SEARCH_HAPTIC_COMMIT =
-            getReleaseFlag(314005577, "ENABLE_SEARCH_HAPTIC_COMMIT", ENABLED,
-                    "Enables haptic hint at end of long pressing on the bottom bar nav handle.");
-
-    public static final IntFlag LPNH_HAPTIC_HINT_START_SCALE_PERCENT =
-            FlagsFactory.getIntFlag(309972570,
-                    "LPNH_HAPTIC_HINT_START_SCALE_PERCENT", 0,
-                    "Haptic hint start scale.",
-                    LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_START_SCALE_PERCENT);
-
-    public static final IntFlag LPNH_HAPTIC_HINT_END_SCALE_PERCENT =
-            FlagsFactory.getIntFlag(309972570,
-                    "LPNH_HAPTIC_HINT_END_SCALE_PERCENT", 100,
-                    "Haptic hint end scale.", LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_END_SCALE_PERCENT);
-
-    public static final IntFlag LPNH_HAPTIC_HINT_SCALE_EXPONENT =
-            FlagsFactory.getIntFlag(309972570,
-                    "LPNH_HAPTIC_HINT_SCALE_EXPONENT", 1,
-                    "Haptic hint scale exponent.",
-                    LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_SCALE_EXPONENT);
-
-    public static final IntFlag LPNH_HAPTIC_HINT_ITERATIONS =
-            FlagsFactory.getIntFlag(309972570, "LPNH_HAPTIC_HINT_ITERATIONS",
-                    50,
-                    "Haptic hint number of iterations.",
-                    LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_ITERATIONS);
-
-    public static final BooleanFlag ENABLE_LPNH_DEEP_PRESS =
-            getReleaseFlag(310952290, "ENABLE_LPNH_DEEP_PRESS", ENABLED,
-                    "Long press of nav handle is instantly triggered if deep press is detected.");
-
-    public static final IntFlag LPNH_HAPTIC_HINT_DELAY =
-            FlagsFactory.getIntFlag(309972570, "LPNH_HAPTIC_HINT_DELAY", 0,
-                    "Delay before haptic hint starts.", LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_DELAY);
-
     // TODO(Block 17): Clean up flags
     // Aconfig migration complete for ENABLE_TASKBAR_PINNING.
     private static final BooleanFlag ENABLE_TASKBAR_PINNING = getDebugFlag(296231746,
-            "ENABLE_TASKBAR_PINNING", TEAMFOOD,
+            "ENABLE_TASKBAR_PINNING", DISABLED,
             "Enables taskbar pinning to allow user to switch between transient and persistent "
                     + "taskbar flavors");
 
@@ -375,7 +283,7 @@
 
     // Aconfig migration complete for ENABLE_HOME_TRANSITION_LISTENER.
     public static final BooleanFlag ENABLE_HOME_TRANSITION_LISTENER = getDebugFlag(306053414,
-            "ENABLE_HOME_TRANSITION_LISTENER", TEAMFOOD,
+            "ENABLE_HOME_TRANSITION_LISTENER", DISABLED,
             "Enables launcher to listen to all transitions that include home activity.");
 
     public static boolean enableHomeTransitionListener() {
@@ -470,7 +378,7 @@
     // Aconfig migration complete for ENABLE_RESPONSIVE_WORKSPACE.
     @VisibleForTesting
     public static final BooleanFlag ENABLE_RESPONSIVE_WORKSPACE = getDebugFlag(241386436,
-            "ENABLE_RESPONSIVE_WORKSPACE", TEAMFOOD,
+            "ENABLE_RESPONSIVE_WORKSPACE", DISABLED,
             "Enables new workspace grid calculations method.");
     public static boolean enableResponsiveWorkspace() {
         return ENABLE_RESPONSIVE_WORKSPACE.get() || Flags.enableResponsiveWorkspace();
@@ -484,51 +392,31 @@
             "ALL_APPS_GONE_VISIBILITY", ENABLED,
             "Set all apps container view's hidden visibility to GONE instead of INVISIBLE.");
 
-    // TODO(Block 34): Empty block
-    // Please only add flags to your assigned block. If you do not have a block:
-    // 1. Assign yourself this block
-    // 2. Add your flag to this block
-    // 3. Add a new empty block below this one
-    // 4. Move this comment to that new empty block
-    // This is all to prevent merge conflicts in the future and help keep track of who owns which
-    // flags.
-    // List of assigned blocks can be found: http://go/gnl-flags-block-directory
-
-    public static class BooleanFlag {
-
-        private final boolean mCurrentValue;
-
-        public BooleanFlag(boolean currentValue) {
-            mCurrentValue = currentValue;
-        }
-
-        public boolean get() {
-            return sBooleanReader.test(this);
-        }
+    public static BooleanFlag getDebugFlag(
+            int bugId, String key, BooleanFlag flagState, String description) {
+        return flagState;
     }
 
-    /**
-     * Class representing an integer flag
-     */
-    public static class IntFlag {
-
-        private final int mCurrentValue;
-
-        public IntFlag(int currentValue) {
-            mCurrentValue = currentValue;
-        }
-
-        public int get() {
-            return sIntReader.applyAsInt(this);
-        }
+    public static BooleanFlag getReleaseFlag(
+            int bugId, String key, BooleanFlag flagState, String description) {
+        return flagState;
     }
 
     /**
      * Enabled state for a flag
      */
-    public enum FlagState {
-        ENABLED,
-        DISABLED,
-        TEAMFOOD    // Enabled in team food
+    public enum BooleanFlag {
+        ENABLED(true),
+        DISABLED(false);
+
+        private final boolean mValue;
+
+        BooleanFlag(boolean value) {
+            mValue = value;
+        }
+
+        public boolean get() {
+            return mValue;
+        }
     }
 }
diff --git a/src/com/android/launcher3/dragndrop/AddItemActivity.java b/src/com/android/launcher3/dragndrop/AddItemActivity.java
index 29aa216..05fdcef 100644
--- a/src/com/android/launcher3/dragndrop/AddItemActivity.java
+++ b/src/com/android/launcher3/dragndrop/AddItemActivity.java
@@ -67,7 +67,7 @@
 import com.android.launcher3.model.data.ItemInfo;
 import com.android.launcher3.model.data.PackageItemInfo;
 import com.android.launcher3.pm.PinRequestHelper;
-import com.android.launcher3.uioverrides.ApiWrapper;
+import com.android.launcher3.util.ApiWrapper;
 import com.android.launcher3.util.PackageManagerHelper;
 import com.android.launcher3.util.SystemUiController;
 import com.android.launcher3.views.AbstractSlideInView;
@@ -259,7 +259,8 @@
                         .setPackage(getPackageName())
                         .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
         Launcher.ACTIVITY_TRACKER.registerCallback(listener, "AddItemActivity.onLongClick");
-        startActivity(homeIntent, ApiWrapper.createFadeOutAnimOptions(this).toBundle());
+        startActivity(homeIntent,
+                ApiWrapper.INSTANCE.get(this).createFadeOutAnimOptions().toBundle());
         logCommand(LAUNCHER_ADD_EXTERNAL_ITEM_DRAGGED);
         mFinishOnPause = true;
         return false;
diff --git a/src/com/android/launcher3/folder/Folder.java b/src/com/android/launcher3/folder/Folder.java
index aa3c5ba..dcc55e6 100644
--- a/src/com/android/launcher3/folder/Folder.java
+++ b/src/com/android/launcher3/folder/Folder.java
@@ -19,6 +19,9 @@
 import static android.text.TextUtils.isEmpty;
 
 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.LauncherSettings.Favorites.ITEM_TYPE_APP_PAIR;
+import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT;
 import static com.android.launcher3.LauncherState.EDIT_MODE;
 import static com.android.launcher3.LauncherState.NORMAL;
 import static com.android.launcher3.compat.AccessibilityManagerCompat.sendCustomAccessibilityEvent;
@@ -66,14 +69,12 @@
 
 import com.android.launcher3.AbstractFloatingView;
 import com.android.launcher3.Alarm;
-import com.android.launcher3.BubbleTextView;
 import com.android.launcher3.CellLayout;
 import com.android.launcher3.DeviceProfile;
 import com.android.launcher3.DragSource;
 import com.android.launcher3.DropTarget;
 import com.android.launcher3.ExtendedEditText;
 import com.android.launcher3.Launcher;
-import com.android.launcher3.LauncherSettings;
 import com.android.launcher3.OnAlarmListener;
 import com.android.launcher3.R;
 import com.android.launcher3.ShortcutAndWidgetContainer;
@@ -166,6 +167,22 @@
     private static final Rect sTempRect = new Rect();
     private static final int MIN_FOLDERS_FOR_HARDWARE_OPTIMIZATION = 10;
 
+    /**
+     * Checks if {@code o} is an {@link ItemInfo} type that can be placed in folders.
+     */
+    public static boolean willAccept(Object o) {
+        return o instanceof ItemInfo info && willAcceptItemType(info.itemType);
+    }
+
+    /**
+     * Checks if {@code itemType} is a type that can be placed in folders.
+     */
+    public static boolean willAcceptItemType(int itemType) {
+        return itemType == ITEM_TYPE_APPLICATION
+                || itemType == ITEM_TYPE_DEEP_SHORTCUT
+                || itemType == ITEM_TYPE_APP_PAIR;
+    }
+
     private final Alarm mReorderAlarm = new Alarm(Looper.getMainLooper());
     private final Alarm mOnExitAlarm = new Alarm(Looper.getMainLooper());
     private final Alarm mOnScrollHintAlarm = new Alarm(Looper.getMainLooper());
@@ -313,9 +330,7 @@
 
     public boolean startDrag(View v, DragOptions options) {
         Object tag = v.getTag();
-        if (tag instanceof WorkspaceItemInfo) {
-            WorkspaceItemInfo item = (WorkspaceItemInfo) tag;
-
+        if (tag instanceof ItemInfo item) {
             mEmptyCellRank = item.rank;
             mCurrentDragView = v;
 
@@ -346,14 +361,12 @@
         }
 
         mContent.removeItem(mCurrentDragView);
-        if (dragObject.dragInfo instanceof WorkspaceItemInfo) {
-            mItemsInvalidated = true;
+        mItemsInvalidated = true;
 
-            // We do not want to get events for the item being removed, as they will get handled
-            // when the drop completes
-            try (SuppressInfoChanges s = new SuppressInfoChanges()) {
-                mInfo.remove((WorkspaceItemInfo) dragObject.dragInfo, true);
-            }
+        // We do not want to get events for the item being removed, as they will get handled
+        // when the drop completes
+        try (SuppressInfoChanges s = new SuppressInfoChanges()) {
+            mInfo.remove(dragObject.dragInfo, true);
         }
         mDragInProgress = true;
         mItemAddedBackToSelfViaIcon = false;
@@ -493,7 +506,7 @@
         mInfo = info;
         mFromTitle = info.title;
         mFromLabelState = info.getFromLabelState();
-        ArrayList<WorkspaceItemInfo> children = info.getContents();
+        ArrayList<ItemInfo> children = info.getContents();
         Collections.sort(children, ITEM_POS_COMPARATOR);
         updateItemLocationsInDatabaseBatch(true);
 
@@ -626,7 +639,7 @@
         // onDropComplete. Perform cleanup once drag-n-drop ends.
         mDragController.addDragListener(this);
 
-        ArrayList<WorkspaceItemInfo> items = new ArrayList<>(mInfo.getContents());
+        ArrayList<ItemInfo> items = new ArrayList<>(mInfo.getContents());
         mEmptyCellRank = items.size();
         items.add(null);    // Add an empty spot at the end
 
@@ -647,7 +660,7 @@
      * is animated relative to the specified View. If the View is null, no animation
      * is played.
      */
-    private void animateOpen(List<WorkspaceItemInfo> items, int pageNo) {
+    private void animateOpen(List<ItemInfo> items, int pageNo) {
         if (items == null || items.size() <= 1) {
             Log.d(TAG, "Couldn't animate folder open because items is: " + items);
             return;
@@ -896,8 +909,7 @@
     public boolean acceptDrop(DragObject d) {
         final ItemInfo item = d.dragInfo;
         final int itemType = item.itemType;
-        return ((itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION ||
-                itemType == LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT));
+        return Folder.willAcceptItemType(itemType);
     }
 
     public void onDragEnter(DragObject d) {
@@ -1050,7 +1062,7 @@
             }
         } else {
             // The drag failed, we need to return the item to the folder
-            WorkspaceItemInfo info = (WorkspaceItemInfo) d.dragInfo;
+            ItemInfo info = d.dragInfo;
             View icon = (mCurrentDragView != null && mCurrentDragView.getTag() == info)
                     ? mCurrentDragView : mContent.createNewView(info);
             ArrayList<View> views = getIconsInReadingOrder();
@@ -1099,7 +1111,7 @@
         ArrayList<ItemInfo> items = new ArrayList<>();
         int total = mInfo.getContents().size();
         for (int i = 0; i < total; i++) {
-            WorkspaceItemInfo itemInfo = mInfo.getContents().get(i);
+            ItemInfo itemInfo = mInfo.getContents().get(i);
             if (verifier.updateRankAndPos(itemInfo, i)) {
                 items.add(itemInfo);
             }
@@ -1112,8 +1124,7 @@
             Executors.MODEL_EXECUTOR.post(() -> {
                 FolderNameInfos nameInfos = new FolderNameInfos();
                 FolderNameProvider fnp = FolderNameProvider.newInstance(getContext());
-                fnp.getSuggestedFolderName(
-                        getContext(), mInfo.getContents(), nameInfos);
+                fnp.getSuggestedFolderName(getContext(), mInfo.getAppContents(), nameInfos);
                 mInfo.suggestedFolderNames = nameInfos;
             });
         }
@@ -1298,15 +1309,15 @@
             d.deferDragViewCleanupPostAnimation = false;
             mRearrangeOnClose = true;
         } else {
-            final WorkspaceItemInfo si;
+            final ItemInfo si;
             if (pasiSi != null) {
                 si = pasiSi;
             } else if (d.dragInfo instanceof WorkspaceItemFactory) {
                 // Came from all apps -- make a copy.
                 si = ((WorkspaceItemFactory) d.dragInfo).makeWorkspaceItem(launcher);
             } else {
-                // WorkspaceItemInfo
-                si = (WorkspaceItemInfo) d.dragInfo;
+                // WorkspaceItemInfo or AppPairInfo
+                si = d.dragInfo;
             }
 
             View currentDragView;
@@ -1314,7 +1325,7 @@
                 currentDragView = mContent.createAndAddViewForRank(si, mEmptyCellRank);
 
                 // Actually move the item in the database if it was an external drag. Call this
-                // before creating the view, so that WorkspaceItemInfo is updated appropriately.
+                // before creating the view, so that the ItemInfo is updated appropriately.
                 mLauncherDelegate.getModelWriter().addOrMoveItemInDatabase(
                         si, mInfo.id, 0, si.cellX, si.cellY);
                 mIsExternalDrag = false;
@@ -1376,14 +1387,14 @@
     // This is used so the item doesn't immediately appear in the folder when added. In one case
     // we need to create the illusion that the item isn't added back to the folder yet, to
     // to correspond to the animation of the icon back into the folder. This is
-    public void hideItem(WorkspaceItemInfo info) {
+    public void hideItem(ItemInfo info) {
         View v = getViewForInfo(info);
         if (v != null) {
             v.setVisibility(INVISIBLE);
         }
     }
 
-    public void showItem(WorkspaceItemInfo info) {
+    public void showItem(ItemInfo info) {
         View v = getViewForInfo(info);
         if (v != null) {
             v.setVisibility(VISIBLE);
@@ -1391,7 +1402,7 @@
     }
 
     @Override
-    public void onAdd(WorkspaceItemInfo item, int rank) {
+    public void onAdd(ItemInfo item, int rank) {
         FolderGridOrganizer verifier = new FolderGridOrganizer(
                 mActivityContext.getDeviceProfile()).setFolderInfo(mInfo);
         verifier.updateRankAndPos(item, rank);
@@ -1406,7 +1417,7 @@
     }
 
     @Override
-    public void onRemove(List<WorkspaceItemInfo> items) {
+    public void onRemove(List<ItemInfo> items) {
         mItemsInvalidated = true;
         items.stream().map(this::getViewForInfo).forEach(mContent::removeItem);
         if (mState == STATE_ANIMATING) {
@@ -1423,7 +1434,7 @@
         }
     }
 
-    private View getViewForInfo(final WorkspaceItemInfo item) {
+    private View getViewForInfo(final ItemInfo item) {
         return mContent.iterateOverItems((info, view) -> info == item);
     }
 
@@ -1432,6 +1443,11 @@
         updateTextViewFocus();
     }
 
+    @Override
+    public void onTitleChanged(CharSequence title) {
+        mFolderName.setText(title);
+    }
+
     /**
      * Utility methods to iterate over items of the view
      */
@@ -1451,7 +1467,7 @@
         return mItemsInReadingOrder;
     }
 
-    public List<BubbleTextView> getItemsOnPage(int page) {
+    public List<View> getItemsOnPage(int page) {
         ArrayList<View> allItems = getIconsInReadingOrder();
         int lastPage = mContent.getPageCount() - 1;
         int totalItemsInFolder = allItems.size();
@@ -1463,9 +1479,9 @@
         int startIndex = page * itemsPerPage;
         int endIndex = Math.min(startIndex + numItemsOnCurrentPage, allItems.size());
 
-        List<BubbleTextView> itemsOnCurrentPage = new ArrayList<>(numItemsOnCurrentPage);
+        List<View> itemsOnCurrentPage = new ArrayList<>(numItemsOnCurrentPage);
         for (int i = startIndex; i < endIndex; ++i) {
-            itemsOnCurrentPage.add((BubbleTextView) allItems.get(i));
+            itemsOnCurrentPage.add(allItems.get(i));
         }
         return itemsOnCurrentPage;
     }
diff --git a/src/com/android/launcher3/folder/FolderAnimationManager.java b/src/com/android/launcher3/folder/FolderAnimationManager.java
index a91373b..7a2ec97 100644
--- a/src/com/android/launcher3/folder/FolderAnimationManager.java
+++ b/src/com/android/launcher3/folder/FolderAnimationManager.java
@@ -43,6 +43,7 @@
 import com.android.launcher3.ShortcutAndWidgetContainer;
 import com.android.launcher3.Utilities;
 import com.android.launcher3.anim.PropertyResetListener;
+import com.android.launcher3.apppairs.AppPairIcon;
 import com.android.launcher3.celllayout.CellLayoutLayoutParams;
 import com.android.launcher3.util.Themes;
 import com.android.launcher3.views.BaseDragLayer;
@@ -127,7 +128,7 @@
                 (BaseDragLayer.LayoutParams) mFolder.getLayoutParams();
         mFolderIcon.getPreviewItemManager().recomputePreviewDrawingParams();
         ClippedFolderIconLayoutRule rule = mFolderIcon.getLayoutRule();
-        final List<BubbleTextView> itemsInPreview = getPreviewIconsOnPage(0);
+        final List<View> itemsInPreview = getPreviewIconsOnPage(0);
 
         // Match position of the FolderIcon
         final Rect folderIconPos = new Rect();
@@ -139,8 +140,8 @@
         // Match size/scale of icons in the preview
         float previewScale = rule.scaleForItem(itemsInPreview.size());
         float previewSize = rule.getIconSize() * previewScale;
-        float initialScale = previewSize / itemsInPreview.get(0).getIconSize()
-                * scaleRelativeToDragLayer;
+        float baseIconSize = getBubbleTextView(itemsInPreview.get(0)).getIconSize();
+        float initialScale = previewSize / baseIconSize * scaleRelativeToDragLayer;
         final float finalScale = 1f;
         float scale = mIsOpening ? initialScale : finalScale;
         mFolder.setPivotX(0);
@@ -198,11 +199,12 @@
         // Initialize the Folder items' text.
         PropertyResetListener colorResetListener =
                 new PropertyResetListener<>(TEXT_ALPHA_PROPERTY, 1f);
-        for (BubbleTextView icon : mFolder.getItemsOnPage(mFolder.mContent.getCurrentPage())) {
+        for (View icon : mFolder.getItemsOnPage(mFolder.mContent.getCurrentPage())) {
+            BubbleTextView titleText = getBubbleTextView(icon);
             if (mIsOpening) {
-                icon.setTextVisibility(false);
+                titleText.setTextVisibility(false);
             }
-            ObjectAnimator anim = icon.createTextAlphaAnimator(mIsOpening);
+            ObjectAnimator anim = titleText.createTextAlphaAnimator(mIsOpening);
             anim.addListener(colorResetListener);
             play(a, anim);
         }
@@ -339,7 +341,7 @@
     /**
      * Returns the list of "preview items" on {@param page}.
      */
-    private List<BubbleTextView> getPreviewIconsOnPage(int page) {
+    private List<View> getPreviewIconsOnPage(int page) {
         return mPreviewVerifier.setFolderInfo(mFolder.mInfo)
                 .previewItemsForPage(page, mFolder.getIconsInReadingOrder());
     }
@@ -351,7 +353,7 @@
             int previewItemOffsetX, int previewItemOffsetY) {
         ClippedFolderIconLayoutRule rule = mFolderIcon.getLayoutRule();
         boolean isOnFirstPage = mFolder.mContent.getCurrentPage() == 0;
-        final List<BubbleTextView> itemsInPreview = getPreviewIconsOnPage(
+        final List<View> itemsInPreview = getPreviewIconsOnPage(
                 isOnFirstPage ? 0 : mFolder.mContent.getCurrentPage());
         final int numItemsInPreview = itemsInPreview.size();
         final int numItemsInFirstPagePreview = isOnFirstPage
@@ -361,48 +363,49 @@
 
         ShortcutAndWidgetContainer cwc = mContent.getPageAt(0).getShortcutsAndWidgets();
         for (int i = 0; i < numItemsInPreview; ++i) {
-            final BubbleTextView btv = itemsInPreview.get(i);
-            CellLayoutLayoutParams btvLp = (CellLayoutLayoutParams) btv.getLayoutParams();
+            final View v = itemsInPreview.get(i);
+            CellLayoutLayoutParams vLp = (CellLayoutLayoutParams) v.getLayoutParams();
 
             // Calculate the final values in the LayoutParams.
-            btvLp.isLockedToGrid = true;
-            cwc.setupLp(btv);
+            vLp.isLockedToGrid = true;
+            cwc.setupLp(v);
 
             // Match scale of icons in the preview of the items on the first page.
             float previewScale = rule.scaleForItem(numItemsInFirstPagePreview);
             float previewSize = rule.getIconSize() * previewScale;
-            float iconScale = previewSize / itemsInPreview.get(i).getIconSize();
+            float baseIconSize = getBubbleTextView(v).getIconSize();
+            float iconScale = previewSize / baseIconSize;
 
             final float initialScale = iconScale / folderScale;
             final float finalScale = 1f;
             float scale = mIsOpening ? initialScale : finalScale;
-            btv.setScaleX(scale);
-            btv.setScaleY(scale);
+            v.setScaleX(scale);
+            v.setScaleY(scale);
 
             // Match positions of the icons in the folder with their positions in the preview
             rule.computePreviewItemDrawingParams(i, numItemsInFirstPagePreview, mTmpParams);
             // The PreviewLayoutRule assumes that the icon size takes up the entire width so we
             // offset by the actual size.
-            int iconOffsetX = (int) ((btvLp.width - btv.getIconSize()) * iconScale) / 2;
+            int iconOffsetX = (int) ((vLp.width - baseIconSize) * iconScale) / 2;
 
             final int previewPosX =
                     (int) ((mTmpParams.transX - iconOffsetX + previewItemOffsetX) / folderScale);
-            final float paddingTop = btv.getPaddingTop() * iconScale;
+            final float paddingTop = v.getPaddingTop() * iconScale;
             final int previewPosY = (int) ((mTmpParams.transY + previewItemOffsetY - paddingTop)
                     / folderScale);
 
-            final float xDistance = previewPosX - btvLp.x;
-            final float yDistance = previewPosY - btvLp.y;
+            final float xDistance = previewPosX - vLp.x;
+            final float yDistance = previewPosY - vLp.y;
 
-            Animator translationX = getAnimator(btv, View.TRANSLATION_X, xDistance, 0f);
+            Animator translationX = getAnimator(v, View.TRANSLATION_X, xDistance, 0f);
             translationX.setInterpolator(previewItemInterpolator);
             play(animatorSet, translationX);
 
-            Animator translationY = getAnimator(btv, View.TRANSLATION_Y, yDistance, 0f);
+            Animator translationY = getAnimator(v, View.TRANSLATION_Y, yDistance, 0f);
             translationY.setInterpolator(previewItemInterpolator);
             play(animatorSet, translationY);
 
-            Animator scaleAnimator = getAnimator(btv, SCALE_PROPERTY, initialScale, finalScale);
+            Animator scaleAnimator = getAnimator(v, SCALE_PROPERTY, initialScale, finalScale);
             scaleAnimator.setInterpolator(previewItemInterpolator);
             play(animatorSet, scaleAnimator);
 
@@ -426,20 +429,20 @@
                     super.onAnimationStart(animation);
                     // Necessary to initialize values here because of the start delay.
                     if (mIsOpening) {
-                        btv.setTranslationX(xDistance);
-                        btv.setTranslationY(yDistance);
-                        btv.setScaleX(initialScale);
-                        btv.setScaleY(initialScale);
+                        v.setTranslationX(xDistance);
+                        v.setTranslationY(yDistance);
+                        v.setScaleX(initialScale);
+                        v.setScaleY(initialScale);
                     }
                 }
 
                 @Override
                 public void onAnimationEnd(Animator animation) {
                     super.onAnimationEnd(animation);
-                    btv.setTranslationX(0.0f);
-                    btv.setTranslationY(0.0f);
-                    btv.setScaleX(1f);
-                    btv.setScaleY(1f);
+                    v.setTranslationX(0.0f);
+                    v.setTranslationY(0.0f);
+                    v.setScaleX(1f);
+                    v.setScaleY(1f);
                 }
             });
         }
@@ -482,4 +485,15 @@
                 ? ObjectAnimator.ofArgb(drawable, property, v1, v2)
                 : ObjectAnimator.ofArgb(drawable, property, v2, v1);
     }
+
+    /**
+     * Gets the {@link com.android.launcher3.BubbleTextView} from an icon. In some cases the
+     * BubbleTextView is the whole icon itself, while in others it is contained within the view and
+     * only serves to store the title text.
+     */
+    private BubbleTextView getBubbleTextView(View v) {
+        return v instanceof AppPairIcon
+                ? ((AppPairIcon) v).getTitleTextView()
+                : (BubbleTextView) v;
+    }
 }
diff --git a/src/com/android/launcher3/folder/FolderIcon.java b/src/com/android/launcher3/folder/FolderIcon.java
index 62ce311..4d88b68 100644
--- a/src/com/android/launcher3/folder/FolderIcon.java
+++ b/src/com/android/launcher3/folder/FolderIcon.java
@@ -71,6 +71,7 @@
 import com.android.launcher3.logger.LauncherAtom.ToState;
 import com.android.launcher3.logging.InstanceId;
 import com.android.launcher3.logging.StatsLogManager;
+import com.android.launcher3.model.data.AppPairInfo;
 import com.android.launcher3.model.data.FolderInfo;
 import com.android.launcher3.model.data.FolderInfo.FolderListener;
 import com.android.launcher3.model.data.FolderInfo.LabelState;
@@ -118,7 +119,7 @@
     ClippedFolderIconLayoutRule mPreviewLayoutRule;
     private PreviewItemManager mPreviewItemManager;
     private PreviewItemDrawingParams mTmpParams = new PreviewItemDrawingParams(0, 0, 0);
-    private List<WorkspaceItemInfo> mCurrentPreviewItems = new ArrayList<>();
+    private List<ItemInfo> mCurrentPreviewItems = new ArrayList<>();
 
     boolean mAnimating = false;
 
@@ -215,7 +216,7 @@
 
         // Keep the notification dot up to date with the sum of all the content's dots.
         FolderDotInfo folderDotInfo = new FolderDotInfo();
-        for (WorkspaceItemInfo si : folderInfo.getContents()) {
+        for (ItemInfo si : folderInfo.getContents()) {
             folderDotInfo.addDotInfo(activity.getDotInfoForItem(si));
         }
         icon.setDotInfo(folderDotInfo);
@@ -261,20 +262,18 @@
 
     private boolean willAcceptItem(ItemInfo item) {
         final int itemType = item.itemType;
-        return ((itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION ||
-                itemType == LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT) &&
-                item != mInfo && !mFolder.isOpen());
+        return (Folder.willAcceptItemType(itemType) && item != mInfo && !mFolder.isOpen());
     }
 
     public boolean acceptDrop(ItemInfo dragInfo) {
         return !mFolder.isDestroyed() && willAcceptItem(dragInfo);
     }
 
-    public void addItem(WorkspaceItemInfo item) {
+    public void addItem(ItemInfo item) {
         mInfo.add(item, true);
     }
 
-    public void removeItem(WorkspaceItemInfo item, boolean animate) {
+    public void removeItem(ItemInfo item, boolean animate) {
         mInfo.remove(item, animate);
     }
 
@@ -287,8 +286,8 @@
         mOpenAlarm.setOnAlarmListener(mOnOpenListener);
         if (SPRING_LOADING_ENABLED &&
                 ((dragInfo instanceof WorkspaceItemFactory)
-                        || (dragInfo instanceof WorkspaceItemInfo)
-                        || (dragInfo instanceof PendingAddShortcutInfo))) {
+                        || (dragInfo instanceof PendingAddShortcutInfo)
+                        || Folder.willAccept(dragInfo))) {
             mOpenAlarm.setAlarm(ON_OPEN_DELAY);
         }
     }
@@ -303,8 +302,8 @@
         return mPreviewItemManager.prepareCreateAnimation(destView);
     }
 
-    public void performCreateAnimation(final WorkspaceItemInfo destInfo, final View destView,
-            final WorkspaceItemInfo srcInfo, final DragObject d, Rect dstRect,
+    public void performCreateAnimation(final ItemInfo destInfo, final View destView,
+            final ItemInfo srcInfo, final DragObject d, Rect dstRect,
             float scaleRelativeToDragLayer) {
         final DragView srcView = d.dragView;
         prepareCreateAnimation(destView);
@@ -330,7 +329,7 @@
         mOpenAlarm.cancelAlarm();
     }
 
-    private void onDrop(final WorkspaceItemInfo item, DragObject d, Rect finalRect,
+    private void onDrop(final ItemInfo item, DragObject d, Rect finalRect,
             float scaleRelativeToDragLayer, int index, boolean itemReturnedOnFailedDrop) {
         item.cellX = -1;
         item.cellY = -1;
@@ -361,7 +360,7 @@
             int numItemsInPreview = Math.min(MAX_NUM_ITEMS_IN_PREVIEW, index + 1);
             boolean itemAdded = false;
             if (itemReturnedOnFailedDrop || index >= MAX_NUM_ITEMS_IN_PREVIEW) {
-                List<WorkspaceItemInfo> oldPreviewItems = new ArrayList<>(mCurrentPreviewItems);
+                List<ItemInfo> oldPreviewItems = new ArrayList<>(mCurrentPreviewItems);
                 mInfo.add(item, index, false);
                 mCurrentPreviewItems.clear();
                 mCurrentPreviewItems.addAll(getPreviewItemsOnPage(0));
@@ -422,7 +421,7 @@
             FolderNameInfos nameInfos = new FolderNameInfos();
             Executors.MODEL_EXECUTOR.post(() -> {
                 d.folderNameProvider.getSuggestedFolderName(
-                        getContext(), mInfo.getContents(), nameInfos);
+                        getContext(), mInfo.getAppContents(), nameInfos);
                 postDelayed(() -> {
                     setLabelSuggestion(nameInfos, d.logInstanceId);
                     invalidate();
@@ -475,15 +474,21 @@
 
 
     public void onDrop(DragObject d, boolean itemReturnedOnFailedDrop) {
-        WorkspaceItemInfo item;
+        ItemInfo item;
         if (d.dragInfo instanceof WorkspaceItemFactory) {
             // Came from all apps -- make a copy
             item = ((WorkspaceItemFactory) d.dragInfo).makeWorkspaceItem(getContext());
         } else if (d.dragSource instanceof BaseItemDragListener){
             // Came from a different window -- make a copy
-            item = new WorkspaceItemInfo((WorkspaceItemInfo) d.dragInfo);
+            if (d.dragInfo instanceof AppPairInfo) {
+                // dragged item is app pair
+                item = new AppPairInfo((AppPairInfo) d.dragInfo);
+            } else {
+                // dragged item is WorkspaceItemInfo
+                item = new WorkspaceItemInfo((WorkspaceItemInfo) d.dragInfo);
+            }
         } else {
-            item = (WorkspaceItemInfo) d.dragInfo;
+            item = d.dragInfo;
         }
         mFolder.notifyDrop();
         onDrop(item, d, null, 1.0f,
@@ -665,7 +670,7 @@
     /**
      * Returns the list of items which should be visible in the preview
      */
-    public List<WorkspaceItemInfo> getPreviewItemsOnPage(int page) {
+    public List<ItemInfo> getPreviewItemsOnPage(int page) {
         return mPreviewVerifier.setFolderInfo(mInfo).previewItemsForPage(page, mInfo.getContents());
     }
 
@@ -690,12 +695,12 @@
     /**
      * Updates the preview items which match the provided condition
      */
-    public void updatePreviewItems(Predicate<WorkspaceItemInfo> itemCheck) {
+    public void updatePreviewItems(Predicate<ItemInfo> itemCheck) {
         mPreviewItemManager.updatePreviewItems(itemCheck);
     }
 
     @Override
-    public void onAdd(WorkspaceItemInfo item, int rank) {
+    public void onAdd(ItemInfo item, int rank) {
         updatePreviewItems(false);
         boolean wasDotted = mDotInfo.hasDot();
         mDotInfo.addDotInfo(mActivity.getDotInfoForItem(item));
@@ -707,7 +712,7 @@
     }
 
     @Override
-    public void onRemove(List<WorkspaceItemInfo> items) {
+    public void onRemove(List<ItemInfo> items) {
         updatePreviewItems(false);
         boolean wasDotted = mDotInfo.hasDot();
         items.stream().map(mActivity::getDotInfoForItem).forEach(mDotInfo::subtractDotInfo);
@@ -718,6 +723,7 @@
         requestLayout();
     }
 
+    @Override
     public void onTitleChanged(CharSequence title) {
         mFolderName.setText(title);
         setContentDescription(getAccessiblityTitle(title));
diff --git a/src/com/android/launcher3/folder/FolderPagedView.java b/src/com/android/launcher3/folder/FolderPagedView.java
index f2bed92..8eaa0dc 100644
--- a/src/com/android/launcher3/folder/FolderPagedView.java
+++ b/src/com/android/launcher3/folder/FolderPagedView.java
@@ -41,8 +41,10 @@
 import com.android.launcher3.R;
 import com.android.launcher3.ShortcutAndWidgetContainer;
 import com.android.launcher3.Utilities;
+import com.android.launcher3.apppairs.AppPairIcon;
 import com.android.launcher3.celllayout.CellLayoutLayoutParams;
 import com.android.launcher3.keyboard.ViewGroupFocusHelper;
+import com.android.launcher3.model.data.AppPairInfo;
 import com.android.launcher3.model.data.ItemInfo;
 import com.android.launcher3.model.data.WorkspaceItemInfo;
 import com.android.launcher3.pageindicators.PageIndicatorDots;
@@ -148,7 +150,7 @@
     /**
      * Binds items to the layout.
      */
-    public void bindItems(List<WorkspaceItemInfo> items) {
+    public void bindItems(List<ItemInfo> items) {
         if (mViewsBound) {
             unbindItems();
         }
@@ -164,8 +166,11 @@
             CellLayout page = (CellLayout) getChildAt(i);
             ShortcutAndWidgetContainer container = page.getShortcutsAndWidgets();
             for (int j = container.getChildCount() - 1; j >= 0; j--) {
-                container.getChildAt(j).setVisibility(View.VISIBLE);
-                mViewCache.recycleView(R.layout.folder_application, container.getChildAt(j));
+                View iconView = container.getChildAt(j);
+                iconView.setVisibility(View.VISIBLE);
+                if (iconView instanceof BubbleTextView) {
+                    mViewCache.recycleView(R.layout.folder_application, iconView);
+                }
             }
             page.removeAllViews();
             mViewCache.recycleView(R.layout.folder_page, page);
@@ -185,7 +190,7 @@
      * Creates and adds an icon corresponding to the provided rank
      * @return the created icon
      */
-    public View createAndAddViewForRank(WorkspaceItemInfo item, int rank) {
+    public View createAndAddViewForRank(ItemInfo item, int rank) {
         View icon = createNewView(item);
         if (!mViewsBound) {
             return icon;
@@ -200,7 +205,7 @@
      * Adds the {@param view} to the layout based on {@param rank} and updated the position
      * related attributes. It assumes that {@param item} is already attached to the view.
      */
-    public void addViewForRank(View view, WorkspaceItemInfo item, int rank) {
+    public void addViewForRank(View view, ItemInfo item, int rank) {
         int pageNo = rank / mOrganizer.getMaxItemsPerPage();
 
         CellLayoutLayoutParams lp = (CellLayoutLayoutParams) view.getLayoutParams();
@@ -209,26 +214,36 @@
     }
 
     @SuppressLint("InflateParams")
-    public View createNewView(WorkspaceItemInfo item) {
+    public View createNewView(ItemInfo item) {
         if (item == null) {
             return null;
         }
-        final BubbleTextView textView = mViewCache.getView(
-                R.layout.folder_application, getContext(), null);
-        textView.applyFromWorkspaceItem(item);
-        textView.setOnClickListener(mFolder.mActivityContext.getItemOnClickListener());
-        textView.setOnLongClickListener(mFolder);
-        textView.setOnFocusChangeListener(mFocusIndicatorHelper);
-        CellLayoutLayoutParams lp = (CellLayoutLayoutParams) textView.getLayoutParams();
+
+        final View icon;
+        if (item instanceof AppPairInfo api) {
+            // TODO (b/332607759): Make view cache work with app pair icons
+            icon = AppPairIcon.inflateIcon(R.layout.folder_app_pair, ActivityContext.lookupContext(
+                    getContext()), null , api, BubbleTextView.DISPLAY_FOLDER);
+        } else {
+            icon = mViewCache.getView(R.layout.folder_application, getContext(), null);
+            ((BubbleTextView) icon).applyFromWorkspaceItem((WorkspaceItemInfo) item);
+        }
+
+        icon.setOnClickListener(mFolder.mActivityContext.getItemOnClickListener());
+        icon.setOnLongClickListener(mFolder);
+        icon.setOnFocusChangeListener(mFocusIndicatorHelper);
+
+        CellLayoutLayoutParams lp = (CellLayoutLayoutParams) icon.getLayoutParams();
         if (lp == null) {
-            textView.setLayoutParams(new CellLayoutLayoutParams(
+            icon.setLayoutParams(new CellLayoutLayoutParams(
                     item.cellX, item.cellY, item.spanX, item.spanY));
         } else {
             lp.setCellX(item.cellX);
             lp.setCellY(item.cellY);
             lp.cellHSpan = lp.cellVSpan = 1;
         }
-        return textView;
+
+        return icon;
     }
 
     @Nullable
@@ -497,13 +512,20 @@
         if (page != null) {
             ShortcutAndWidgetContainer parent = page.getShortcutsAndWidgets();
             for (int i = parent.getChildCount() - 1; i >= 0; i--) {
-                BubbleTextView icon = ((BubbleTextView) parent.getChildAt(i));
-                icon.verifyHighRes();
+                View iconView = parent.getChildAt(i);
+                Drawable d = null;
+                if (iconView instanceof BubbleTextView btv) {
+                    btv.verifyHighRes();
+                    d = btv.getIcon();
+                } else if (iconView instanceof AppPairIcon api) {
+                    api.verifyHighRes();
+                    d = api.getIconDrawableArea().getDrawable();
+                }
+
                 // Set the callback back to the actual icon, in case
                 // it was captured by the FolderIcon
-                Drawable d = icon.getIcon();
                 if (d != null) {
-                    d.setCallback(icon);
+                    d.setCallback(iconView);
                 }
             }
         }
diff --git a/src/com/android/launcher3/folder/LauncherDelegate.java b/src/com/android/launcher3/folder/LauncherDelegate.java
index 33bcf21..07215c4 100644
--- a/src/com/android/launcher3/folder/LauncherDelegate.java
+++ b/src/com/android/launcher3/folder/LauncherDelegate.java
@@ -33,7 +33,7 @@
 import com.android.launcher3.logging.StatsLogManager.StatsLogger;
 import com.android.launcher3.model.ModelWriter;
 import com.android.launcher3.model.data.FolderInfo;
-import com.android.launcher3.model.data.WorkspaceItemInfo;
+import com.android.launcher3.model.data.ItemInfo;
 import com.android.launcher3.views.ActivityContext;
 import com.android.launcher3.views.BaseDragLayer;
 
@@ -86,7 +86,7 @@
                 FolderInfo info = folder.mInfo;
                 if (itemCount <= 1) {
                     View newIcon = null;
-                    WorkspaceItemInfo finalItem = null;
+                    ItemInfo finalItem = null;
 
                     if (itemCount == 1) {
                         // Move the item from the folder to the workspace, in the position of the
diff --git a/src/com/android/launcher3/folder/PreviewItemDrawingParams.java b/src/com/android/launcher3/folder/PreviewItemDrawingParams.java
index 58efdc1..0faa1c9 100644
--- a/src/com/android/launcher3/folder/PreviewItemDrawingParams.java
+++ b/src/com/android/launcher3/folder/PreviewItemDrawingParams.java
@@ -17,7 +17,7 @@
 
 import android.graphics.drawable.Drawable;
 
-import com.android.launcher3.model.data.WorkspaceItemInfo;
+import com.android.launcher3.model.data.ItemInfo;
 
 /**
  * Manages the parameters used to draw a Folder preview item.
@@ -30,7 +30,7 @@
     public FolderPreviewItemAnim anim;
     public boolean hidden;
     public Drawable drawable;
-    public WorkspaceItemInfo item;
+    public ItemInfo item;
 
     PreviewItemDrawingParams(float transX, float transY, float scale) {
         this.transX = transX;
diff --git a/src/com/android/launcher3/folder/PreviewItemManager.java b/src/com/android/launcher3/folder/PreviewItemManager.java
index 9001a0c..6311638 100644
--- a/src/com/android/launcher3/folder/PreviewItemManager.java
+++ b/src/com/android/launcher3/folder/PreviewItemManager.java
@@ -16,6 +16,7 @@
 
 package com.android.launcher3.folder;
 
+import static com.android.launcher3.BubbleTextView.DISPLAY_FOLDER;
 import static com.android.launcher3.folder.ClippedFolderIconLayoutRule.ENTER_INDEX;
 import static com.android.launcher3.folder.ClippedFolderIconLayoutRule.EXIT_INDEX;
 import static com.android.launcher3.folder.ClippedFolderIconLayoutRule.MAX_NUM_ITEMS_IN_PREVIEW;
@@ -41,7 +42,12 @@
 
 import com.android.launcher3.BubbleTextView;
 import com.android.launcher3.Utilities;
+import com.android.launcher3.apppairs.AppPairIcon;
+import com.android.launcher3.apppairs.AppPairIconDrawingParams;
+import com.android.launcher3.apppairs.AppPairIconGraphic;
 import com.android.launcher3.graphics.PreloadIconDrawable;
+import com.android.launcher3.model.data.AppPairInfo;
+import com.android.launcher3.model.data.ItemInfo;
 import com.android.launcher3.model.data.ItemInfoWithIcon;
 import com.android.launcher3.model.data.WorkspaceItemInfo;
 import com.android.launcher3.util.Themes;
@@ -125,7 +131,9 @@
     }
 
     Drawable prepareCreateAnimation(final View destView) {
-        Drawable animateDrawable = ((BubbleTextView) destView).getIcon();
+        Drawable animateDrawable = destView instanceof AppPairIcon
+                ? ((AppPairIcon) destView).getIconDrawableArea().getDrawable()
+                : ((BubbleTextView) destView).getIcon();
         computePreviewDrawingParams(animateDrawable.getIntrinsicWidth(),
                 destView.getMeasuredWidth());
         mReferenceDrawable = animateDrawable;
@@ -258,7 +266,7 @@
     }
 
     void buildParamsForPage(int page, ArrayList<PreviewItemDrawingParams> params, boolean animate) {
-        List<WorkspaceItemInfo> items = mIcon.getPreviewItemsOnPage(page);
+        List<ItemInfo> items = mIcon.getPreviewItemsOnPage(page);
 
         // We adjust the size of the list to match the number of items in the preview.
         while (items.size() < params.size()) {
@@ -328,16 +336,18 @@
         mNumOfPrevItems = numOfPrevItemsAux;
     }
 
-    void updatePreviewItems(Predicate<WorkspaceItemInfo> itemCheck) {
+    void updatePreviewItems(Predicate<ItemInfo> itemCheck) {
         boolean modified = false;
         for (PreviewItemDrawingParams param : mFirstPageParams) {
-            if (itemCheck.test(param.item)) {
+            if (itemCheck.test(param.item)
+                    || (param.item instanceof AppPairInfo api && api.anyMatch(itemCheck))) {
                 setDrawable(param, param.item);
                 modified = true;
             }
         }
         for (PreviewItemDrawingParams param : mCurrentPageParams) {
-            if (itemCheck.test(param.item)) {
+            if (itemCheck.test(param.item)
+                    || (param.item instanceof AppPairInfo api && api.anyMatch(itemCheck))) {
                 setDrawable(param, param.item);
                 modified = true;
             }
@@ -370,15 +380,14 @@
      * @param newItems The list of items in the new preview.
      * @param dropped  The item that was dropped onto the FolderIcon.
      */
-    public void onDrop(List<WorkspaceItemInfo> oldItems, List<WorkspaceItemInfo> newItems,
-            WorkspaceItemInfo dropped) {
+    public void onDrop(List<ItemInfo> oldItems, List<ItemInfo> newItems, ItemInfo dropped) {
         int numItems = newItems.size();
         final ArrayList<PreviewItemDrawingParams> params = mFirstPageParams;
         buildParamsForPage(0, params, false);
 
         // New preview items for items that are moving in (except for the dropped item).
-        List<WorkspaceItemInfo> moveIn = new ArrayList<>();
-        for (WorkspaceItemInfo newItem : newItems) {
+        List<ItemInfo> moveIn = new ArrayList<>();
+        for (ItemInfo newItem : newItems) {
             if (!oldItems.contains(newItem) && !newItem.equals(dropped)) {
                 moveIn.add(newItem);
             }
@@ -401,10 +410,10 @@
         }
 
         // Old preview items that need to be moved out.
-        List<WorkspaceItemInfo> moveOut = new ArrayList<>(oldItems);
+        List<ItemInfo> moveOut = new ArrayList<>(oldItems);
         moveOut.removeAll(newItems);
         for (int i = 0; i < moveOut.size(); ++i) {
-            WorkspaceItemInfo item = moveOut.get(i);
+            ItemInfo item = moveOut.get(i);
             int oldIndex = oldItems.indexOf(item);
             PreviewItemDrawingParams p = computePreviewItemDrawingParams(oldIndex, numItems, null);
             updateTransitionParam(p, item, oldIndex, EXIT_INDEX, numItems);
@@ -418,7 +427,7 @@
         }
     }
 
-    private void updateTransitionParam(final PreviewItemDrawingParams p, WorkspaceItemInfo item,
+    private void updateTransitionParam(final PreviewItemDrawingParams p, ItemInfo item,
             int prevIndex, int newIndex, int numItems) {
         setDrawable(p, item);
 
@@ -431,16 +440,24 @@
     }
 
     @VisibleForTesting
-    public void setDrawable(PreviewItemDrawingParams p, WorkspaceItemInfo item) {
-        if (item.hasPromiseIconUi() || (item.runtimeStatusFlags
-                & ItemInfoWithIcon.FLAG_SHOW_DOWNLOAD_PROGRESS_MASK) != 0) {
-            PreloadIconDrawable drawable = newPendingIcon(mContext, item);
-            p.drawable = drawable;
-        } else {
-            p.drawable = item.newIcon(mContext,
-                    Themes.isThemedIconEnabled(mContext) ? FLAG_THEMED : 0);
+    public void setDrawable(PreviewItemDrawingParams p, ItemInfo item) {
+        if (item instanceof WorkspaceItemInfo wii) {
+            if (wii.hasPromiseIconUi() || (wii.runtimeStatusFlags
+                    & ItemInfoWithIcon.FLAG_SHOW_DOWNLOAD_PROGRESS_MASK) != 0) {
+                PreloadIconDrawable drawable = newPendingIcon(mContext, wii);
+                p.drawable = drawable;
+            } else {
+                p.drawable = wii.newIcon(mContext,
+                        Themes.isThemedIconEnabled(mContext) ? FLAG_THEMED : 0);
+            }
+            p.drawable.setBounds(0, 0, mIconSize, mIconSize);
+        } else if (item instanceof AppPairInfo api) {
+            AppPairIconDrawingParams appPairParams =
+                    new AppPairIconDrawingParams(mContext, DISPLAY_FOLDER);
+            p.drawable = AppPairIconGraphic.composeDrawable(api, appPairParams);
+            p.drawable.setBounds(0, 0, mIconSize, mIconSize);
         }
-        p.drawable.setBounds(0, 0, mIconSize, mIconSize);
+
         p.item = item;
         // Set the callback to FolderIcon as it is responsible to drawing the icon. The
         // callback will be released when the folder is opened.
diff --git a/src/com/android/launcher3/icons/IconCache.java b/src/com/android/launcher3/icons/IconCache.java
index 1633eba..af704a8 100644
--- a/src/com/android/launcher3/icons/IconCache.java
+++ b/src/com/android/launcher3/icons/IconCache.java
@@ -51,6 +51,7 @@
 import androidx.annotation.VisibleForTesting;
 import androidx.core.util.Pair;
 
+import com.android.launcher3.Flags;
 import com.android.launcher3.InvariantDeviceProfile;
 import com.android.launcher3.Utilities;
 import com.android.launcher3.icons.ComponentWithLabel.ComponentCachingLogic;
@@ -248,7 +249,7 @@
     @SuppressWarnings("NewApi")
     public synchronized void getTitleAndIcon(ItemInfoWithIcon info,
             LauncherActivityInfo activityInfo, boolean useLowResIcon) {
-        boolean isAppArchived = Utilities.enableSupportForArchiving() && activityInfo != null
+        boolean isAppArchived = Flags.enableSupportForArchiving() && activityInfo != null
                 && activityInfo.getActivityInfo().isArchived;
         // If we already have activity info, no need to use package icon
         getTitleAndIcon(info, () -> activityInfo, isAppArchived, useLowResIcon,
diff --git a/src/com/android/launcher3/logging/StatsLogManager.java b/src/com/android/launcher3/logging/StatsLogManager.java
index 52fb122..441bbb5 100644
--- a/src/com/android/launcher3/logging/StatsLogManager.java
+++ b/src/com/android/launcher3/logging/StatsLogManager.java
@@ -23,6 +23,7 @@
 import android.content.Context;
 import android.view.View;
 
+import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.slice.SliceItem;
 
@@ -53,11 +54,18 @@
     public static final int LAUNCHER_STATE_ALLAPPS = 4;
     public static final int LAUNCHER_STATE_UNCHANGED = 5;
 
+    @NonNull
+    protected final Context mContext;
+    @Nullable
+    protected final ActivityContext mActivityContext;
+
+    private KeyboardStateManager mKeyboardStateManager;
     private InstanceId mInstanceId;
 
-    protected @Nullable ActivityContext mActivityContext = null;
-    protected @Nullable Context mContext = null;
-    private KeyboardStateManager mKeyboardStateManager;
+    public StatsLogManager(@NonNull Context context) {
+        mContext = context;
+        mActivityContext = ActivityContext.lookupContextNoThrow(context);
+    }
 
     /**
      * Returns event enum based on the two state transition information when swipe
@@ -210,6 +218,9 @@
         @UiEvent(doc = "User tapped on free form icon on a task menu.")
         LAUNCHER_SYSTEM_SHORTCUT_FREE_FORM_TAP(519),
 
+        @UiEvent(doc = "User tapped on desktop icon on a task menu.")
+        LAUNCHER_SYSTEM_SHORTCUT_DESKTOP_TAP(1706),
+
         @UiEvent(doc = "User tapped on pause app system shortcut.")
         LAUNCHER_SYSTEM_SHORTCUT_PAUSE_TAP(521),
 
@@ -1194,10 +1205,7 @@
      * Creates a new instance of {@link StatsLogManager} based on provided context.
      */
     public static StatsLogManager newInstance(Context context) {
-        StatsLogManager manager = Overrides.getObject(StatsLogManager.class,
+        return Overrides.getObject(StatsLogManager.class,
                 context.getApplicationContext(), R.string.stats_log_manager_class);
-        manager.mActivityContext = ActivityContext.lookupContextNoThrow(context);
-        manager.mContext = context;
-        return manager;
     }
 }
diff --git a/src/com/android/launcher3/model/AllAppsList.java b/src/com/android/launcher3/model/AllAppsList.java
index 8659471..8c5ea79 100644
--- a/src/com/android/launcher3/model/AllAppsList.java
+++ b/src/com/android/launcher3/model/AllAppsList.java
@@ -33,6 +33,7 @@
 import androidx.annotation.Nullable;
 
 import com.android.launcher3.AppFilter;
+import com.android.launcher3.Flags;
 import com.android.launcher3.Utilities;
 import com.android.launcher3.compat.AlphabeticIndexCompat;
 import com.android.launcher3.icons.IconCache;
@@ -330,7 +331,7 @@
                             PackageManagerHelper.getLoadingProgress(info),
                             PackageInstallInfo.STATUS_INSTALLED_DOWNLOADING);
                     applicationInfo.intent = launchIntent;
-                    if (Utilities.enableSupportForArchiving()) {
+                    if (Flags.enableSupportForArchiving()) {
                         // In case an app is archived, the respective item flag corresponding to
                         // archiving should also be applied during package updates
                         if (info.getActivityInfo().isArchived) {
diff --git a/src/com/android/launcher3/model/BgDataModel.java b/src/com/android/launcher3/model/BgDataModel.java
index 44e45da..d5de4ce 100644
--- a/src/com/android/launcher3/model/BgDataModel.java
+++ b/src/com/android/launcher3/model/BgDataModel.java
@@ -44,6 +44,7 @@
 import com.android.launcher3.Workspace;
 import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.model.data.AppInfo;
+import com.android.launcher3.model.data.AppPairInfo;
 import com.android.launcher3.model.data.CollectionInfo;
 import com.android.launcher3.model.data.FolderInfo;
 import com.android.launcher3.model.data.ItemInfo;
@@ -259,10 +260,15 @@
         itemsIdMap.put(item.id, item);
         switch (item.itemType) {
             case LauncherSettings.Favorites.ITEM_TYPE_FOLDER:
-            case LauncherSettings.Favorites.ITEM_TYPE_APP_PAIR:
-                collections.put(item.id, (CollectionInfo) item);
+                collections.put(item.id, (FolderInfo) item);
                 workspaceItems.add(item);
                 break;
+            case LauncherSettings.Favorites.ITEM_TYPE_APP_PAIR:
+                collections.put(item.id, (AppPairInfo) item);
+                // Fall through here. App pairs are both containers (like folders) and containable
+                // items (can be placed in folders). So we need to add app pairs to the folders
+                // array (above) but also verify the existence of their container, like regular
+                // apps (below).
             case LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT:
             case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION:
                 if (item.container == LauncherSettings.Favorites.CONTAINER_DESKTOP ||
@@ -277,7 +283,7 @@
                             Log.e(TAG, msg);
                         }
                     } else {
-                        findOrMakeFolder(item.container).add((WorkspaceItemInfo) item);
+                        findOrMakeFolder(item.container).add(item);
                     }
                 }
                 break;
diff --git a/src/com/android/launcher3/model/FirstScreenBroadcast.java b/src/com/android/launcher3/model/FirstScreenBroadcast.java
index 1deb665..cc20cd1 100644
--- a/src/com/android/launcher3/model/FirstScreenBroadcast.java
+++ b/src/com/android/launcher3/model/FirstScreenBroadcast.java
@@ -115,7 +115,7 @@
         for (ItemInfo info : firstScreenItems) {
             if (info instanceof CollectionInfo ci) {
                 String collectionItemInfoPackage;
-                for (ItemInfo collectionItemInfo : cloneOnMainThread(ci.getContents())) {
+                for (ItemInfo collectionItemInfo : cloneOnMainThread(ci.getAppContents())) {
                     collectionItemInfoPackage = getPackageName(collectionItemInfo);
                     if (collectionItemInfoPackage != null
                             && packages.contains(collectionItemInfoPackage)) {
diff --git a/src/com/android/launcher3/model/GridSizeMigrationUtil.java b/src/com/android/launcher3/model/GridSizeMigrationUtil.java
index 299c952..f24a7c1 100644
--- a/src/com/android/launcher3/model/GridSizeMigrationUtil.java
+++ b/src/com/android/launcher3/model/GridSizeMigrationUtil.java
@@ -49,6 +49,7 @@
 import com.android.launcher3.model.data.ItemInfo;
 import com.android.launcher3.pm.InstallSessionHelper;
 import com.android.launcher3.provider.LauncherDbUtils.SQLiteTransaction;
+import com.android.launcher3.util.ContentWriter;
 import com.android.launcher3.util.GridOccupancy;
 import com.android.launcher3.util.IntArray;
 import com.android.launcher3.widget.LauncherAppWidgetProviderInfo;
@@ -674,6 +675,11 @@
         private String mProvider;
         private Map<String, Set<Integer>> mFolderItems = new HashMap<>();
 
+        /**
+         * Id of the specific widget.
+         */
+        public int appWidgetId = NO_ID;
+
         /** Comparator according to the reading order */
         @Override
         public int compareTo(DbEntry another) {
@@ -707,6 +713,18 @@
             values.put(LauncherSettings.Favorites.SPANY, spanY);
         }
 
+        @Override
+        public void writeToValues(@NonNull ContentWriter writer) {
+            super.writeToValues(writer);
+            writer.put(LauncherSettings.Favorites.APPWIDGET_ID, appWidgetId);
+        }
+
+        @Override
+        public void readFromValues(@NonNull ContentValues values) {
+            super.readFromValues(values);
+            appWidgetId = values.getAsInteger(LauncherSettings.Favorites.APPWIDGET_ID);
+        }
+
         /** This id is not used in the DB is only used while doing the migration and it identifies
          * an entry on each workspace. For example two calculator icons would have the same
          * migration id even thought they have different database ids.
@@ -717,7 +735,10 @@
                 case LauncherSettings.Favorites.ITEM_TYPE_APP_PAIR:
                     return getFolderMigrationId();
                 case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET:
-                    return mProvider;
+                    // mProvider is the app the widget belongs to and appWidgetId it's the unique
+                    // is of the widget, we need both because if you remove a widget and then add it
+                    // again, then it can change and the WidgetProvider would not know the widget.
+                    return mProvider + appWidgetId;
                 case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION:
                     final String intentStr = cleanIntentString(mIntent);
                     try {
diff --git a/src/com/android/launcher3/model/ItemInstallQueue.java b/src/com/android/launcher3/model/ItemInstallQueue.java
index d350879..90aba2a 100644
--- a/src/com/android/launcher3/model/ItemInstallQueue.java
+++ b/src/com/android/launcher3/model/ItemInstallQueue.java
@@ -40,6 +40,7 @@
 import androidx.annotation.Nullable;
 import androidx.annotation.WorkerThread;
 
+import com.android.launcher3.Flags;
 import com.android.launcher3.InvariantDeviceProfile;
 import com.android.launcher3.Launcher;
 import com.android.launcher3.LauncherAppState;
@@ -300,7 +301,7 @@
                     } else {
                         lai = laiList.get(0);
                         si.intent = makeLaunchIntent(lai);
-                        if (Utilities.enableSupportForArchiving()
+                        if (Flags.enableSupportForArchiving()
                                 && lai.getActivityInfo().isArchived) {
                             si.runtimeStatusFlags |= FLAG_ARCHIVED;
                         }
diff --git a/src/com/android/launcher3/model/LoaderTask.java b/src/com/android/launcher3/model/LoaderTask.java
index 30cccd5..ac4c087 100644
--- a/src/com/android/launcher3/model/LoaderTask.java
+++ b/src/com/android/launcher3/model/LoaderTask.java
@@ -81,7 +81,6 @@
 import com.android.launcher3.model.data.FolderInfo;
 import com.android.launcher3.model.data.IconRequestInfo;
 import com.android.launcher3.model.data.ItemInfo;
-import com.android.launcher3.model.data.ItemInfoWithIcon;
 import com.android.launcher3.model.data.LauncherAppWidgetInfo;
 import com.android.launcher3.model.data.WorkspaceItemInfo;
 import com.android.launcher3.pm.InstallSessionHelper;
@@ -422,7 +421,7 @@
 
             final HashMap<PackageUserKey, SessionInfo> installingPkgs =
                     mSessionHelper.getActiveSessions();
-            if (Utilities.enableSupportForArchiving()) {
+            if (Flags.enableSupportForArchiving()) {
                 mInstallingPkgsCached = installingPkgs;
             }
             installingPkgs.forEach(mApp.getIconCache()::updateSessionCache);
@@ -494,9 +493,7 @@
             }
 
             appPair.getContents().sort(Folder.ITEM_POS_COMPARATOR);
-            // Fetch hi-res icons if needed.
-            appPair.getContents().stream().filter(ItemInfoWithIcon::usingLowResIcon)
-                    .forEach(member -> mIconCache.getTitleAndIcon(member, false));
+            appPair.fetchHiResIconsIfNeeded(mIconCache);
         }
     }
 
@@ -566,12 +563,16 @@
             // Ranks are the source of truth for folder items, so cellX and cellY can be
             // ignored for now. Database will be updated once user manually modifies folder.
             for (int rank = 0; rank < size; ++rank) {
-                WorkspaceItemInfo info = folder.getContents().get(rank);
+                ItemInfo info = folder.getContents().get(rank);
                 info.rank = rank;
 
-                if (info.usingLowResIcon() && info.itemType == Favorites.ITEM_TYPE_APPLICATION
+                if (info instanceof WorkspaceItemInfo wii
+                        && wii.usingLowResIcon()
+                        && wii.itemType == Favorites.ITEM_TYPE_APPLICATION
                         && verifiers.stream().anyMatch(it -> it.isItemInPreview(info.rank))) {
-                    mIconCache.getTitleAndIcon(info, false);
+                    mIconCache.getTitleAndIcon(wii, false);
+                } else if (info instanceof AppPairInfo api) {
+                    api.fetchHiResIconsIfNeeded(mIconCache);
                 }
             }
         }
@@ -694,7 +695,7 @@
             for (int i = 0; i < apps.size(); i++) {
                 LauncherActivityInfo app = apps.get(i);
                 AppInfo appInfo = new AppInfo(app, mUserCache.getUserInfo(user), quietMode);
-                if (Utilities.enableSupportForArchiving() && app.getApplicationInfo().isArchived) {
+                if (Flags.enableSupportForArchiving() && app.getApplicationInfo().isArchived) {
                     // For archived apps, include progress info in case there is a pending
                     // install session post restart of device.
                     String appPackageName = app.getApplicationInfo().packageName;
@@ -788,7 +789,7 @@
                 FolderNameInfos suggestionInfos = new FolderNameInfos();
                 CollectionInfo info = mBgDataModel.collections.valueAt(i);
                 if (info instanceof FolderInfo fi && fi.suggestedFolderNames == null) {
-                    provider.getSuggestedFolderName(mApp.getContext(), fi.getContents(),
+                    provider.getSuggestedFolderName(mApp.getContext(), fi.getAppContents(),
                             suggestionInfos);
                     fi.suggestedFolderNames = suggestionInfos;
                 }
diff --git a/src/com/android/launcher3/model/ModelDelegate.java b/src/com/android/launcher3/model/ModelDelegate.java
index 7e7bfb3..8360b14 100644
--- a/src/com/android/launcher3/model/ModelDelegate.java
+++ b/src/com/android/launcher3/model/ModelDelegate.java
@@ -45,28 +45,29 @@
             boolean isPrimaryInstance) {
         ModelDelegate delegate = Overrides.getObject(
                 ModelDelegate.class, context, R.string.model_delegate_class);
-        delegate.init(context, app, appsList, dataModel, isPrimaryInstance);
+        delegate.init(app, appsList, dataModel, isPrimaryInstance);
         return delegate;
     }
 
-    protected Context mContext;
+    protected final Context mContext;
     protected LauncherAppState mApp;
     protected AllAppsList mAppsList;
     protected BgDataModel mDataModel;
     protected boolean mIsPrimaryInstance;
 
-    public ModelDelegate() { }
+    public ModelDelegate(Context context) {
+        mContext = context;
+    }
 
     /**
      * Initializes the object with the given params.
      */
-    private void init(Context context, LauncherAppState app, AllAppsList appsList,
+    private void init(LauncherAppState app, AllAppsList appsList,
             BgDataModel dataModel, boolean isPrimaryInstance) {
         this.mApp = app;
         this.mAppsList = appsList;
         this.mDataModel = dataModel;
         this.mIsPrimaryInstance = isPrimaryInstance;
-        this.mContext = context;
     }
 
     /** Called periodically to validate and update any data */
diff --git a/src/com/android/launcher3/model/PackageUpdatedTask.java b/src/com/android/launcher3/model/PackageUpdatedTask.java
index ea1ae2e..1923065 100644
--- a/src/com/android/launcher3/model/PackageUpdatedTask.java
+++ b/src/com/android/launcher3/model/PackageUpdatedTask.java
@@ -48,7 +48,7 @@
 import com.android.launcher3.pm.PackageInstallInfo;
 import com.android.launcher3.pm.UserCache;
 import com.android.launcher3.shortcuts.ShortcutRequest;
-import com.android.launcher3.uioverrides.ApiWrapper;
+import com.android.launcher3.util.ApiWrapper;
 import com.android.launcher3.util.FlagOp;
 import com.android.launcher3.util.IntSet;
 import com.android.launcher3.util.ItemInfoMatcher;
@@ -276,7 +276,7 @@
                                     PackageInstallInfo.STATUS_INSTALLED_DOWNLOADING);
                             // In case an app is archived, we need to make sure that archived state
                             // in WorkspaceItemInfo is refreshed.
-                            if (Utilities.enableSupportForArchiving() && !activities.isEmpty()) {
+                            if (Flags.enableSupportForArchiving() && !activities.isEmpty()) {
                                 boolean newArchivalState = activities.get(
                                         0).getActivityInfo().isArchived;
                                 if (newArchivalState != si.isArchived()) {
@@ -286,7 +286,7 @@
                             }
                             if (si.itemType == Favorites.ITEM_TYPE_APPLICATION) {
                                 if (activities != null && !activities.isEmpty()) {
-                                    si.status = ApiWrapper
+                                    si.status = ApiWrapper.INSTANCE.get(context)
                                             .isNonResizeableActivity(activities.get(0))
                                             ? si.status | WorkspaceItemInfo.FLAG_NON_RESIZEABLE
                                             : si.status & ~WorkspaceItemInfo.FLAG_NON_RESIZEABLE;
diff --git a/src/com/android/launcher3/model/WorkspaceItemProcessor.kt b/src/com/android/launcher3/model/WorkspaceItemProcessor.kt
index aa29290..ee45c0f 100644
--- a/src/com/android/launcher3/model/WorkspaceItemProcessor.kt
+++ b/src/com/android/launcher3/model/WorkspaceItemProcessor.kt
@@ -26,11 +26,13 @@
 import android.text.TextUtils
 import android.util.Log
 import android.util.LongSparseArray
+import com.android.launcher3.Flags
 import com.android.launcher3.InvariantDeviceProfile
 import com.android.launcher3.LauncherAppState
 import com.android.launcher3.LauncherSettings.Favorites
 import com.android.launcher3.Utilities
 import com.android.launcher3.backuprestore.LauncherRestoreEventLogger.RestoreError
+import com.android.launcher3.config.FeatureFlags
 import com.android.launcher3.logging.FileLog
 import com.android.launcher3.model.data.AppPairInfo
 import com.android.launcher3.model.data.FolderInfo
@@ -40,7 +42,7 @@
 import com.android.launcher3.model.data.WorkspaceItemInfo
 import com.android.launcher3.pm.PackageInstallInfo
 import com.android.launcher3.shortcuts.ShortcutKey
-import com.android.launcher3.uioverrides.ApiWrapper
+import com.android.launcher3.util.ApiWrapper
 import com.android.launcher3.util.ComponentKey
 import com.android.launcher3.util.PackageManagerHelper
 import com.android.launcher3.util.PackageUserKey
@@ -324,7 +326,7 @@
             }
             val activityInfo = c.launcherActivityInfo
             if (activityInfo != null) {
-                if (ApiWrapper.isNonResizeableActivity(activityInfo)) {
+                if (ApiWrapper.INSTANCE.get(app.context).isNonResizeableActivity(activityInfo)) {
                     info.status = info.status or WorkspaceItemInfo.FLAG_NON_RESIZEABLE
                 }
                 info.setProgressLevel(
@@ -334,7 +336,7 @@
             }
             if (
                 (c.restoreFlag != 0 ||
-                    Utilities.enableSupportForArchiving() &&
+                    Flags.enableSupportForArchiving() &&
                         activityInfo != null &&
                         activityInfo.applicationInfo.isArchived) && !TextUtils.isEmpty(targetPkg)
             ) {
@@ -346,7 +348,7 @@
                             ItemInfoWithIcon.FLAG_INSTALL_SESSION_ACTIVE.inv()
                 } else if (
                     activityInfo == null ||
-                        (Utilities.enableSupportForArchiving() &&
+                        (Flags.enableSupportForArchiving() &&
                             activityInfo.applicationInfo.isArchived)
                 ) {
                     // For archived apps, include progress info in case there is
@@ -372,10 +374,16 @@
         // If we generated a placeholder Folder before this point, it may need to be replaced with
         // an app pair.
         if (c.itemType == Favorites.ITEM_TYPE_APP_PAIR && collection is FolderInfo) {
+            if (!FeatureFlags.enableAppPairs()) {
+                // If app pairs are not enabled, stop loading.
+                Log.e(TAG, "app pairs flag is off, did not load app pair")
+                return
+            }
+
             val folderInfo: FolderInfo = collection
             val newAppPair = AppPairInfo()
             // Move the placeholder's contents over to the new app pair.
-            folderInfo.contents.forEach(newAppPair::add)
+            folderInfo.getContents().forEach(newAppPair::add)
             collection = newAppPair
             // Remove the placeholder and add the app pair into the data model.
             bgDataModel.collections.remove(c.id)
@@ -472,7 +480,7 @@
                         !isSafeMode &&
                         (si == null) &&
                         (lapi == null) &&
-                        !(Utilities.enableSupportForArchiving() &&
+                        !(Flags.enableSupportForArchiving() &&
                             pmHelper.isAppArchived(component.packageName))
                 ) {
                     // Restore never started
diff --git a/src/com/android/launcher3/model/data/AppInfo.java b/src/com/android/launcher3/model/data/AppInfo.java
index 210d720..93ba619 100644
--- a/src/com/android/launcher3/model/data/AppInfo.java
+++ b/src/com/android/launcher3/model/data/AppInfo.java
@@ -181,7 +181,7 @@
         if (PackageManagerHelper.isAppSuspended(appInfo)) {
             info.runtimeStatusFlags |= FLAG_DISABLED_SUSPENDED;
         }
-        if (Utilities.enableSupportForArchiving() && lai.getActivityInfo().isArchived) {
+        if (Flags.enableSupportForArchiving() && lai.getActivityInfo().isArchived) {
             info.runtimeStatusFlags |= FLAG_ARCHIVED;
         }
         info.runtimeStatusFlags |= (appInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0
diff --git a/src/com/android/launcher3/model/data/AppPairInfo.kt b/src/com/android/launcher3/model/data/AppPairInfo.kt
index 4081316..fad365c 100644
--- a/src/com/android/launcher3/model/data/AppPairInfo.kt
+++ b/src/com/android/launcher3/model/data/AppPairInfo.kt
@@ -18,11 +18,15 @@
 
 import android.content.Context
 import com.android.launcher3.LauncherSettings
+import com.android.launcher3.R
+import com.android.launcher3.icons.IconCache
 import com.android.launcher3.logger.LauncherAtom
 import com.android.launcher3.views.ActivityContext
 
 /** A type of app collection that launches multiple apps into split screen. */
 class AppPairInfo() : CollectionInfo() {
+    private var contents: ArrayList<WorkspaceItemInfo> = ArrayList()
+
     init {
         itemType = LauncherSettings.Favorites.ITEM_TYPE_APP_PAIR
     }
@@ -33,11 +37,28 @@
         add(app2)
     }
 
-    /** Adds an element to the contents array. */
-    override fun add(item: WorkspaceItemInfo) {
+    /** Creates a new AppPairInfo that is a copy of the provided one. */
+    constructor(appPairInfo: AppPairInfo) : this() {
+        contents = appPairInfo.contents.clone() as ArrayList<WorkspaceItemInfo>
+        copyFrom(appPairInfo)
+    }
+
+    /** Adds an element to the contents ArrayList. */
+    override fun add(item: ItemInfo) {
+        if (item !is WorkspaceItemInfo) {
+            throw RuntimeException("tried to add an illegal type into an app pair")
+        }
+
         contents.add(item)
     }
 
+    /** Returns the app pair's member apps as an ArrayList of [ItemInfo]. */
+    override fun getContents(): ArrayList<ItemInfo> =
+        ArrayList(contents.stream().map { it as ItemInfo }.toList())
+
+    /** Returns the app pair's member apps as an ArrayList of [WorkspaceItemInfo]. */
+    override fun getAppContents(): ArrayList<WorkspaceItemInfo> = contents
+
     /** Returns the first app in the pair. */
     fun getFirstApp() = contents[0]
 
@@ -50,7 +71,34 @@
     /** Checks if the app pair is launchable at the current screen size. */
     fun isLaunchable(context: Context) =
         (ActivityContext.lookupContext(context) as ActivityContext).getDeviceProfile().isTablet ||
-            noneMatch { it.hasStatusFlag(WorkspaceItemInfo.FLAG_NON_RESIZEABLE) }
+            getAppContents().stream().noneMatch {
+                it.hasStatusFlag(WorkspaceItemInfo.FLAG_NON_RESIZEABLE)
+            }
+
+    /** Fetches high-res icons for member apps if needed. */
+    fun fetchHiResIconsIfNeeded(iconCache: IconCache) {
+        getAppContents().stream().filter(ItemInfoWithIcon::usingLowResIcon).forEach { member ->
+            iconCache.getTitleAndIcon(member, false)
+        }
+    }
+
+    /**
+     * App pairs will draw as "disabled" if either of the following is true:
+     * 1) One of the member WorkspaceItemInfos is disabled (i.e. the app software itself is paused
+     *    or can't be launched for some other reason).
+     * 2) One of the member apps can't be launched due to screen size requirements.
+     */
+    fun shouldDrawAsDisabled(context: Context): Boolean {
+        return isDisabled || !isLaunchable(context)
+    }
+
+    /** Generates a default title for the app pair and sets it. */
+    fun generateTitle(context: Context): CharSequence? {
+        val app1: CharSequence? = getFirstApp().title
+        val app2: CharSequence? = getSecondApp().title
+        title = context.getString(R.string.app_pair_default_title, app1, app2)
+        return title
+    }
 
     /** Generates an ItemInfo for logging. */
     override fun buildProto(cInfo: CollectionInfo?): LauncherAtom.ItemInfo {
diff --git a/src/com/android/launcher3/model/data/CollectionInfo.kt b/src/com/android/launcher3/model/data/CollectionInfo.kt
index 2b865a5..4f5e12f 100644
--- a/src/com/android/launcher3/model/data/CollectionInfo.kt
+++ b/src/com/android/launcher3/model/data/CollectionInfo.kt
@@ -22,19 +22,21 @@
 import java.util.function.Predicate
 
 abstract class CollectionInfo : ItemInfo() {
-    var contents: ArrayList<WorkspaceItemInfo> = ArrayList()
+    /** Adds an ItemInfo to the collection. Throws if given an illegal type. */
+    abstract fun add(item: ItemInfo)
 
-    abstract fun add(item: WorkspaceItemInfo)
+    /** Returns the collection's contents as an ArrayList of [ItemInfo]. */
+    abstract fun getContents(): ArrayList<ItemInfo>
+
+    /**
+     * Returns the collection's contents as an ArrayList of [WorkspaceItemInfo]. Does not include
+     * other collection [ItemInfo]s that are inside this collection; rather, it should collect
+     * *their* contents and adds them to the ArrayList.
+     */
+    abstract fun getAppContents(): ArrayList<WorkspaceItemInfo>
 
     /** Convenience function. Checks contents to see if any match a given predicate. */
-    fun anyMatch(matcher: Predicate<in WorkspaceItemInfo>): Boolean {
-        return contents.stream().anyMatch(matcher)
-    }
-
-    /** Convenience function. Returns true if none of the contents match a given predicate. */
-    fun noneMatch(matcher: Predicate<in WorkspaceItemInfo>): Boolean {
-        return contents.stream().noneMatch(matcher)
-    }
+    fun anyMatch(matcher: Predicate<ItemInfo>) = getContents().stream().anyMatch(matcher)
 
     override fun onAddToDatabase(writer: ContentWriter) {
         super.onAddToDatabase(writer)
diff --git a/src/com/android/launcher3/model/data/FolderInfo.java b/src/com/android/launcher3/model/data/FolderInfo.java
index 1bbb2fe..18d2b85 100644
--- a/src/com/android/launcher3/model/data/FolderInfo.java
+++ b/src/com/android/launcher3/model/data/FolderInfo.java
@@ -29,6 +29,7 @@
 
 import com.android.launcher3.LauncherSettings;
 import com.android.launcher3.Utilities;
+import com.android.launcher3.folder.Folder;
 import com.android.launcher3.folder.FolderNameInfos;
 import com.android.launcher3.logger.LauncherAtom;
 import com.android.launcher3.logger.LauncherAtom.Attribute;
@@ -98,14 +99,20 @@
 
     public FolderNameInfos suggestedFolderNames;
 
+    /**
+     * The apps and shortcuts
+     */
+    private final ArrayList<ItemInfo> contents = new ArrayList<>();
+
     private ArrayList<FolderListener> mListeners = new ArrayList<>();
 
     public FolderInfo() {
         itemType = LauncherSettings.Favorites.ITEM_TYPE_FOLDER;
     }
 
-    /** Adds a app or shortcut to the contents array without animation. */
-    public void add(@NonNull WorkspaceItemInfo item) {
+    /** Adds a app or shortcut to the contents ArrayList without animation. */
+    @Override
+    public void add(@NonNull ItemInfo item) {
         add(item, false /* animate */);
     }
 
@@ -114,14 +121,18 @@
      *
      * @param item
      */
-    public void add(WorkspaceItemInfo item, boolean animate) {
+    public void add(ItemInfo item, boolean animate) {
         add(item, getContents().size(), animate);
     }
 
     /**
      * Add an app or shortcut for a specified rank.
      */
-    public void add(WorkspaceItemInfo item, int rank, boolean animate) {
+    public void add(ItemInfo item, int rank, boolean animate) {
+        if (!Folder.willAccept(item)) {
+            throw new RuntimeException("tried to add an illegal type into a folder");
+        }
+
         rank = Utilities.boundToRange(rank, 0, getContents().size());
         getContents().add(rank, item);
         for (int i = 0; i < mListeners.size(); i++) {
@@ -135,21 +146,49 @@
      *
      * @param item
      */
-    public void remove(WorkspaceItemInfo item, boolean animate) {
+    public void remove(ItemInfo item, boolean animate) {
         removeAll(Collections.singletonList(item), animate);
     }
 
     /**
      * Remove all matching app or shortcut. Does not change the DB.
      */
-    public void removeAll(List<WorkspaceItemInfo> items, boolean animate) {
-        getContents().removeAll(items);
+    public void removeAll(List<ItemInfo> items, boolean animate) {
+        contents.removeAll(items);
         for (int i = 0; i < mListeners.size(); i++) {
             mListeners.get(i).onRemove(items);
         }
         itemsChanged(animate);
     }
 
+    /**
+     * Returns the folder's contents as an ArrayList of {@link ItemInfo}. Includes
+     * {@link WorkspaceItemInfo} and {@link AppPairInfo}s.
+     */
+    @NonNull
+    @Override
+    public ArrayList<ItemInfo> getContents() {
+        return contents;
+    }
+
+    /**
+     * Returns the folder's contents as an ArrayList of {@link WorkspaceItemInfo}. Note: Does not
+     * return any {@link AppPairInfo}s contained in the folder, instead collects *their* contents
+     * and adds them to the ArrayList.
+     */
+    @Override
+    public ArrayList<WorkspaceItemInfo> getAppContents()  {
+        ArrayList<WorkspaceItemInfo> workspaceItemInfos = new ArrayList<>();
+        for (ItemInfo item : contents) {
+            if (item instanceof WorkspaceItemInfo wii) {
+                workspaceItemInfos.add(wii);
+            } else if (item instanceof AppPairInfo api) {
+                workspaceItemInfos.addAll(api.getAppContents());
+            }
+        }
+        return workspaceItemInfos;
+    }
+
     @Override
     public void onAddToDatabase(@NonNull ContentWriter writer) {
         super.onAddToDatabase(writer);
@@ -171,9 +210,11 @@
     }
 
     public interface FolderListener {
-        void onAdd(WorkspaceItemInfo item, int rank);
-        void onRemove(List<WorkspaceItemInfo> item);
+        void onAdd(ItemInfo item, int rank);
+        void onRemove(List<ItemInfo> item);
         void onItemsChanged(boolean animate);
+        void onTitleChanged(CharSequence title);
+
     }
 
     public boolean hasOption(int optionFlag) {
@@ -246,6 +287,10 @@
         if (modelWriter != null) {
             modelWriter.updateItemInDatabase(this);
         }
+
+        for (int i = 0; i < mListeners.size(); i++) {
+            mListeners.get(i).onTitleChanged(title);
+        }
     }
 
     /**
@@ -263,10 +308,17 @@
     public ItemInfo makeShallowCopy() {
         FolderInfo folderInfo = new FolderInfo();
         folderInfo.copyFrom(this);
-        folderInfo.setContents(this.getContents());
         return folderInfo;
     }
 
+    @Override
+    public void copyFrom(@NonNull ItemInfo info) {
+        super.copyFrom(info);
+        if (info instanceof FolderInfo fi) {
+            contents.addAll(fi.getContents());
+        }
+    }
+
     /**
      * Returns index of the accepted suggestion.
      */
diff --git a/src/com/android/launcher3/model/data/ItemInfoWithIcon.java b/src/com/android/launcher3/model/data/ItemInfoWithIcon.java
index 9fbc6bf..3a74ff2 100644
--- a/src/com/android/launcher3/model/data/ItemInfoWithIcon.java
+++ b/src/com/android/launcher3/model/data/ItemInfoWithIcon.java
@@ -22,13 +22,14 @@
 
 import androidx.annotation.Nullable;
 
+import com.android.launcher3.Flags;
 import com.android.launcher3.Utilities;
 import com.android.launcher3.icons.BitmapInfo;
 import com.android.launcher3.icons.BitmapInfo.DrawableCreationFlags;
 import com.android.launcher3.icons.FastBitmapDrawable;
 import com.android.launcher3.logging.FileLog;
 import com.android.launcher3.pm.PackageInstallInfo;
-import com.android.launcher3.uioverrides.ApiWrapper;
+import com.android.launcher3.util.ApiWrapper;
 
 /**
  * Represents an ItemInfo which also holds an icon.
@@ -162,15 +163,15 @@
      * Returns true if the app corresponding to the item is archived.
      */
     public boolean isArchived() {
-        if (!Utilities.enableSupportForArchiving()) {
+        if (!Flags.enableSupportForArchiving()) {
             return false;
         }
         return (runtimeStatusFlags & FLAG_ARCHIVED) != 0;
     }
 
-    /** Returns true if the app is archived and has an active install session. */
-    public boolean isActiveArchive() {
-        return isArchived() && (runtimeStatusFlags & FLAG_INSTALL_SESSION_ACTIVE) != 0;
+    /** Returns true if the app is archived and doesn't have an active install session. */
+    public boolean isInactiveArchive() {
+        return isArchived() && (runtimeStatusFlags & FLAG_INSTALL_SESSION_ACTIVE) == 0;
     }
 
     /**
@@ -251,8 +252,8 @@
         String targetPackage = getTargetPackage();
 
         return targetPackage != null
-                ? ApiWrapper.getAppMarketActivityIntent(
-                context, targetPackage, Process.myUserHandle())
+                ? ApiWrapper.INSTANCE.get(context).getAppMarketActivityIntent(
+                        targetPackage, Process.myUserHandle())
                 : null;
     }
 
diff --git a/src/com/android/launcher3/model/data/WorkspaceItemInfo.java b/src/com/android/launcher3/model/data/WorkspaceItemInfo.java
index 9917ad7..5ae7003 100644
--- a/src/com/android/launcher3/model/data/WorkspaceItemInfo.java
+++ b/src/com/android/launcher3/model/data/WorkspaceItemInfo.java
@@ -32,7 +32,7 @@
 import com.android.launcher3.icons.IconCache;
 import com.android.launcher3.pm.UserCache;
 import com.android.launcher3.shortcuts.ShortcutKey;
-import com.android.launcher3.uioverrides.ApiWrapper;
+import com.android.launcher3.util.ApiWrapper;
 import com.android.launcher3.util.ContentWriter;
 
 import java.util.Arrays;
@@ -201,7 +201,7 @@
             runtimeStatusFlags &= ~FLAG_DISABLED_VERSION_LOWER;
         }
 
-        Person[] persons = ApiWrapper.getPersons(shortcutInfo);
+        Person[] persons = ApiWrapper.INSTANCE.get(context).getPersons(shortcutInfo);
         personKeys = persons.length == 0 ? Utilities.EMPTY_STRING_ARRAY
             : Arrays.stream(persons).map(Person::getKey).sorted().toArray(String[]::new);
     }
diff --git a/src/com/android/launcher3/pm/InstallSessionHelper.java b/src/com/android/launcher3/pm/InstallSessionHelper.java
index f3769d5..4a3318e 100644
--- a/src/com/android/launcher3/pm/InstallSessionHelper.java
+++ b/src/com/android/launcher3/pm/InstallSessionHelper.java
@@ -29,6 +29,7 @@
 import androidx.annotation.Nullable;
 import androidx.annotation.WorkerThread;
 
+import com.android.launcher3.Flags;
 import com.android.launcher3.LauncherPrefs;
 import com.android.launcher3.SessionCommitReceiver;
 import com.android.launcher3.Utilities;
@@ -217,7 +218,7 @@
                 && !promiseIconAddedForId(sessionInfo.getSessionId())) {
             // In case of unarchival, we do not want to add a workspace promise icon if one is
             // not already present. For general app installations however, we do support it.
-            if (!Utilities.enableSupportForArchiving() || !sessionInfo.isUnarchival()) {
+            if (!Flags.enableSupportForArchiving() || !sessionInfo.isUnarchival()) {
                 FileLog.d(LOG, "Adding package name to install queue: "
                         + sessionInfo.getAppPackageName());
 
@@ -232,7 +233,7 @@
 
     public boolean verifySessionInfo(@Nullable final PackageInstaller.SessionInfo sessionInfo) {
         // For archived apps we always want to show promise icons and the checks below don't apply.
-        if (Utilities.enableSupportForArchiving() && sessionInfo != null
+        if (Flags.enableSupportForArchiving() && sessionInfo != null
                 && sessionInfo.isUnarchival()) {
             return true;
         }
diff --git a/src/com/android/launcher3/pm/InstallSessionTracker.java b/src/com/android/launcher3/pm/InstallSessionTracker.java
index eacbc11..24d58f3 100644
--- a/src/com/android/launcher3/pm/InstallSessionTracker.java
+++ b/src/com/android/launcher3/pm/InstallSessionTracker.java
@@ -31,6 +31,7 @@
 import androidx.annotation.Nullable;
 import androidx.annotation.WorkerThread;
 
+import com.android.launcher3.Flags;
 import com.android.launcher3.Utilities;
 import com.android.launcher3.util.PackageUserKey;
 
@@ -80,7 +81,7 @@
 
         helper.tryQueuePromiseAppIcon(sessionInfo);
 
-        if (Utilities.enableSupportForArchiving() && sessionInfo != null
+        if (Flags.enableSupportForArchiving() && sessionInfo != null
                 && sessionInfo.isUnarchival()) {
             // For archived apps, icon could already be present on the workspace. To make sure
             // the icon state is updated, we send a change event.
diff --git a/src/com/android/launcher3/pm/UserCache.java b/src/com/android/launcher3/pm/UserCache.java
index 032de31..185e0b5 100644
--- a/src/com/android/launcher3/pm/UserCache.java
+++ b/src/com/android/launcher3/pm/UserCache.java
@@ -17,7 +17,6 @@
 package com.android.launcher3.pm;
 
 import static com.android.launcher3.Utilities.ATLEAST_U;
-import static com.android.launcher3.uioverrides.ApiWrapper.queryAllUsers;
 import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
 
 import android.content.Context;
@@ -34,6 +33,7 @@
 
 import com.android.launcher3.icons.BitmapInfo;
 import com.android.launcher3.icons.UserBadgeDrawable;
+import com.android.launcher3.util.ApiWrapper;
 import com.android.launcher3.util.FlagOp;
 import com.android.launcher3.util.MainThreadInitializedObject;
 import com.android.launcher3.util.SafeCloseable;
@@ -119,7 +119,7 @@
 
     @WorkerThread
     private void updateCache() {
-        mUserToSerialMap = queryAllUsers(mContext);
+        mUserToSerialMap = ApiWrapper.INSTANCE.get(mContext).queryAllUsers();
     }
 
     /**
diff --git a/src/com/android/launcher3/popup/RemoteActionShortcut.java b/src/com/android/launcher3/popup/RemoteActionShortcut.java
index 688da49..0860ae5 100644
--- a/src/com/android/launcher3/popup/RemoteActionShortcut.java
+++ b/src/com/android/launcher3/popup/RemoteActionShortcut.java
@@ -33,22 +33,22 @@
 import android.widget.Toast;
 
 import com.android.launcher3.AbstractFloatingView;
-import com.android.launcher3.BaseDraggingActivity;
 import com.android.launcher3.R;
 import com.android.launcher3.Utilities;
 import com.android.launcher3.model.data.ItemInfo;
+import com.android.launcher3.views.ActivityContext;
 
 import java.lang.ref.WeakReference;
 
-public class RemoteActionShortcut extends SystemShortcut<BaseDraggingActivity> {
+public class RemoteActionShortcut<T extends Context & ActivityContext> extends SystemShortcut<T> {
     private static final String TAG = "RemoteActionShortcut";
     private static final boolean DEBUG = Utilities.IS_DEBUG_DEVICE;
 
     private final RemoteAction mAction;
 
     public RemoteActionShortcut(RemoteAction action,
-            BaseDraggingActivity activity, ItemInfo itemInfo, View originalView) {
-        super(0, R.id.action_remote_action_shortcut, activity, itemInfo, originalView);
+            T context, ItemInfo itemInfo, View originalView) {
+        super(0, R.id.action_remote_action_shortcut, context, itemInfo, originalView);
         mAction = action;
     }
 
@@ -80,7 +80,7 @@
         mTarget.getStatsLogManager().logger().withItemInfo(mItemInfo)
                 .log(LAUNCHER_SYSTEM_SHORTCUT_PAUSE_TAP);
 
-        final WeakReference<BaseDraggingActivity> weakTarget = new WeakReference<>(mTarget);
+        final WeakReference<T> weakTarget = new WeakReference<>(mTarget);
         final String actionIdentity = mAction.getTitle() + ", "
                 + mItemInfo.getTargetComponent().getPackageName();
 
@@ -95,7 +95,7 @@
                             mItemInfo.getTargetComponent().getPackageName()),
                     (pendingIntent, intent, resultCode, resultData, resultExtras) -> {
                         if (DEBUG) Log.d(TAG, "Action is complete: " + actionIdentity);
-                        final BaseDraggingActivity target = weakTarget.get();
+                        final T target = weakTarget.get();
                         if (resultData != null && !resultData.isEmpty()) {
                             Log.e(TAG, "Remote action returned result: " + actionIdentity
                                     + " : " + resultData);
diff --git a/src/com/android/launcher3/popup/SystemShortcut.java b/src/com/android/launcher3/popup/SystemShortcut.java
index 0af7e67..f56d732 100644
--- a/src/com/android/launcher3/popup/SystemShortcut.java
+++ b/src/com/android/launcher3/popup/SystemShortcut.java
@@ -22,6 +22,7 @@
 import androidx.annotation.Nullable;
 
 import com.android.launcher3.AbstractFloatingView;
+import com.android.launcher3.AbstractFloatingViewHelper;
 import com.android.launcher3.Flags;
 import com.android.launcher3.R;
 import com.android.launcher3.SecondaryDropTarget;
@@ -31,7 +32,7 @@
 import com.android.launcher3.model.data.ItemInfo;
 import com.android.launcher3.model.data.WorkspaceItemInfo;
 import com.android.launcher3.pm.UserCache;
-import com.android.launcher3.uioverrides.ApiWrapper;
+import com.android.launcher3.util.ApiWrapper;
 import com.android.launcher3.util.ComponentKey;
 import com.android.launcher3.util.InstantAppResolver;
 import com.android.launcher3.util.PackageManagerHelper;
@@ -61,23 +62,23 @@
     protected final ItemInfo mItemInfo;
     protected final View mOriginalView;
 
+    private final AbstractFloatingViewHelper mAbstractFloatingViewHelper;
+
     public SystemShortcut(int iconResId, int labelResId, T target, ItemInfo itemInfo,
             View originalView) {
+        this(iconResId, labelResId, target, itemInfo, originalView,
+                new AbstractFloatingViewHelper());
+    }
+
+    public SystemShortcut(int iconResId, int labelResId, T target, ItemInfo itemInfo,
+            View originalView, AbstractFloatingViewHelper abstractFloatingViewHelper) {
         mIconResId = iconResId;
         mLabelResId = labelResId;
         mAccessibilityActionId = labelResId;
         mTarget = target;
         mItemInfo = itemInfo;
         mOriginalView = originalView;
-    }
-
-    public SystemShortcut(SystemShortcut<T> other) {
-        mIconResId = other.mIconResId;
-        mLabelResId = other.mLabelResId;
-        mAccessibilityActionId = other.mAccessibilityActionId;
-        mTarget = other.mTarget;
-        mItemInfo = other.mItemInfo;
-        mOriginalView = other.mOriginalView;
+        mAbstractFloatingViewHelper = abstractFloatingViewHelper;
     }
 
     public void setIconAndLabelFor(View iconView, TextView labelView) {
@@ -178,7 +179,7 @@
 
         @Override
         public void onClick(View view) {
-            dismissTaskMenuView(mTarget);
+            dismissTaskMenuView();
             Rect sourceBounds = Utilities.getViewBounds(view);
             new PackageManagerHelper(view.getContext()).startDetailsActivityForInfo(
                     mItemInfo, sourceBounds, ActivityOptions.makeBasic().toBundle());
@@ -259,10 +260,8 @@
         @Override
         public void onClick(View view) {
             Intent intent =
-                    ApiWrapper.getAppMarketActivityIntent(
-                            view.getContext(),
-                            mItemInfo.getTargetComponent().getPackageName(),
-                            mSpaceUser);
+                    ApiWrapper.INSTANCE.get(view.getContext()).getAppMarketActivityIntent(
+                            mItemInfo.getTargetComponent().getPackageName(), mSpaceUser);
             mTarget.startActivitySafely(view, intent, mItemInfo);
             AbstractFloatingView.closeAllOpenViews(mTarget);
             mTarget.getStatsLogManager()
@@ -303,9 +302,8 @@
 
         @Override
         public void onClick(View view) {
-            Intent intent = ApiWrapper.getAppMarketActivityIntent(view.getContext(),
-                    mItemInfo.getTargetComponent().getPackageName(),
-                    Process.myUserHandle());
+            Intent intent = ApiWrapper.INSTANCE.get(view.getContext()).getAppMarketActivityIntent(
+                    mItemInfo.getTargetComponent().getPackageName(), Process.myUserHandle());
             mTarget.startActivitySafely(view, intent, mItemInfo);
             AbstractFloatingView.closeAllOpenViews(mTarget);
         }
@@ -327,7 +325,7 @@
 
         @Override
         public void onClick(View view) {
-            dismissTaskMenuView(mTarget);
+            dismissTaskMenuView();
             mTarget.getStatsLogManager().logger()
                     .withItemInfo(mItemInfo)
                     .log(LAUNCHER_SYSTEM_SHORTCUT_DONT_SUGGEST_APP_TAP);
@@ -370,7 +368,7 @@
 
         @Override
         public void onClick(View view) {
-            dismissTaskMenuView(mTarget);
+            dismissTaskMenuView();
             SecondaryDropTarget.performUninstall(view.getContext(), mComponentName, mItemInfo);
             mTarget.getStatsLogManager()
                     .logger()
@@ -379,8 +377,8 @@
         }
     }
 
-    public static <T extends ActivityContext> void dismissTaskMenuView(T activity) {
-        AbstractFloatingView.closeOpenViews(activity, true,
+    protected void dismissTaskMenuView() {
+        mAbstractFloatingViewHelper.closeOpenViews(mTarget, true,
                 AbstractFloatingView.TYPE_ALL & ~AbstractFloatingView.TYPE_REBIND_SAFE);
     }
 }
diff --git a/src/com/android/launcher3/provider/RestoreDbTask.java b/src/com/android/launcher3/provider/RestoreDbTask.java
index 9f2b10f..d702e51 100644
--- a/src/com/android/launcher3/provider/RestoreDbTask.java
+++ b/src/com/android/launcher3/provider/RestoreDbTask.java
@@ -70,7 +70,7 @@
 import com.android.launcher3.model.data.WorkspaceItemInfo;
 import com.android.launcher3.pm.UserCache;
 import com.android.launcher3.provider.LauncherDbUtils.SQLiteTransaction;
-import com.android.launcher3.uioverrides.ApiWrapper;
+import com.android.launcher3.util.ApiWrapper;
 import com.android.launcher3.util.ContentWriter;
 import com.android.launcher3.util.IntArray;
 import com.android.launcher3.util.LogConfig;
@@ -126,6 +126,9 @@
         if (Flags.enableNarrowGridRestore()) {
             String oldPhoneFileName = idp.dbFile;
             removeOldDBs(context, oldPhoneFileName);
+            // The idp before this contains data about the old phone, after this it becomes the idp
+            // of the current phone.
+            idp.reset(context);
             trySettingPreviousGidAsCurrent(context, idp, oldPhoneFileName);
         } else {
             idp.reinitializeAfterRestore(context);
@@ -557,9 +560,8 @@
 
     protected static void maybeOverrideShortcuts(Context context, ModelDbController controller,
             SQLiteDatabase db, long currentUser) {
-        Map<String, LauncherActivityInfo> activityOverrides = ApiWrapper.getActivityOverrides(
-                context);
-
+        Map<String, LauncherActivityInfo> activityOverrides =
+                ApiWrapper.INSTANCE.get(context).getActivityOverrides();
         if (activityOverrides == null || activityOverrides.isEmpty()) {
             return;
         }
diff --git a/src/com/android/launcher3/secondarydisplay/SecondaryDisplayLauncher.java b/src/com/android/launcher3/secondarydisplay/SecondaryDisplayLauncher.java
index 910b029..0299a23 100644
--- a/src/com/android/launcher3/secondarydisplay/SecondaryDisplayLauncher.java
+++ b/src/com/android/launcher3/secondarydisplay/SecondaryDisplayLauncher.java
@@ -200,11 +200,6 @@
     }
 
     @Override
-    public <T extends View> T getOverviewPanel() {
-        return null;
-    }
-
-    @Override
     public View getRootView() {
         return mDragLayer;
     }
diff --git a/src/com/android/launcher3/states/RotationHelper.java b/src/com/android/launcher3/states/RotationHelper.java
index 6950fb5..fdb37f0 100644
--- a/src/com/android/launcher3/states/RotationHelper.java
+++ b/src/com/android/launcher3/states/RotationHelper.java
@@ -35,6 +35,7 @@
 import androidx.annotation.WorkerThread;
 
 import com.android.launcher3.BaseActivity;
+import com.android.launcher3.DeviceProfile;
 import com.android.launcher3.LauncherPrefs;
 import com.android.launcher3.util.DisplayController;
 
@@ -42,6 +43,7 @@
  * Utility class to manage launcher rotation
  */
 public class RotationHelper implements OnSharedPreferenceChangeListener,
+        DeviceProfile.OnDeviceProfileChangeListener,
         DisplayController.DisplayInfoChangeListener {
 
     public static final String ALLOW_ROTATION_PREFERENCE_KEY = "pref_allowRotation";
@@ -119,10 +121,24 @@
         }
     }
 
+    /**
+     * Listening to both onDisplayInfoChanged and onDeviceProfileChanged to reduce delay. While
+     * onDeviceProfileChanged is triggered earlier, it only receives callback when Launcher is in
+     * the foreground. When in the background, we can still rely on onDisplayInfoChanged to update,
+     * assuming that the delay is tolerable since it takes time to change to foreground.
+     */
     @Override
     public void onDisplayInfoChanged(Context context, DisplayController.Info info, int flags) {
+        onIgnoreAutoRotateChanged(info.isTablet(info.realBounds));
+    }
+
+    @Override
+    public void onDeviceProfileChanged(DeviceProfile dp) {
+        onIgnoreAutoRotateChanged(dp.isTablet);
+    }
+
+    private void onIgnoreAutoRotateChanged(boolean ignoreAutoRotateSettings) {
         if (mDestroyed) return;
-        boolean ignoreAutoRotateSettings = info.isTablet(info.realBounds);
         if (mIgnoreAutoRotateSettings != ignoreAutoRotateSettings) {
             setIgnoreAutoRotateSettings(ignoreAutoRotateSettings);
             notifyChange();
@@ -161,12 +177,14 @@
         DisplayController.Info info = displayController.getInfo();
         setIgnoreAutoRotateSettings(info.isTablet(info.realBounds));
         displayController.addChangeListener(this);
+        mActivity.addOnDeviceProfileChangeListener(this);
         notifyChange();
     }
 
     public void destroy() {
         if (mDestroyed) return;
         mDestroyed = true;
+        mActivity.removeOnDeviceProfileChangeListener(this);
         DisplayController.INSTANCE.get(mActivity).removeChangeListener(this);
         LauncherPrefs.get(mActivity).removeListener(this, ALLOW_ROTATION);
     }
diff --git a/src/com/android/launcher3/touch/ItemClickHandler.java b/src/com/android/launcher3/touch/ItemClickHandler.java
index 0c25e96..2a9ebbd 100644
--- a/src/com/android/launcher3/touch/ItemClickHandler.java
+++ b/src/com/android/launcher3/touch/ItemClickHandler.java
@@ -41,6 +41,7 @@
 
 import com.android.launcher3.BubbleTextView;
 import com.android.launcher3.BuildConfig;
+import com.android.launcher3.Flags;
 import com.android.launcher3.InvariantDeviceProfile;
 import com.android.launcher3.Launcher;
 import com.android.launcher3.LauncherSettings;
@@ -63,7 +64,7 @@
 import com.android.launcher3.shortcuts.ShortcutKey;
 import com.android.launcher3.testing.TestLogging;
 import com.android.launcher3.testing.shared.TestProtocol;
-import com.android.launcher3.uioverrides.ApiWrapper;
+import com.android.launcher3.util.ApiWrapper;
 import com.android.launcher3.util.ItemInfoMatcher;
 import com.android.launcher3.views.FloatingIconView;
 import com.android.launcher3.views.Snackbar;
@@ -157,20 +158,27 @@
                             ? R.string.app_pair_needs_unfold
                             : R.string.app_pair_unlaunchable_at_screen_size,
                     Toast.LENGTH_SHORT).show();
+            return;
         } else if (appPairIcon.getInfo().isDisabled()) {
             WorkspaceItemInfo app1 = appPairIcon.getInfo().getFirstApp();
             WorkspaceItemInfo app2 = appPairIcon.getInfo().getSecondApp();
             // Show the user why the app pair is disabled.
-            if (app1.isDisabled() && !handleDisabledItemClicked(app1, launcher)) {
-                // If handleDisabledItemClicked() did not handle the error message, we initiate an
-                // app launch so Framework can tell the user why the app is suspended.
-                onClickAppShortcut(v, app1, launcher);
-            } else if (app2.isDisabled() && !handleDisabledItemClicked(app2, launcher)) {
-                onClickAppShortcut(v, app2, launcher);
+            if (app1.isDisabled() && app2.isDisabled()) {
+                // Both apps are disabled, show "app pair is not available" toast.
+                Toast.makeText(launcher, R.string.app_pair_not_available, Toast.LENGTH_SHORT)
+                        .show();
+                return;
+            } else if ((app1.isDisabled() && handleDisabledItemClicked(app1, launcher))
+                    || (app2.isDisabled() && handleDisabledItemClicked(app2, launcher))) {
+                // Only one is disabled, and handleDisabledItemClicked() will show a toast, so we
+                // are done.
+                return;
             }
-        } else {
-            launcher.launchAppPair(appPairIcon);
         }
+
+        // Either the app pair is not disabled, or it is a disabled state that can be handled by
+        // framework directly (e.g. one app is paused), so go ahead and launch.
+        launcher.launchAppPair(appPairIcon);
     }
 
     /**
@@ -227,7 +235,7 @@
                 }
             }
             // Fallback to using custom market intent.
-            Intent intent = ApiWrapper.getAppMarketActivityIntent(launcher,
+            Intent intent = ApiWrapper.INSTANCE.get(launcher).getAppMarketActivityIntent(
                     packageName, Process.myUserHandle());
             launcher.startActivitySafely(v, intent, item);
         };
@@ -339,7 +347,7 @@
 
         // Check for abandoned promise
         if ((v instanceof BubbleTextView) && shortcut.hasPromiseIconUi()
-                && (!Utilities.enableSupportForArchiving() || !shortcut.isArchived())) {
+                && (!Flags.enableSupportForArchiving() || !shortcut.isArchived())) {
             String packageName = shortcut.getIntent().getComponent() != null
                     ? shortcut.getIntent().getComponent().getPackageName()
                     : shortcut.getIntent().getPackage();
@@ -365,12 +373,12 @@
         if (item instanceof ItemInfoWithIcon itemInfoWithIcon) {
             if ((itemInfoWithIcon.runtimeStatusFlags
                     & ItemInfoWithIcon.FLAG_INSTALL_SESSION_ACTIVE) != 0) {
-                intent = ApiWrapper.getAppMarketActivityIntent(launcher,
+                intent = ApiWrapper.INSTANCE.get(launcher).getAppMarketActivityIntent(
                         itemInfoWithIcon.getTargetComponent().getPackageName(),
                         Process.myUserHandle());
             } else if (itemInfoWithIcon.itemType
                     == LauncherSettings.Favorites.ITEM_TYPE_PRIVATE_SPACE_INSTALL_APP_BUTTON) {
-                intent = ApiWrapper.getAppMarketActivityIntent(launcher,
+                intent = ApiWrapper.INSTANCE.get(launcher).getAppMarketActivityIntent(
                         BuildConfig.APPLICATION_ID,
                         launcher.getAppsView().getPrivateProfileManager().getProfileUser());
                 launcher.getStatsLogManager().logger().log(
diff --git a/src/com/android/launcher3/touch/ItemLongClickListener.java b/src/com/android/launcher3/touch/ItemLongClickListener.java
index 116f13a..89057a2 100644
--- a/src/com/android/launcher3/touch/ItemLongClickListener.java
+++ b/src/com/android/launcher3/touch/ItemLongClickListener.java
@@ -39,6 +39,7 @@
 import com.android.launcher3.folder.Folder;
 import com.android.launcher3.logging.StatsLogManager.StatsLogger;
 import com.android.launcher3.model.data.ItemInfo;
+import com.android.launcher3.model.data.PrivateSpaceInstallAppButtonInfo;
 import com.android.launcher3.testing.TestLogging;
 import com.android.launcher3.testing.shared.TestProtocol;
 import com.android.launcher3.views.BubbleTextHolder;
@@ -150,7 +151,10 @@
         if (launcher.getWorkspace().isSwitchingState()) return false;
 
         StatsLogger logger = launcher.getStatsLogManager().logger();
-        if (v.getTag() instanceof ItemInfo) {
+        if (v.getTag() instanceof ItemInfo itemInfo) {
+            if (itemInfo instanceof PrivateSpaceInstallAppButtonInfo) {
+                return false;
+            }
             logger.withItemInfo((ItemInfo) v.getTag());
         }
         logger.log(LAUNCHER_ALLAPPS_ITEM_LONG_PRESSED);
diff --git a/src_no_quickstep/com/android/launcher3/uioverrides/ApiWrapper.java b/src/com/android/launcher3/util/ApiWrapper.java
similarity index 67%
rename from src_no_quickstep/com/android/launcher3/uioverrides/ApiWrapper.java
rename to src/com/android/launcher3/util/ApiWrapper.java
index 90271c1..6429a43 100644
--- a/src_no_quickstep/com/android/launcher3/uioverrides/ApiWrapper.java
+++ b/src/com/android/launcher3/util/ApiWrapper.java
@@ -14,7 +14,9 @@
  * limitations under the License.
  */
 
-package com.android.launcher3.uioverrides;
+package com.android.launcher3.util;
+
+import static com.android.launcher3.util.MainThreadInitializedObject.forOverride;
 
 import android.app.ActivityOptions;
 import android.app.Person;
@@ -28,10 +30,12 @@
 import android.os.UserManager;
 import android.util.ArrayMap;
 
-import com.android.launcher3.Utilities;
-import com.android.launcher3.util.UserIconInfo;
+import androidx.annotation.Nullable;
 
-import java.util.ArrayList;
+import com.android.launcher3.BuildConfig;
+import com.android.launcher3.R;
+import com.android.launcher3.Utilities;
+
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
@@ -39,30 +43,40 @@
 /**
  * A wrapper for the hidden API calls
  */
-public class ApiWrapper {
+public class ApiWrapper implements ResourceBasedOverride, SafeCloseable {
 
-    public static final boolean TASKBAR_DRAWN_IN_PROCESS = false;
+    public static final MainThreadInitializedObject<ApiWrapper> INSTANCE =
+            forOverride(ApiWrapper.class, R.string.api_wrapper_class);
 
-    public static Person[] getPersons(ShortcutInfo si) {
+    protected final Context mContext;
+
+    public ApiWrapper(Context context) {
+        mContext = context;
+    }
+
+    /**
+     * Returns the list of persons associated with the provided shortcut info
+     */
+    public Person[] getPersons(ShortcutInfo si) {
         return Utilities.EMPTY_PERSON_ARRAY;
     }
 
-    public static Map<String, LauncherActivityInfo> getActivityOverrides(Context context) {
+    public Map<String, LauncherActivityInfo> getActivityOverrides() {
         return Collections.emptyMap();
     }
 
     /**
      * Creates an ActivityOptions to play fade-out animation on closing targets
      */
-    public static ActivityOptions createFadeOutAnimOptions(Context context) {
-        return ActivityOptions.makeCustomAnimation(context, 0, android.R.anim.fade_out);
+    public ActivityOptions createFadeOutAnimOptions() {
+        return ActivityOptions.makeCustomAnimation(mContext, 0, android.R.anim.fade_out);
     }
 
     /**
      * Returns a map of all users on the device to their corresponding UI properties
      */
-    public static Map<UserHandle, UserIconInfo> queryAllUsers(Context context) {
-        UserManager um = context.getSystemService(UserManager.class);
+    public Map<UserHandle, UserIconInfo> queryAllUsers() {
+        UserManager um = mContext.getSystemService(UserManager.class);
         Map<UserHandle, UserIconInfo> users = new ArrayMap<>();
         List<UserHandle> usersActual = um.getUserProfiles();
         if (usersActual != null) {
@@ -72,7 +86,7 @@
                 // Simple check to check if the provided user is work profile
                 // TODO: Migrate to a better platform API
                 NoopDrawable d = new NoopDrawable();
-                boolean isWork = (d != context.getPackageManager().getUserBadgedIcon(d, user));
+                boolean isWork = (d != mContext.getPackageManager().getUserBadgedIcon(d, user));
                 UserIconInfo info = new UserIconInfo(
                         user,
                         isWork ? UserIconInfo.TYPE_WORK : UserIconInfo.TYPE_MAIN,
@@ -87,16 +101,15 @@
      * Returns the list of the system packages that are installed at user creation.
      * An empty list denotes that all system packages are installed for that user at creation.
      */
-    public static List<String> getPreInstalledSystemPackages(Context context, UserHandle user) {
-        return new ArrayList<>();
+    public List<String> getPreInstalledSystemPackages(UserHandle user) {
+        return Collections.emptyList();
     }
 
     /**
      * Returns an intent which can be used to start the App Market activity (Installer
      * Activity).
      */
-    public static Intent getAppMarketActivityIntent(Context context, String packageName,
-            UserHandle user) {
+    public Intent getAppMarketActivityIntent(String packageName, UserHandle user) {
         return new Intent(Intent.ACTION_VIEW)
                 .setData(new Uri.Builder()
                         .scheme("market")
@@ -104,24 +117,27 @@
                         .appendQueryParameter("id", packageName)
                         .build())
                 .putExtra(Intent.EXTRA_REFERRER, new Uri.Builder().scheme("android-app")
-                        .authority(context.getPackageName()).build());
+                        .authority(BuildConfig.APPLICATION_ID).build());
     }
 
     /**
      * Returns an intent which can be used to open Private Space Settings.
      */
-    public static Intent getPrivateSpaceSettingsIntent(Context context) {
+    @Nullable
+    public Intent getPrivateSpaceSettingsIntent() {
         return null;
     }
 
     /**
      * Checks if an activity is flagged as non-resizeable.
      */
-    public static boolean isNonResizeableActivity(LauncherActivityInfo lai) {
+    public boolean isNonResizeableActivity(LauncherActivityInfo lai) {
         // Overridden in quickstep
         return false;
     }
 
+    @Override
+    public void close() { }
 
     private static class NoopDrawable extends ColorDrawable {
         @Override
diff --git a/src/com/android/launcher3/util/LogConfig.java b/src/com/android/launcher3/util/LogConfig.java
index e5bbcb1..d59c339 100644
--- a/src/com/android/launcher3/util/LogConfig.java
+++ b/src/com/android/launcher3/util/LogConfig.java
@@ -65,4 +65,9 @@
      * When turned on, we enable AGA related session summary logging.
      */
     public static final String AGA_SESSION_SUMMARY_LOG = "AGASessionSummaryLog";
+
+    /**
+     * When turned on, we enable long press nav handle related logging.
+     */
+    public static final String NAV_HANDLE_LONG_PRESS = "NavHandleLongPress";
 }
diff --git a/src/com/android/launcher3/util/OnboardingPrefs.kt b/src/com/android/launcher3/util/OnboardingPrefs.kt
index 4528cba..370b4c8 100644
--- a/src/com/android/launcher3/util/OnboardingPrefs.kt
+++ b/src/com/android/launcher3/util/OnboardingPrefs.kt
@@ -75,4 +75,8 @@
 
     @JvmField
     val HOTSEAT_LONGPRESS_TIP_SEEN = backedUpItem("launcher.hotseat_longpress_tip_seen", false)
+
+    @JvmField
+    val TASKBAR_CIRCLE_TO_SEARCH_EDU_SEEN =
+        backedUpItem("launcher.taskbar_circle_to_search_edu_seen", false)
 }
diff --git a/src/com/android/launcher3/util/PackageManagerHelper.java b/src/com/android/launcher3/util/PackageManagerHelper.java
index b66b96a..608bed7 100644
--- a/src/com/android/launcher3/util/PackageManagerHelper.java
+++ b/src/com/android/launcher3/util/PackageManagerHelper.java
@@ -16,6 +16,8 @@
 
 package com.android.launcher3.util;
 
+import static com.android.launcher3.model.data.ItemInfoWithIcon.FLAG_INSTALL_SESSION_ACTIVE;
+
 import android.content.ActivityNotFoundException;
 import android.content.ComponentName;
 import android.content.Context;
@@ -38,6 +40,7 @@
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 
+import com.android.launcher3.Flags;
 import com.android.launcher3.PendingAddItemInfo;
 import com.android.launcher3.R;
 import com.android.launcher3.Utilities;
@@ -46,9 +49,7 @@
 import com.android.launcher3.model.data.ItemInfoWithIcon;
 import com.android.launcher3.model.data.LauncherAppWidgetInfo;
 import com.android.launcher3.model.data.WorkspaceItemInfo;
-import com.android.launcher3.uioverrides.ApiWrapper;
 
-import java.net.URISyntaxException;
 import java.util.List;
 import java.util.Objects;
 
@@ -110,7 +111,7 @@
     @SuppressWarnings("NewApi")
     public boolean isAppArchivedForUser(@NonNull final String packageName,
             @NonNull final UserHandle user) {
-        if (!Utilities.enableSupportForArchiving()) {
+        if (!Flags.enableSupportForArchiving()) {
             return false;
         }
         final ApplicationInfo info = getApplicationInfo(
@@ -167,30 +168,12 @@
     }
 
     /**
-     * Creates a new market search intent.
-     */
-    public static Intent getMarketSearchIntent(Context context, String query) {
-        try {
-            Intent intent = Intent.parseUri(context.getString(R.string.market_search_intent), 0);
-            if (!TextUtils.isEmpty(query)) {
-                intent.setData(
-                        intent.getData().buildUpon().appendQueryParameter("q", query).build());
-            }
-            return intent;
-        } catch (URISyntaxException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    /**
      * Starts the details activity for {@code info}
      */
     public void startDetailsActivityForInfo(ItemInfo info, Rect sourceBounds, Bundle opts) {
-        if (info instanceof ItemInfoWithIcon
-                && (((ItemInfoWithIcon) info).runtimeStatusFlags
-                & ItemInfoWithIcon.FLAG_INSTALL_SESSION_ACTIVE) != 0) {
-            ItemInfoWithIcon appInfo = (ItemInfoWithIcon) info;
-            mContext.startActivity(ApiWrapper.getAppMarketActivityIntent(mContext,
+        if (info instanceof ItemInfoWithIcon appInfo
+                && (appInfo.runtimeStatusFlags & FLAG_INSTALL_SESSION_ACTIVE) != 0) {
+            mContext.startActivity(ApiWrapper.INSTANCE.get(mContext).getAppMarketActivityIntent(
                     appInfo.getTargetComponent().getPackageName(), Process.myUserHandle()));
             return;
         }
@@ -291,6 +274,6 @@
     @SuppressWarnings("NewApi")
     private boolean isPackageInstalledOrArchived(ApplicationInfo info) {
         return (info.flags & ApplicationInfo.FLAG_INSTALLED) != 0 || (
-                Utilities.enableSupportForArchiving() && info.isArchived);
+                Flags.enableSupportForArchiving() && info.isArchived);
     }
 }
diff --git a/src/com/android/launcher3/util/ResourceBasedOverride.java b/src/com/android/launcher3/util/ResourceBasedOverride.java
index e2c4992..36b9cf7 100644
--- a/src/com/android/launcher3/util/ResourceBasedOverride.java
+++ b/src/com/android/launcher3/util/ResourceBasedOverride.java
@@ -34,16 +34,20 @@
         public static <T extends ResourceBasedOverride> T getObject(
                 Class<T> clazz, Context context, int resId) {
             String className = context.getString(resId);
-            if (!TextUtils.isEmpty(className)) {
-                try {
-                    Class<?> cls = Class.forName(className);
-                    return (T) cls.getDeclaredConstructor(Context.class).newInstance(context);
-                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException
-                        | ClassCastException | NoSuchMethodException | InvocationTargetException e) {
+            boolean isOverridden = !TextUtils.isEmpty(className);
+
+            // First try to load the class with "Context" param
+            try {
+                Class<?> cls = isOverridden ? Class.forName(className) : clazz;
+                return (T) cls.getDeclaredConstructor(Context.class).newInstance(context);
+            } catch (ClassNotFoundException | InstantiationException | IllegalAccessException
+                     | ClassCastException | NoSuchMethodException | InvocationTargetException e) {
+                if (isOverridden) {
                     Log.e(TAG, "Bad overriden class", e);
                 }
             }
 
+            // Load the base class with no parameter
             try {
                 return clazz.newInstance();
             } catch (InstantiationException|IllegalAccessException e) {
diff --git a/src/com/android/launcher3/util/VibratorWrapper.java b/src/com/android/launcher3/util/VibratorWrapper.java
index e1695e9..cd60c1d 100644
--- a/src/com/android/launcher3/util/VibratorWrapper.java
+++ b/src/com/android/launcher3/util/VibratorWrapper.java
@@ -19,11 +19,6 @@
 import static android.os.VibrationEffect.createPredefined;
 import static android.provider.Settings.System.HAPTIC_FEEDBACK_ENABLED;
 
-import static com.android.launcher3.config.FeatureFlags.LPNH_HAPTIC_HINT_DELAY;
-import static com.android.launcher3.config.FeatureFlags.LPNH_HAPTIC_HINT_END_SCALE_PERCENT;
-import static com.android.launcher3.config.FeatureFlags.LPNH_HAPTIC_HINT_ITERATIONS;
-import static com.android.launcher3.config.FeatureFlags.LPNH_HAPTIC_HINT_SCALE_EXPONENT;
-import static com.android.launcher3.config.FeatureFlags.LPNH_HAPTIC_HINT_START_SCALE_PERCENT;
 import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
 import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
 
@@ -40,7 +35,6 @@
 import androidx.annotation.Nullable;
 
 import com.android.launcher3.Utilities;
-import com.android.launcher3.config.FeatureFlags;
 
 /**
  * Wrapper around {@link Vibrator} to easily perform haptic feedback where necessary.
@@ -71,9 +65,6 @@
     @Nullable
     private final VibrationEffect mBumpEffect;
 
-    @Nullable
-    private final VibrationEffect mSearchEffect;
-
     private long mLastDragTime;
     private final int mThresholdUntilNextDragCallMillis;
 
@@ -133,25 +124,6 @@
             mBumpEffect = null;
             mThresholdUntilNextDragCallMillis = 0;
         }
-
-        if (mVibrator.areAllPrimitivesSupported(
-                VibrationEffect.Composition.PRIMITIVE_QUICK_RISE,
-                VibrationEffect.Composition.PRIMITIVE_TICK)) {
-            if (FeatureFlags.ENABLE_SEARCH_HAPTIC_HINT.get()) {
-                mSearchEffect = VibrationEffect.startComposition()
-                        .addPrimitive(VibrationEffect.Composition.PRIMITIVE_TICK, 1f)
-                        .compose();
-            } else {
-                // quiet ramp, short pause, then sharp tick
-                mSearchEffect = VibrationEffect.startComposition()
-                        .addPrimitive(VibrationEffect.Composition.PRIMITIVE_QUICK_RISE, 0.25f)
-                        .addPrimitive(VibrationEffect.Composition.PRIMITIVE_TICK, 1f, 50)
-                        .compose();
-            }
-        } else {
-            // fallback for devices without composition support
-            mSearchEffect = VibrationEffect.createPredefined(VibrationEffect.EFFECT_HEAVY_CLICK);
-        }
     }
 
     /**
@@ -233,13 +205,6 @@
         }
     }
 
-    /** Indicates that search has been invoked. */
-    public void vibrateForSearch() {
-        if (mSearchEffect != null) {
-            vibrate(mSearchEffect);
-        }
-    }
-
     /** Indicates that Taskbar has been invoked. */
     public void vibrateForTaskbarUnstash() {
         if (Utilities.ATLEAST_S && mVibrator.areAllPrimitivesSupported(PRIMITIVE_LOW_TICK)) {
@@ -251,32 +216,4 @@
             vibrate(primitiveLowTickEffect);
         }
     }
-
-    /** Indicates that search will be invoked if the current gesture is maintained. */
-    public void vibrateForSearchHint() {
-        if (FeatureFlags.ENABLE_SEARCH_HAPTIC_HINT.get() && Utilities.ATLEAST_S
-                && mVibrator.areAllPrimitivesSupported(PRIMITIVE_LOW_TICK)) {
-            float startScale = LPNH_HAPTIC_HINT_START_SCALE_PERCENT.get() / 100f;
-            float endScale = LPNH_HAPTIC_HINT_END_SCALE_PERCENT.get() / 100f;
-            int scaleExponent = LPNH_HAPTIC_HINT_SCALE_EXPONENT.get();
-            int iterations = LPNH_HAPTIC_HINT_ITERATIONS.get();
-            int delayMs = LPNH_HAPTIC_HINT_DELAY.get();
-
-            VibrationEffect.Composition composition = VibrationEffect.startComposition();
-            for (int i = 0; i < iterations; i++) {
-                float t = i / (iterations - 1f);
-                float scale = (float) Math.pow((1 - t) * startScale + t * endScale,
-                        scaleExponent);
-                if (i == 0) {
-                    // Adds a delay before the ramp starts
-                    composition.addPrimitive(PRIMITIVE_LOW_TICK, scale,
-                            delayMs);
-                } else {
-                    composition.addPrimitive(PRIMITIVE_LOW_TICK, scale);
-                }
-            }
-
-            vibrate(composition.compose());
-        }
-    }
 }
diff --git a/src/com/android/launcher3/util/window/WindowManagerProxy.java b/src/com/android/launcher3/util/window/WindowManagerProxy.java
index 4a906d3..998191e 100644
--- a/src/com/android/launcher3/util/window/WindowManagerProxy.java
+++ b/src/com/android/launcher3/util/window/WindowManagerProxy.java
@@ -94,6 +94,13 @@
     }
 
     /**
+     * Returns true if taskbar is drawn in process
+     */
+    public boolean isTaskbarDrawnInProcess() {
+        return mTaskbarDrawnInProcess;
+    }
+
+    /**
      * Returns a map of normalized info of internal displays to estimated window bounds
      * for that display
      */
diff --git a/src/com/android/launcher3/views/AbstractSlideInView.java b/src/com/android/launcher3/views/AbstractSlideInView.java
index 4c9371d..9f6e8f8 100644
--- a/src/com/android/launcher3/views/AbstractSlideInView.java
+++ b/src/com/android/launcher3/views/AbstractSlideInView.java
@@ -82,7 +82,6 @@
             };
     protected static final float TRANSLATION_SHIFT_CLOSED = 1f;
     protected static final float TRANSLATION_SHIFT_OPENED = 0f;
-    private static final float VIEW_NO_SCALE = 1f;
     private static final int DEFAULT_DURATION = 300;
 
     protected final T mActivityContext;
@@ -129,9 +128,13 @@
     protected @Nullable OnCloseListener mOnCloseBeginListener;
     protected List<OnCloseListener> mOnCloseListeners = new ArrayList<>();
 
-    protected final AnimatedFloat mSlideInViewScale =
-            new AnimatedFloat(this::onScaleProgressChanged, VIEW_NO_SCALE);
-    protected boolean mIsBackProgressing;
+    /**
+     * How far through a "user initiated dismissal" the UI is. e.g. Predictive back, swipe to home,
+     * 0 is regular state, 1 is fully dismissed.
+     */
+    protected final AnimatedFloat mSwipeToDismissProgress =
+            new AnimatedFloat(this::onUserSwipeToDismissProgressChanged, 0f);
+    protected boolean mIsDismissInProgress;
     private @Nullable Drawable mContentBackground;
     private @Nullable View mContentBackgroundParentView;
 
@@ -285,31 +288,31 @@
     @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
     public void onBackProgressed(BackEvent backEvent) {
         final float progress = backEvent.getProgress();
-        float deceleratedProgress =
-                Interpolators.PREDICTIVE_BACK_DECELERATED_EASE.getInterpolation(progress);
-        mIsBackProgressing = progress > 0f;
-        mSlideInViewScale.updateValue(PREDICTIVE_BACK_MIN_SCALE
-                + (1 - PREDICTIVE_BACK_MIN_SCALE) * (1 - deceleratedProgress));
+        float deceleratedProgress = Interpolators.BACK_GESTURE.getInterpolation(progress);
+        mSwipeToDismissProgress.updateValue(deceleratedProgress);
     }
 
-    protected void onScaleProgressChanged() {
-        float scaleProgress = mSlideInViewScale.value;
-        SCALE_PROPERTY.set(this, scaleProgress);
-        setClipChildren(!mIsBackProgressing);
-        setClipToPadding(!mIsBackProgressing);
-        mContent.setClipChildren(!mIsBackProgressing);
-        mContent.setClipToPadding(!mIsBackProgressing);
+    protected void onUserSwipeToDismissProgressChanged() {
+        float progress = mSwipeToDismissProgress.value;
+        mIsDismissInProgress = progress > 0f;
+
+        float scale = PREDICTIVE_BACK_MIN_SCALE + (1 - PREDICTIVE_BACK_MIN_SCALE) * (1f - progress);
+        SCALE_PROPERTY.set(this, scale);
+        setClipChildren(!mIsDismissInProgress);
+        setClipToPadding(!mIsDismissInProgress);
+        mContent.setClipChildren(!mIsDismissInProgress);
+        mContent.setClipToPadding(!mIsDismissInProgress);
         invalidate();
     }
 
     @Override
     public void onBackCancelled() {
         super.onBackCancelled();
-        animateSlideInViewToNoScale();
+        animateSwipeToDismissProgressToStart();
     }
 
-    protected void animateSlideInViewToNoScale() {
-        mSlideInViewScale.animateToValue(1f)
+    protected void animateSwipeToDismissProgressToStart() {
+        mSwipeToDismissProgress.animateToValue(0f)
                 .setDuration(REVERT_SWIPE_ALL_APPS_TO_HOME_ANIMATION_DURATION_MS)
                 .start();
     }
@@ -340,7 +343,7 @@
                 mContentBackgroundParentView.getTop() + (int) mContent.getTranslationY(),
                 mContentBackgroundParentView.getRight(),
                 mContentBackgroundParentView.getBottom()
-                        + (mIsBackProgressing ? getBottomOffsetPx() : 0));
+                        + (mIsDismissInProgress ? getBottomOffsetPx() : 0));
         mContentBackground.draw(canvas);
     }
 
diff --git a/src/com/android/launcher3/views/WidgetsEduView.java b/src/com/android/launcher3/views/WidgetsEduView.java
index 45ff9de..53fbd8f 100644
--- a/src/com/android/launcher3/views/WidgetsEduView.java
+++ b/src/com/android/launcher3/views/WidgetsEduView.java
@@ -70,9 +70,9 @@
     }
 
     @Override
-    protected void onScaleProgressChanged() {
-        super.onScaleProgressChanged();
-        setTranslationY(getMeasuredHeight() * (1 - mSlideInViewScale.value) / 2);
+    protected void onUserSwipeToDismissProgressChanged() {
+        super.onUserSwipeToDismissProgressChanged();
+        setTranslationY(getMeasuredHeight() * (mSwipeToDismissProgress.value / 2));
     }
 
     private void show() {
diff --git a/src/com/android/launcher3/widget/BaseWidgetSheet.java b/src/com/android/launcher3/widget/BaseWidgetSheet.java
index 76ffbbd..c17ae09 100644
--- a/src/com/android/launcher3/widget/BaseWidgetSheet.java
+++ b/src/com/android/launcher3/widget/BaseWidgetSheet.java
@@ -20,6 +20,7 @@
 import static com.android.launcher3.Flags.enableUnfoldedTwoPanePicker;
 import static com.android.launcher3.Flags.enableWidgetTapToAdd;
 import static com.android.launcher3.LauncherPrefs.WIDGETS_EDUCATION_TIP_SEEN;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_WIDGET_ADD_BUTTON_TAP;
 
 import android.content.Context;
 import android.graphics.Canvas;
@@ -32,6 +33,7 @@
 import android.view.WindowInsets;
 import android.view.animation.Interpolator;
 
+import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.annotation.Px;
 import androidx.core.view.ViewCompat;
@@ -45,7 +47,6 @@
 import com.android.launcher3.PendingAddItemInfo;
 import com.android.launcher3.R;
 import com.android.launcher3.Utilities;
-import com.android.launcher3.logging.StatsLogManager;
 import com.android.launcher3.popup.PopupDataProvider;
 import com.android.launcher3.testing.TestLogging;
 import com.android.launcher3.testing.shared.TestProtocol;
@@ -55,6 +56,8 @@
 import com.android.launcher3.views.AbstractSlideInView;
 import com.android.launcher3.views.ArrowTipView;
 
+import java.util.concurrent.atomic.AtomicBoolean;
+
 /**
  * Base class for various widgets popup
  */
@@ -163,12 +166,25 @@
     /**
      * Click handler for tap to add button.
      */
-    public void addWidget(PendingAddItemInfo info) {
+    private void addWidget(@NonNull PendingAddItemInfo info) {
+        // Using a boolean flag here to make sure the callback is only run once. This should never
+        // happen because we close the sheet and it will be reconstructed the next time it is
+        // needed.
+        final AtomicBoolean hasRun = new AtomicBoolean(false);
+        addOnCloseListener(() -> {
+            if (!hasRun.get()) {
+                Launcher.getLauncher(mActivityContext).getAccessibilityDelegate().addToWorkspace(
+                        info, /*accessibility=*/ false,
+                        /*finishCallback=*/ (success) -> {
+                            mActivityContext.getStatsLogManager()
+                                    .logger()
+                                    .withItemInfo(info)
+                                    .log(LAUNCHER_WIDGET_ADD_BUTTON_TAP);
+                        });
+                hasRun.set(true);
+            }
+        });
         handleClose(true);
-        Launcher.getLauncher(mActivityContext).getAccessibilityDelegate()
-                .addToWorkspace(info, /*accessibility=*/ false, /*finishCallback=*/ null);
-        mActivityContext.getStatsLogManager().logger().withItemInfo(info).log(
-                StatsLogManager.LauncherEvent.LAUNCHER_WIDGET_ADD_BUTTON_TAP);
     }
 
     @Override
diff --git a/src/com/android/launcher3/widget/WidgetCell.java b/src/com/android/launcher3/widget/WidgetCell.java
index 3dff555..ab007fb 100644
--- a/src/com/android/launcher3/widget/WidgetCell.java
+++ b/src/com/android/launcher3/widget/WidgetCell.java
@@ -26,7 +26,6 @@
 import android.content.Context;
 import android.graphics.Bitmap;
 import android.graphics.drawable.Drawable;
-import android.os.Process;
 import android.text.TextUtils;
 import android.util.AttributeSet;
 import android.util.Log;
@@ -39,7 +38,6 @@
 import android.view.accessibility.AccessibilityNodeInfo;
 import android.widget.Button;
 import android.widget.FrameLayout;
-import android.widget.ImageView;
 import android.widget.LinearLayout;
 import android.widget.RemoteViews;
 import android.widget.TextView;
@@ -88,7 +86,6 @@
     private Size mPreviewContainerSize = new Size(0, 0);
     private FrameLayout mWidgetImageContainer;
     private WidgetImageView mWidgetImage;
-    private ImageView mWidgetBadge;
     private TextView mWidgetName;
     private TextView mWidgetDims;
     private TextView mWidgetDescription;
@@ -142,7 +139,6 @@
 
         mWidgetImageContainer = findViewById(R.id.widget_preview_container);
         mWidgetImage = findViewById(R.id.widget_preview);
-        mWidgetBadge = findViewById(R.id.widget_badge);
         mWidgetName = findViewById(R.id.widget_name);
         mWidgetDims = findViewById(R.id.widget_dims);
         mWidgetDescription = findViewById(R.id.widget_description);
@@ -182,8 +178,6 @@
         mWidgetImage.animate().cancel();
         mWidgetImage.setDrawable(null);
         mWidgetImage.setVisibility(View.VISIBLE);
-        mWidgetBadge.setImageDrawable(null);
-        mWidgetBadge.setVisibility(View.GONE);
         mWidgetName.setText(null);
         mWidgetDims.setText(null);
         mWidgetDescription.setText(null);
@@ -397,17 +391,6 @@
         }
     }
 
-    /** Used to show the badge when the widget is in the recommended section
-     */
-    public void showBadge() {
-        if (Process.myUserHandle().equals(mItem.user)) {
-            mWidgetBadge.setVisibility(View.GONE);
-        } else {
-            mWidgetBadge.setVisibility(View.VISIBLE);
-            mWidgetBadge.setImageResource(R.drawable.ic_work_app_badge);
-        }
-    }
-
     /**
      * Shows or hides the long description displayed below each widget.
      *
diff --git a/src/com/android/launcher3/widget/WidgetImageView.java b/src/com/android/launcher3/widget/WidgetImageView.java
index f0a23be..f332054 100644
--- a/src/com/android/launcher3/widget/WidgetImageView.java
+++ b/src/com/android/launcher3/widget/WidgetImageView.java
@@ -24,8 +24,6 @@
 import android.util.AttributeSet;
 import android.view.View;
 
-import com.android.launcher3.R;
-
 /**
  * View that draws a bitmap horizontally centered. If the image width is greater than the view
  * width, the image is scaled down appropriately.
@@ -33,8 +31,6 @@
 public class WidgetImageView extends View {
 
     private final RectF mDstRectF = new RectF();
-    private final int mBadgeMargin;
-
     private Drawable mDrawable;
 
     public WidgetImageView(Context context) {
@@ -47,9 +43,6 @@
 
     public WidgetImageView(Context context, AttributeSet attrs, int defStyle) {
         super(context, attrs, defStyle);
-
-        mBadgeMargin = context.getResources()
-                .getDimensionPixelSize(R.dimen.profile_badge_margin);
     }
 
     /** Set the drawable to use for this view. */
diff --git a/src/com/android/launcher3/widget/WidgetsBottomSheet.java b/src/com/android/launcher3/widget/WidgetsBottomSheet.java
index e6b9c9b..f1b80e4 100644
--- a/src/com/android/launcher3/widget/WidgetsBottomSheet.java
+++ b/src/com/android/launcher3/widget/WidgetsBottomSheet.java
@@ -280,6 +280,6 @@
     @Override
     public void addHintCloseAnim(
             float distanceToMove, Interpolator interpolator, PendingAnimation target) {
-        target.setInt(this, PADDING_BOTTOM, (int) (distanceToMove + mInsets.bottom), interpolator);
+        target.addAnimatedFloat(mSwipeToDismissProgress, 0f, 1f, interpolator);
     }
 }
diff --git a/src/com/android/launcher3/widget/picker/WidgetRecommendationsView.java b/src/com/android/launcher3/widget/picker/WidgetRecommendationsView.java
index 255a6d2..4f73e66 100644
--- a/src/com/android/launcher3/widget/picker/WidgetRecommendationsView.java
+++ b/src/com/android/launcher3/widget/picker/WidgetRecommendationsView.java
@@ -18,7 +18,9 @@
 
 import static com.android.launcher3.widget.util.WidgetsTableUtils.groupWidgetItemsUsingRowPxWithoutReordering;
 
+import android.content.ComponentName;
 import android.content.Context;
+import android.os.Bundle;
 import android.util.AttributeSet;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -31,14 +33,19 @@
 import com.android.launcher3.DeviceProfile;
 import com.android.launcher3.PagedView;
 import com.android.launcher3.R;
+import com.android.launcher3.Utilities;
 import com.android.launcher3.model.WidgetItem;
 import com.android.launcher3.pageindicators.PageIndicatorDots;
 
 import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 import java.util.TreeMap;
 import java.util.function.Consumer;
+import java.util.stream.Collectors;
 
 /**
  * A {@link PagedView} that displays widget recommendations in categories with dots as paged
@@ -46,6 +53,8 @@
  */
 public final class WidgetRecommendationsView extends PagedView<PageIndicatorDots> {
     private @Px float mAvailableHeight = Float.MAX_VALUE;
+    private static final String INITIALLY_DISPLAYED_WIDGETS_STATE_KEY =
+            "widgetRecommendationsView:mDisplayedWidgets";
     private static final int MAX_CATEGORIES = 3;
     private TextView mRecommendationPageTitle;
     private final List<String> mCategoryTitles = new ArrayList<>();
@@ -57,6 +66,7 @@
     private OnLongClickListener mWidgetCellOnLongClickListener;
     @Nullable
     private OnClickListener mWidgetCellOnClickListener;
+    private Set<ComponentName> mDisplayedWidgets = Collections.emptySet();
 
     public WidgetRecommendationsView(Context context) {
         this(context, /* attrs= */ null);
@@ -76,6 +86,38 @@
         mRecommendationPageTitle = parent.findViewById(R.id.recommendations_page_title);
     }
 
+    /**
+     * Saves the necessary state in the provided bundle. To be called in case of orientation /
+     * other config changes.
+     */
+    public void saveState(Bundle bundle) {
+        // Save the widgets that were displayed, so that, on rotation / fold / unfold, we can
+        // maintain the "initial" set of widgets that user first saw (if they fit).
+        bundle.putParcelableArrayList(INITIALLY_DISPLAYED_WIDGETS_STATE_KEY,
+                new ArrayList<>(mDisplayedWidgets));
+    }
+
+    /**
+     * Restores the state that was saved by the saveState method during orientation / other config
+     * changes.
+     */
+    public void restoreState(Bundle bundle) {
+        ArrayList<ComponentName> componentList;
+        if (Utilities.ATLEAST_T) {
+            componentList = bundle.getParcelableArrayList(
+                    INITIALLY_DISPLAYED_WIDGETS_STATE_KEY, ComponentName.class);
+        } else {
+            componentList = bundle.getParcelableArrayList(
+                    INITIALLY_DISPLAYED_WIDGETS_STATE_KEY);
+        }
+
+        // Restore the "initial" set of widgets that were displayed, so that, on rotation / fold /
+        // unfold, we can maintain the set of widgets that user first saw (if they fit).
+        if (componentList != null) {
+            mDisplayedWidgets = new HashSet<>(componentList);
+        }
+    }
+
     /** Sets a {@link android.view.View.OnLongClickListener} for all widget cells in this table. */
     public void setWidgetCellLongClickListener(OnLongClickListener onLongClickListener) {
         mWidgetCellOnLongClickListener = onLongClickListener;
@@ -112,10 +154,18 @@
         this.mAvailableHeight = availableHeight;
         clear();
 
-        int displayedWidgets = maybeDisplayInTable(recommendedWidgets, deviceProfile,
+        Set<ComponentName> displayedWidgets = maybeDisplayInTable(recommendedWidgets,
+                deviceProfile,
                 availableWidth, cellPadding);
+
+        if (mDisplayedWidgets.isEmpty()) {
+            // Save the widgets shown for the first time user opened the picker; so that, they can
+            // be maintained across orientation changes.
+            mDisplayedWidgets = displayedWidgets;
+        }
+
         updateTitleAndIndicator(/* requestedPage= */ 0);
-        return displayedWidgets;
+        return displayedWidgets.size();
     }
 
     /**
@@ -144,20 +194,21 @@
         clear();
 
         int displayedCategories = 0;
-        int totalDisplayedWidgets = 0;
+        Set<ComponentName> allDisplayedWidgets = new HashSet<>();
 
         // Render top MAX_CATEGORIES in separate tables. Each table becomes a page.
         for (Map.Entry<WidgetRecommendationCategory, List<WidgetItem>> entry :
                 new TreeMap<>(recommendations).entrySet()) {
             // If none of the recommendations for the category could fit in the mAvailableHeight, we
             // don't want to add that category; and we look for the next one.
-            int displayedCount = maybeDisplayInTable(entry.getValue(), deviceProfile,
+            Set<ComponentName> displayedWidgetsForCategory = maybeDisplayInTable(entry.getValue(),
+                    deviceProfile,
                     availableWidth, cellPadding);
-            if (displayedCount > 0) {
+            if (!displayedWidgetsForCategory.isEmpty()) {
                 mCategoryTitles.add(
                         context.getResources().getString(entry.getKey().categoryTitleRes));
                 displayedCategories++;
-                totalDisplayedWidgets += displayedCount;
+                allDisplayedWidgets.addAll(displayedWidgetsForCategory);
             }
 
             if (displayedCategories == MAX_CATEGORIES) {
@@ -165,11 +216,17 @@
             }
         }
 
+        if (mDisplayedWidgets.isEmpty()) {
+            // Save the widgets shown for the first time user opened the picker; so that, they can
+            // be maintained across orientation changes.
+            mDisplayedWidgets = allDisplayedWidgets;
+        }
+
         updateTitleAndIndicator(requestedPage);
         // For purpose of recommendations section, we don't want paging dots to be halved in two
         // pane display, so, we always provide isTwoPanels = "false".
         mPageIndicator.setPauseScroll(/*pause=*/false, /*isTwoPanels=*/false);
-        return totalDisplayedWidgets;
+        return allDisplayedWidgets.size();
     }
 
     private void clear() {
@@ -241,20 +298,25 @@
     }
 
     /**
-     * Groups the provided recommendations into rows and displays them in a table if at least one
-     * fits.
-     * <p>Returns false if none of the recommendations could fit.</p>
+     * Groups the provided recommendations into rows and displays ones that fit in a table.
+     * <p>Returns the set of widgets that could fit.</p>
      */
-    private int maybeDisplayInTable(List<WidgetItem> recommendedWidgets,
+    private Set<ComponentName> maybeDisplayInTable(List<WidgetItem> recommendedWidgets,
             DeviceProfile deviceProfile,
             final @Px int availableWidth, final @Px int cellPadding) {
+        List<WidgetItem> filteredRecommendedWidgets = recommendedWidgets;
+        // Show only those widgets that were displayed when user first opened the picker.
+        if (!mDisplayedWidgets.isEmpty()) {
+            filteredRecommendedWidgets = recommendedWidgets.stream().filter(
+                    w -> mDisplayedWidgets.contains(w.componentName)).toList();
+        }
         Context context = getContext();
         LayoutInflater inflater = LayoutInflater.from(context);
 
         // Since we are limited by space, we don't sort recommendations - to show most relevant
         // (if possible).
         List<ArrayList<WidgetItem>> rows = groupWidgetItemsUsingRowPxWithoutReordering(
-                recommendedWidgets,
+                filteredRecommendedWidgets,
                 context,
                 deviceProfile,
                 availableWidth,
@@ -268,13 +330,17 @@
         recommendationsTable.setWidgetCellOnClickListener(mWidgetCellOnClickListener);
         recommendationsTable.setWidgetCellLongClickListener(mWidgetCellOnLongClickListener);
 
-        int displayedCount = recommendationsTable.setRecommendedWidgets(rows,
+        List<ArrayList<WidgetItem>> displayedItems = recommendationsTable.setRecommendedWidgets(
+                rows,
                 deviceProfile, mAvailableHeight);
-        if (displayedCount > 0) {
+
+        if (!displayedItems.isEmpty()) {
             addView(recommendationsTable);
         }
 
-        return displayedCount;
+        return displayedItems.stream().flatMap(
+                        items -> items.stream().map(w -> w.componentName))
+                .collect(Collectors.toSet());
     }
 
     /** Returns location of a widget cell for displaying the "touch and hold" education tip. */
diff --git a/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java b/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java
index fcd2571..c3067a5 100644
--- a/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java
+++ b/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java
@@ -17,7 +17,6 @@
 
 import static com.android.launcher3.Flags.enableCategorizedWidgetSuggestions;
 import static com.android.launcher3.Flags.enableUnfoldedTwoPanePicker;
-import static com.android.launcher3.LauncherAnimUtils.VIEW_TRANSLATE_Y;
 import static com.android.launcher3.LauncherPrefs.WIDGETS_EDUCATION_DIALOG_SEEN;
 import static com.android.launcher3.allapps.ActivityAllAppsContainerView.AdapterHolder.SEARCH;
 import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_WIDGETSTRAY_SEARCHED;
@@ -548,6 +547,14 @@
     public void exitSearchMode() {
         if (!mIsInSearchMode) return;
         onSearchResults(new ArrayList<>());
+        WidgetsRecyclerView searchRecyclerView = mAdapters.get(
+                AdapterHolder.SEARCH).mWidgetsRecyclerView;
+        // Remove all views when exiting the search mode; this prevents animating from stale results
+        // to new ones the next time we enter search mode. By the time recycler view is hidden,
+        // layout may not have happened to clear up existing results. So, instead of waiting for it
+        // to happen, we clear the views here.
+        searchRecyclerView.swapAdapter(
+                searchRecyclerView.getAdapter(), /*removeAndRecycleExistingViews=*/ true);
         setViewVisibilityBasedOnSearch(/*isInSearchMode=*/ false);
         if (mHasWorkProfile) {
             mViewPager.snapToPage(AdapterHolder.PRIMARY);
@@ -626,15 +633,15 @@
     }
 
     @Px
-    private float getMaxAvailableHeightForRecommendations() {
+    protected float getMaxAvailableHeightForRecommendations() {
         // There isn't enough space to show recommendations in landscape orientation on phones with
         // a full sheet design. Tablets use a two pane picker.
-        if (!isTwoPane() && mDeviceProfile.isLandscape) {
+        if (mDeviceProfile.isLandscape) {
             return 0f;
         }
 
         return (mDeviceProfile.heightPx - mDeviceProfile.bottomSheetTopPadding)
-                * getRecommendationSectionHeightRatio();
+                * RECOMMENDATION_TABLE_HEIGHT_RATIO;
     }
 
     /** b/209579563: "Widgets" header should be focused first. */
@@ -643,14 +650,6 @@
         return mHeaderTitle;
     }
 
-    /**
-     * Ratio of recommendations section with respect to bottom sheet's height on scale of 0 to 1.
-     */
-    @Px
-    protected float getRecommendationSectionHeightRatio() {
-        return RECOMMENDATION_TABLE_HEIGHT_RATIO;
-    }
-
     private void open(boolean animate) {
         if (animate) {
             if (getPopupContainer().getInsets().bottom > 0) {
@@ -726,6 +725,7 @@
         // picker and calls save/restore hierarchy state. We save the state of recommendations
         // across those updates.
         bundle.putInt(RECOMMENDATIONS_SAVED_STATE_KEY, mRecommendationsCurrentPage);
+        mWidgetRecommendationsView.saveState(bundle);
         SparseArray<Parcelable> superState = new SparseArray<>();
         super.saveHierarchyState(superState);
         bundle.putSparseParcelableArray(SUPER_SAVED_STATE_KEY, superState);
@@ -737,6 +737,7 @@
         Bundle state = (Bundle) sparseArray.get(0);
         mRecommendationsCurrentPage = state.getInt(
                 RECOMMENDATIONS_SAVED_STATE_KEY, /*defaultValue=*/0);
+        mWidgetRecommendationsView.restoreState(state);
         super.restoreHierarchyState(state.getSparseParcelableArray(SUPER_SAVED_STATE_KEY));
     }
 
@@ -806,8 +807,7 @@
     @Override
     public void addHintCloseAnim(
             float distanceToMove, Interpolator interpolator, PendingAnimation target) {
-        target.setFloat(getRecyclerView(), VIEW_TRANSLATE_Y, -distanceToMove, interpolator);
-        target.setViewAlpha(getRecyclerView(), 0.5f, interpolator);
+        target.addAnimatedFloat(mSwipeToDismissProgress, 0f, 1f, interpolator);
     }
 
     @Override
@@ -903,7 +903,7 @@
     public void onBackInvoked() {
         if (mIsInSearchMode) {
             mSearchBar.reset();
-            animateSlideInViewToNoScale();
+            animateSwipeToDismissProgressToStart();
         } else {
             super.onBackInvoked();
         }
diff --git a/src/com/android/launcher3/widget/picker/WidgetsRecommendationTableLayout.java b/src/com/android/launcher3/widget/picker/WidgetsRecommendationTableLayout.java
index 7a2b4ef..a565780 100644
--- a/src/com/android/launcher3/widget/picker/WidgetsRecommendationTableLayout.java
+++ b/src/com/android/launcher3/widget/picker/WidgetsRecommendationTableLayout.java
@@ -83,14 +83,15 @@
      * <p>If the content can't fit {@code recommendationTableMaxHeight}, this view will remove a
      * last row from the {@code recommendedWidgets} until it fits or only one row left.
      *
-     * <p>Returns {@code false} if none of the widgets could fit</p>
+     * <p>Returns the list of widgets that could fit</p>
      */
-    public int setRecommendedWidgets(List<ArrayList<WidgetItem>> recommendedWidgets,
+    public List<ArrayList<WidgetItem>> setRecommendedWidgets(
+            List<ArrayList<WidgetItem>> recommendedWidgets,
             DeviceProfile deviceProfile, float recommendationTableMaxHeight) {
         List<ArrayList<WidgetItem>> rows = selectRowsThatFitInAvailableHeight(recommendedWidgets,
                 recommendationTableMaxHeight, deviceProfile);
         bindData(rows);
-        return rows.stream().mapToInt(ArrayList::size).sum();
+        return rows;
     }
 
     private void bindData(List<ArrayList<WidgetItem>> recommendationTable) {
@@ -109,7 +110,6 @@
                 WidgetCell widgetCell = addItemCell(tableRow);
                 widgetCell.applyFromCellItem(widgetItem);
                 widgetCell.showAppIconInWidgetTitle(true);
-                widgetCell.showBadge();
                 if (enableCategorizedWidgetSuggestions()) {
                     widgetCell.showDescription(false);
                     widgetCell.showDimensions(false);
diff --git a/src/com/android/launcher3/widget/picker/WidgetsTwoPaneSheet.java b/src/com/android/launcher3/widget/picker/WidgetsTwoPaneSheet.java
index c60bca0..14985bf 100644
--- a/src/com/android/launcher3/widget/picker/WidgetsTwoPaneSheet.java
+++ b/src/com/android/launcher3/widget/picker/WidgetsTwoPaneSheet.java
@@ -74,7 +74,7 @@
     private ScrollView mRightPaneScrollView;
     private WidgetsListTableViewHolderBinder mWidgetsListTableViewHolderBinder;
 
-    private boolean mOldIsBackSwipeProgressing;
+    private boolean mOldIsSwipeToDismissInProgress;
     private int mActivePage = -1;
     private PackageUserKey mSelectedHeader;
 
@@ -154,14 +154,14 @@
     }
 
     @Override
-    protected void onScaleProgressChanged() {
-        super.onScaleProgressChanged();
-        boolean isBackSwipeProgressing = mSlideInViewScale.value > 0;
-        if (isBackSwipeProgressing == mOldIsBackSwipeProgressing) {
+    protected void onUserSwipeToDismissProgressChanged() {
+        super.onUserSwipeToDismissProgressChanged();
+        boolean isSwipeToDismissInProgress = mSwipeToDismissProgress.value > 0;
+        if (isSwipeToDismissInProgress == mOldIsSwipeToDismissInProgress) {
             return;
         }
-        mOldIsBackSwipeProgressing = isBackSwipeProgressing;
-        if (isBackSwipeProgressing) {
+        mOldIsSwipeToDismissInProgress = isSwipeToDismissInProgress;
+        if (isSwipeToDismissInProgress) {
             modifyAttributesOnViewTree(mPrimaryWidgetListView, (ViewParent) mContent,
                     CLIP_CHILDREN_FALSE_MODIFIER);
             modifyAttributesOnViewTree(mRightPaneScrollView,  (ViewParent) mContent,
@@ -276,8 +276,15 @@
 
     @Override
     @Px
-    protected float getRecommendationSectionHeightRatio() {
-        return RECOMMENDATION_SECTION_HEIGHT_RATIO_TWO_PANE;
+    protected float getMaxAvailableHeightForRecommendations() {
+        if (mRecommendedWidgetsCount > 0) {
+            // If widgets were already selected for display, we show them all on orientation change
+            // in a two pane picker
+            return Float.MAX_VALUE;
+        }
+
+        return (mDeviceProfile.heightPx - mDeviceProfile.bottomSheetTopPadding)
+                * RECOMMENDATION_SECTION_HEIGHT_RATIO_TWO_PANE;
     }
 
     @Override
diff --git a/src/com/android/quickstep/views/RecentsViewContainer.java b/src/com/android/quickstep/views/RecentsViewContainer.java
new file mode 100644
index 0000000..0c3f4f1
--- /dev/null
+++ b/src/com/android/quickstep/views/RecentsViewContainer.java
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2024 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.views;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.ContextWrapper;
+import android.content.LocusId;
+import android.os.Bundle;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.Window;
+
+import com.android.launcher3.BaseActivity;
+import com.android.launcher3.util.SystemUiController;
+import com.android.launcher3.views.ActivityContext;
+import com.android.launcher3.views.ScrimView;
+
+/**
+ * Interface to be implemented by the parent view of RecentsView
+ */
+public interface RecentsViewContainer extends ActivityContext {
+
+    /**
+     * Returns an instance of an implementation of RecentsViewContainer
+     * @param context will find instance of recentsViewContainer from given context.
+     */
+    static <T extends RecentsViewContainer> T containerFromContext(Context context) {
+        if (context instanceof RecentsViewContainer) {
+            return (T) context;
+        } else if (context instanceof ContextWrapper) {
+            return containerFromContext(((ContextWrapper) context).getBaseContext());
+        } else {
+            throw new IllegalArgumentException("Cannot find RecentsViewContainer in parent tree");
+        }
+    }
+
+    /**
+     * Returns {@link SystemUiController} to manage various window flags to control system UI.
+     */
+    SystemUiController getSystemUiController();
+
+    /**
+     * Returns {@link ScrimView}
+     */
+    ScrimView getScrimView();
+
+    /**
+     * Returns the Overview Panel as a View
+     */
+    <T extends View> T getOverviewPanel();
+
+    /**
+     * Returns the RootView
+     */
+    View getRootView();
+
+    /**
+     * Dispatches a generic motion event to the view hierarchy.
+     * Returns the current RecentsViewContainer as context
+     */
+    default Context asContext() {
+        return (Context) this;
+    }
+
+    /**
+     * @see Window.Callback#dispatchGenericMotionEvent(MotionEvent)
+     */
+    boolean dispatchGenericMotionEvent(MotionEvent ev);
+
+    /**
+     * @see Window.Callback#dispatchKeyEvent(KeyEvent)
+     */
+    boolean dispatchKeyEvent(KeyEvent ev);
+
+    /**
+     * Returns overview actions view as a view
+     */
+    View getActionsView();
+
+    /**
+     * @see BaseActivity#addForceInvisibleFlag(int)
+     * @param flag {@link BaseActivity.InvisibilityFlags}
+     */
+    void addForceInvisibleFlag(@BaseActivity.InvisibilityFlags int flag);
+
+    /**
+     * @see BaseActivity#clearForceInvisibleFlag(int)
+     * @param flag {@link BaseActivity.InvisibilityFlags}
+     */
+    void clearForceInvisibleFlag(@BaseActivity.InvisibilityFlags int flag);
+
+    /**
+     * @see android.app.Activity#setLocusContext(LocusId, Bundle)
+     * @param id {@link LocusId}
+     * @param bundle {@link Bundle}
+     */
+    void setLocusContext(LocusId id, Bundle bundle);
+
+    /**
+     * @see BaseActivity#isStarted()
+     * @return boolean
+     */
+    boolean isStarted();
+
+    /**
+     * @see BaseActivity#addEventCallback(int, Runnable)
+     * @param event {@link BaseActivity.ActivityEvent}
+     * @param callback runnable to be executed upon event
+     */
+    void addEventCallback(@BaseActivity.ActivityEvent int event, Runnable callback);
+
+    /**
+     * @see BaseActivity#removeEventCallback(int, Runnable)
+     * @param event {@link BaseActivity.ActivityEvent}
+     * @param callback runnable to be executed upon event
+     */
+    void removeEventCallback(@BaseActivity.ActivityEvent int event, Runnable callback);
+
+    /**
+     * @see com.android.quickstep.util.TISBindHelper#runOnBindToTouchInteractionService(Runnable)
+     * @param r runnable to be executed upon event
+     */
+    void runOnBindToTouchInteractionService(Runnable r);
+
+    /**
+     * @see Activity#getWindow()
+     * @return Window
+     */
+    Window getWindow();
+
+    /**
+     * @see
+     * BaseActivity#addMultiWindowModeChangedListener(BaseActivity.MultiWindowModeChangedListener)
+     * @param listener {@link BaseActivity.MultiWindowModeChangedListener}
+     */
+    void addMultiWindowModeChangedListener(
+            BaseActivity.MultiWindowModeChangedListener listener);
+
+    /**
+     * @see
+     * BaseActivity#removeMultiWindowModeChangedListener(
+     * BaseActivity.MultiWindowModeChangedListener)
+     * @param listener {@link BaseActivity.MultiWindowModeChangedListener}
+     */
+    void removeMultiWindowModeChangedListener(
+            BaseActivity.MultiWindowModeChangedListener listener);
+
+    /**
+     * Begins transition from overview back to homescreen
+     */
+    void returnToHomescreen();
+}
diff --git a/src_no_quickstep/com/android/launcher3/uioverrides/flags/FlagsFactory.java b/src_no_quickstep/com/android/launcher3/uioverrides/flags/FlagsFactory.java
deleted file mode 100644
index b193d37..0000000
--- a/src_no_quickstep/com/android/launcher3/uioverrides/flags/FlagsFactory.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2023 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.uioverrides.flags;
-
-import static com.android.launcher3.config.FeatureFlags.FlagState.ENABLED;
-
-import androidx.annotation.Nullable;
-
-import com.android.launcher3.ConstantItem;
-import com.android.launcher3.config.FeatureFlags.BooleanFlag;
-import com.android.launcher3.config.FeatureFlags.FlagState;
-import com.android.launcher3.config.FeatureFlags.IntFlag;
-
-import java.io.PrintWriter;
-
-/**
- * Helper class to create various flags for launcher build. The base implementation does
- * not provide any flagging system, and simply replies with the default value.
- */
-public class FlagsFactory {
-
-    /**
-     * Creates a new debug flag
-     */
-    public static BooleanFlag getDebugFlag(
-            int bugId, String key, FlagState flagState, String description) {
-        return new BooleanFlag(flagState == ENABLED);
-    }
-
-    /**
-     * Creates a new debug flag
-     */
-    public static BooleanFlag getReleaseFlag(
-            int bugId, String key, FlagState flagState, String description) {
-        return new BooleanFlag(flagState == ENABLED);
-    }
-
-    /**
-     * Creates a new integer flag. Integer flags are always release flags
-     */
-    public static IntFlag getIntFlag(
-            int bugId, String key, int defaultValueInCode, String description) {
-        return new IntFlag(defaultValueInCode);
-    }
-
-    /**
-     * Creates a new debug integer flag and it is saved in LauncherPrefs.
-     */
-    public static IntFlag getIntFlag(
-            int bugId, String key, int defaultValueInCode, String description,
-            @Nullable ConstantItem<Integer> launcherPrefFlag) {
-        return new IntFlag(defaultValueInCode);
-    }
-
-    /**
-     * Dumps the current flags state to the print writer
-     */
-    public static void dump(PrintWriter pw) { }
-}
diff --git a/tests/Android.bp b/tests/Android.bp
index 13a1cbb..3822ff8 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -194,6 +194,7 @@
         "androidx.core_core-animation-testing",
         "androidx.test.ext.junit",
         "androidx.test.rules",
+        "uiautomator-helpers",
         "mockito-robolectric-prebuilt",
         "mockito-kotlin2",
         "platform-parametric-runner-lib",
diff --git a/tests/src/com/android/launcher3/AppWidgetsRestoredReceiverTest.kt b/tests/multivalentTests/src/com/android/launcher3/AppWidgetsRestoredReceiverTest.kt
similarity index 100%
rename from tests/src/com/android/launcher3/AppWidgetsRestoredReceiverTest.kt
rename to tests/multivalentTests/src/com/android/launcher3/AppWidgetsRestoredReceiverTest.kt
diff --git a/tests/src/com/android/launcher3/logging/StartupLatencyLoggerTest.kt b/tests/multivalentTests/src/com/android/launcher3/logging/StartupLatencyLoggerTest.kt
similarity index 100%
rename from tests/src/com/android/launcher3/logging/StartupLatencyLoggerTest.kt
rename to tests/multivalentTests/src/com/android/launcher3/logging/StartupLatencyLoggerTest.kt
diff --git a/tests/multivalentTests/src/com/android/launcher3/util/TestUtil.java b/tests/multivalentTests/src/com/android/launcher3/util/TestUtil.java
index 95444ba..3646f0c 100644
--- a/tests/multivalentTests/src/com/android/launcher3/util/TestUtil.java
+++ b/tests/multivalentTests/src/com/android/launcher3/util/TestUtil.java
@@ -46,12 +46,8 @@
 
 import androidx.test.uiautomator.UiDevice;
 
-import com.android.launcher3.config.FeatureFlags;
-import com.android.launcher3.config.FeatureFlags.BooleanFlag;
-import com.android.launcher3.config.FeatureFlags.IntFlag;
 import com.android.launcher3.tapl.LauncherInstrumentation;
 import com.android.launcher3.tapl.Workspace;
-import com.android.launcher3.util.rule.TestStabilityRule;
 
 import org.junit.Assert;
 
@@ -66,8 +62,6 @@
 import java.util.concurrent.FutureTask;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
-import java.util.function.Predicate;
-import java.util.function.ToIntFunction;
 
 public class TestUtil {
     private static final String TAG = "TestUtil";
@@ -138,49 +132,12 @@
      */
     public static Point[] getCornersAndCenterPositions(LauncherInstrumentation launcher) {
         final Point dimensions = launcher.getWorkspace().getIconGridDimensions();
-        if (TestStabilityRule.isPresubmit()) {
-            // Return only center in presubmit to fit under the presubmit SLO.
-            return new Point[]{
-                    new Point(dimensions.x / 2, dimensions.y / 2)
-            };
-        } else {
-            return new Point[]{
-                    new Point(0, 1),
-                    new Point(0, dimensions.y - 2),
-                    new Point(dimensions.x - 1, 1),
-                    new Point(dimensions.x - 1, dimensions.y - 2),
-                    new Point(dimensions.x / 2, dimensions.y / 2)
-            };
-        }
-    }
-
-    /**
-     * Utility class to override a boolean flag during test. Note that the returned SafeCloseable
-     * must be closed to restore the original state
-     */
-    public static SafeCloseable overrideFlag(BooleanFlag flag, boolean value) {
-        Predicate<BooleanFlag> originalProxy = FeatureFlags.sBooleanReader;
-        Predicate<BooleanFlag> testProxy = f -> f == flag ? value : originalProxy.test(f);
-        FeatureFlags.sBooleanReader = testProxy;
-        return () -> {
-            if (FeatureFlags.sBooleanReader == testProxy) {
-                FeatureFlags.sBooleanReader = originalProxy;
-            }
-        };
-    }
-
-    /**
-     * Utility class to override a int flag during test. Note that the returned SafeCloseable
-     * must be closed to restore the original state
-     */
-    public static SafeCloseable overrideFlag(IntFlag flag, int value) {
-        ToIntFunction<IntFlag> originalProxy = FeatureFlags.sIntReader;
-        ToIntFunction<IntFlag> testProxy = f -> f == flag ? value : originalProxy.applyAsInt(f);
-        FeatureFlags.sIntReader = testProxy;
-        return () -> {
-            if (FeatureFlags.sIntReader == testProxy) {
-                FeatureFlags.sIntReader = originalProxy;
-            }
+        return new Point[]{
+                new Point(0, 1),
+                new Point(0, dimensions.y - 2),
+                new Point(dimensions.x - 1, 1),
+                new Point(dimensions.x - 1, dimensions.y - 2),
+                new Point(dimensions.x / 2, dimensions.y / 2)
         };
     }
 
diff --git a/tests/multivalentTests/src/com/android/launcher3/widget/picker/OWNERS b/tests/multivalentTests/src/com/android/launcher3/widget/picker/OWNERS
new file mode 100644
index 0000000..775b0c7
--- /dev/null
+++ b/tests/multivalentTests/src/com/android/launcher3/widget/picker/OWNERS
@@ -0,0 +1,18 @@
+set noparent
+
+# Bug component: 1481801
+# People who can approve changes for submission
+#
+
+# Widget Picker OWNERS
+zakcohen@google.com
+shamalip@google.com
+wvk@google.com
+
+# For Tests
+vadimt@google.com
+
+# Launcher OWNERS
+captaincole@google.com
+sunnygoyal@google.com
+
diff --git a/tests/src/com/android/launcher3/widget/picker/search/WidgetsSearchBarControllerTest.java b/tests/multivalentTests/src/com/android/launcher3/widget/picker/search/WidgetsSearchBarControllerTest.java
similarity index 100%
rename from tests/src/com/android/launcher3/widget/picker/search/WidgetsSearchBarControllerTest.java
rename to tests/multivalentTests/src/com/android/launcher3/widget/picker/search/WidgetsSearchBarControllerTest.java
diff --git a/tests/src/com/android/launcher3/AbstractDeviceProfileTest.kt b/tests/src/com/android/launcher3/AbstractDeviceProfileTest.kt
index ffcf83f..577334b 100644
--- a/tests/src/com/android/launcher3/AbstractDeviceProfileTest.kt
+++ b/tests/src/com/android/launcher3/AbstractDeviceProfileTest.kt
@@ -38,17 +38,18 @@
 import com.android.launcher3.util.window.CachedDisplayInfo
 import com.android.launcher3.util.window.WindowManagerProxy
 import com.google.common.truth.Truth
-import org.junit.Rule
-import org.mockito.kotlin.any
-import org.mockito.kotlin.mock
-import org.mockito.kotlin.spy
-import org.mockito.kotlin.whenever
 import java.io.BufferedReader
 import java.io.File
 import java.io.PrintWriter
 import java.io.StringWriter
 import kotlin.math.max
 import kotlin.math.min
+import org.junit.Rule
+import org.mockito.kotlin.any
+import org.mockito.kotlin.doReturn
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.spy
+import org.mockito.kotlin.whenever
 
 /**
  * This is an abstract class for DeviceProfile tests that create an InvariantDeviceProfile based on
@@ -286,6 +287,9 @@
             .thenReturn(
                 if (isGestureMode) NavigationMode.NO_BUTTON else NavigationMode.THREE_BUTTONS
             )
+        doReturn(WindowManagerProxy.INSTANCE[runningContext].isTaskbarDrawnInProcess)
+            .whenever(windowManagerProxy)
+            .isTaskbarDrawnInProcess()
 
         val density = densityDpi / DisplayMetrics.DENSITY_DEFAULT.toFloat()
         val config =
diff --git a/tests/src/com/android/launcher3/AbstractFloatingViewHelperTest.kt b/tests/src/com/android/launcher3/AbstractFloatingViewHelperTest.kt
new file mode 100644
index 0000000..7ff544d
--- /dev/null
+++ b/tests/src/com/android/launcher3/AbstractFloatingViewHelperTest.kt
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2024 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
+
+import android.view.View
+import com.android.launcher3.dragndrop.DragLayer
+import com.android.launcher3.views.ActivityContext
+import org.junit.Before
+import org.junit.Test
+import org.mockito.kotlin.any
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.never
+import org.mockito.kotlin.verify
+import org.mockito.kotlin.verifyZeroInteractions
+import org.mockito.kotlin.whenever
+
+/** Test for AbstractFloatingViewHelper */
+class AbstractFloatingViewHelperTest {
+    private val activityContext: ActivityContext = mock()
+    private val dragLayer: DragLayer = mock()
+    private val view: View = mock()
+    private val folderView: AbstractFloatingView = mock()
+    private val taskMenuView: AbstractFloatingView = mock()
+    private val abstractFloatingViewHelper = AbstractFloatingViewHelper()
+
+    @Before
+    fun setup() {
+        whenever(activityContext.dragLayer).thenReturn(dragLayer)
+        whenever(dragLayer.childCount).thenReturn(3)
+        whenever(dragLayer.getChildAt(0)).thenReturn(view)
+        whenever(dragLayer.getChildAt(1)).thenReturn(folderView)
+        whenever(dragLayer.getChildAt(2)).thenReturn(taskMenuView)
+        whenever(folderView.isOfType(any())).thenAnswer {
+            (it.getArgument<Int>(0) and AbstractFloatingView.TYPE_FOLDER) != 0
+        }
+        whenever(taskMenuView.isOfType(any())).thenAnswer {
+            (it.getArgument<Int>(0) and AbstractFloatingView.TYPE_TASK_MENU) != 0
+        }
+    }
+
+    @Test
+    fun closeOpenViews_all() {
+        abstractFloatingViewHelper.closeOpenViews(
+            activityContext,
+            true,
+            AbstractFloatingView.TYPE_ALL
+        )
+
+        verifyZeroInteractions(view)
+        verify(folderView).close(true)
+        verify(taskMenuView).close(true)
+    }
+
+    @Test
+    fun closeOpenViews_taskMenu() {
+        abstractFloatingViewHelper.closeOpenViews(
+            activityContext,
+            true,
+            AbstractFloatingView.TYPE_TASK_MENU
+        )
+
+        verifyZeroInteractions(view)
+        verify(folderView, never()).close(any())
+        verify(taskMenuView).close(true)
+    }
+
+    @Test
+    fun closeOpenViews_other() {
+        abstractFloatingViewHelper.closeOpenViews(
+            activityContext,
+            true,
+            AbstractFloatingView.TYPE_PIN_IME_POPUP
+        )
+
+        verifyZeroInteractions(view)
+        verify(folderView, never()).close(any())
+        verify(taskMenuView, never()).close(any())
+    }
+
+    @Test
+    fun closeOpenViews_both_animationOff() {
+        abstractFloatingViewHelper.closeOpenViews(
+            activityContext,
+            false,
+            AbstractFloatingView.TYPE_FOLDER or AbstractFloatingView.TYPE_TASK_MENU
+        )
+
+        verifyZeroInteractions(view)
+        verify(folderView).close(false)
+        verify(taskMenuView).close(false)
+    }
+}
diff --git a/tests/src/com/android/launcher3/LauncherIntentTest.java b/tests/src/com/android/launcher3/LauncherIntentTest.java
index e8822c3..aeeb42a 100644
--- a/tests/src/com/android/launcher3/LauncherIntentTest.java
+++ b/tests/src/com/android/launcher3/LauncherIntentTest.java
@@ -29,23 +29,17 @@
 import com.android.launcher3.allapps.SearchRecyclerView;
 import com.android.launcher3.ui.AbstractLauncherUiTest;
 
-import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
 @LargeTest
 @RunWith(AndroidJUnit4.class)
-public class LauncherIntentTest extends AbstractLauncherUiTest {
+public class LauncherIntentTest extends AbstractLauncherUiTest<Launcher> {
 
     public final Intent allAppsIntent = new Intent(Intent.ACTION_ALL_APPS);
 
     @Test
-    @Ignore("b/329152799")
     public void testAllAppsIntent() {
-        // setup by moving to home
-        mLauncher.goHome();
-        assertTrue("Launcher internal state is not Home", isInState(() -> LauncherState.NORMAL));
-
         // Try executing ALL_APPS intent
         executeOnLauncher(launcher -> launcher.onNewIntent(allAppsIntent));
         // A-Z view with Main adapter should be loaded
@@ -58,16 +52,10 @@
         executeOnLauncher(launcher -> launcher.onNewIntent(allAppsIntent));
         // A-Z view with Main adapter should be loaded
         assertOnMainAdapterAToZView();
-
-        // finish
-        mLauncher.goHome();
-        assertTrue("Launcher internal state is not Home", isInState(() -> LauncherState.NORMAL));
     }
 
     // Highlights the search bar, then fills text to display the SearchView.
     private void moveToSearchView() {
-        mLauncher.goHome().switchToAllApps();
-
         // All Apps view should be loaded
         assertTrue("Launcher internal state is not All Apps",
                 isInState(() -> LauncherState.ALL_APPS));
diff --git a/tests/src/com/android/launcher3/allapps/PrivateProfileManagerTest.java b/tests/src/com/android/launcher3/allapps/PrivateProfileManagerTest.java
index 476bda5..2dcbda4 100644
--- a/tests/src/com/android/launcher3/allapps/PrivateProfileManagerTest.java
+++ b/tests/src/com/android/launcher3/allapps/PrivateProfileManagerTest.java
@@ -26,7 +26,6 @@
 import static com.android.launcher3.util.rule.TestStabilityRule.PLATFORM_POSTSUBMIT;
 
 import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.Mockito.doNothing;
@@ -39,6 +38,7 @@
 import android.content.pm.LauncherApps;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
+import android.content.res.Resources;
 import android.os.Process;
 import android.os.UserHandle;
 import android.os.UserManager;
@@ -47,8 +47,8 @@
 
 import com.android.launcher3.logging.StatsLogManager;
 import com.android.launcher3.pm.UserCache;
-import com.android.launcher3.uioverrides.ApiWrapper;
 import com.android.launcher3.util.ActivityContextWrapper;
+import com.android.launcher3.util.ApiWrapper;
 import com.android.launcher3.util.UserIconInfo;
 import com.android.launcher3.util.rule.TestStabilityRule;
 
@@ -97,6 +97,8 @@
     private LauncherApps mLauncherApps;
     @Mock
     private AllAppsRecyclerView mAllAppsRecyclerView;
+    @Mock
+    private Resources mResources;
 
     @Before
     public void setUp() {
@@ -106,6 +108,8 @@
         when(mUserCache.getUserInfo(Process.myUserHandle())).thenReturn(MAIN_ICON_INFO);
         when(mUserCache.getUserInfo(PRIVATE_HANDLE)).thenReturn(PRIVATE_ICON_INFO);
         when(mAllApps.getContext()).thenReturn(mContext);
+        when(mContext.getResources()).thenReturn(mResources);
+        when(mContext.getApplicationContext()).thenReturn(getApplicationContext());
         when(mAllApps.getAppsStore()).thenReturn(mAllAppsStore);
         when(mAllApps.getActiveRecyclerView()).thenReturn(mAllAppsRecyclerView);
         when(mContext.getPackageManager()).thenReturn(mPackageManager);
@@ -145,6 +149,7 @@
     public void quietModeFlagPresent_privateSpaceIsResetToDisabled() {
         PrivateProfileManager privateProfileManager = spy(mPrivateProfileManager);
         doNothing().when(privateProfileManager).resetPrivateSpaceDecorator(anyInt());
+        doNothing().when(privateProfileManager).executeLock();
         when(mAllAppsStore.hasModelFlag(FLAG_PRIVATE_PROFILE_QUIET_MODE_ENABLED))
                 .thenReturn(false, true);
 
@@ -181,6 +186,7 @@
     public void transitioningToLocked_resetCallsExecuteLock() throws Exception {
         PrivateProfileManager privateProfileManager = spy(mPrivateProfileManager);
         doNothing().when(privateProfileManager).resetPrivateSpaceDecorator(anyInt());
+        doNothing().when(privateProfileManager).executeLock();
         when(mAllAppsStore.hasModelFlag(FLAG_PRIVATE_PROFILE_QUIET_MODE_ENABLED))
                 .thenReturn(true);
         doNothing().when(privateProfileManager).expandPrivateSpace();
@@ -195,14 +201,16 @@
 
     @Test
     public void openPrivateSpaceSettings_triggersCorrectIntent() {
-        Intent expectedIntent = ApiWrapper.getPrivateSpaceSettingsIntent(mContext);
+        Intent expectedIntent = ApiWrapper.INSTANCE.get(mContext).getPrivateSpaceSettingsIntent();
         ArgumentCaptor<Intent> acIntent = ArgumentCaptor.forClass(Intent.class);
         mPrivateProfileManager.setPrivateSpaceSettingsAvailable(true);
 
         mPrivateProfileManager.openPrivateSpaceSettings();
 
         Mockito.verify(mContext).startActivity(acIntent.capture());
-        assertEquals("Intent Action is different", expectedIntent, acIntent.getValue());
+        assertEquals("Intent Action is different",
+                expectedIntent == null ? null : expectedIntent.toUri(0),
+                acIntent.getValue() == null ? null : acIntent.getValue().toUri(0));
     }
 
     private static void awaitTasksCompleted() throws Exception {
diff --git a/tests/src/com/android/launcher3/allapps/PrivateSpaceHeaderViewTest.java b/tests/src/com/android/launcher3/allapps/PrivateSpaceHeaderViewTest.java
index 7ac276a..351b921 100644
--- a/tests/src/com/android/launcher3/allapps/PrivateSpaceHeaderViewTest.java
+++ b/tests/src/com/android/launcher3/allapps/PrivateSpaceHeaderViewTest.java
@@ -303,7 +303,7 @@
         assertEquals(NUM_PRIVATE_SPACE_APPS + 1 + 1,
                 mAlphabeticalAppsList.getAdapterItems().size());
         assertEquals(position,
-                privateProfileManager.scrollForViewToBeVisibleInContainer(
+                privateProfileManager.scrollForHeaderToBeVisibleInContainer(
                         new AllAppsRecyclerView(mContext),
                         mAlphabeticalAppsList.getAdapterItems(),
                         PS_HEADER_HEIGHT,
@@ -339,7 +339,7 @@
         assertEquals(NUM_PRIVATE_SPACE_APPS + 1 + 1,
                 mAlphabeticalAppsList.getAdapterItems().size());
         assertEquals(position,
-                privateProfileManager.scrollForViewToBeVisibleInContainer(
+                privateProfileManager.scrollForHeaderToBeVisibleInContainer(
                         new AllAppsRecyclerView(mContext),
                         mAlphabeticalAppsList.getAdapterItems(),
                         BIGGER_PS_HEADER_HEIGHT,
@@ -369,7 +369,7 @@
         // The number of adapterItems should be the private space apps + one main app.
         assertEquals(NUM_PRIVATE_SPACE_APPS + 1,
                 mAlphabeticalAppsList.getAdapterItems().size());
-        assertEquals(SCROLL_NO_WHERE, privateProfileManager.scrollForViewToBeVisibleInContainer(
+        assertEquals(SCROLL_NO_WHERE, privateProfileManager.scrollForHeaderToBeVisibleInContainer(
                 new AllAppsRecyclerView(mContext),
                 mAlphabeticalAppsList.getAdapterItems(),
                 BIGGER_PS_HEADER_HEIGHT,
diff --git a/tests/src/com/android/launcher3/allapps/TaplAllAppsIconsWorkingTest.java b/tests/src/com/android/launcher3/allapps/TaplAllAppsIconsWorkingTest.java
index 10e9f8a..0b233e5 100644
--- a/tests/src/com/android/launcher3/allapps/TaplAllAppsIconsWorkingTest.java
+++ b/tests/src/com/android/launcher3/allapps/TaplAllAppsIconsWorkingTest.java
@@ -18,6 +18,7 @@
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 
+import com.android.launcher3.Launcher;
 import com.android.launcher3.LauncherState;
 import com.android.launcher3.tapl.AppIcon;
 import com.android.launcher3.tapl.HomeAllApps;
@@ -30,7 +31,7 @@
  * The test runs in Out of process (Oop) and in process.
  * Makes sure the basic behaviors of Icons on AllApps are working.
  */
-public class TaplAllAppsIconsWorkingTest extends AbstractLauncherUiTest {
+public class TaplAllAppsIconsWorkingTest extends AbstractLauncherUiTest<Launcher> {
 
     /**
      * Makes sure we can launch an icon from All apps
diff --git a/tests/src/com/android/launcher3/allapps/TaplKeyboardFocusTest.java b/tests/src/com/android/launcher3/allapps/TaplKeyboardFocusTest.java
index 0360470..20684eb 100644
--- a/tests/src/com/android/launcher3/allapps/TaplKeyboardFocusTest.java
+++ b/tests/src/com/android/launcher3/allapps/TaplKeyboardFocusTest.java
@@ -26,6 +26,7 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
+import com.android.launcher3.Launcher;
 import com.android.launcher3.LauncherState;
 import com.android.launcher3.tapl.HomeAllApps;
 import com.android.launcher3.ui.AbstractLauncherUiTest;
@@ -37,7 +38,7 @@
 
 @SmallTest
 @RunWith(AndroidJUnit4.class)
-public class TaplKeyboardFocusTest extends AbstractLauncherUiTest {
+public class TaplKeyboardFocusTest extends AbstractLauncherUiTest<Launcher> {
 
     @Test
     public void testAllAppsFocusApp() {
diff --git a/tests/src/com/android/launcher3/allapps/TaplOpenCloseAllAppsTest.java b/tests/src/com/android/launcher3/allapps/TaplOpenCloseAllAppsTest.java
index e462c4f..f3f6fa5 100644
--- a/tests/src/com/android/launcher3/allapps/TaplOpenCloseAllAppsTest.java
+++ b/tests/src/com/android/launcher3/allapps/TaplOpenCloseAllAppsTest.java
@@ -28,6 +28,7 @@
 import androidx.test.filters.FlakyTest;
 import androidx.test.platform.app.InstrumentationRegistry;
 
+import com.android.launcher3.Launcher;
 import com.android.launcher3.LauncherState;
 import com.android.launcher3.tapl.AllApps;
 import com.android.launcher3.ui.AbstractLauncherUiTest;
@@ -40,7 +41,7 @@
  * Test that we can open and close the all apps in multiple situations.
  * The test runs in Out of process (Oop) and in process.
  */
-public class TaplOpenCloseAllAppsTest extends AbstractLauncherUiTest {
+public class TaplOpenCloseAllAppsTest extends AbstractLauncherUiTest<Launcher> {
 
     public static final String READ_DEVICE_CONFIG_PERMISSION =
             "android.permission.READ_DEVICE_CONFIG";
diff --git a/tests/src/com/android/launcher3/appiconmenu/TaplAppIconMenuTest.java b/tests/src/com/android/launcher3/appiconmenu/TaplAppIconMenuTest.java
index c69d1b9..55d3252 100644
--- a/tests/src/com/android/launcher3/appiconmenu/TaplAppIconMenuTest.java
+++ b/tests/src/com/android/launcher3/appiconmenu/TaplAppIconMenuTest.java
@@ -38,7 +38,7 @@
  * Tests the AppIconMenu (the menu that appears when you long press an app icon) and also make sure
  * we can launch a shortcut from it.
  */
-public class TaplAppIconMenuTest extends AbstractLauncherUiTest {
+public class TaplAppIconMenuTest extends AbstractLauncherUiTest<Launcher> {
 
     private boolean isOptionsPopupVisible(Launcher launcher) {
         final ArrowPopup<?> popup = launcher.getOptionsPopup();
diff --git a/tests/src/com/android/launcher3/celllayout/TaplReorderWidgetsTest.java b/tests/src/com/android/launcher3/celllayout/TaplReorderWidgetsTest.java
index 1b03645..389d027 100644
--- a/tests/src/com/android/launcher3/celllayout/TaplReorderWidgetsTest.java
+++ b/tests/src/com/android/launcher3/celllayout/TaplReorderWidgetsTest.java
@@ -30,6 +30,7 @@
 import androidx.test.filters.SmallTest;
 
 import com.android.launcher3.InvariantDeviceProfile;
+import com.android.launcher3.Launcher;
 import com.android.launcher3.LauncherAppState;
 import com.android.launcher3.MultipageCellLayout;
 import com.android.launcher3.celllayout.board.CellLayoutBoard;
@@ -59,7 +60,7 @@
 
 @SmallTest
 @RunWith(AndroidJUnit4.class)
-public class TaplReorderWidgetsTest extends AbstractLauncherUiTest {
+public class TaplReorderWidgetsTest extends AbstractLauncherUiTest<Launcher> {
 
     @Rule
     public ShellCommandRule mGrantWidgetRule = ShellCommandRule.grantWidgetBind();
diff --git a/tests/src/com/android/launcher3/celllayout/testgenerator/ValidGridMigrationTestCaseGenerator.kt b/tests/src/com/android/launcher3/celllayout/testgenerator/ValidGridMigrationTestCaseGenerator.kt
index e773a86..a006fd7 100644
--- a/tests/src/com/android/launcher3/celllayout/testgenerator/ValidGridMigrationTestCaseGenerator.kt
+++ b/tests/src/com/android/launcher3/celllayout/testgenerator/ValidGridMigrationTestCaseGenerator.kt
@@ -31,16 +31,17 @@
  *   account for cases where the user have the same item multiple times.
  */
 fun generateItemsForTest(
-    testCase: GridMigrationUnitTestCase,
-    repeatAfter: Int
+    boards: List<CellLayoutBoard>,
+    repeatAfterRange: Point
 ): List<WorkspaceItem> {
     val id = AtomicInteger(0)
     val widgetId = AtomicInteger(LauncherAppWidgetInfo.CUSTOM_WIDGET_ID - 1)
-    val boards = testCase.boards
     // Repeat the same appWidgetProvider and intent to have repeating widgets and icons and test
     // that case too
-    val getIntent = { i: Int -> "Intent ${i % repeatAfter}" }
-    val getProvider = { i: Int -> "com.test/test.Provider${i % repeatAfter}" }
+    val getIntent = { i: Int -> "Intent ${(i + repeatAfterRange.x) % repeatAfterRange.y}" }
+    val getProvider = { i: Int ->
+        "com.test/test.Provider${(i + repeatAfterRange.x) % repeatAfterRange.y }"
+    }
     val hotseatEntries =
         (0 until boards[0].width).map {
             WorkspaceItem(
@@ -97,11 +98,12 @@
                     container = LauncherSettings.Favorites.CONTAINER_DESKTOP
                 )
             }
-    return widgetEntries + hotseatEntries // + iconEntries
+    return widgetEntries + hotseatEntries + iconEntries
 }
 
 data class GridMigrationUnitTestCase(
     val boards: List<CellLayoutBoard>,
+    val destBoards: List<CellLayoutBoard>,
     val srcSize: Point,
     val targetSize: Point,
     val seed: Long
@@ -135,11 +137,27 @@
         return boards
     }
 
-    fun generateTestCase(): GridMigrationUnitTestCase {
-        var seed = generator.nextLong()
+    fun generateTestCase(isDestEmpty: Boolean): GridMigrationUnitTestCase {
+        val seed = generator.nextLong()
         val randomBoardGenerator = RandomBoardGenerator(Random(seed))
         val width = randomBoardGenerator.getRandom(3, MAX_BOARD_SIZE)
         val height = randomBoardGenerator.getRandom(3, MAX_BOARD_SIZE)
+        val targetSize =
+            Point(
+                randomBoardGenerator.getRandom(3, MAX_BOARD_SIZE),
+                randomBoardGenerator.getRandom(3, MAX_BOARD_SIZE)
+            )
+        val destBoards =
+            if (isDestEmpty) {
+                listOf()
+            } else {
+                generateBoards(
+                    boardGenerator = randomBoardGenerator,
+                    width = targetSize.x,
+                    height = targetSize.y,
+                    boardCount = randomBoardGenerator.getRandom(3, MAX_BOARD_COUNT)
+                )
+            }
         return GridMigrationUnitTestCase(
             boards =
                 generateBoards(
@@ -148,12 +166,9 @@
                     height = height,
                     boardCount = randomBoardGenerator.getRandom(3, MAX_BOARD_COUNT)
                 ),
+            destBoards = destBoards,
             srcSize = Point(width, height),
-            targetSize =
-                Point(
-                    randomBoardGenerator.getRandom(3, MAX_BOARD_SIZE),
-                    randomBoardGenerator.getRandom(3, MAX_BOARD_SIZE)
-                ),
+            targetSize = targetSize,
             seed = seed
         )
     }
diff --git a/tests/src/com/android/launcher3/compat/TaplPromiseIconUiTest.java b/tests/src/com/android/launcher3/compat/TaplPromiseIconUiTest.java
index 7ed0fa5..1500538 100644
--- a/tests/src/com/android/launcher3/compat/TaplPromiseIconUiTest.java
+++ b/tests/src/com/android/launcher3/compat/TaplPromiseIconUiTest.java
@@ -52,7 +52,7 @@
  */
 @LargeTest
 @RunWith(AndroidJUnit4.class)
-public class TaplPromiseIconUiTest extends AbstractLauncherUiTest {
+public class TaplPromiseIconUiTest extends AbstractLauncherUiTest<Launcher> {
 
     @Rule
     public final CheckFlagsRule mCheckFlagsRule =
diff --git a/tests/src/com/android/launcher3/dragging/TaplDragTest.java b/tests/src/com/android/launcher3/dragging/TaplDragTest.java
index bf1ba39..d64d096 100644
--- a/tests/src/com/android/launcher3/dragging/TaplDragTest.java
+++ b/tests/src/com/android/launcher3/dragging/TaplDragTest.java
@@ -33,6 +33,7 @@
 import android.platform.test.annotations.PlatinumTest;
 import android.util.Log;
 
+import com.android.launcher3.Launcher;
 import com.android.launcher3.tapl.Folder;
 import com.android.launcher3.tapl.FolderIcon;
 import com.android.launcher3.tapl.HomeAllApps;
@@ -57,7 +58,7 @@
  *    * Can drag an icon from AllApps into the workspace
  *    * Can drag an icon on the Workspace to other positions of the Workspace.
  */
-public class TaplDragTest extends AbstractLauncherUiTest {
+public class TaplDragTest extends AbstractLauncherUiTest<Launcher> {
 
     /**
      * Adds two icons to the Workspace and combines them into a folder, then makes sure the icons
diff --git a/tests/src/com/android/launcher3/dragging/TaplUninstallRemoveTest.java b/tests/src/com/android/launcher3/dragging/TaplUninstallRemoveTest.java
index e21309f..df71ec0 100644
--- a/tests/src/com/android/launcher3/dragging/TaplUninstallRemoveTest.java
+++ b/tests/src/com/android/launcher3/dragging/TaplUninstallRemoveTest.java
@@ -17,7 +17,6 @@
 
 import static com.android.launcher3.testing.shared.TestProtocol.ICON_MISSING;
 import static com.android.launcher3.testing.shared.TestProtocol.UIOBJECT_STALE_ELEMENT;
-import static com.android.launcher3.ui.AbstractLauncherUiTest.initialize;
 import static com.android.launcher3.util.TestConstants.AppNames.DUMMY_APP_NAME;
 import static com.android.launcher3.util.TestConstants.AppNames.GMAIL_APP_NAME;
 import static com.android.launcher3.util.TestConstants.AppNames.MAPS_APP_NAME;
@@ -32,6 +31,7 @@
 import android.platform.test.annotations.PlatinumTest;
 import android.util.Log;
 
+import com.android.launcher3.Launcher;
 import com.android.launcher3.tapl.HomeAllApps;
 import com.android.launcher3.tapl.HomeAppIcon;
 import com.android.launcher3.tapl.Workspace;
@@ -51,7 +51,7 @@
  * Test runs in Out of process (Oop) and In process (Ipc)
  * Test the behaviour of uninstalling and removing apps both from AllApps, Workspace and Hotseat.
  */
-public class TaplUninstallRemoveTest extends AbstractLauncherUiTest {
+public class TaplUninstallRemoveTest extends AbstractLauncherUiTest<Launcher> {
 
     /**
      * Deletes app both built-in and user-installed from the Workspace and makes sure it's no longer
diff --git a/tests/src/com/android/launcher3/folder/PreviewItemManagerTest.kt b/tests/src/com/android/launcher3/folder/PreviewItemManagerTest.kt
index 3a1883c..da14425 100644
--- a/tests/src/com/android/launcher3/folder/PreviewItemManagerTest.kt
+++ b/tests/src/com/android/launcher3/folder/PreviewItemManagerTest.kt
@@ -29,7 +29,7 @@
 import com.android.launcher3.icons.FastBitmapDrawable
 import com.android.launcher3.icons.UserBadgeDrawable
 import com.android.launcher3.model.data.FolderInfo
-import com.android.launcher3.model.data.WorkspaceItemInfo
+import com.android.launcher3.model.data.ItemInfo
 import com.android.launcher3.util.ActivityContextWrapper
 import com.android.launcher3.util.FlagOp
 import com.android.launcher3.util.LauncherLayoutBuilder
@@ -47,7 +47,7 @@
 
     private lateinit var previewItemManager: PreviewItemManager
     private lateinit var context: Context
-    private lateinit var folderItems: ArrayList<WorkspaceItemInfo>
+    private lateinit var folderItems: ArrayList<ItemInfo>
     private lateinit var modelHelper: LauncherModelHelper
     private lateinit var folderIcon: FolderIcon
 
@@ -72,15 +72,17 @@
                     .build()
             )
             .loadModelSync()
-        folderItems = modelHelper.bgDataModel.collections.valueAt(0).contents
+        folderItems = modelHelper.bgDataModel.collections.valueAt(0).getContents()
         folderIcon.mInfo = modelHelper.bgDataModel.collections.valueAt(0) as FolderInfo
-        folderIcon.mInfo.contents = folderItems
+        folderIcon.mInfo.getContents().addAll(folderItems)
 
+        // Use getAppContents() to "cast" contents to WorkspaceItemInfo so we can set bitmaps
+        val folderApps = modelHelper.bgDataModel.collections.valueAt(0).getAppContents()
         // Set first icon to be themed.
-        folderItems[0]
+        folderApps[0]
             .bitmap
             .setMonoIcon(
-                folderItems[0].bitmap.icon,
+                folderApps[0].bitmap.icon,
                 BaseIconFactory(
                     context,
                     context.resources.configuration.densityDpi,
@@ -89,7 +91,7 @@
             )
 
         // Set second icon to be non-themed.
-        folderItems[1]
+        folderApps[1]
             .bitmap
             .setMonoIcon(
                 null,
@@ -101,23 +103,21 @@
             )
 
         // Set third icon to be themed with badge.
-        folderItems[2]
+        folderApps[2]
             .bitmap
             .setMonoIcon(
-                folderItems[2].bitmap.icon,
+                folderApps[2].bitmap.icon,
                 BaseIconFactory(
                     context,
                     context.resources.configuration.densityDpi,
                     previewItemManager.mIconSize
                 )
             )
-        folderItems[2].bitmap =
-            folderItems[2].bitmap.withFlags(profileFlagOp(UserIconInfo.TYPE_WORK))
+        folderApps[2].bitmap = folderApps[2].bitmap.withFlags(profileFlagOp(UserIconInfo.TYPE_WORK))
 
         // Set fourth icon to be non-themed with badge.
-        folderItems[3].bitmap =
-            folderItems[3].bitmap.withFlags(profileFlagOp(UserIconInfo.TYPE_WORK))
-        folderItems[3]
+        folderApps[3].bitmap = folderApps[3].bitmap.withFlags(profileFlagOp(UserIconInfo.TYPE_WORK))
+        folderApps[3]
             .bitmap
             .setMonoIcon(
                 null,
diff --git a/tests/src/com/android/launcher3/model/CacheDataUpdatedTaskTest.java b/tests/src/com/android/launcher3/model/CacheDataUpdatedTaskTest.java
index abb0c39..d3a6355 100644
--- a/tests/src/com/android/launcher3/model/CacheDataUpdatedTaskTest.java
+++ b/tests/src/com/android/launcher3/model/CacheDataUpdatedTaskTest.java
@@ -160,6 +160,6 @@
     }
 
     private List<WorkspaceItemInfo> allItems() {
-        return ((FolderInfo) mModelHelper.getBgDataModel().itemsIdMap.get(1)).getContents();
+        return ((FolderInfo) mModelHelper.getBgDataModel().itemsIdMap.get(1)).getAppContents();
     }
 }
diff --git a/tests/src/com/android/launcher3/model/FolderIconLoadTest.kt b/tests/src/com/android/launcher3/model/FolderIconLoadTest.kt
index ed587a1..2e209a4 100644
--- a/tests/src/com/android/launcher3/model/FolderIconLoadTest.kt
+++ b/tests/src/com/android/launcher3/model/FolderIconLoadTest.kt
@@ -168,8 +168,8 @@
         val collections = modelHelper.getBgDataModel().collections
 
         assertThat(collections.size()).isEqualTo(1)
-        assertThat(collections.valueAt(0).contents.size).isEqualTo(itemCount)
-        return collections.valueAt(0).contents
+        assertThat(collections.valueAt(0).getAppContents().size).isEqualTo(itemCount)
+        return collections.valueAt(0).getAppContents()
     }
 
     private fun verifyHighRes(items: ArrayList<WorkspaceItemInfo>, vararg indices: Int) {
diff --git a/tests/src/com/android/launcher3/model/gridmigration/ValidGridMigrationUnitTest.kt b/tests/src/com/android/launcher3/model/gridmigration/ValidGridMigrationUnitTest.kt
index 1002976..58b915f 100644
--- a/tests/src/com/android/launcher3/model/gridmigration/ValidGridMigrationUnitTest.kt
+++ b/tests/src/com/android/launcher3/model/gridmigration/ValidGridMigrationUnitTest.kt
@@ -40,14 +40,22 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 
+private data class Grid(val tableName: String, val size: Point, val items: List<WorkspaceItem>) {
+    fun toGridState(): DeviceGridState =
+        DeviceGridState(size.x, size.y, size.x, InvariantDeviceProfile.TYPE_PHONE, tableName)
+}
+
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class ValidGridMigrationUnitTest {
 
     companion object {
         const val SEED = 1044542
-        const val REPEAT_AFTER = 10
+        val REPEAT_AFTER = Point(0, 10)
+        val REPEAT_AFTER_DST = Point(6, 15)
         const val TAG = "ValidGridMigrationUnitTest"
+        const val SMALL_TEST_SIZE = 60
+        const val LARGE_TEST_SIZE = 1000
     }
 
     private lateinit var context: Context
@@ -57,14 +65,10 @@
         context = InstrumentationRegistry.getInstrumentation().targetContext
     }
 
-    private fun validate(
-        srcItems: List<WorkspaceItem>,
-        dstItems: List<WorkspaceItem>,
-        destinationSize: Point
-    ) {
+    private fun validate(srcGrid: Grid, dstGrid: Grid, resultItems: List<WorkspaceItem>) {
         // This returns a map with the number of repeated elements
         // ex { calculatorIcon : 6, weatherWidget : 2 }
-        val itemsToSet = { it: List<WorkspaceItem> ->
+        val itemsToMap = { it: List<WorkspaceItem> ->
             it.filter { it.container != Favorites.CONTAINER_HOTSEAT }
                 .groupingBy {
                     when (it.type) {
@@ -77,34 +81,36 @@
                 }
                 .eachCount()
         }
-        for (it in dstItems) {
-            assert((it.x in 0..destinationSize.x) && (it.y in 0..destinationSize.y)) {
-                "Item outside of the board size. Size = $destinationSize Item = $it"
+        resultItems.forEach {
+            assert((it.x in 0..dstGrid.size.x) && (it.y in 0..dstGrid.size.y)) {
+                "Item outside of the board size. Size = ${dstGrid.size} Item = $it"
             }
             assert(
-                (it.x + it.spanX in 0..destinationSize.x) &&
-                    (it.y + it.spanY in 0..destinationSize.y)
+                (it.x + it.spanX in 0..dstGrid.size.x) && (it.y + it.spanY in 0..dstGrid.size.y)
             ) {
-                "Item doesn't fit in the grid. Size = $destinationSize Item = $it"
+                "Item doesn't fit in the grid. Size = ${dstGrid.size} Item = $it"
             }
         }
 
-        assert(itemsToSet(srcItems) == itemsToSet(dstItems)) {
-            "The srcItems do not match the dstItems src = $srcItems  dst = $dstItems"
+        val srcCountMap = itemsToMap(srcGrid.items)
+        val resultCountMap = itemsToMap(resultItems)
+        val diff = resultCountMap - srcCountMap
+
+        diff.forEach { (k, count) ->
+            assert(count >= 0) { "Source item $k not present on the result" }
         }
     }
 
-    private fun addItemsToDb(db: SQLiteDatabase, tableName: String, items: List<WorkspaceItem>) {
+    private fun addItemsToDb(db: SQLiteDatabase, grid: Grid) {
         LauncherDbUtils.SQLiteTransaction(db).use { transaction ->
-            items.forEach { insertIntoDb(tableName, it, transaction.db) }
+            grid.items.forEach { insertIntoDb(grid.tableName, it, transaction.db) }
             transaction.commit()
         }
     }
 
     private fun migrate(
-        srcItems: List<WorkspaceItem>,
-        srcSize: Point,
-        targetSize: Point
+        srcGrid: Grid,
+        dstGrid: Grid,
     ): List<WorkspaceItem> {
         val userSerial = UserCache.INSTANCE[context].getSerialNumberForUser(Process.myUserHandle())
         val dbHelper =
@@ -114,46 +120,64 @@
                 { UserCache.INSTANCE.get(context).getSerialNumberForUser(it) },
                 {}
             )
-        val srcTableName = Favorites.TMP_TABLE
-        val dstTableName = Favorites.TABLE_NAME
-        Favorites.addTableToDb(dbHelper.writableDatabase, userSerial, false, srcTableName)
-        addItemsToDb(dbHelper.writableDatabase, srcTableName, srcItems)
+
+        Favorites.addTableToDb(dbHelper.writableDatabase, userSerial, false, srcGrid.tableName)
+
+        addItemsToDb(dbHelper.writableDatabase, srcGrid)
+        addItemsToDb(dbHelper.writableDatabase, dstGrid)
+
         LauncherDbUtils.SQLiteTransaction(dbHelper.writableDatabase).use {
             GridSizeMigrationUtil.migrate(
                 dbHelper,
-                GridSizeMigrationUtil.DbReader(it.db, srcTableName, context, MockSet(1)),
-                GridSizeMigrationUtil.DbReader(it.db, dstTableName, context, MockSet(1)),
-                targetSize.x,
-                targetSize,
-                DeviceGridState(
-                    srcSize.x,
-                    srcSize.y,
-                    srcSize.x,
-                    InvariantDeviceProfile.TYPE_PHONE,
-                    srcTableName
-                ),
-                DeviceGridState(
-                    targetSize.x,
-                    targetSize.y,
-                    targetSize.x,
-                    InvariantDeviceProfile.TYPE_PHONE,
-                    dstTableName
-                )
+                GridSizeMigrationUtil.DbReader(it.db, srcGrid.tableName, context, MockSet(1)),
+                GridSizeMigrationUtil.DbReader(it.db, dstGrid.tableName, context, MockSet(1)),
+                dstGrid.size.x,
+                dstGrid.size,
+                srcGrid.toGridState(),
+                dstGrid.toGridState()
             )
             it.commit()
         }
-        return readDb(dstTableName, dbHelper.readableDatabase)
+        return readDb(dstGrid.tableName, dbHelper.readableDatabase)
     }
 
     @Test
     fun runTestCase() {
         val caseGenerator = ValidGridMigrationTestCaseGenerator(Random(SEED.toLong()))
-        for (i in 0..50) {
-            val testCase = caseGenerator.generateTestCase()
+        for (i in 0..SMALL_TEST_SIZE) {
+            val testCase = caseGenerator.generateTestCase(isDestEmpty = true)
             Log.d(TAG, "Test case = $testCase")
-            val srcItemList = generateItemsForTest(testCase, REPEAT_AFTER)
-            val dstItemList = migrate(srcItemList, testCase.srcSize, testCase.targetSize)
-            validate(srcItemList, dstItemList, testCase.targetSize)
+            val srcGrid =
+                Grid(
+                    tableName = Favorites.TMP_TABLE,
+                    size = testCase.srcSize,
+                    items = generateItemsForTest(testCase.boards, REPEAT_AFTER)
+                )
+            val dstGrid =
+                Grid(tableName = Favorites.TABLE_NAME, size = testCase.targetSize, items = listOf())
+            validate(srcGrid, dstGrid, migrate(srcGrid, dstGrid))
+        }
+    }
+
+    @Test
+    fun mergeBoards() {
+        val caseGenerator = ValidGridMigrationTestCaseGenerator(Random(SEED.toLong()))
+        for (i in 0..SMALL_TEST_SIZE) {
+            val testCase = caseGenerator.generateTestCase(isDestEmpty = false)
+            Log.d(TAG, "Test case = $testCase")
+            val srcGrid =
+                Grid(
+                    tableName = Favorites.TMP_TABLE,
+                    size = testCase.srcSize,
+                    items = generateItemsForTest(testCase.boards, REPEAT_AFTER)
+                )
+            val dstGrid =
+                Grid(
+                    tableName = Favorites.TABLE_NAME,
+                    size = testCase.targetSize,
+                    items = generateItemsForTest(testCase.destBoards, REPEAT_AFTER_DST)
+                )
+            validate(srcGrid, dstGrid, migrate(srcGrid, dstGrid))
         }
     }
 
@@ -162,12 +186,18 @@
     @Test
     fun runExtensiveTestCases() {
         val caseGenerator = ValidGridMigrationTestCaseGenerator(Random(SEED.toLong()))
-        for (i in 0..1000) {
-            val testCase = caseGenerator.generateTestCase()
+        for (i in 0..LARGE_TEST_SIZE) {
+            val testCase = caseGenerator.generateTestCase(isDestEmpty = true)
             Log.d(TAG, "Test case = $testCase")
-            val srcItemList = generateItemsForTest(testCase, REPEAT_AFTER)
-            val dstItemList = migrate(srcItemList, testCase.srcSize, testCase.targetSize)
-            validate(srcItemList, dstItemList, testCase.targetSize)
+            val srcGrid =
+                Grid(
+                    tableName = Favorites.TMP_TABLE,
+                    size = testCase.srcSize,
+                    items = generateItemsForTest(testCase.boards, REPEAT_AFTER)
+                )
+            val dstGrid =
+                Grid(tableName = Favorites.TABLE_NAME, size = testCase.targetSize, items = listOf())
+            validate(srcGrid, dstGrid, migrate(srcGrid, dstGrid))
         }
     }
 }
diff --git a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
index d8635f9..7109083 100644
--- a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
+++ b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
@@ -95,7 +95,7 @@
 /**
  * Base class for all instrumentation tests providing various utility methods.
  */
-public abstract class AbstractLauncherUiTest {
+public abstract class AbstractLauncherUiTest<LAUNCHER_TYPE extends Launcher> {
 
     public static final long DEFAULT_ACTIVITY_TIMEOUT = TimeUnit.SECONDS.toMillis(10);
     public static final long DEFAULT_BROADCAST_TIMEOUT_SECS = 5;
@@ -251,7 +251,7 @@
         final ViewCaptureRule viewCaptureRule = new ViewCaptureRule(
                 Launcher.ACTIVITY_TRACKER::getCreatedActivity);
         final RuleChain inner = RuleChain
-                .outerRule(new PortraitLandscapeRunner(this))
+                .outerRule(new PortraitLandscapeRunner<LAUNCHER_TYPE>(this))
                 .around(new FailureWatcher(mLauncher, viewCaptureRule::getViewCaptureData))
                 // .around(viewCaptureRule) // b/315482167
                 .around(new TestIsolationRule(mLauncher, true));
@@ -426,12 +426,12 @@
         }
     }
 
-    protected <T> T getFromLauncher(Function<Launcher, T> f) {
+    protected <T> T getFromLauncher(Function<LAUNCHER_TYPE, T> f) {
         if (!TestHelpers.isInLauncherProcess()) return null;
         return getOnUiThread(() -> f.apply(Launcher.ACTIVITY_TRACKER.getCreatedActivity()));
     }
 
-    protected void executeOnLauncher(Consumer<Launcher> f) {
+    protected void executeOnLauncher(Consumer<LAUNCHER_TYPE> f) {
         getFromLauncher(launcher -> {
             f.accept(launcher);
             return null;
@@ -441,7 +441,7 @@
     // Execute an action on Launcher, but forgive it when launcher is null.
     // Launcher can be null if teardown is happening after a failed setup step where launcher
     // activity failed to be created.
-    protected void executeOnLauncherInTearDown(Consumer<Launcher> f) {
+    protected void executeOnLauncherInTearDown(Consumer<LAUNCHER_TYPE> f) {
         executeOnLauncher(launcher -> {
             if (launcher != null) f.accept(launcher);
         });
@@ -469,20 +469,20 @@
     // Cannot be used in TaplTests after injecting any gesture using Tapl because this can hide
     // flakiness.
     protected void waitForLauncherCondition(String
-            message, Function<Launcher, Boolean> condition) {
+            message, Function<LAUNCHER_TYPE, Boolean> condition) {
         waitForLauncherCondition(message, condition, DEFAULT_ACTIVITY_TIMEOUT);
     }
 
     // Cannot be used in TaplTests after injecting any gesture using Tapl because this can hide
     // flakiness.
-    protected <T> T getOnceNotNull(String message, Function<Launcher, T> f) {
+    protected <O> O getOnceNotNull(String message, Function<LAUNCHER_TYPE, O> f) {
         return getOnceNotNull(message, f, DEFAULT_ACTIVITY_TIMEOUT);
     }
 
     // Cannot be used in TaplTests after injecting any gesture using Tapl because this can hide
     // flakiness.
     protected void waitForLauncherCondition(
-            String message, Function<Launcher, Boolean> condition, long timeout) {
+            String message, Function<LAUNCHER_TYPE, Boolean> condition, long timeout) {
         verifyKeyguardInvisible();
         if (!TestHelpers.isInLauncherProcess()) return;
         Wait.atMost(message, () -> getFromLauncher(condition), timeout, mLauncher);
@@ -490,7 +490,7 @@
 
     // Cannot be used in TaplTests after injecting any gesture using Tapl because this can hide
     // flakiness.
-    protected <T> T getOnceNotNull(String message, Function<Launcher, T> f, long timeout) {
+    protected <T> T getOnceNotNull(String message, Function<LAUNCHER_TYPE, T> f, long timeout) {
         if (!TestHelpers.isInLauncherProcess()) return null;
 
         final Object[] output = new Object[1];
@@ -506,7 +506,7 @@
     // flakiness.
     protected void waitForLauncherCondition(
             String message,
-            Runnable testThreadAction, Function<Launcher, Boolean> condition,
+            Runnable testThreadAction, Function<LAUNCHER_TYPE, Boolean> condition,
             long timeout) {
         if (!TestHelpers.isInLauncherProcess()) return;
         Wait.atMost(message, () -> {
@@ -648,7 +648,7 @@
                 "Launcher still active", launcher -> launcher == null, DEFAULT_UI_TIMEOUT);
     }
 
-    protected boolean isInLaunchedApp(Launcher launcher) {
+    protected boolean isInLaunchedApp(LAUNCHER_TYPE launcher) {
         return launcher == null || !launcher.hasBeenResumed();
     }
 
@@ -658,11 +658,11 @@
                 launcher -> launcher.getStateManager().getState() == state.get());
     }
 
-    protected int getAllAppsScroll(Launcher launcher) {
+    protected int getAllAppsScroll(LAUNCHER_TYPE launcher) {
         return launcher.getAppsView().getActiveRecyclerView().computeVerticalScrollOffset();
     }
 
-    protected void onLauncherActivityClose(Launcher launcher) {
+    protected void onLauncherActivityClose(LAUNCHER_TYPE launcher) {
     }
 
     protected HomeAppIcon createShortcutInCenterIfNotExist(String name) {
diff --git a/tests/src/com/android/launcher3/ui/PortraitLandscapeRunner.java b/tests/src/com/android/launcher3/ui/PortraitLandscapeRunner.java
index f01bdb3..c4e74f2 100644
--- a/tests/src/com/android/launcher3/ui/PortraitLandscapeRunner.java
+++ b/tests/src/com/android/launcher3/ui/PortraitLandscapeRunner.java
@@ -3,9 +3,9 @@
 import android.util.Log;
 import android.view.Surface;
 
+import com.android.launcher3.Launcher;
 import com.android.launcher3.tapl.TestHelpers;
 import com.android.launcher3.util.rule.FailureWatcher;
-import com.android.launcher3.util.rule.TestStabilityRule;
 
 import org.junit.rules.TestRule;
 import org.junit.runner.Description;
@@ -15,11 +15,12 @@
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
+import java.util.Objects;
 import java.util.concurrent.TimeUnit;
 
-public class PortraitLandscapeRunner implements TestRule {
+public class PortraitLandscapeRunner<LAUNCHER_TYPE extends Launcher> implements TestRule {
     private static final String TAG = "PortraitLandscapeRunner";
-    private AbstractLauncherUiTest mTest;
+    private AbstractLauncherUiTest<LAUNCHER_TYPE> mTest;
 
     // Annotation for tests that need to be run in portrait and landscape modes.
     @Retention(RetentionPolicy.RUNTIME)
@@ -27,18 +28,14 @@
     public @interface PortraitLandscape {
     }
 
-    public PortraitLandscapeRunner(AbstractLauncherUiTest test) {
+    public PortraitLandscapeRunner(AbstractLauncherUiTest<LAUNCHER_TYPE> test) {
         mTest = test;
     }
 
     @Override
     public Statement apply(Statement base, Description description) {
         if (!TestHelpers.isInLauncherProcess()
-                || description.getAnnotation(PortraitLandscape.class) == null
-                // If running in presubmit, don't run in both orientations.
-                // It's important to keep presubmits fast even if we will occasionally miss
-                // regressions in presubmit.
-                || TestStabilityRule.isPresubmit()) {
+                || description.getAnnotation(PortraitLandscape.class) == null) {
             return base;
         }
 
@@ -52,7 +49,7 @@
 
                         mTest.mDevice.pressHome();
                         mTest.waitForLauncherCondition("Launcher activity wasn't created",
-                                launcher -> launcher != null,
+                                Objects::nonNull,
                                 TimeUnit.SECONDS.toMillis(20));
 
                         mTest.executeOnLauncher(launcher ->
diff --git a/tests/src/com/android/launcher3/ui/TaplTestsLauncher3Test.java b/tests/src/com/android/launcher3/ui/TaplTestsLauncher3Test.java
index 4eae7e1..342eedf 100644
--- a/tests/src/com/android/launcher3/ui/TaplTestsLauncher3Test.java
+++ b/tests/src/com/android/launcher3/ui/TaplTestsLauncher3Test.java
@@ -21,13 +21,17 @@
 import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
+import com.android.launcher3.util.rule.ScreenRecordRule.ScreenRecord;
+import com.android.launcher3.Launcher;
+
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
 @LargeTest
 @RunWith(AndroidJUnit4.class)
-public class TaplTestsLauncher3Test extends AbstractLauncherUiTest {
+public class TaplTestsLauncher3Test extends AbstractLauncherUiTest<Launcher> {
 
+    @ScreenRecord // b/322823478
     @Test
     public void testDevicePressMenu() throws Exception {
         mDevice.pressMenu();
diff --git a/tests/src/com/android/launcher3/ui/TaplWorkProfileTest.java b/tests/src/com/android/launcher3/ui/TaplWorkProfileTest.java
index a9947a0..cccda88 100644
--- a/tests/src/com/android/launcher3/ui/TaplWorkProfileTest.java
+++ b/tests/src/com/android/launcher3/ui/TaplWorkProfileTest.java
@@ -35,6 +35,7 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.LargeTest;
 
+import com.android.launcher3.Launcher;
 import com.android.launcher3.LauncherPrefs;
 import com.android.launcher3.R;
 import com.android.launcher3.allapps.ActivityAllAppsContainerView;
@@ -58,7 +59,7 @@
 
 @LargeTest
 @RunWith(AndroidJUnit4.class)
-public class TaplWorkProfileTest extends AbstractLauncherUiTest {
+public class TaplWorkProfileTest extends AbstractLauncherUiTest<Launcher> {
 
     private static final int WORK_PAGE = ActivityAllAppsContainerView.AdapterHolder.WORK;
 
@@ -195,6 +196,7 @@
 
     }
 
+    @ScreenRecord // b/322823478
     @Test
     public void testEdu() {
         assumeTrue(mWorkProfileSetupSuccessful);
diff --git a/tests/src/com/android/launcher3/ui/widget/TaplAddConfigWidgetTest.java b/tests/src/com/android/launcher3/ui/widget/TaplAddConfigWidgetTest.java
index 1db6014..e6e02b4 100644
--- a/tests/src/com/android/launcher3/ui/widget/TaplAddConfigWidgetTest.java
+++ b/tests/src/com/android/launcher3/ui/widget/TaplAddConfigWidgetTest.java
@@ -52,7 +52,7 @@
  */
 @LargeTest
 @RunWith(AndroidJUnit4.class)
-public class TaplAddConfigWidgetTest extends AbstractLauncherUiTest {
+public class TaplAddConfigWidgetTest extends AbstractLauncherUiTest<Launcher> {
 
     @Rule
     public ShellCommandRule mGrantWidgetRule = ShellCommandRule.grantWidgetBind();
diff --git a/tests/src/com/android/launcher3/ui/widget/TaplAddWidgetTest.java b/tests/src/com/android/launcher3/ui/widget/TaplAddWidgetTest.java
index 6c24329..7845dec 100644
--- a/tests/src/com/android/launcher3/ui/widget/TaplAddWidgetTest.java
+++ b/tests/src/com/android/launcher3/ui/widget/TaplAddWidgetTest.java
@@ -25,6 +25,7 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.LargeTest;
 
+import com.android.launcher3.Launcher;
 import com.android.launcher3.celllayout.FavoriteItemsTransaction;
 import com.android.launcher3.tapl.Widget;
 import com.android.launcher3.tapl.WidgetResizeFrame;
@@ -46,7 +47,7 @@
  */
 @LargeTest
 @RunWith(AndroidJUnit4.class)
-public class TaplAddWidgetTest extends AbstractLauncherUiTest {
+public class TaplAddWidgetTest extends AbstractLauncherUiTest<Launcher> {
 
     @Rule
     public ShellCommandRule mGrantWidgetRule = ShellCommandRule.grantWidgetBind();
diff --git a/tests/src/com/android/launcher3/ui/widget/TaplBindWidgetTest.java b/tests/src/com/android/launcher3/ui/widget/TaplBindWidgetTest.java
index e69cb4c..28d1faa 100644
--- a/tests/src/com/android/launcher3/ui/widget/TaplBindWidgetTest.java
+++ b/tests/src/com/android/launcher3/ui/widget/TaplBindWidgetTest.java
@@ -43,6 +43,7 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.LargeTest;
 
+import com.android.launcher3.Launcher;
 import com.android.launcher3.LauncherAppState;
 import com.android.launcher3.LauncherModel;
 import com.android.launcher3.LauncherSettings;
@@ -76,7 +77,7 @@
  */
 @LargeTest
 @RunWith(AndroidJUnit4.class)
-public class TaplBindWidgetTest extends AbstractLauncherUiTest {
+public class TaplBindWidgetTest extends AbstractLauncherUiTest<Launcher> {
 
     @Rule
     public ShellCommandRule mGrantWidgetRule = ShellCommandRule.grantWidgetBind();
diff --git a/tests/src/com/android/launcher3/ui/widget/TaplRequestPinItemTest.java b/tests/src/com/android/launcher3/ui/widget/TaplRequestPinItemTest.java
index 90a6d22..74047f0 100644
--- a/tests/src/com/android/launcher3/ui/widget/TaplRequestPinItemTest.java
+++ b/tests/src/com/android/launcher3/ui/widget/TaplRequestPinItemTest.java
@@ -59,7 +59,7 @@
  */
 @LargeTest
 @RunWith(AndroidJUnit4.class)
-public class TaplRequestPinItemTest extends AbstractLauncherUiTest {
+public class TaplRequestPinItemTest extends AbstractLauncherUiTest<Launcher> {
 
     @Rule
     public ShellCommandRule mGrantWidgetRule = ShellCommandRule.grantWidgetBind();
diff --git a/tests/src/com/android/launcher3/ui/widget/TaplWidgetPickerTest.java b/tests/src/com/android/launcher3/ui/widget/TaplWidgetPickerTest.java
index 4acdddc..79724e1 100644
--- a/tests/src/com/android/launcher3/ui/widget/TaplWidgetPickerTest.java
+++ b/tests/src/com/android/launcher3/ui/widget/TaplWidgetPickerTest.java
@@ -43,7 +43,7 @@
  */
 @MediumTest
 @RunWith(AndroidJUnit4.class)
-public class TaplWidgetPickerTest extends AbstractLauncherUiTest {
+public class TaplWidgetPickerTest extends AbstractLauncherUiTest<Launcher> {
     // b/325377690 : To get the log printed where DOWN key event is getting lost from TAPL.
     @Rule public final TestRule mEnableInputTransportPublisherRule =
             createEnableInputTransportPublisherRule();
diff --git a/tests/src/com/android/launcher3/ui/workspace/TaplThemeIconsTest.java b/tests/src/com/android/launcher3/ui/workspace/TaplThemeIconsTest.java
index c60ee8c..d653317 100644
--- a/tests/src/com/android/launcher3/ui/workspace/TaplThemeIconsTest.java
+++ b/tests/src/com/android/launcher3/ui/workspace/TaplThemeIconsTest.java
@@ -31,6 +31,7 @@
 import androidx.test.filters.LargeTest;
 
 import com.android.launcher3.BubbleTextView;
+import com.android.launcher3.Launcher;
 import com.android.launcher3.icons.ThemedIconDrawable;
 import com.android.launcher3.tapl.HomeAllApps;
 import com.android.launcher3.tapl.HomeAppIcon;
@@ -49,7 +50,7 @@
  * Note running these tests will clear the workspace on the device.
  */
 @LargeTest
-public class TaplThemeIconsTest extends AbstractLauncherUiTest {
+public class TaplThemeIconsTest extends AbstractLauncherUiTest<Launcher> {
 
     private static final String APP_NAME = "IconThemedActivity";
     private static final String SHORTCUT_NAME = "Shortcut 1";
diff --git a/tests/src/com/android/launcher3/ui/workspace/TaplTwoPanelWorkspaceTest.java b/tests/src/com/android/launcher3/ui/workspace/TaplTwoPanelWorkspaceTest.java
index 43fc8ff..2ce8eef 100644
--- a/tests/src/com/android/launcher3/ui/workspace/TaplTwoPanelWorkspaceTest.java
+++ b/tests/src/com/android/launcher3/ui/workspace/TaplTwoPanelWorkspaceTest.java
@@ -37,6 +37,7 @@
 import com.android.launcher3.ui.PortraitLandscapeRunner.PortraitLandscape;
 import com.android.launcher3.util.LauncherLayoutBuilder;
 import com.android.launcher3.util.TestUtil;
+import com.android.launcher3.util.rule.ScreenRecordRule;
 
 import org.junit.After;
 import org.junit.Before;
@@ -54,7 +55,7 @@
  */
 @LargeTest
 @RunWith(AndroidJUnit4.class)
-public class TaplTwoPanelWorkspaceTest extends AbstractLauncherUiTest {
+public class TaplTwoPanelWorkspaceTest extends AbstractLauncherUiTest<Launcher> {
 
     private AutoCloseable mLauncherLayout;
 
@@ -240,6 +241,7 @@
         });
     }
 
+    @ScreenRecordRule.ScreenRecord // b/329935119
     @Test
     @PortraitLandscape
     public void testEmptyPageDoesNotGetRemovedIfPagePairIsNotEmpty() {
diff --git a/tests/src/com/android/launcher3/ui/workspace/TaplWorkspaceTest.java b/tests/src/com/android/launcher3/ui/workspace/TaplWorkspaceTest.java
index 4edeb42..9afde0d 100644
--- a/tests/src/com/android/launcher3/ui/workspace/TaplWorkspaceTest.java
+++ b/tests/src/com/android/launcher3/ui/workspace/TaplWorkspaceTest.java
@@ -37,7 +37,7 @@
 /**
  * Test the basic interactions of the Workspace, adding pages, moving the pages and removing pages.
  */
-public class TaplWorkspaceTest extends AbstractLauncherUiTest {
+public class TaplWorkspaceTest extends AbstractLauncherUiTest<Launcher> {
 
     private AutoCloseable mLauncherLayout;
 
diff --git a/tests/src/com/android/launcher3/util/ItemInflaterTest.kt b/tests/src/com/android/launcher3/util/ItemInflaterTest.kt
index 0065527..dae09bb 100644
--- a/tests/src/com/android/launcher3/util/ItemInflaterTest.kt
+++ b/tests/src/com/android/launcher3/util/ItemInflaterTest.kt
@@ -139,9 +139,9 @@
     @Test
     fun test_folder_inflated_on_UI() {
         val itemInfo = FolderInfo()
-        itemInfo.contents.add(workspaceItemInfo())
-        itemInfo.contents.add(workspaceItemInfo())
-        itemInfo.contents.add(workspaceItemInfo())
+        itemInfo.add(workspaceItemInfo())
+        itemInfo.add(workspaceItemInfo())
+        itemInfo.add(workspaceItemInfo())
 
         val view =
             MAIN_EXECUTOR.submit(Callable { underTest.inflateItem(itemInfo, modelWriter) }).get()
@@ -155,9 +155,9 @@
         setFlagsRule.enableFlags(Flags.FLAG_ENABLE_WORKSPACE_INFLATION)
 
         val itemInfo = FolderInfo()
-        itemInfo.contents.add(workspaceItemInfo())
-        itemInfo.contents.add(workspaceItemInfo())
-        itemInfo.contents.add(workspaceItemInfo())
+        itemInfo.add(workspaceItemInfo())
+        itemInfo.add(workspaceItemInfo())
+        itemInfo.add(workspaceItemInfo())
 
         val view =
             VIEW_PREINFLATION_EXECUTOR.submit(
@@ -173,8 +173,8 @@
     fun test_app_pair_inflated_on_UI() {
         val itemInfo = AppPairInfo()
         itemInfo.itemType = ITEM_TYPE_APP_PAIR
-        itemInfo.contents.add(workspaceItemInfo())
-        itemInfo.contents.add(workspaceItemInfo())
+        itemInfo.add(workspaceItemInfo())
+        itemInfo.add(workspaceItemInfo())
 
         val view =
             MAIN_EXECUTOR.submit(Callable { underTest.inflateItem(itemInfo, modelWriter) }).get()
@@ -189,8 +189,8 @@
 
         val itemInfo = AppPairInfo()
         itemInfo.itemType = ITEM_TYPE_APP_PAIR
-        itemInfo.contents.add(workspaceItemInfo())
-        itemInfo.contents.add(workspaceItemInfo())
+        itemInfo.add(workspaceItemInfo())
+        itemInfo.add(workspaceItemInfo())
 
         val view =
             VIEW_PREINFLATION_EXECUTOR.submit(
diff --git a/tests/tapl/com/android/launcher3/tapl/AllApps.java b/tests/tapl/com/android/launcher3/tapl/AllApps.java
index 847dc4b..245ec09 100644
--- a/tests/tapl/com/android/launcher3/tapl/AllApps.java
+++ b/tests/tapl/com/android/launcher3/tapl/AllApps.java
@@ -416,6 +416,14 @@
         }
     }
 
+    /** Returns PrivateSpaceContainer if present in view. */
+    @NonNull
+    public PrivateSpaceContainer getPrivateSpaceUnlockedView() {
+        final UiObject2 allAppsContainer = verifyActiveContainer();
+        final UiObject2 appListRecycler = getAppListRecycler(allAppsContainer);
+        return new PrivateSpaceContainer(mLauncher, appListRecycler);
+    }
+
     protected abstract void verifyVisibleContainerOnDismiss();
 
     /**
diff --git a/tests/tapl/com/android/launcher3/tapl/BaseOverview.java b/tests/tapl/com/android/launcher3/tapl/BaseOverview.java
index 3f70bb9..68829e0 100644
--- a/tests/tapl/com/android/launcher3/tapl/BaseOverview.java
+++ b/tests/tapl/com/android/launcher3/tapl/BaseOverview.java
@@ -398,8 +398,9 @@
         if (isTablet && Math.abs(task.getExactCenterX() - mLauncher.getExactScreenCenterX()) >= 1) {
             return false;
         }
-        if (!mLauncher.isAppPairsEnabled() && task.isTaskSplit()) {
-            // Overview actions aren't visible for split screen tasks.
+        if (task.isTaskSplit() && (!mLauncher.isAppPairsEnabled() || !isTablet)) {
+            // Overview actions aren't visible for split screen tasks, except for save app pair
+            // button on tablets.
             return false;
         }
         return true;
diff --git a/tests/tapl/com/android/launcher3/tapl/OverviewActions.java b/tests/tapl/com/android/launcher3/tapl/OverviewActions.java
index d7c40a0..486a63b 100644
--- a/tests/tapl/com/android/launcher3/tapl/OverviewActions.java
+++ b/tests/tapl/com/android/launcher3/tapl/OverviewActions.java
@@ -17,6 +17,7 @@
 package com.android.launcher3.tapl;
 
 import androidx.annotation.NonNull;
+import androidx.test.uiautomator.By;
 import androidx.test.uiautomator.UiObject2;
 
 /**
@@ -110,4 +111,12 @@
             }
         }
     }
+
+    /** Asserts that an item matching the given string is present in the overview actions. */
+    public void assertHasAction(String text) {
+        try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
+                "want to check if the action [" + text + "] is present")) {
+            mLauncher.waitForObjectInContainer(mOverviewActions, By.text(text));
+        }
+    }
 }
diff --git a/tests/tapl/com/android/launcher3/tapl/PrivateSpaceContainer.java b/tests/tapl/com/android/launcher3/tapl/PrivateSpaceContainer.java
new file mode 100644
index 0000000..2c16e01
--- /dev/null
+++ b/tests/tapl/com/android/launcher3/tapl/PrivateSpaceContainer.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2024 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.tapl;
+
+import androidx.test.uiautomator.UiObject2;
+
+/**
+ * View containing Private Space elements.
+ */
+public class PrivateSpaceContainer {
+    private static final String PS_HEADER_RES_ID = "ps_header_layout";
+    private static final String INSTALL_APP_TITLE = "Install apps";
+    private static final String DIVIDER_RES_ID = "private_space_divider";
+
+    private final LauncherInstrumentation mLauncher;
+    private final UiObject2 mAppListRecycler;
+
+    PrivateSpaceContainer(LauncherInstrumentation launcherInstrumentation,
+            UiObject2 appListRecycler) {
+        mLauncher = launcherInstrumentation;
+        mAppListRecycler = appListRecycler;
+
+        verifyHeaderIsPresent();
+        verifyInstallAppButtonIsPresent();
+        verifyDividerIsPresent();
+    }
+
+    // Assert PS Header is in view.
+    // Assert PS header has the correct elements.
+    private void verifyHeaderIsPresent() {
+        final UiObject2 psHeader = mLauncher.waitForObjectInContainer(mAppListRecycler,
+                PS_HEADER_RES_ID);
+        new PrivateSpaceHeader(mLauncher, psHeader, true);
+    }
+
+
+    // Assert Install App Item is present in view.
+    private void verifyInstallAppButtonIsPresent() {
+        mLauncher.getAllApps().getAppIcon(INSTALL_APP_TITLE);
+    }
+
+    // Assert Sys App Divider is present in view.
+    private void verifyDividerIsPresent() {
+        mLauncher.waitForObjectInContainer(mAppListRecycler, DIVIDER_RES_ID);
+    }
+}
diff --git a/tests/tapl/com/android/launcher3/tapl/PrivateSpaceHeader.java b/tests/tapl/com/android/launcher3/tapl/PrivateSpaceHeader.java
new file mode 100644
index 0000000..3a7f038
--- /dev/null
+++ b/tests/tapl/com/android/launcher3/tapl/PrivateSpaceHeader.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2024 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.tapl;
+
+import androidx.test.uiautomator.UiObject2;
+
+/**
+ * View containing Private Space Header.
+ */
+public class PrivateSpaceHeader {
+    private static final String PS_HEADER_TEXT_RES_ID = "ps_container_header";
+    private static final String SETTINGS_BUTTON_RES_ID = "ps_settings_button";
+    private static final String UNLOCK_BUTTON_VIEW_RES_ID = "ps_lock_unlock_button";
+    private static final String LOCK_ICON_RES_ID = "lock_icon";
+    private static final String LOCK_TEXT_RES_ID = "lock_text";
+
+    private final UiObject2 mPrivateSpaceHeader;
+    private final boolean mPrivateSpaceEnabled;
+    private final LauncherInstrumentation mLauncher;
+
+    PrivateSpaceHeader(LauncherInstrumentation launcherInstrumentation,
+            UiObject2 privateSpaceHeader, boolean privateSpaceEnabled) {
+        mLauncher = launcherInstrumentation;
+        mPrivateSpaceHeader = privateSpaceHeader;
+        mPrivateSpaceEnabled =  privateSpaceEnabled;
+        verifyPrivateSpaceHeaderState();
+    }
+
+    /** Verify elements in Private Space Header as per state */
+    private void verifyPrivateSpaceHeaderState() {
+        if (mPrivateSpaceEnabled) {
+            verifyUnlockedState();
+        } else {
+            mLauncher.fail("Private Space found in non enabled state");
+        }
+    }
+
+    /** Verify Unlocked State elements in Private Space Header */
+    private void verifyUnlockedState() {
+        UiObject2 headerText = mLauncher.waitForObjectInContainer(mPrivateSpaceHeader,
+                PS_HEADER_TEXT_RES_ID);
+        mLauncher.assertEquals("PS Header Text is incorrect ",
+                "Private", headerText.getText());
+
+        UiObject2 settingsButton = mLauncher.waitForObjectInContainer(mPrivateSpaceHeader,
+                SETTINGS_BUTTON_RES_ID);
+        mLauncher.waitForObjectEnabled(settingsButton, "Private Space Settings Button");
+        mLauncher.assertTrue("PS Settings button is non-clickable", settingsButton.isClickable());
+
+        UiObject2 unLockButtonView = mLauncher.waitForObjectInContainer(mPrivateSpaceHeader,
+                UNLOCK_BUTTON_VIEW_RES_ID);
+        mLauncher.waitForObjectEnabled(unLockButtonView, "Private Space Unlock Button");
+        mLauncher.assertTrue("PS Unlock Button is non-clickable", unLockButtonView.isClickable());
+
+        mLauncher.waitForObjectInContainer(mPrivateSpaceHeader,
+                LOCK_ICON_RES_ID);
+
+        UiObject2 lockText = mLauncher.waitForObjectInContainer(mPrivateSpaceHeader,
+                LOCK_TEXT_RES_ID);
+        mLauncher.assertEquals("PS lock text is incorrect", "Lock", lockText.getText());
+
+    }
+}