Merge "Fix widget dissapearing because of change of appWidgetId" into main
diff --git a/quickstep/res/color/bubblebar_drop_target_bg_color.xml b/quickstep/res/color/bubblebar_drop_target_bg_color.xml
new file mode 100644
index 0000000..ca37c7f
--- /dev/null
+++ b/quickstep/res/color/bubblebar_drop_target_bg_color.xml
@@ -0,0 +1,19 @@
+<?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.
+  -->
+<selector xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
+    <item android:alpha="0.35" android:color="?androidprv:attr/materialColorPrimaryContainer" />
+</selector>
\ No newline at end of file
diff --git a/quickstep/res/drawable/bg_bubble_bar_drop_target.xml b/quickstep/res/drawable/bg_bubble_bar_drop_target.xml
new file mode 100644
index 0000000..79e4318
--- /dev/null
+++ b/quickstep/res/drawable/bg_bubble_bar_drop_target.xml
@@ -0,0 +1,24 @@
+<?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.
+  -->
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
+    android:shape="rectangle">
+    <corners android:radius="@dimen/bubblebar_drop_target_corner_radius" />
+    <solid android:color="@color/bubblebar_drop_target_bg_color" />
+    <stroke
+        android:width="1dp"
+        android:color="?androidprv:attr/materialColorPrimaryContainer" />
+</shape>
diff --git a/quickstep/res/layout/bubble_bar_drop_target.xml b/quickstep/res/layout/bubble_bar_drop_target.xml
new file mode 100644
index 0000000..23f240c
--- /dev/null
+++ b/quickstep/res/layout/bubble_bar_drop_target.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.
+  -->
+
+<View xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="@dimen/bubblebar_size"
+    android:layout_height="@dimen/bubblebar_size"
+    android:background="@drawable/bg_bubble_bar_drop_target"
+    android:elevation="@dimen/bubblebar_elevation" />
\ No newline at end of file
diff --git a/quickstep/res/values-ar/strings.xml b/quickstep/res/values-ar/strings.xml
index 9b68f49..048ff8b 100644
--- a/quickstep/res/values-ar/strings.xml
+++ b/quickstep/res/values-ar/strings.xml
@@ -95,12 +95,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>
diff --git a/quickstep/res/values-bg/strings.xml b/quickstep/res/values-bg/strings.xml
index be66004..bd677da 100644
--- a/quickstep/res/values-bg/strings.xml
+++ b/quickstep/res/values-bg/strings.xml
@@ -95,7 +95,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>
diff --git a/quickstep/res/values-ca/strings.xml b/quickstep/res/values-ca/strings.xml
index 1cffbdf..5d6e0d8 100644
--- a/quickstep/res/values-ca/strings.xml
+++ b/quickstep/res/values-ca/strings.xml
@@ -129,7 +129,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..5ebf7eb 100644
--- a/quickstep/res/values-cs/strings.xml
+++ b/quickstep/res/values-cs/strings.xml
@@ -112,7 +112,7 @@
     <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>
diff --git a/quickstep/res/values-es-rUS/strings.xml b/quickstep/res/values-es-rUS/strings.xml
index 580a8df..5d5c2c1 100644
--- a/quickstep/res/values-es-rUS/strings.xml
+++ b/quickstep/res/values-es-rUS/strings.xml
@@ -129,7 +129,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..79964d8 100644
--- a/quickstep/res/values-es/strings.xml
+++ b/quickstep/res/values-es/strings.xml
@@ -129,7 +129,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-fi/strings.xml b/quickstep/res/values-fi/strings.xml
index e913f85..ca44b7a 100644
--- a/quickstep/res/values-fi/strings.xml
+++ b/quickstep/res/values-fi/strings.xml
@@ -109,9 +109,9 @@
     <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>
diff --git a/quickstep/res/values-hu/strings.xml b/quickstep/res/values-hu/strings.xml
index 017c5f6..a61da68 100644
--- a/quickstep/res/values-hu/strings.xml
+++ b/quickstep/res/values-hu/strings.xml
@@ -129,7 +129,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-in/strings.xml b/quickstep/res/values-in/strings.xml
index 7fefe9c..64a8235 100644
--- a/quickstep/res/values-in/strings.xml
+++ b/quickstep/res/values-in/strings.xml
@@ -97,10 +97,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,7 +113,7 @@
     <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_close" msgid="887022990168191073">"Tutup"</string>
diff --git a/quickstep/res/values-kn/strings.xml b/quickstep/res/values-kn/strings.xml
index 903534a..6dd4d52 100644
--- a/quickstep/res/values-kn/strings.xml
+++ b/quickstep/res/values-kn/strings.xml
@@ -112,7 +112,7 @@
     <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>
diff --git a/quickstep/res/values-mk/strings.xml b/quickstep/res/values-mk/strings.xml
index b4c9569..4a3e62b 100644
--- a/quickstep/res/values-mk/strings.xml
+++ b/quickstep/res/values-mk/strings.xml
@@ -95,7 +95,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>
diff --git a/quickstep/res/values-my/strings.xml b/quickstep/res/values-my/strings.xml
index 762f669..06ed2c5 100644
--- a/quickstep/res/values-my/strings.xml
+++ b/quickstep/res/values-my/strings.xml
@@ -129,7 +129,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-nl/strings.xml b/quickstep/res/values-nl/strings.xml
index 999da4e..74543a5 100644
--- a/quickstep/res/values-nl/strings.xml
+++ b/quickstep/res/values-nl/strings.xml
@@ -97,7 +97,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>
diff --git a/quickstep/res/values-zh-rCN/strings.xml b/quickstep/res/values-zh-rCN/strings.xml
index 3f6cc2c..fea79bb 100644
--- a/quickstep/res/values-zh-rCN/strings.xml
+++ b/quickstep/res/values-zh-rCN/strings.xml
@@ -95,7 +95,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,7 +110,7 @@
     <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>
diff --git a/quickstep/res/values-zh-rHK/strings.xml b/quickstep/res/values-zh-rHK/strings.xml
index 050c47c..c1c78ab 100644
--- a/quickstep/res/values-zh-rHK/strings.xml
+++ b/quickstep/res/values-zh-rHK/strings.xml
@@ -95,7 +95,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>
diff --git a/quickstep/res/values/dimens.xml b/quickstep/res/values/dimens.xml
index 93ef735..caa949e 100644
--- a/quickstep/res/values/dimens.xml
+++ b/quickstep/res/values/dimens.xml
@@ -417,6 +417,7 @@
     <!-- Container size with pointer included: bubblebar_size + bubblebar_pointer_size -->
     <dimen name="bubblebar_size_with_pointer">80dp</dimen>
     <dimen name="bubblebar_elevation">1dp</dimen>
+    <dimen name="bubblebar_drag_elevation">2dp</dimen>
     <dimen name="bubblebar_hotseat_adjustment_threshold">90dp</dimen>
 
     <dimen name="bubblebar_icon_size">50dp</dimen>
@@ -432,6 +433,11 @@
     <dimen name="bubblebar_dismiss_target_icon_size">24dp</dimen>
     <dimen name="bubblebar_dismiss_target_bottom_margin">50dp</dimen>
     <dimen name="bubblebar_dismiss_floating_gradient_height">548dp</dimen>
+    <dimen name="bubblebar_dismiss_zone_width">192dp</dimen>
+    <dimen name="bubblebar_dismiss_zone_height">242dp</dimen>
+
+    <!-- Bubble bar drop target -->
+    <dimen name="bubblebar_drop_target_corner_radius">36dp</dimen>
 
     <!-- Launcher splash screen -->
     <!-- Note: keep this value in sync with the WindowManager/Shell dimens.xml -->
diff --git a/quickstep/src/com/android/launcher3/model/QuickstepModelDelegate.java b/quickstep/src/com/android/launcher3/model/QuickstepModelDelegate.java
index 0ce1cb8..c0e0587 100644
--- a/quickstep/src/com/android/launcher3/model/QuickstepModelDelegate.java
+++ b/quickstep/src/com/android/launcher3/model/QuickstepModelDelegate.java
@@ -18,8 +18,8 @@
 import static android.text.format.DateUtils.DAY_IN_MILLIS;
 import static android.text.format.DateUtils.formatElapsedTime;
 
-import static com.android.launcher3.LauncherPrefs.nonRestorableItem;
 import static com.android.launcher3.EncryptionType.ENCRYPTED;
+import static com.android.launcher3.LauncherPrefs.nonRestorableItem;
 import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_HOTSEAT_PREDICTION;
 import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_PREDICTION;
 import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_WIDGETS_PREDICTION;
@@ -65,7 +65,7 @@
 import com.android.launcher3.logging.InstanceIdSequence;
 import com.android.launcher3.model.BgDataModel.FixedContainerItems;
 import com.android.launcher3.model.data.AppInfo;
-import com.android.launcher3.model.data.FolderInfo;
+import com.android.launcher3.model.data.CollectionInfo;
 import com.android.launcher3.model.data.ItemInfo;
 import com.android.launcher3.model.data.WorkspaceItemInfo;
 import com.android.launcher3.pm.UserCache;
@@ -233,7 +233,7 @@
             }
             InstanceId instanceId = new InstanceIdSequence().newInstanceId();
             for (ItemInfo info : itemsIdMap) {
-                FolderInfo parent = getContainer(info, itemsIdMap);
+                CollectionInfo parent = getContainer(info, itemsIdMap);
                 StatsLogCompatManager.writeSnapshot(info.buildProto(parent), instanceId);
             }
             additionalSnapshotEvents(instanceId);
@@ -270,7 +270,7 @@
                         }
 
                         for (ItemInfo info : itemsIdMap) {
-                            FolderInfo parent = getContainer(info, itemsIdMap);
+                            CollectionInfo parent = getContainer(info, itemsIdMap);
                             LauncherAtom.ItemInfo itemInfo = info.buildProto(parent);
                             Log.d(TAG, itemInfo.toString());
                             StatsEvent statsEvent = StatsLogCompatManager.buildStatsEvent(itemInfo,
@@ -293,18 +293,19 @@
         }
     }
 
-    private static FolderInfo getContainer(ItemInfo info, IntSparseArrayMap<ItemInfo> itemsIdMap) {
+    private static CollectionInfo getContainer(
+            ItemInfo info, IntSparseArrayMap<ItemInfo> itemsIdMap) {
         if (info.container > 0) {
             ItemInfo containerInfo = itemsIdMap.get(info.container);
 
-            if (!(containerInfo instanceof FolderInfo)) {
+            if (!(containerInfo instanceof CollectionInfo)) {
                 Log.e(TAG, String.format(
                         "Item info: %s found with invalid container: %s",
                         info,
                         containerInfo));
             }
             // Allow crash to help debug b/173838775
-            return (FolderInfo) containerInfo;
+            return (CollectionInfo) containerInfo;
         }
         return null;
     }
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
index 26212c1..8769f11 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
@@ -89,6 +89,7 @@
 import com.android.launcher3.logger.LauncherAtom;
 import com.android.launcher3.logging.StatsLogManager;
 import com.android.launcher3.model.data.AppInfo;
+import com.android.launcher3.model.data.AppPairInfo;
 import com.android.launcher3.model.data.FolderInfo;
 import com.android.launcher3.model.data.ItemInfo;
 import com.android.launcher3.model.data.WorkspaceItemInfo;
@@ -98,6 +99,7 @@
 import com.android.launcher3.taskbar.TaskbarTranslationController.TransitionCallback;
 import com.android.launcher3.taskbar.allapps.TaskbarAllAppsController;
 import com.android.launcher3.taskbar.bubbles.BubbleBarController;
+import com.android.launcher3.taskbar.bubbles.BubbleBarPinController;
 import com.android.launcher3.taskbar.bubbles.BubbleBarView;
 import com.android.launcher3.taskbar.bubbles.BubbleBarViewController;
 import com.android.launcher3.taskbar.bubbles.BubbleControllers;
@@ -254,7 +256,10 @@
                     new BubbleStashController(this),
                     new BubbleStashedHandleViewController(this, bubbleHandleView),
                     new BubbleDragController(this),
-                    new BubbleDismissController(this, mDragLayer)));
+                    new BubbleDismissController(this, mDragLayer),
+                    new BubbleBarPinController(this, mDragLayer,
+                            () -> getDeviceProfile().getDisplayInfo().currentSize)
+            ));
         }
 
         // Construct controllers.
@@ -1082,19 +1087,19 @@
             ActivityManagerWrapper.getInstance().startActivityFromRecents(task.key,
                     ActivityOptions.makeBasic());
             mControllers.taskbarStashController.updateAndAnimateTransientTaskbar(true);
-        } else if (tag instanceof FolderInfo fi && fi.itemType == Favorites.ITEM_TYPE_FOLDER) {
+        } else if (tag instanceof FolderInfo) {
             // Tapping an expandable folder icon on Taskbar
             shouldCloseAllOpenViews = false;
             expandFolder((FolderIcon) view);
-        } else if (tag instanceof FolderInfo fi && fi.itemType == Favorites.ITEM_TYPE_APP_PAIR) {
+        } else if (tag instanceof AppPairInfo api) {
             // Tapping an app pair icon on Taskbar
             if (recents != null && recents.isSplitSelectionActive()) {
                 Toast.makeText(this, "Unable to split with an app pair. Select another app.",
                         Toast.LENGTH_SHORT).show();
             } else {
                 // Else launch the selected app pair
-                launchFromTaskbar(recents, view, fi.contents);
-                mControllers.uiController.onTaskbarIconLaunched(fi);
+                launchFromTaskbar(recents, view, api.getContents());
+                mControllers.uiController.onTaskbarIconLaunched(api);
                 mControllers.taskbarStashController.updateAndAnimateTransientTaskbar(true);
             }
         } else if (tag instanceof WorkspaceItemInfo) {
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarPopupController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarPopupController.java
index ca192c8..4462f20 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarPopupController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarPopupController.java
@@ -116,9 +116,9 @@
                 }
             } else if (info instanceof FolderInfo && v instanceof FolderIcon) {
                 FolderInfo fi = (FolderInfo) info;
-                if (fi.contents.stream().anyMatch(matcher)) {
+                if (fi.anyMatch(matcher)) {
                     FolderDotInfo folderDotInfo = new FolderDotInfo();
-                    for (WorkspaceItemInfo si : fi.contents) {
+                    for (WorkspaceItemInfo si : fi.getContents()) {
                         folderDotInfo.addDotInfo(mPopupDataProvider.getDotInfoForItem(si));
                     }
                     ((FolderIcon) v).setDotInfo(folderDotInfo);
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java
index 7c3af57..dc2684e 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java
@@ -18,6 +18,7 @@
 import static android.content.pm.PackageManager.FEATURE_PC;
 import static android.view.accessibility.AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED;
 
+import static com.android.launcher3.BubbleTextView.DISPLAY_TASKBAR;
 import static com.android.launcher3.Flags.enableCursorHoverStates;
 import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_APP_PAIR;
 import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_FOLDER;
@@ -52,6 +53,8 @@
 import com.android.launcher3.apppairs.AppPairIcon;
 import com.android.launcher3.folder.FolderIcon;
 import com.android.launcher3.folder.PreviewBackground;
+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;
 import com.android.launcher3.model.data.WorkspaceItemInfo;
@@ -282,7 +285,7 @@
         removeView(view);
         view.setOnClickListener(null);
         view.setOnLongClickListener(null);
-        if (!(view.getTag() instanceof FolderInfo)) {
+        if (!(view.getTag() instanceof CollectionInfo)) {
             mActivityContext.getViewCache().recycleView(view.getSourceLayoutResId(), view);
         }
         view.setTag(null);
@@ -316,8 +319,8 @@
             boolean isCollection = false;
             if (hotseatItemInfo.isPredictedItem()) {
                 expectedLayoutResId = R.layout.taskbar_predicted_app_icon;
-            } else if (hotseatItemInfo instanceof FolderInfo fi) {
-                expectedLayoutResId = fi.itemType == ITEM_TYPE_APP_PAIR
+            } else if (hotseatItemInfo instanceof CollectionInfo ci) {
+                expectedLayoutResId = ci.itemType == ITEM_TYPE_APP_PAIR
                         ? R.layout.app_pair_icon
                         : R.layout.folder_icon;
                 isCollection = true;
@@ -345,17 +348,18 @@
 
             if (hotseatView == null) {
                 if (isCollection) {
-                    FolderInfo folderInfo = (FolderInfo) hotseatItemInfo;
+                    CollectionInfo collectionInfo = (CollectionInfo) hotseatItemInfo;
                     switch (hotseatItemInfo.itemType) {
                         case ITEM_TYPE_FOLDER:
                             hotseatView = FolderIcon.inflateFolderAndIcon(
-                                    expectedLayoutResId, mActivityContext, this, folderInfo);
+                                    expectedLayoutResId, mActivityContext, this,
+                                    (FolderInfo) collectionInfo);
                             ((FolderIcon) hotseatView).setTextVisible(false);
                             break;
                         case ITEM_TYPE_APP_PAIR:
                             hotseatView = AppPairIcon.inflateIcon(
-                                    expectedLayoutResId, mActivityContext, this, folderInfo,
-                                    BubbleTextView.DISPLAY_TASKBAR);
+                                    expectedLayoutResId, mActivityContext, this,
+                                    (AppPairInfo) collectionInfo, DISPLAY_TASKBAR);
                             ((AppPairIcon) hotseatView).setTextVisible(false);
                             break;
                         default:
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java
index 4b1963b..1f7f0a7 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java
@@ -813,8 +813,8 @@
      * 3) All Apps button
      */
     public View getFirstIconMatch(Predicate<ItemInfo> matcher) {
-        Predicate<ItemInfo> folderMatcher = ItemInfoMatcher.forFolderMatch(matcher);
-        return mTaskbarView.getFirstMatch(matcher, folderMatcher);
+        Predicate<ItemInfo> collectionMatcher = ItemInfoMatcher.forFolderMatch(matcher);
+        return mTaskbarView.getFirstMatch(matcher, collectionMatcher);
     }
 
     /**
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarBackground.kt b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarBackground.kt
index 79fdeda..8eeb055 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarBackground.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarBackground.kt
@@ -15,6 +15,7 @@
  */
 package com.android.launcher3.taskbar.bubbles
 
+import android.content.Context
 import android.graphics.Canvas
 import android.graphics.Color
 import android.graphics.ColorFilter
@@ -27,12 +28,10 @@
 import com.android.launcher3.Utilities
 import com.android.launcher3.Utilities.mapToRange
 import com.android.launcher3.icons.GraphicsUtils.setColorAlphaBound
-import com.android.launcher3.taskbar.TaskbarActivityContext
 import com.android.wm.shell.common.TriangleShape
 
 /** Drawable for the background of the bubble bar. */
-class BubbleBarBackground(context: TaskbarActivityContext, private val backgroundHeight: Float) :
-    Drawable() {
+class BubbleBarBackground(context: Context, private val backgroundHeight: Float) : Drawable() {
 
     private val DARK_THEME_SHADOW_ALPHA = 51f
     private val LIGHT_THEME_SHADOW_ALPHA = 25f
@@ -46,6 +45,7 @@
 
     var arrowPositionX: Float = 0f
         private set
+
     private var showingArrow: Boolean = false
     private var arrowDrawable: ShapeDrawable
 
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarPinController.kt b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarPinController.kt
new file mode 100644
index 0000000..8ed9949
--- /dev/null
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarPinController.kt
@@ -0,0 +1,104 @@
+/*
+ * 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.taskbar.bubbles
+
+import android.annotation.SuppressLint
+import android.content.Context
+import android.graphics.Point
+import android.graphics.RectF
+import android.view.Gravity.BOTTOM
+import android.view.Gravity.LEFT
+import android.view.Gravity.RIGHT
+import android.view.LayoutInflater
+import android.view.View
+import android.widget.FrameLayout
+import androidx.core.view.updateLayoutParams
+import com.android.launcher3.R
+import com.android.wm.shell.common.bubbles.BaseBubblePinController
+import com.android.wm.shell.common.bubbles.BubbleBarLocation
+
+/**
+ * Controller to manage pinning bubble bar to left or right when dragging starts from the bubble bar
+ */
+class BubbleBarPinController(
+    private val context: Context,
+    private val container: FrameLayout,
+    private val screenSizeProvider: () -> Point
+) : BaseBubblePinController() {
+
+    private lateinit var bubbleBarViewController: BubbleBarViewController
+    private lateinit var bubbleStashController: BubbleStashController
+    private var dropTargetView: View? = null
+
+    fun init(bubbleControllers: BubbleControllers) {
+        bubbleBarViewController = bubbleControllers.bubbleBarViewController
+        bubbleStashController = bubbleControllers.bubbleStashController
+    }
+
+    override fun getScreenCenterX(): Int {
+        return screenSizeProvider.invoke().x / 2
+    }
+
+    override fun getExclusionRect(): RectF {
+        val rect =
+            RectF(
+                0f,
+                0f,
+                context.resources.getDimension(R.dimen.bubblebar_dismiss_zone_width),
+                context.resources.getDimension(R.dimen.bubblebar_dismiss_zone_height)
+            )
+        val screenSize = screenSizeProvider.invoke()
+        val middleX = screenSize.x / 2
+        // Center it around the bottom center of the screen
+        rect.offsetTo(middleX - rect.width() / 2, screenSize.y - rect.height())
+        return rect
+    }
+
+    override fun createDropTargetView(): View {
+        return LayoutInflater.from(context)
+            .inflate(R.layout.bubble_bar_drop_target, container, false)
+            .also { view ->
+                dropTargetView = view
+                container.addView(view)
+            }
+    }
+
+    override fun getDropTargetView(): View? {
+        return dropTargetView
+    }
+
+    override fun removeDropTargetView(view: View) {
+        container.removeView(view)
+        dropTargetView = null
+    }
+
+    @SuppressLint("RtlHardcoded")
+    override fun updateLocation(location: BubbleBarLocation) {
+        val onLeft = location.isOnLeft(container.isLayoutRtl)
+
+        val bounds = bubbleBarViewController.bubbleBarBounds
+        val horizontalMargin = bubbleBarViewController.horizontalMargin
+        dropTargetView?.updateLayoutParams<FrameLayout.LayoutParams> {
+            width = bounds.width()
+            height = bounds.height()
+            gravity = BOTTOM or (if (onLeft) LEFT else RIGHT)
+            leftMargin = horizontalMargin
+            rightMargin = horizontalMargin
+            bottomMargin = -bubbleStashController.bubbleBarTranslationY.toInt()
+        }
+    }
+}
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarView.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarView.java
index a5da65f..4ca7c89 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarView.java
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarView.java
@@ -39,8 +39,6 @@
 
 import com.android.launcher3.R;
 import com.android.launcher3.anim.SpringAnimationBuilder;
-import com.android.launcher3.taskbar.TaskbarActivityContext;
-import com.android.launcher3.views.ActivityContext;
 import com.android.wm.shell.common.bubbles.BubbleBarLocation;
 
 import java.util.List;
@@ -159,8 +157,6 @@
 
     public BubbleBarView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
         super(context, attrs, defStyleAttr, defStyleRes);
-        TaskbarActivityContext activityContext = ActivityContext.lookupContext(context);
-
         setAlpha(0);
         setVisibility(INVISIBLE);
         mIconOverlapAmount = getResources().getDimensionPixelSize(R.dimen.bubblebar_icon_overlap);
@@ -171,7 +167,7 @@
 
         setClipToPadding(false);
 
-        mBubbleBarBackground = new BubbleBarBackground(activityContext,
+        mBubbleBarBackground = new BubbleBarBackground(context,
                 getResources().getDimensionPixelSize(R.dimen.bubblebar_size));
         setBackgroundDrawable(mBubbleBarBackground);
 
@@ -379,6 +375,36 @@
         return mRelativePivotY;
     }
 
+    /** Prepares for animating a bubble while being stashed. */
+    public void prepareForAnimatingBubbleWhileStashed(String bubbleKey) {
+        // 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.
+        setBackground(null);
+        for (int i = 0; i < getChildCount(); i++) {
+            final BubbleView view = (BubbleView) getChildAt(i);
+            final String key = view.getBubble().getKey();
+            if (!bubbleKey.equals(key)) {
+                view.setVisibility(INVISIBLE);
+            }
+        }
+        setVisibility(VISIBLE);
+        setAlpha(1);
+        setTranslationY(0);
+        setScaleX(1);
+        setScaleY(1);
+    }
+
+    /** Resets the state after the bubble animation completed. */
+    public void onAnimatingBubbleCompleted() {
+        setBackground(mBubbleBarBackground);
+        for (int i = 0; i < getChildCount(); i++) {
+            final BubbleView view = (BubbleView) getChildAt(i);
+            view.setVisibility(VISIBLE);
+            view.setAlpha(1f);
+        }
+    }
+
     // TODO: (b/280605790) animate it
     @Override
     public void addView(View child, int index, ViewGroup.LayoutParams params) {
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java
index 0f019a3..96d91ea 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java
@@ -34,6 +34,7 @@
 import com.android.launcher3.taskbar.TaskbarControllers;
 import com.android.launcher3.taskbar.TaskbarInsetsController;
 import com.android.launcher3.taskbar.TaskbarStashController;
+import com.android.launcher3.taskbar.bubbles.animation.BubbleBarViewAnimator;
 import com.android.launcher3.util.MultiPropertyFactory;
 import com.android.launcher3.util.MultiValueAlpha;
 import com.android.quickstep.SystemUiProxy;
@@ -81,6 +82,8 @@
     private boolean mHiddenForNoBubbles = true;
     private boolean mShouldShowEducation;
 
+    private BubbleBarViewAnimator mBubbleBarViewAnimator;
+
     public BubbleBarViewController(TaskbarActivityContext activity, BubbleBarView barView) {
         mActivity = activity;
         mBarView = barView;
@@ -113,6 +116,8 @@
         mBarView.addOnLayoutChangeListener((view, i, i1, i2, i3, i4, i5, i6, i7) ->
                 mTaskbarInsetsController.onTaskbarOrBubblebarWindowHeightOrInsetsChanged()
         );
+
+        mBubbleBarViewAnimator = new BubbleBarViewAnimator(mBarView, mBubbleStashController);
     }
 
     private void onBubbleClicked(View v) {
@@ -316,6 +321,12 @@
                     new FrameLayout.LayoutParams(mIconSize, mIconSize, Gravity.LEFT));
             b.getView().setOnClickListener(mBubbleClickListener);
             mBubbleDragController.setupBubbleView(b.getView());
+
+            boolean isStashedOrGone =
+                    mBubbleStashController.isStashed() || mBarView.getVisibility() != VISIBLE;
+            if (b instanceof BubbleBarBubble && isStashedOrGone) {
+                mBubbleBarViewAnimator.animateBubbleInForStashed((BubbleBarBubble) b);
+            }
         } else {
             Log.w(TAG, "addBubble, bubble was null!");
         }
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleControllers.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleControllers.java
index c47427d..90f1be3 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleControllers.java
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleControllers.java
@@ -29,6 +29,7 @@
     public final BubbleStashedHandleViewController bubbleStashedHandleViewController;
     public final BubbleDragController bubbleDragController;
     public final BubbleDismissController bubbleDismissController;
+    public final BubbleBarPinController bubbleBarPinController;
 
     private final RunnableList mPostInitRunnables = new RunnableList();
 
@@ -43,13 +44,15 @@
             BubbleStashController bubbleStashController,
             BubbleStashedHandleViewController bubbleStashedHandleViewController,
             BubbleDragController bubbleDragController,
-            BubbleDismissController bubbleDismissController) {
+            BubbleDismissController bubbleDismissController,
+            BubbleBarPinController bubbleBarPinController) {
         this.bubbleBarController = bubbleBarController;
         this.bubbleBarViewController = bubbleBarViewController;
         this.bubbleStashController = bubbleStashController;
         this.bubbleStashedHandleViewController = bubbleStashedHandleViewController;
         this.bubbleDragController = bubbleDragController;
         this.bubbleDismissController = bubbleDismissController;
+        this.bubbleBarPinController = bubbleBarPinController;
     }
 
     /**
@@ -64,6 +67,7 @@
         bubbleStashController.init(taskbarControllers, this);
         bubbleDragController.init(/* bubbleControllers = */ this);
         bubbleDismissController.init(/* bubbleControllers = */ this);
+        bubbleBarPinController.init(this);
 
         mPostInitRunnables.executeAllAndDestroy();
     }
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleDismissController.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleDismissController.java
index 73c71c8..a40f33c 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleDismissController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleDismissController.java
@@ -67,6 +67,9 @@
     @Nullable
     private BubbleDragAnimator mAnimator;
 
+    @Nullable
+    private Listener mListener;
+
     public BubbleDismissController(TaskbarActivityContext activity, TaskbarDragLayer dragLayer) {
         mActivity = activity;
         mDragLayer = dragLayer;
@@ -82,6 +85,13 @@
     }
 
     /**
+     * Set listener to be notified of dismiss events
+     */
+    public void setListener(@Nullable Listener listener) {
+        mListener = listener;
+    }
+
+    /**
      * Setup the dismiss view and magnetized object that will be attracted to magnetic target.
      * Should be called before handling events or showing/hiding dismiss view.
      *
@@ -189,6 +199,9 @@
                     @NonNull MagnetizedObject<?> draggedObject) {
                 if (mAnimator == null) return;
                 mAnimator.animateDismissCaptured();
+                if (mListener != null) {
+                    mListener.onStuckToDismissChanged(true /* stuck */);
+                }
             }
 
             @Override
@@ -197,6 +210,9 @@
                     float velX, float velY, boolean wasFlungOut) {
                 if (mAnimator == null) return;
                 mAnimator.animateDismissReleased();
+                if (mListener != null) {
+                    mListener.onStuckToDismissChanged(false /* stuck */);
+                }
             }
 
             @Override
@@ -206,4 +222,10 @@
             }
         });
     }
+
+    /** Interface to receive updates about the dismiss state */
+    public interface Listener {
+        /** Called when view is stuck or unstuck from dismiss target */
+        void onStuckToDismissChanged(boolean stuck);
+    }
 }
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleDragController.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleDragController.java
index 08fd681..dab7d9d 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleDragController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleDragController.java
@@ -25,10 +25,11 @@
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 
+import com.android.launcher3.R;
 import com.android.launcher3.taskbar.TaskbarActivityContext;
 
 /**
- * Controls bubble bar drag to dismiss interaction.
+ * Controls bubble bar drag interactions.
  * Interacts with {@link BubbleDismissController}, used by {@link BubbleBarViewController}.
  * Supported interactions:
  * - Drag a single bubble view into dismiss target to remove it.
@@ -39,6 +40,7 @@
     private final TaskbarActivityContext mActivity;
     private BubbleBarViewController mBubbleBarViewController;
     private BubbleDismissController mBubbleDismissController;
+    private BubbleBarPinController mBubbleBarPinController;
 
     public BubbleDragController(TaskbarActivityContext activity) {
         mActivity = activity;
@@ -52,6 +54,12 @@
     public void init(@NonNull BubbleControllers bubbleControllers) {
         mBubbleBarViewController = bubbleControllers.bubbleBarViewController;
         mBubbleDismissController = bubbleControllers.bubbleDismissController;
+        mBubbleBarPinController = bubbleControllers.bubbleBarPinController;
+        mBubbleBarPinController.setListener(location -> {
+            // TODO(b/330585397): update bubble bar location in shell
+        });
+        mBubbleDismissController.setListener(
+                stuck -> mBubbleBarPinController.setDropTargetHidden(stuck));
     }
 
     /**
@@ -88,6 +96,10 @@
     @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) {
@@ -102,12 +114,31 @@
                 // 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);
+                mBubbleBarPinController.onDragStart(
+                        bubbleBarView.getBubbleBarLocation().isOnLeft(bubbleBarView.isLayoutRtl()));
+            }
+
+            @Override
+            protected void onDragUpdate(float x, float y) {
+                mBubbleBarPinController.onDragUpdate(x, y);
+            }
+
+            @Override
+            protected void onDragRelease() {
+                mBubbleBarPinController.onDragEnd();
+            }
+
+            @Override
+            protected void onDragDismiss() {
+                mBubbleBarPinController.onDragEnd();
             }
 
             @Override
             void onDragEnd() {
                 // Restoring the initial pivot for the bubble bar view
                 bubbleBarView.setRelativePivot(initialRelativePivot.x, initialRelativePivot.y);
+                bubbleBarView.setElevation(restingElevation);
             }
         });
     }
@@ -170,6 +201,13 @@
         abstract void onDragStart();
 
         /**
+         * Called when bubble is dragged to new coordinates.
+         * Not called while bubble is stuck to the dismiss target.
+         */
+        protected void onDragUpdate(float x, float y) {
+        }
+
+        /**
          * Called when the dragging interaction has ended and all the animations have completed
          */
         abstract void onDragEnd();
@@ -232,8 +270,10 @@
          * @param event the motion event
          */
         protected void onTouchMove(@NonNull View view, @NonNull MotionEvent event) {
-            final float dx = event.getRawX() - mTouchDownLocation.x;
-            final float dy = event.getRawY() - mTouchDownLocation.y;
+            float rawX = event.getRawX();
+            float rawY = event.getRawY();
+            final float dx = rawX - mTouchDownLocation.x;
+            final float dy = rawY - mTouchDownLocation.y;
             switch (mState) {
                 case TOUCHED:
                     final boolean movedOut = Math.hypot(dx, dy) > mTouchSlop;
@@ -244,7 +284,7 @@
                     }
                     break;
                 case DRAGGING:
-                    drag(view, event, dx, dy);
+                    drag(view, event, dx, dy, rawX, rawY);
                     break;
             }
         }
@@ -293,10 +333,12 @@
             mBubbleDismissController.showDismissView();
         }
 
-        private void drag(@NonNull View view, @NonNull MotionEvent event, float dx, float dy) {
+        private void drag(@NonNull View view, @NonNull MotionEvent event, float dx, float dy,
+                float x, float y) {
             if (mBubbleDismissController.handleTouchEvent(event)) return;
             view.setTranslationX(mViewInitialPosition.x + dx);
             view.setTranslationY(mViewInitialPosition.y + dy);
+            onDragUpdate(x, y);
         }
 
         private void stopDragging(@NonNull View view, @NonNull MotionEvent event) {
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleView.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleView.java
index 6549ad6..bcdc718 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleView.java
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleView.java
@@ -145,7 +145,7 @@
     }
 
     /** Sets the bubble being rendered in this view. */
-    void setBubble(BubbleBarBubble bubble) {
+    public void setBubble(BubbleBarBubble bubble) {
         mBubble = bubble;
         mBubbleIcon.setImageBitmap(bubble.getIcon());
         mAppIcon.setImageBitmap(bubble.getBadge());
@@ -159,7 +159,7 @@
      * the list of bubbles. It doesn't show an app icon because it is part of system UI / doesn't
      * come from an app.
      */
-    void setOverflow(BubbleBarOverflow overflow, Bitmap bitmap) {
+    public void setOverflow(BubbleBarOverflow overflow, Bitmap bitmap) {
         mBubble = overflow;
         mBubbleIcon.setImageBitmap(bitmap);
         mAppIcon.setVisibility(GONE); // Overflow doesn't show the app badge
@@ -168,7 +168,7 @@
 
     /** Returns the bubble being rendered in this view. */
     @Nullable
-    BubbleBarItem getBubble() {
+    public BubbleBarItem getBubble() {
         return mBubble;
     }
 
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/animation/BubbleBarViewAnimator.kt b/quickstep/src/com/android/launcher3/taskbar/bubbles/animation/BubbleBarViewAnimator.kt
new file mode 100644
index 0000000..bcb9f4d
--- /dev/null
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/animation/BubbleBarViewAnimator.kt
@@ -0,0 +1,118 @@
+/*
+ * 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.taskbar.bubbles.animation
+
+import android.view.View
+import android.view.View.VISIBLE
+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.wm.shell.shared.animation.PhysicsAnimator
+
+/** Handles animations for bubble bar bubbles. */
+class BubbleBarViewAnimator
+@JvmOverloads
+constructor(
+    private val bubbleBarView: BubbleBarView,
+    private val bubbleStashController: BubbleStashController,
+    private val scheduler: Scheduler = HandlerScheduler(bubbleBarView)
+) {
+
+    private companion object {
+        /** 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
+    }
+
+    /** An interface for scheduling jobs. */
+    interface Scheduler {
+
+        /** Schedule the given [block] to run. */
+        fun post(block: () -> Unit)
+
+        /** Schedule the given [block] to start with a delay of [delayMillis]. */
+        fun postDelayed(delayMillis: Long, block: () -> Unit)
+    }
+
+    /** A [Scheduler] that uses a Handler to run jobs. */
+    private class HandlerScheduler(private val view: View) : Scheduler {
+
+        override fun post(block: () -> Unit) {
+            view.post(block)
+        }
+
+        override fun postDelayed(delayMillis: Long, block: () -> Unit) {
+            view.postDelayed(block, delayMillis)
+        }
+    }
+
+    private val springConfig =
+        PhysicsAnimator.SpringConfig(
+            stiffness = SpringForce.STIFFNESS_LOW,
+            dampingRatio = SpringForce.DAMPING_RATIO_MEDIUM_BOUNCY
+        )
+
+    /** Animates a bubble for the state where the bubble bar is stashed. */
+    fun animateBubbleInForStashed(b: BubbleBarBubble) {
+        val bubbleView = b.view
+        val animator = PhysicsAnimator.getInstance(bubbleView)
+        if (animator.isRunning()) animator.cancel()
+        // 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)
+        scheduler.post(showAnimation)
+        scheduler.postDelayed(FLYOUT_DELAY_MS, hideAnimation)
+    }
+
+    /** Returns a lambda that starts the animation that shows the new bubble. */
+    private fun buildShowAnimation(
+        bubbleView: BubbleView,
+        key: String,
+        animator: PhysicsAnimator<BubbleView>
+    ): () -> Unit = {
+        bubbleBarView.prepareForAnimatingBubbleWhileStashed(key)
+        animator.setDefaultSpringConfig(springConfig)
+        animator
+            .spring(DynamicAnimation.ALPHA, 1f)
+            .spring(DynamicAnimation.TRANSLATION_Y, BUBBLE_ANIMATION_TRANSLATION_Y)
+        bubbleView.alpha = 0f
+        bubbleView.visibility = VISIBLE
+        animator.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()
+                }
+            }
+        animator.start()
+    }
+}
diff --git a/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java b/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java
index d265918..e078a49 100644
--- a/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java
+++ b/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java
@@ -61,7 +61,7 @@
 import com.android.launcher3.model.AllAppsList;
 import com.android.launcher3.model.BaseModelUpdateTask;
 import com.android.launcher3.model.BgDataModel;
-import com.android.launcher3.model.data.FolderInfo;
+import com.android.launcher3.model.data.CollectionInfo;
 import com.android.launcher3.model.data.ItemInfo;
 import com.android.launcher3.util.Executors;
 import com.android.launcher3.util.LogConfig;
@@ -375,7 +375,7 @@
                 Executors.MODEL_EXECUTOR.execute(
                         () -> write(event, applyOverwrites(mItemInfo.buildProto())));
             } else {
-                // Item is inside the folder, fetch folder info in a BG thread
+                // Item is inside a collection, fetch collection info in a BG thread
                 // and then write to StatsLog.
                 appState.getModel().enqueueModelUpdateTask(
                         new BaseModelUpdateTask() {
@@ -383,8 +383,9 @@
                             public void execute(@NonNull final LauncherAppState app,
                                     @NonNull final BgDataModel dataModel,
                                     @NonNull final AllAppsList apps) {
-                                FolderInfo folderInfo = dataModel.folders.get(mItemInfo.container);
-                                write(event, applyOverwrites(mItemInfo.buildProto(folderInfo)));
+                                CollectionInfo collectionInfo =
+                                        dataModel.collections.get(mItemInfo.container);
+                                write(event, applyOverwrites(mItemInfo.buildProto(collectionInfo)));
                             }
                         });
             }
diff --git a/quickstep/src/com/android/quickstep/util/AppPairsController.java b/quickstep/src/com/android/quickstep/util/AppPairsController.java
index ecb6118..f4da867 100644
--- a/quickstep/src/com/android/quickstep/util/AppPairsController.java
+++ b/quickstep/src/com/android/quickstep/util/AppPairsController.java
@@ -53,7 +53,7 @@
 import com.android.launcher3.logging.InstanceId;
 import com.android.launcher3.logging.StatsLogManager;
 import com.android.launcher3.model.data.AppInfo;
-import com.android.launcher3.model.data.FolderInfo;
+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.taskbar.TaskbarActivityContext;
@@ -149,25 +149,17 @@
 
         app1.rank = encodeRank(SPLIT_POSITION_TOP_OR_LEFT, snapPosition);
         app2.rank = encodeRank(SPLIT_POSITION_BOTTOM_OR_RIGHT, snapPosition);
-        FolderInfo newAppPair = FolderInfo.createAppPair(app1, app2);
-
-        if (newAppPair.contents.size() != 2) {
-            // if app pair doesn't have exactly 2 members, log an error and do not create the app
-            // pair.
-            Log.wtf(TAG,
-                    "tried to save an app pair with " + newAppPair.contents.size() + " members");
-            return;
-        }
+        AppPairInfo newAppPair = new AppPairInfo(app1, app2);
 
         IconCache iconCache = LauncherAppState.getInstance(mContext).getIconCache();
         MODEL_EXECUTOR.execute(() -> {
-            newAppPair.contents.forEach(member -> {
+            newAppPair.getContents().forEach(member -> {
                 member.title = "";
                 member.bitmap = iconCache.getDefaultIcon(newAppPair.user);
                 iconCache.getTitleAndIcon(member, member.usingLowResIcon());
             });
-            newAppPair.title = getDefaultTitle(newAppPair.contents.get(0).title,
-                    newAppPair.contents.get(1).title);
+            newAppPair.title = getDefaultTitle(newAppPair.getFirstApp().title,
+                    newAppPair.getSecondApp().title);
             MAIN_EXECUTOR.execute(() -> {
                 LauncherAccessibilityDelegate delegate =
                         Launcher.getLauncher(mContext).getAccessibilityDelegate();
@@ -194,8 +186,8 @@
      *            monitoring
      */
     public void launchAppPair(AppPairIcon appPairIcon, int cuj) {
-        WorkspaceItemInfo app1 = appPairIcon.getInfo().contents.get(0);
-        WorkspaceItemInfo app2 = appPairIcon.getInfo().contents.get(1);
+        WorkspaceItemInfo app1 = appPairIcon.getInfo().getFirstApp();
+        WorkspaceItemInfo app2 = appPairIcon.getInfo().getSecondApp();
         ComponentKey app1Key = new ComponentKey(app1.getTargetComponent(), app1.user);
         ComponentKey app2Key = new ComponentKey(app2.getTargetComponent(), app2.user);
         mSplitSelectStateController.setLaunchingCuj(cuj);
diff --git a/quickstep/src/com/android/quickstep/util/SplitAnimationController.kt b/quickstep/src/com/android/quickstep/util/SplitAnimationController.kt
index 8f5c9c1..6b27004 100644
--- a/quickstep/src/com/android/quickstep/util/SplitAnimationController.kt
+++ b/quickstep/src/com/android/quickstep/util/SplitAnimationController.kt
@@ -659,8 +659,8 @@
 
         // Create a new floating view in Launcher, positioned above the launching icon
         val drawableArea = launchingIconView.iconDrawableArea
-        val appIcon1 = launchingIconView.info.contents[0].newIcon(launchingIconView.context)
-        val appIcon2 = launchingIconView.info.contents[1].newIcon(launchingIconView.context)
+        val appIcon1 = launchingIconView.info.getFirstApp().newIcon(launchingIconView.context)
+        val appIcon2 = launchingIconView.info.getSecondApp().newIcon(launchingIconView.context)
         appIcon1.setBounds(0, 0, dp.iconSizePx, dp.iconSizePx)
         appIcon2.setBounds(0, 0, dp.iconSizePx, dp.iconSizePx)
         val floatingView =
diff --git a/quickstep/src/com/android/quickstep/util/SplitToWorkspaceController.java b/quickstep/src/com/android/quickstep/util/SplitToWorkspaceController.java
index 87be091..2282c46 100644
--- a/quickstep/src/com/android/quickstep/util/SplitToWorkspaceController.java
+++ b/quickstep/src/com/android/quickstep/util/SplitToWorkspaceController.java
@@ -16,7 +16,6 @@
 
 package com.android.quickstep.util;
 
-import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_APP_PAIR;
 import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
 import static com.android.window.flags.Flags.enableDesktopWindowingMode;
 
@@ -44,7 +43,7 @@
 import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.icons.BitmapInfo;
 import com.android.launcher3.icons.IconCache;
-import com.android.launcher3.model.data.FolderInfo;
+import com.android.launcher3.model.data.AppPairInfo;
 import com.android.launcher3.model.data.ItemInfo;
 import com.android.launcher3.model.data.PackageItemInfo;
 import com.android.launcher3.model.data.WorkspaceItemInfo;
@@ -126,7 +125,7 @@
             intent = appInfo.intent;
             user = appInfo.user;
             bitmapInfo = appInfo.bitmap;
-        } else if (tag instanceof FolderInfo fi && fi.itemType == ITEM_TYPE_APP_PAIR) {
+        } else if (tag instanceof AppPairInfo) {
             // Prompt the user to select something else by wiggling the instructions view
             mController.getSplitInstructionsView().goBoing();
             return true;
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
new file mode 100644
index 0000000..c17aeaa
--- /dev/null
+++ b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/bubbles/animation/BubbleBarViewAnimatorTest.kt
@@ -0,0 +1,142 @@
+/*
+ * 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.taskbar.bubbles.animation
+
+import android.content.Context
+import android.graphics.Color
+import android.graphics.Path
+import android.graphics.drawable.ColorDrawable
+import android.view.LayoutInflater
+import android.view.View.INVISIBLE
+import android.view.View.VISIBLE
+import android.widget.FrameLayout
+import androidx.core.graphics.drawable.toBitmap
+import androidx.dynamicanimation.animation.DynamicAnimation
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import androidx.test.platform.app.InstrumentationRegistry
+import com.android.launcher3.R
+import com.android.launcher3.taskbar.bubbles.BubbleBarBubble
+import com.android.launcher3.taskbar.bubbles.BubbleBarOverflow
+import com.android.launcher3.taskbar.bubbles.BubbleBarView
+import com.android.launcher3.taskbar.bubbles.BubbleStashController
+import com.android.launcher3.taskbar.bubbles.BubbleView
+import com.android.wm.shell.common.bubbles.BubbleInfo
+import com.android.wm.shell.shared.animation.PhysicsAnimatorTestUtils
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.whenever
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class BubbleBarViewAnimatorTest {
+
+    private val context = ApplicationProvider.getApplicationContext<Context>()
+    private val animatorScheduler = TestBubbleBarViewAnimatorScheduler()
+
+    @Before
+    fun setUp() {
+        PhysicsAnimatorTestUtils.prepareForTest()
+    }
+
+    @Test
+    fun animateBubbleInForStashed() {
+        lateinit var overflowView: BubbleView
+        lateinit var bubbleView: BubbleView
+        lateinit var bubble: BubbleBarBubble
+        val bubbleBarView = BubbleBarView(context)
+        InstrumentationRegistry.getInstrumentation().runOnMainSync {
+            bubbleBarView.layoutParams = FrameLayout.LayoutParams(0, 0)
+            val inflater = LayoutInflater.from(context)
+
+            val bitmap = ColorDrawable(Color.WHITE).toBitmap(width = 20, height = 20)
+            overflowView =
+                inflater.inflate(R.layout.bubblebar_item_view, bubbleBarView, false) as BubbleView
+            overflowView.setOverflow(BubbleBarOverflow(overflowView), bitmap)
+            bubbleBarView.addView(overflowView)
+
+            val bubbleInfo = BubbleInfo("key", 0, null, null, 0, context.packageName, null, false)
+            bubbleView =
+                inflater.inflate(R.layout.bubblebar_item_view, bubbleBarView, false) as BubbleView
+            bubble =
+                BubbleBarBubble(bubbleInfo, bubbleView, bitmap, bitmap, Color.WHITE, Path(), "")
+            bubbleView.setBubble(bubble)
+            bubbleBarView.addView(bubbleView)
+        }
+        InstrumentationRegistry.getInstrumentation().waitForIdleSync()
+
+        val bubbleStashController = mock<BubbleStashController>()
+        whenever(bubbleStashController.isStashed).thenReturn(true)
+
+        val animator =
+            BubbleBarViewAnimator(bubbleBarView, bubbleStashController, animatorScheduler)
+
+        InstrumentationRegistry.getInstrumentation().runOnMainSync {
+            animator.animateBubbleInForStashed(bubble)
+        }
+
+        InstrumentationRegistry.getInstrumentation().waitForIdleSync()
+
+        assertThat(overflowView.visibility).isEqualTo(INVISIBLE)
+        assertThat(bubbleBarView.visibility).isEqualTo(VISIBLE)
+        assertThat(bubbleView.visibility).isEqualTo(VISIBLE)
+
+        PhysicsAnimatorTestUtils.blockUntilAnimationsEnd(
+            DynamicAnimation.ALPHA,
+            DynamicAnimation.TRANSLATION_Y
+        )
+
+        assertThat(bubbleView.alpha).isEqualTo(1)
+        assertThat(bubbleView.translationY).isEqualTo(-50)
+
+        assertThat(animatorScheduler.delayedBlock).isNotNull()
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(animatorScheduler.delayedBlock!!)
+
+        InstrumentationRegistry.getInstrumentation().waitForIdleSync()
+
+        PhysicsAnimatorTestUtils.blockUntilAnimationsEnd(
+            DynamicAnimation.ALPHA,
+            DynamicAnimation.TRANSLATION_Y
+        )
+
+        assertThat(bubbleView.alpha).isEqualTo(1)
+        assertThat(bubbleView.visibility).isEqualTo(VISIBLE)
+        assertThat(bubbleView.translationY).isEqualTo(0)
+        assertThat(bubbleBarView.alpha).isEqualTo(0)
+        assertThat(overflowView.alpha).isEqualTo(1)
+        assertThat(overflowView.visibility).isEqualTo(VISIBLE)
+    }
+
+    private class TestBubbleBarViewAnimatorScheduler : BubbleBarViewAnimator.Scheduler {
+
+        var delayedBlock: (() -> Unit)? = null
+            private set
+
+        override fun post(block: () -> Unit) {
+            block.invoke()
+        }
+
+        override fun postDelayed(delayMillis: Long, block: () -> Unit) {
+            check(delayedBlock == null) { "there is already a pending block waiting to run" }
+            delayedBlock = block
+        }
+    }
+}
diff --git a/res/values-am/strings.xml b/res/values-am/strings.xml
index a19ea97..2121e40 100644
--- a/res/values-am/strings.xml
+++ b/res/values-am/strings.xml
@@ -188,8 +188,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..30284b0 100644
--- a/res/values-ar/strings.xml
+++ b/res/values-ar/strings.xml
@@ -29,7 +29,7 @@
     <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>
@@ -188,8 +188,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..f7775ab 100644
--- a/res/values-as/strings.xml
+++ b/res/values-as/strings.xml
@@ -188,8 +188,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..d9f4acd 100644
--- a/res/values-az/strings.xml
+++ b/res/values-az/strings.xml
@@ -188,8 +188,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..2ae1c59 100644
--- a/res/values-b+sr+Latn/strings.xml
+++ b/res/values-b+sr+Latn/strings.xml
@@ -43,7 +43,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>
@@ -188,8 +188,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..c5147ed 100644
--- a/res/values-be/strings.xml
+++ b/res/values-be/strings.xml
@@ -188,8 +188,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..ae94d14 100644
--- a/res/values-bg/strings.xml
+++ b/res/values-bg/strings.xml
@@ -188,8 +188,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..d25b9c5 100644
--- a/res/values-bn/strings.xml
+++ b/res/values-bn/strings.xml
@@ -188,8 +188,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..42365c1 100644
--- a/res/values-bs/strings.xml
+++ b/res/values-bs/strings.xml
@@ -188,8 +188,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 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>
diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml
index 4ffd4bb..933084f 100644
--- a/res/values-ca/strings.xml
+++ b/res/values-ca/strings.xml
@@ -118,7 +118,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,8 +188,7 @@
     <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>
diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml
index 61521ae..267f40b 100644
--- a/res/values-cs/strings.xml
+++ b/res/values-cs/strings.xml
@@ -188,8 +188,7 @@
     <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>
diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml
index f85a2a9..65347e0 100644
--- a/res/values-da/strings.xml
+++ b/res/values-da/strings.xml
@@ -188,8 +188,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-el/strings.xml b/res/values-el/strings.xml
index 04e42b2..838ccc7 100644
--- a/res/values-el/strings.xml
+++ b/res/values-el/strings.xml
@@ -188,8 +188,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-es-rUS/strings.xml b/res/values-es-rUS/strings.xml
index c377990..02335ab 100644
--- a/res/values-es-rUS/strings.xml
+++ b/res/values-es-rUS/strings.xml
@@ -188,8 +188,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..9e494ad 100644
--- a/res/values-es/strings.xml
+++ b/res/values-es/strings.xml
@@ -188,8 +188,7 @@
     <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>
diff --git a/res/values-et/strings.xml b/res/values-et/strings.xml
index 610c243..4cbf751 100644
--- a/res/values-et/strings.xml
+++ b/res/values-et/strings.xml
@@ -188,8 +188,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..71ef150 100644
--- a/res/values-eu/strings.xml
+++ b/res/values-eu/strings.xml
@@ -188,8 +188,7 @@
     <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>
diff --git a/res/values-fa/strings.xml b/res/values-fa/strings.xml
index dc48d82..bf9263b 100644
--- a/res/values-fa/strings.xml
+++ b/res/values-fa/strings.xml
@@ -188,8 +188,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..0e8573d 100644
--- a/res/values-fi/strings.xml
+++ b/res/values-fi/strings.xml
@@ -188,8 +188,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/strings.xml b/res/values-fr/strings.xml
index 54ad858..627e996 100644
--- a/res/values-fr/strings.xml
+++ b/res/values-fr/strings.xml
@@ -123,8 +123,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,8 +188,7 @@
     <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>
diff --git a/res/values-gl/strings.xml b/res/values-gl/strings.xml
index 0a7c96c..e330b05 100644
--- a/res/values-gl/strings.xml
+++ b/res/values-gl/strings.xml
@@ -188,8 +188,7 @@
     <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>
diff --git a/res/values-gu/strings.xml b/res/values-gu/strings.xml
index c3be263..912d798 100644
--- a/res/values-gu/strings.xml
+++ b/res/values-gu/strings.xml
@@ -188,8 +188,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..0c4da56 100644
--- a/res/values-hi/strings.xml
+++ b/res/values-hi/strings.xml
@@ -188,8 +188,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..b754e95 100644
--- a/res/values-hr/strings.xml
+++ b/res/values-hr/strings.xml
@@ -188,8 +188,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">"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>
diff --git a/res/values-hy/strings.xml b/res/values-hy/strings.xml
index bdb473b..e1aaad2 100644
--- a/res/values-hy/strings.xml
+++ b/res/values-hy/strings.xml
@@ -188,13 +188,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="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_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..d0b0964 100644
--- a/res/values-in/strings.xml
+++ b/res/values-in/strings.xml
@@ -188,8 +188,7 @@
     <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>
diff --git a/res/values-is/strings.xml b/res/values-is/strings.xml
index 1287322..506d68e 100644
--- a/res/values-is/strings.xml
+++ b/res/values-is/strings.xml
@@ -188,8 +188,7 @@
     <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>
diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml
index 4805748..ed122fe 100644
--- a/res/values-it/strings.xml
+++ b/res/values-it/strings.xml
@@ -188,8 +188,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..b25150a 100644
--- a/res/values-iw/strings.xml
+++ b/res/values-iw/strings.xml
@@ -188,8 +188,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..b8977be 100644
--- a/res/values-ja/strings.xml
+++ b/res/values-ja/strings.xml
@@ -188,8 +188,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..6f7bd9b 100644
--- a/res/values-ka/strings.xml
+++ b/res/values-ka/strings.xml
@@ -188,8 +188,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..4156253 100644
--- a/res/values-kk/strings.xml
+++ b/res/values-kk/strings.xml
@@ -188,8 +188,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..3aca213 100644
--- a/res/values-km/strings.xml
+++ b/res/values-km/strings.xml
@@ -188,8 +188,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..93c63ff 100644
--- a/res/values-kn/strings.xml
+++ b/res/values-kn/strings.xml
@@ -188,8 +188,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..5457674 100644
--- a/res/values-ko/strings.xml
+++ b/res/values-ko/strings.xml
@@ -188,8 +188,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..a0a605e 100644
--- a/res/values-ky/strings.xml
+++ b/res/values-ky/strings.xml
@@ -187,11 +187,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..e3142da 100644
--- a/res/values-lo/strings.xml
+++ b/res/values-lo/strings.xml
@@ -188,8 +188,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..f0573a9 100644
--- a/res/values-lt/strings.xml
+++ b/res/values-lt/strings.xml
@@ -188,8 +188,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..8a4ab47 100644
--- a/res/values-lv/strings.xml
+++ b/res/values-lv/strings.xml
@@ -188,8 +188,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..051ab2e 100644
--- a/res/values-mk/strings.xml
+++ b/res/values-mk/strings.xml
@@ -188,14 +188,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..ce5ccc6 100644
--- a/res/values-ml/strings.xml
+++ b/res/values-ml/strings.xml
@@ -188,8 +188,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..254947a 100644
--- a/res/values-mn/strings.xml
+++ b/res/values-mn/strings.xml
@@ -188,8 +188,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..9e524ac 100644
--- a/res/values-mr/strings.xml
+++ b/res/values-mr/strings.xml
@@ -188,8 +188,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..d2a8732 100644
--- a/res/values-ms/strings.xml
+++ b/res/values-ms/strings.xml
@@ -188,8 +188,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..d32e6f1 100644
--- a/res/values-my/strings.xml
+++ b/res/values-my/strings.xml
@@ -188,8 +188,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-nb/strings.xml b/res/values-nb/strings.xml
index 4a352f5..22002e8 100644
--- a/res/values-nb/strings.xml
+++ b/res/values-nb/strings.xml
@@ -188,8 +188,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..15bc8e4 100644
--- a/res/values-ne/strings.xml
+++ b/res/values-ne/strings.xml
@@ -188,8 +188,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..b2e106c 100644
--- a/res/values-nl/strings.xml
+++ b/res/values-nl/strings.xml
@@ -177,7 +177,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 +188,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..bdd39e1 100644
--- a/res/values-or/strings.xml
+++ b/res/values-or/strings.xml
@@ -188,8 +188,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..2b89ebf 100644
--- a/res/values-pa/strings.xml
+++ b/res/values-pa/strings.xml
@@ -188,8 +188,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..2c7908c 100644
--- a/res/values-pl/strings.xml
+++ b/res/values-pl/strings.xml
@@ -188,8 +188,7 @@
     <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>
diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml
index 07fe3db..2e10d80 100644
--- a/res/values-pt/strings.xml
+++ b/res/values-pt/strings.xml
@@ -188,8 +188,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..81f7250 100644
--- a/res/values-ro/strings.xml
+++ b/res/values-ro/strings.xml
@@ -188,8 +188,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..9c35b9d 100644
--- a/res/values-ru/strings.xml
+++ b/res/values-ru/strings.xml
@@ -188,8 +188,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..506c634 100644
--- a/res/values-si/strings.xml
+++ b/res/values-si/strings.xml
@@ -188,8 +188,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..58e280c 100644
--- a/res/values-sk/strings.xml
+++ b/res/values-sk/strings.xml
@@ -188,8 +188,7 @@
     <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>
diff --git a/res/values-sq/strings.xml b/res/values-sq/strings.xml
index 062a5e1..fe3650a 100644
--- a/res/values-sq/strings.xml
+++ b/res/values-sq/strings.xml
@@ -188,8 +188,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..5bae891 100644
--- a/res/values-sr/strings.xml
+++ b/res/values-sr/strings.xml
@@ -43,7 +43,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>
@@ -188,8 +188,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..5bec2a9 100644
--- a/res/values-sv/strings.xml
+++ b/res/values-sv/strings.xml
@@ -188,8 +188,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..f0c28cd 100644
--- a/res/values-sw/strings.xml
+++ b/res/values-sw/strings.xml
@@ -188,8 +188,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..edca769 100644
--- a/res/values-ta/strings.xml
+++ b/res/values-ta/strings.xml
@@ -188,8 +188,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..20649ad 100644
--- a/res/values-te/strings.xml
+++ b/res/values-te/strings.xml
@@ -188,8 +188,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..05b3910 100644
--- a/res/values-th/strings.xml
+++ b/res/values-th/strings.xml
@@ -188,8 +188,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..0ea7e16 100644
--- a/res/values-tl/strings.xml
+++ b/res/values-tl/strings.xml
@@ -29,7 +29,7 @@
     <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>
@@ -188,8 +188,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..d509343 100644
--- a/res/values-tr/strings.xml
+++ b/res/values-tr/strings.xml
@@ -188,8 +188,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..7f586ba 100644
--- a/res/values-uk/strings.xml
+++ b/res/values-uk/strings.xml
@@ -188,8 +188,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..57cb87f 100644
--- a/res/values-ur/strings.xml
+++ b/res/values-ur/strings.xml
@@ -188,8 +188,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..eacf845 100644
--- a/res/values-uz/strings.xml
+++ b/res/values-uz/strings.xml
@@ -188,8 +188,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..5e76aed 100644
--- a/res/values-vi/strings.xml
+++ b/res/values-vi/strings.xml
@@ -188,8 +188,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..3b1d0c7 100644
--- a/res/values-zh-rCN/strings.xml
+++ b/res/values-zh-rCN/strings.xml
@@ -29,10 +29,10 @@
     <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>
     <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 +188,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..da8b547 100644
--- a/res/values-zh-rHK/strings.xml
+++ b/res/values-zh-rHK/strings.xml
@@ -188,8 +188,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..6a7313f 100644
--- a/res/values-zh-rTW/strings.xml
+++ b/res/values-zh-rTW/strings.xml
@@ -188,8 +188,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..3db9e5d 100644
--- a/res/values-zu/strings.xml
+++ b/res/values-zu/strings.xml
@@ -188,8 +188,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/src/com/android/launcher3/BubbleTextView.java b/src/com/android/launcher3/BubbleTextView.java
index 5d5a28c..4c8ed15 100644
--- a/src/com/android/launcher3/BubbleTextView.java
+++ b/src/com/android/launcher3/BubbleTextView.java
@@ -435,8 +435,7 @@
     }
 
     @UiThread
-    @VisibleForTesting
-    public void applyLabel(ItemInfoWithIcon info) {
+    public void applyLabel(ItemInfo info) {
         CharSequence label = info.title;
         if (label != null) {
             mLastOriginalText = label;
diff --git a/src/com/android/launcher3/DeleteDropTarget.java b/src/com/android/launcher3/DeleteDropTarget.java
index 9a5627a..58789fd 100644
--- a/src/com/android/launcher3/DeleteDropTarget.java
+++ b/src/com/android/launcher3/DeleteDropTarget.java
@@ -27,7 +27,7 @@
 import com.android.launcher3.accessibility.LauncherAccessibilityDelegate;
 import com.android.launcher3.dragndrop.DragOptions;
 import com.android.launcher3.logging.StatsLogManager;
-import com.android.launcher3.model.data.FolderInfo;
+import com.android.launcher3.model.data.CollectionInfo;
 import com.android.launcher3.model.data.ItemInfo;
 import com.android.launcher3.model.data.LauncherAppWidgetInfo;
 import com.android.launcher3.model.data.WorkspaceItemInfo;
@@ -75,7 +75,7 @@
         }
 
         return (info instanceof LauncherAppWidgetInfo)
-                || (info instanceof FolderInfo);
+                || (info instanceof CollectionInfo);
     }
 
     @Override
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 912583c..cfa8967 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -202,6 +202,8 @@
 import com.android.launcher3.model.ModelWriter;
 import com.android.launcher3.model.StringCache;
 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;
 import com.android.launcher3.model.data.LauncherAppWidgetInfo;
@@ -803,13 +805,19 @@
     @Override
     public void invalidateParent(ItemInfo info) {
         if (info.container >= 0) {
-            View folderIcon = getWorkspace().getHomescreenIconByItemId(info.container);
-            if (folderIcon instanceof FolderIcon && folderIcon.getTag() instanceof FolderInfo) {
+            View collectionIcon = getWorkspace().getHomescreenIconByItemId(info.container);
+            if (collectionIcon instanceof FolderIcon folderIcon
+                    && collectionIcon.getTag() instanceof FolderInfo) {
                 if (new FolderGridOrganizer(getDeviceProfile())
                         .setFolderInfo((FolderInfo) folderIcon.getTag())
                         .isItemInPreview(info.rank)) {
                     folderIcon.invalidate();
                 }
+            } else if (collectionIcon instanceof AppPairIcon appPairIcon
+                    && collectionIcon.getTag() instanceof AppPairInfo appPairInfo) {
+                if (appPairInfo.getContents().contains(info)) {
+                    appPairIcon.getIconDrawableArea().redraw();
+                }
             }
         }
     }
@@ -2008,24 +2016,26 @@
     public boolean removeItem(View v, final ItemInfo itemInfo, boolean deleteFromDb,
             @Nullable final String reason) {
         if (itemInfo instanceof WorkspaceItemInfo) {
-            // Remove the shortcut from the folder before removing it from launcher
-            View folderIcon = mWorkspace.getHomescreenIconByItemId(itemInfo.container);
-            if (folderIcon instanceof FolderIcon) {
-                ((FolderInfo) folderIcon.getTag()).remove((WorkspaceItemInfo) itemInfo, true);
+            View collectionIcon = mWorkspace.getHomescreenIconByItemId(itemInfo.container);
+            if (collectionIcon instanceof FolderIcon) {
+                // Remove the shortcut from the folder before removing it from launcher
+                ((FolderInfo) collectionIcon.getTag()).remove((WorkspaceItemInfo) itemInfo, true);
+            } else if (collectionIcon instanceof AppPairIcon appPairIcon) {
+                removeItem(appPairIcon, appPairIcon.getInfo(), deleteFromDb,
+                        "removing app pair because one of its member apps was removed");
             } else {
                 mWorkspace.removeWorkspaceItem(v);
             }
             if (deleteFromDb) {
                 getModelWriter().deleteItemFromDatabase(itemInfo, reason);
             }
-        } else if (itemInfo instanceof FolderInfo) {
-            final FolderInfo folderInfo = (FolderInfo) itemInfo;
+        } else if (itemInfo instanceof CollectionInfo ci) {
             if (v instanceof FolderIcon) {
                 ((FolderIcon) v).removeListeners();
             }
             mWorkspace.removeWorkspaceItem(v);
             if (deleteFromDb) {
-                getModelWriter().deleteFolderAndContentsFromDatabase(folderInfo);
+                getModelWriter().deleteCollectionAndContentsFromDatabase(ci);
             }
         } else if (itemInfo instanceof LauncherAppWidgetInfo) {
             final LauncherAppWidgetInfo widgetInfo = (LauncherAppWidgetInfo) itemInfo;
diff --git a/src/com/android/launcher3/LauncherPrefs.kt b/src/com/android/launcher3/LauncherPrefs.kt
index 27e084c..cb19b14 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
@@ -319,7 +318,7 @@
         val LONG_PRESS_NAV_HANDLE_TIMEOUT_MS =
             nonRestorableItem(
                 "LPNH_TIMEOUT_MS",
-                ViewConfiguration.getLongPressTimeout(),
+                450,
                 EncryptionType.MOVE_TO_DEVICE_PROTECTED
             )
         @JvmField
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index ca34dd1..ce3c55a 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -95,6 +95,7 @@
 import com.android.launcher3.logging.InstanceId;
 import com.android.launcher3.logging.StatsLogManager;
 import com.android.launcher3.logging.StatsLogManager.LauncherEvent;
+import com.android.launcher3.model.data.AppPairInfo;
 import com.android.launcher3.model.data.FolderInfo;
 import com.android.launcher3.model.data.ItemInfo;
 import com.android.launcher3.model.data.LauncherAppWidgetInfo;
@@ -3313,7 +3314,7 @@
                     }
                 } else if (child instanceof FolderIcon) {
                     FolderInfo folderInfo = (FolderInfo) info;
-                    List<WorkspaceItemInfo> matches = folderInfo.contents.stream()
+                    List<WorkspaceItemInfo> matches = folderInfo.getContents().stream()
                             .filter(matcher)
                             .collect(Collectors.toList());
                     if (!matches.isEmpty()) {
@@ -3322,6 +3323,11 @@
                             ((FolderIcon) child).getFolder().close(false /* animate */);
                         }
                     }
+                } else if (info instanceof AppPairInfo api) {
+                    // If an app pair's member apps are being removed, delete the whole app pair.
+                    if (api.anyMatch(matcher)) {
+                        mLauncher.removeItem(child, info, true);
+                    }
                 }
             }
         }
@@ -3373,9 +3379,9 @@
                 }
             } else if (info instanceof FolderInfo && v instanceof FolderIcon) {
                 FolderInfo fi = (FolderInfo) info;
-                if (fi.contents.stream().anyMatch(matcher)) {
+                if (fi.anyMatch(matcher)) {
                     FolderDotInfo folderDotInfo = new FolderDotInfo();
-                    for (WorkspaceItemInfo si : fi.contents) {
+                    for (WorkspaceItemInfo si : fi.getContents()) {
                         folderDotInfo.addDotInfo(mLauncher.getDotInfoForItem(si));
                     }
                     ((FolderIcon) v).setDotInfo(folderDotInfo);
diff --git a/src/com/android/launcher3/accessibility/BaseAccessibilityDelegate.java b/src/com/android/launcher3/accessibility/BaseAccessibilityDelegate.java
index 19d0421..29862ae 100644
--- a/src/com/android/launcher3/accessibility/BaseAccessibilityDelegate.java
+++ b/src/com/android/launcher3/accessibility/BaseAccessibilityDelegate.java
@@ -28,7 +28,7 @@
 import com.android.launcher3.LauncherSettings;
 import com.android.launcher3.dragndrop.DragController;
 import com.android.launcher3.dragndrop.DragOptions;
-import com.android.launcher3.model.data.FolderInfo;
+import com.android.launcher3.model.data.CollectionInfo;
 import com.android.launcher3.model.data.ItemInfo;
 import com.android.launcher3.model.data.LauncherAppWidgetInfo;
 import com.android.launcher3.model.data.WorkspaceItemInfo;
@@ -45,6 +45,7 @@
     public enum DragType {
         ICON,
         FOLDER,
+        APP_PAIR,
         WIDGET
     }
 
@@ -103,7 +104,7 @@
                     && item.container != LauncherSettings.Favorites.CONTAINER_HOTSEAT_PREDICTION;
         }
         return (item instanceof LauncherAppWidgetInfo)
-                || (item instanceof FolderInfo);
+                || (item instanceof CollectionInfo);
     }
 
     @Override
diff --git a/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java b/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java
index 66b8216..bb25b6d 100644
--- a/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java
+++ b/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java
@@ -39,6 +39,8 @@
 import com.android.launcher3.folder.Folder;
 import com.android.launcher3.keyboard.KeyboardDragAndDropView;
 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;
 import com.android.launcher3.model.data.LauncherAppWidgetInfo;
@@ -317,6 +319,8 @@
         mDragInfo.dragType = DragType.ICON;
         if (info instanceof FolderInfo) {
             mDragInfo.dragType = DragType.FOLDER;
+        } else if (info instanceof AppPairInfo) {
+            mDragInfo.dragType = DragType.APP_PAIR;
         } else if (info instanceof LauncherAppWidgetInfo) {
             mDragInfo.dragType = DragType.WIDGET;
         }
@@ -430,16 +434,16 @@
                         LauncherSettings.Favorites.CONTAINER_DESKTOP,
                         screenId, coordinates[0], coordinates[1]);
                 bindItem(info, accessibility, finishCallback);
-            } else if (item instanceof FolderInfo fi) {
+            } else if (item instanceof CollectionInfo ci) {
                 Workspace<?> workspace = mContext.getWorkspace();
                 workspace.snapToPage(workspace.getPageIndexForScreenId(screenId));
-                mContext.getModelWriter().addItemToDatabase(fi,
+                mContext.getModelWriter().addItemToDatabase(ci,
                         LauncherSettings.Favorites.CONTAINER_DESKTOP, screenId, coordinates[0],
                         coordinates[1]);
-                fi.contents.forEach(member -> {
-                    mContext.getModelWriter().addItemToDatabase(member, fi.id, -1, -1, -1);
-                });
-                bindItem(fi, accessibility, finishCallback);
+                ci.getContents().forEach(member ->
+                        mContext.getModelWriter()
+                                .addItemToDatabase(member, ci.id, -1, -1, -1));
+                bindItem(ci, accessibility, finishCallback);
             }
         }));
         return true;
diff --git a/src/com/android/launcher3/accessibility/WorkspaceAccessibilityHelper.java b/src/com/android/launcher3/accessibility/WorkspaceAccessibilityHelper.java
index a8624dd..52073cc 100644
--- a/src/com/android/launcher3/accessibility/WorkspaceAccessibilityHelper.java
+++ b/src/com/android/launcher3/accessibility/WorkspaceAccessibilityHelper.java
@@ -149,7 +149,7 @@
                 // Find the first item in the folder.
                 FolderInfo folder = (FolderInfo) info;
                 WorkspaceItemInfo firstItem = null;
-                for (WorkspaceItemInfo shortcut : folder.contents) {
+                for (WorkspaceItemInfo shortcut : folder.getContents()) {
                     if (firstItem == null || firstItem.rank > shortcut.rank) {
                         firstItem = shortcut;
                     }
diff --git a/src/com/android/launcher3/apppairs/AppPairIcon.java b/src/com/android/launcher3/apppairs/AppPairIcon.java
index bbeb341..9010f82 100644
--- a/src/com/android/launcher3/apppairs/AppPairIcon.java
+++ b/src/com/android/launcher3/apppairs/AppPairIcon.java
@@ -33,7 +33,7 @@
 import com.android.launcher3.R;
 import com.android.launcher3.Reorderable;
 import com.android.launcher3.dragndrop.DraggableView;
-import com.android.launcher3.model.data.FolderInfo;
+import com.android.launcher3.model.data.AppPairInfo;
 import com.android.launcher3.model.data.WorkspaceItemInfo;
 import com.android.launcher3.util.MultiTranslateDelegate;
 import com.android.launcher3.views.ActivityContext;
@@ -50,17 +50,12 @@
 public class AppPairIcon extends FrameLayout implements DraggableView, Reorderable {
     private static final String TAG = "AppPairIcon";
 
-    /**
-     * Indicates that the app pair is currently launchable on the current screen.
-     */
-    private boolean mIsLaunchableAtScreenSize = true;
-
     // A view that holds the app pair icon graphic.
     private AppPairIconGraphic mIconGraphic;
     // A view that holds the app pair's title.
     private BubbleTextView mAppPairName;
     // The underlying ItemInfo that stores info about the app pair members, etc.
-    private FolderInfo mInfo;
+    private AppPairInfo mInfo;
     // The containing element that holds this icon: workspace, taskbar, folder, etc. Affects certain
     // aspects of how the icon is drawn.
     private int mContainer;
@@ -81,7 +76,7 @@
      * Builds an AppPairIcon to be added to the Launcher.
      */
     public static AppPairIcon inflateIcon(int resId, ActivityContext activity,
-            @Nullable ViewGroup group, FolderInfo appPairInfo, int container) {
+            @Nullable ViewGroup group, AppPairInfo appPairInfo, int container) {
         DeviceProfile grid = activity.getDeviceProfile();
         LayoutInflater inflater = (group != null)
                 ? LayoutInflater.from(group.getContext())
@@ -89,7 +84,7 @@
         AppPairIcon icon = (AppPairIcon) inflater.inflate(resId, group, false);
 
         // Sort contents, so that left-hand app comes first
-        appPairInfo.contents.sort(Comparator.comparingInt(a -> a.rank));
+        appPairInfo.getContents().sort(Comparator.comparingInt(a -> a.rank));
 
         icon.setTag(appPairInfo);
         icon.setOnClickListener(activity.getItemOnClickListener());
@@ -100,8 +95,6 @@
         icon.mIconGraphic = icon.findViewById(R.id.app_pair_icon_graphic);
         icon.mIconGraphic.init(icon, container);
 
-        icon.checkDisabledState();
-
         // Set up app pair title
         icon.mAppPairName = icon.findViewById(R.id.app_pair_icon_name);
         FrameLayout.LayoutParams lp =
@@ -115,7 +108,7 @@
         // 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.setText(appPairInfo.title);
+        icon.mAppPairName.applyLabel(appPairInfo);
 
         // Set up accessibility
         icon.setContentDescription(icon.getAccessibilityTitle(appPairInfo));
@@ -127,9 +120,9 @@
     /**
      * Returns a formatted accessibility title for app pairs.
      */
-    public String getAccessibilityTitle(FolderInfo appPairInfo) {
-        CharSequence app1 = appPairInfo.contents.get(0).title;
-        CharSequence app2 = appPairInfo.contents.get(1).title;
+    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);
     }
 
@@ -174,7 +167,7 @@
         return mScaleForReorderBounce;
     }
 
-    public FolderInfo getInfo() {
+    public AppPairInfo getInfo() {
         return mInfo;
     }
 
@@ -186,41 +179,20 @@
         return mIconGraphic;
     }
 
-    public boolean isLaunchableAtScreenSize() {
-        return mIsLaunchableAtScreenSize;
-    }
-
-    /**
-     * Updates the "disabled" state of the app pair in the current device configuration.
-     * App pairs can be "disabled" in two ways:
-     * 1) One of the member WorkspaceItemInfos is disabled (i.e. the app software itself is paused
-     * by the user or can't be launched for some other reason).
-     * 2) This specific instance of an app pair can't be launched due to screen size requirements.
-     */
-    public void checkDisabledState() {
-        DeviceProfile dp = ActivityContext.lookupContext(getContext()).getDeviceProfile();
-        // If user is on a small screen, we can't launch if either of the apps is non-resizeable
-        mIsLaunchableAtScreenSize =
-                dp.isTablet || getInfo().contents.stream().noneMatch(
-                        wii -> wii.hasStatusFlag(WorkspaceItemInfo.FLAG_NON_RESIZEABLE));
-        // Invalidate to update icons
-        mIconGraphic.redraw();
-    }
-
     /**
      * Called when WorkspaceItemInfos get updated, and the app pair icon may need to be redrawn.
      */
     public void maybeRedrawForWorkspaceUpdate(Predicate<WorkspaceItemInfo> 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().contents.stream().anyMatch(itemCheck)) {
-            checkDisabledState();
+        if (getInfo().anyMatch(itemCheck)) {
+            mIconGraphic.redraw();
         }
     }
 
     /**
      * Inside folders, icons are vertically centered in their rows. See
-     * {@link BubbleTextView#onMeasure(int, int)} for comparison.
+     * {@link BubbleTextView} for comparison.
      */
     @Override
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
diff --git a/src/com/android/launcher3/apppairs/AppPairIconGraphic.kt b/src/com/android/launcher3/apppairs/AppPairIconGraphic.kt
index 04050b0..a3a1cfc 100644
--- a/src/com/android/launcher3/apppairs/AppPairIconGraphic.kt
+++ b/src/com/android/launcher3/apppairs/AppPairIconGraphic.kt
@@ -23,12 +23,12 @@
 import android.util.AttributeSet
 import android.view.Gravity
 import android.widget.FrameLayout
+import androidx.annotation.OpenForTesting
 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.FolderInfo
-import com.android.launcher3.model.data.WorkspaceItemInfo
+import com.android.launcher3.model.data.AppPairInfo
 import com.android.launcher3.util.Themes
 import com.android.launcher3.views.ActivityContext
 
@@ -36,29 +36,32 @@
  * A FrameLayout marking the area on an [AppPairIcon] where the visual icon will be drawn. One of
  * two child UI elements on an [AppPairIcon], along with a BubbleTextView holding the text title.
  */
-class AppPairIconGraphic @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
+@OpenForTesting
+open class AppPairIconGraphic
+@JvmOverloads
+constructor(context: Context, attrs: AttributeSet? = null) :
     FrameLayout(context, attrs), OnDeviceProfileChangeListener {
     private val TAG = "AppPairIconGraphic"
 
     companion object {
-        /** Composes a drawable for this icon, consisting of a background and 2 app icons. */
+        /**
+         * 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.
+         */
         @JvmStatic
-        fun composeDrawable(appPairInfo: FolderInfo, p: AppPairIconDrawingParams): Drawable {
+        fun composeDrawable(appPairInfo: AppPairInfo, p: AppPairIconDrawingParams): Drawable {
             // Generate new icons, using themed flag if needed.
             val flags = if (Themes.isThemedIconEnabled(p.context)) BitmapInfo.FLAG_THEMED else 0
-            val appIcon1 = appPairInfo.contents[0].newIcon(p.context, flags)
-            val appIcon2 = appPairInfo.contents[1].newIcon(p.context, flags)
+            val appIcon1 = appPairInfo.getFirstApp().newIcon(p.context, flags)
+            val appIcon2 = appPairInfo.getSecondApp().newIcon(p.context, flags)
             appIcon1.setBounds(0, 0, p.memberIconSize.toInt(), p.memberIconSize.toInt())
             appIcon2.setBounds(0, 0, p.memberIconSize.toInt(), p.memberIconSize.toInt())
 
-            // Check disabled status.
-            val activity: ActivityContext = ActivityContext.lookupContext(p.context)
-            val isLaunchableAtScreenSize =
-                activity.deviceProfile.isTablet ||
-                    appPairInfo.contents.stream().noneMatch { wii: WorkspaceItemInfo ->
-                        wii.hasStatusFlag(WorkspaceItemInfo.FLAG_NON_RESIZEABLE)
-                    }
-            val shouldDrawAsDisabled = appPairInfo.isDisabled || !isLaunchableAtScreenSize
+            val shouldDrawAsDisabled =
+                appPairInfo.isDisabled || !appPairInfo.isLaunchable(p.context)
 
             // Set disabled status on icons.
             appIcon1.setIsDisabled(shouldDrawAsDisabled)
@@ -124,7 +127,6 @@
      */
     fun getIconBounds(outBounds: Rect) {
         outBounds.set(0, 0, drawParams.backgroundSize.toInt(), drawParams.backgroundSize.toInt())
-
         outBounds.offset(
             // x-coordinate in parent's coordinate system
             ((parentIcon.width - drawParams.backgroundSize) / 2).toInt(),
diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java
index 1c34c72..b7c9161 100644
--- a/src/com/android/launcher3/config/FeatureFlags.java
+++ b/src/com/android/launcher3/config/FeatureFlags.java
@@ -33,7 +33,6 @@
 import static com.android.wm.shell.Flags.enableTaskbarNavbarUnification;
 
 import android.content.res.Resources;
-import android.view.ViewConfiguration;
 
 import androidx.annotation.VisibleForTesting;
 
@@ -132,7 +131,7 @@
                     "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,
+            getReleaseFlag(301680992, "CUSTOM_LPNH_THRESHOLDS", ENABLED,
                     "Add dev options to customize the LPNH trigger slop and milliseconds");
 
     public static final BooleanFlag ANIMATE_LPNH =
@@ -155,8 +154,7 @@
                     LONG_PRESS_NAV_HANDLE_EXTRA_TOUCH_WIDTH_DP);
 
     public static final IntFlag LPNH_TIMEOUT_MS =
-            FlagsFactory.getIntFlag(301680992, "LPNH_TIMEOUT_MS",
-                    ViewConfiguration.getLongPressTimeout(),
+            FlagsFactory.getIntFlag(301680992, "LPNH_TIMEOUT_MS", 450,
                     "Controls lpnh timeout in milliseconds", LONG_PRESS_NAV_HANDLE_TIMEOUT_MS);
 
     public static final BooleanFlag ENABLE_SHOW_KEYBOARD_OPTION_IN_ALL_APPS = getReleaseFlag(
diff --git a/src/com/android/launcher3/dragndrop/DragController.java b/src/com/android/launcher3/dragndrop/DragController.java
index b6e5977..bc5a164 100644
--- a/src/com/android/launcher3/dragndrop/DragController.java
+++ b/src/com/android/launcher3/dragndrop/DragController.java
@@ -33,6 +33,7 @@
 import com.android.launcher3.DropTarget;
 import com.android.launcher3.Flags;
 import com.android.launcher3.logging.InstanceId;
+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;
@@ -289,7 +290,8 @@
         // Cancel the current drag if we are removing an app that we are dragging
         if (mDragObject != null) {
             ItemInfo dragInfo = mDragObject.dragInfo;
-            if (dragInfo instanceof WorkspaceItemInfo && matcher.test(dragInfo)) {
+            if ((dragInfo instanceof WorkspaceItemInfo && matcher.test(dragInfo))
+                    || (dragInfo instanceof AppPairInfo api && api.anyMatch(matcher))) {
                 cancelDrag();
             }
         }
diff --git a/src/com/android/launcher3/folder/Folder.java b/src/com/android/launcher3/folder/Folder.java
index c8c634a..aa3c5ba 100644
--- a/src/com/android/launcher3/folder/Folder.java
+++ b/src/com/android/launcher3/folder/Folder.java
@@ -493,7 +493,7 @@
         mInfo = info;
         mFromTitle = info.title;
         mFromLabelState = info.getFromLabelState();
-        ArrayList<WorkspaceItemInfo> children = info.contents;
+        ArrayList<WorkspaceItemInfo> children = info.getContents();
         Collections.sort(children, ITEM_POS_COMPARATOR);
         updateItemLocationsInDatabaseBatch(true);
 
@@ -626,7 +626,7 @@
         // onDropComplete. Perform cleanup once drag-n-drop ends.
         mDragController.addDragListener(this);
 
-        ArrayList<WorkspaceItemInfo> items = new ArrayList<>(mInfo.contents);
+        ArrayList<WorkspaceItemInfo> items = new ArrayList<>(mInfo.getContents());
         mEmptyCellRank = items.size();
         items.add(null);    // Add an empty spot at the end
 
@@ -639,7 +639,7 @@
      * is played.
      */
     public void animateOpen() {
-        animateOpen(mInfo.contents, 0);
+        animateOpen(mInfo.getContents(), 0);
     }
 
     /**
@@ -1097,9 +1097,9 @@
                 mActivityContext.getDeviceProfile()).setFolderInfo(mInfo);
 
         ArrayList<ItemInfo> items = new ArrayList<>();
-        int total = mInfo.contents.size();
+        int total = mInfo.getContents().size();
         for (int i = 0; i < total; i++) {
-            WorkspaceItemInfo itemInfo = mInfo.contents.get(i);
+            WorkspaceItemInfo itemInfo = mInfo.getContents().get(i);
             if (verifier.updateRankAndPos(itemInfo, i)) {
                 items.add(itemInfo);
             }
@@ -1113,7 +1113,7 @@
                 FolderNameInfos nameInfos = new FolderNameInfos();
                 FolderNameProvider fnp = FolderNameProvider.newInstance(getContext());
                 fnp.getSuggestedFolderName(
-                        getContext(), mInfo.contents, nameInfos);
+                        getContext(), mInfo.getContents(), nameInfos);
                 mInfo.suggestedFolderNames = nameInfos;
             });
         }
@@ -1217,7 +1217,7 @@
     }
 
     public int getItemCount() {
-        return mInfo.contents.size();
+        return mInfo.getContents().size();
     }
 
     void replaceFolderWithFinalItem() {
diff --git a/src/com/android/launcher3/folder/FolderGridOrganizer.java b/src/com/android/launcher3/folder/FolderGridOrganizer.java
index cc24761..593673d 100644
--- a/src/com/android/launcher3/folder/FolderGridOrganizer.java
+++ b/src/com/android/launcher3/folder/FolderGridOrganizer.java
@@ -57,7 +57,7 @@
      * Updates the organizer with the provided folder info
      */
     public FolderGridOrganizer setFolderInfo(FolderInfo info) {
-        return setContentSize(info.contents.size());
+        return setContentSize(info.getContents().size());
     }
 
     /**
diff --git a/src/com/android/launcher3/folder/FolderIcon.java b/src/com/android/launcher3/folder/FolderIcon.java
index ee0d5fc..62ce311 100644
--- a/src/com/android/launcher3/folder/FolderIcon.java
+++ b/src/com/android/launcher3/folder/FolderIcon.java
@@ -215,7 +215,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.contents) {
+        for (WorkspaceItemInfo si : folderInfo.getContents()) {
             folderDotInfo.addDotInfo(activity.getDotInfoForItem(si));
         }
         icon.setDotInfo(folderDotInfo);
@@ -422,7 +422,7 @@
             FolderNameInfos nameInfos = new FolderNameInfos();
             Executors.MODEL_EXECUTOR.post(() -> {
                 d.folderNameProvider.getSuggestedFolderName(
-                        getContext(), mInfo.contents, nameInfos);
+                        getContext(), mInfo.getContents(), nameInfos);
                 postDelayed(() -> {
                     setLabelSuggestion(nameInfos, d.logInstanceId);
                     invalidate();
@@ -487,7 +487,7 @@
         }
         mFolder.notifyDrop();
         onDrop(item, d, null, 1.0f,
-                itemReturnedOnFailedDrop ? item.rank : mInfo.contents.size(),
+                itemReturnedOnFailedDrop ? item.rank : mInfo.getContents().size(),
                 itemReturnedOnFailedDrop
         );
     }
@@ -666,7 +666,7 @@
      * Returns the list of items which should be visible in the preview
      */
     public List<WorkspaceItemInfo> getPreviewItemsOnPage(int page) {
-        return mPreviewVerifier.setFolderInfo(mInfo).previewItemsForPage(page, mInfo.contents);
+        return mPreviewVerifier.setFolderInfo(mInfo).previewItemsForPage(page, mInfo.getContents());
     }
 
     @Override
@@ -809,7 +809,7 @@
      * Returns a formatted accessibility title for folder
      */
     public String getAccessiblityTitle(CharSequence title) {
-        int size = mInfo.contents.size();
+        int size = mInfo.getContents().size();
         if (size < MAX_NUM_ITEMS_IN_PREVIEW) {
             return getContext().getString(R.string.folder_name_format_exact, title, size);
         } else {
diff --git a/src/com/android/launcher3/folder/FolderNameProvider.java b/src/com/android/launcher3/folder/FolderNameProvider.java
index bf59594..5d2bb3a 100644
--- a/src/com/android/launcher3/folder/FolderNameProvider.java
+++ b/src/com/android/launcher3/folder/FolderNameProvider.java
@@ -35,7 +35,7 @@
 import com.android.launcher3.model.BgDataModel;
 import com.android.launcher3.model.StringCache;
 import com.android.launcher3.model.data.AppInfo;
-import com.android.launcher3.model.data.FolderInfo;
+import com.android.launcher3.model.data.CollectionInfo;
 import com.android.launcher3.model.data.WorkspaceItemInfo;
 import com.android.launcher3.util.IntSparseArrayMap;
 import com.android.launcher3.util.Preconditions;
@@ -62,7 +62,7 @@
      * name edit box can also be used to provide suggestion.
      */
     public static final int SUGGEST_MAX = 4;
-    protected IntSparseArrayMap<FolderInfo> mFolderInfos;
+    protected IntSparseArrayMap<CollectionInfo> mCollectionInfos;
     protected List<AppInfo> mAppInfos;
 
     /**
@@ -79,7 +79,7 @@
     }
 
     public static FolderNameProvider newInstance(Context context, List<AppInfo> appInfos,
-            IntSparseArrayMap<FolderInfo> folderInfos) {
+            IntSparseArrayMap<CollectionInfo> folderInfos) {
         Preconditions.assertWorkerThread();
         FolderNameProvider fnp = Overrides.getObject(FolderNameProvider.class,
                 context.getApplicationContext(), R.string.folder_name_provider_class);
@@ -93,9 +93,9 @@
                 new FolderNameWorker());
     }
 
-    private void load(List<AppInfo> appInfos, IntSparseArrayMap<FolderInfo> folderInfos) {
+    private void load(List<AppInfo> appInfos, IntSparseArrayMap<CollectionInfo> folderInfos) {
         mAppInfos = appInfos;
-        mFolderInfos = folderInfos;
+        mCollectionInfos = folderInfos;
     }
 
     /**
@@ -195,7 +195,7 @@
         @Override
         public void execute(@NonNull final LauncherAppState app,
                 @NonNull final BgDataModel dataModel, @NonNull final AllAppsList apps) {
-            mFolderInfos = dataModel.folders.clone();
+            mCollectionInfos = dataModel.collections.clone();
             mAppInfos = Arrays.asList(apps.copyData());
         }
     }
diff --git a/src/com/android/launcher3/folder/LauncherDelegate.java b/src/com/android/launcher3/folder/LauncherDelegate.java
index 78298b3..33bcf21 100644
--- a/src/com/android/launcher3/folder/LauncherDelegate.java
+++ b/src/com/android/launcher3/folder/LauncherDelegate.java
@@ -93,7 +93,7 @@
                         // folder
                         CellLayout cellLayout = mLauncher.getCellLayout(info.container,
                                 mLauncher.getCellPosMapper().mapModelToPresenter(info).screenId);
-                        finalItem =  info.contents.remove(0);
+                        finalItem =  info.getContents().remove(0);
                         newIcon = mLauncher.getItemInflater().inflateItem(
                                 finalItem, mLauncher.getModelWriter(), cellLayout);
                         mLauncher.getModelWriter().addOrMoveItemInDatabase(finalItem,
diff --git a/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java b/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java
index 9aee379..6b3bb51 100644
--- a/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java
+++ b/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java
@@ -82,6 +82,8 @@
 import com.android.launcher3.model.BgDataModel.FixedContainerItems;
 import com.android.launcher3.model.WidgetItem;
 import com.android.launcher3.model.WidgetsModel;
+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;
 import com.android.launcher3.model.data.LauncherAppWidgetInfo;
@@ -388,16 +390,16 @@
         addInScreenFromBind(icon, info);
     }
 
-    private void inflateAndAddCollectionIcon(FolderInfo info) {
+    private void inflateAndAddCollectionIcon(CollectionInfo info) {
         boolean isOnDesktop = info.container == Favorites.CONTAINER_DESKTOP;
         CellLayout screen = isOnDesktop
                 ? mWorkspaceScreens.get(info.screenId)
                 : mHotseat;
-        FrameLayout folderIcon = info.itemType == Favorites.ITEM_TYPE_FOLDER
-                ? FolderIcon.inflateIcon(R.layout.folder_icon, this, screen, info)
-                : AppPairIcon.inflateIcon(R.layout.app_pair_icon, this, screen, info,
+        FrameLayout collectionIcon = info.itemType == Favorites.ITEM_TYPE_FOLDER
+                ? FolderIcon.inflateIcon(R.layout.folder_icon, this, screen, (FolderInfo) info)
+                : AppPairIcon.inflateIcon(R.layout.app_pair_icon, this, screen, (AppPairInfo) info,
                         isOnDesktop ? DISPLAY_WORKSPACE : DISPLAY_TASKBAR);
-        addInScreenFromBind(folderIcon, info);
+        addInScreenFromBind(collectionIcon, info);
     }
 
     private void inflateAndAddWidgets(
@@ -501,7 +503,7 @@
                     break;
                 case Favorites.ITEM_TYPE_FOLDER:
                 case Favorites.ITEM_TYPE_APP_PAIR:
-                    inflateAndAddCollectionIcon((FolderInfo) itemInfo);
+                    inflateAndAddCollectionIcon((CollectionInfo) itemInfo);
                     break;
                 default:
                     break;
diff --git a/src/com/android/launcher3/model/AddWorkspaceItemsTask.java b/src/com/android/launcher3/model/AddWorkspaceItemsTask.java
index 96a8da9..ce563b7 100644
--- a/src/com/android/launcher3/model/AddWorkspaceItemsTask.java
+++ b/src/com/android/launcher3/model/AddWorkspaceItemsTask.java
@@ -31,7 +31,7 @@
 import com.android.launcher3.logging.FileLog;
 import com.android.launcher3.model.BgDataModel.Callbacks;
 import com.android.launcher3.model.data.AppInfo;
-import com.android.launcher3.model.data.FolderInfo;
+import com.android.launcher3.model.data.CollectionInfo;
 import com.android.launcher3.model.data.ItemInfo;
 import com.android.launcher3.model.data.ItemInfoWithIcon;
 import com.android.launcher3.model.data.LauncherAppWidgetInfo;
@@ -131,8 +131,8 @@
                 int screenId = coords[0];
 
                 ItemInfo itemInfo;
-                if (item instanceof WorkspaceItemInfo || item instanceof FolderInfo ||
-                        item instanceof LauncherAppWidgetInfo) {
+                if (item instanceof WorkspaceItemInfo || item instanceof CollectionInfo
+                        || item instanceof LauncherAppWidgetInfo) {
                     itemInfo = item;
                 } else if (item instanceof WorkspaceItemFactory) {
                     itemInfo = ((WorkspaceItemFactory) item).makeWorkspaceItem(app.getContext());
diff --git a/src/com/android/launcher3/model/BgDataModel.java b/src/com/android/launcher3/model/BgDataModel.java
index 0e1c8f4..44e45da 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.CollectionInfo;
 import com.android.launcher3.model.data.FolderInfo;
 import com.android.launcher3.model.data.ItemInfo;
 import com.android.launcher3.model.data.LauncherAppWidgetInfo;
@@ -102,9 +103,9 @@
     public final ArrayList<LauncherAppWidgetInfo> appWidgets = new ArrayList<>();
 
     /**
-     * Map of id to FolderInfos of all the folders created by LauncherModel
+     * Map of id to CollectionInfos of all the folders or app pairs created by LauncherModel
      */
-    public final IntSparseArrayMap<FolderInfo> folders = new IntSparseArrayMap<>();
+    public final IntSparseArrayMap<CollectionInfo> collections = new IntSparseArrayMap<>();
 
     /**
      * Extra container based items
@@ -144,7 +145,7 @@
     public synchronized void clear() {
         workspaceItems.clear();
         appWidgets.clear();
-        folders.clear();
+        collections.clear();
         itemsIdMap.clear();
         deepShortcutMap.clear();
         extraItems.clear();
@@ -179,9 +180,9 @@
         for (int i = 0; i < appWidgets.size(); i++) {
             writer.println(prefix + '\t' + appWidgets.get(i).toString());
         }
-        writer.println(prefix + " ---- folder items ");
-        for (int i = 0; i < folders.size(); i++) {
-            writer.println(prefix + '\t' + folders.valueAt(i).toString());
+        writer.println(prefix + " ---- collection items ");
+        for (int i = 0; i < collections.size(); i++) {
+            writer.println(prefix + '\t' + collections.valueAt(i).toString());
         }
         writer.println(prefix + " ---- extra items ");
         for (int i = 0; i < extraItems.size(); i++) {
@@ -211,12 +212,12 @@
             switch (item.itemType) {
                 case LauncherSettings.Favorites.ITEM_TYPE_FOLDER:
                 case LauncherSettings.Favorites.ITEM_TYPE_APP_PAIR:
-                    folders.remove(item.id);
+                    collections.remove(item.id);
                     if (FeatureFlags.IS_STUDIO_BUILD) {
                         for (ItemInfo info : itemsIdMap) {
                             if (info.container == item.id) {
-                                // We are deleting a folder which still contains items that
-                                // think they are contained by that folder.
+                                // We are deleting a collection which still contains items that
+                                // think they are contained by that collection.
                                 String msg = "deleting a collection (" + item + ") which still "
                                         + "contains items (" + info + ")";
                                 Log.e(TAG, msg);
@@ -259,7 +260,7 @@
         switch (item.itemType) {
             case LauncherSettings.Favorites.ITEM_TYPE_FOLDER:
             case LauncherSettings.Favorites.ITEM_TYPE_APP_PAIR:
-                folders.put(item.id, (FolderInfo) item);
+                collections.put(item.id, (CollectionInfo) item);
                 workspaceItems.add(item);
                 break;
             case LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT:
@@ -269,14 +270,14 @@
                     workspaceItems.add(item);
                 } else {
                     if (newItem) {
-                        if (!folders.containsKey(item.container)) {
+                        if (!collections.containsKey(item.container)) {
                             // Adding an item to a nonexistent collection.
                             String msg = "attempted to add item: " + item + " to a nonexistent app"
                                     + " collection";
                             Log.e(TAG, msg);
                         }
                     } else {
-                        findOrMakeFolder(item.container).add((WorkspaceItemInfo) item, false);
+                        findOrMakeFolder(item.container).add((WorkspaceItemInfo) item);
                     }
                 }
                 break;
@@ -371,15 +372,18 @@
      * Return an existing FolderInfo object if we have encountered this ID previously,
      * or make a new one.
      */
-    public synchronized FolderInfo findOrMakeFolder(int id) {
+    public synchronized CollectionInfo findOrMakeFolder(int id) {
         // See if a placeholder was created for us already
-        FolderInfo folderInfo = folders.get(id);
-        if (folderInfo == null) {
-            // No placeholder -- create a new instance
-            folderInfo = new FolderInfo();
-            folders.put(id, folderInfo);
+        CollectionInfo collectionInfo = collections.get(id);
+        if (collectionInfo == null) {
+            // No placeholder -- create a new blank folder instance. At this point, we don't know
+            // if the desired container is supposed to be a folder or an app pair. In the case that
+            // it is an app pair, the blank folder will be replaced by a blank app pair when the app
+            // pair is getting processed, in WorkspaceItemProcessor.processFolderOrAppPair().
+            collectionInfo = new FolderInfo();
+            collections.put(id, collectionInfo);
         }
-        return folderInfo;
+        return collectionInfo;
     }
 
     /**
diff --git a/src/com/android/launcher3/model/FirstScreenBroadcast.java b/src/com/android/launcher3/model/FirstScreenBroadcast.java
index 9e91b9d..1deb665 100644
--- a/src/com/android/launcher3/model/FirstScreenBroadcast.java
+++ b/src/com/android/launcher3/model/FirstScreenBroadcast.java
@@ -36,6 +36,7 @@
 import androidx.annotation.WorkerThread;
 
 import com.android.launcher3.LauncherSettings;
+import com.android.launcher3.model.data.CollectionInfo;
 import com.android.launcher3.model.data.FolderInfo;
 import com.android.launcher3.model.data.ItemInfo;
 import com.android.launcher3.model.data.LauncherAppWidgetInfo;
@@ -67,7 +68,8 @@
     private static final String ACTION_FIRST_SCREEN_ACTIVE_INSTALLS
             = "com.android.launcher3.action.FIRST_SCREEN_ACTIVE_INSTALLS";
 
-    private static final String FOLDER_ITEM_EXTRA = "folderItem";
+    // String retained as "folderItem" for back-compatibility reasons.
+    private static final String COLLECTION_ITEM_EXTRA = "folderItem";
     private static final String WORKSPACE_ITEM_EXTRA = "workspaceItem";
     private static final String HOTSEAT_ITEM_EXTRA = "hotseatItem";
     private static final String WIDGET_ITEM_EXTRA = "widgetItem";
@@ -105,20 +107,19 @@
     @WorkerThread
     private void sendBroadcastToInstaller(Context context, String installerPackageName,
             Set<String> packages, List<ItemInfo> firstScreenItems) {
-        Set<String> folderItems = new HashSet<>();
+        Set<String> collectionItems = new HashSet<>();
         Set<String> workspaceItems = new HashSet<>();
         Set<String> hotseatItems = new HashSet<>();
         Set<String> widgetItems = new HashSet<>();
 
         for (ItemInfo info : firstScreenItems) {
-            if (info instanceof FolderInfo) {
-                FolderInfo folderInfo = (FolderInfo) info;
-                String folderItemInfoPackage;
-                for (ItemInfo folderItemInfo : cloneOnMainThread(folderInfo.contents)) {
-                    folderItemInfoPackage = getPackageName(folderItemInfo);
-                    if (folderItemInfoPackage != null
-                            && packages.contains(folderItemInfoPackage)) {
-                        folderItems.add(folderItemInfoPackage);
+            if (info instanceof CollectionInfo ci) {
+                String collectionItemInfoPackage;
+                for (ItemInfo collectionItemInfo : cloneOnMainThread(ci.getContents())) {
+                    collectionItemInfoPackage = getPackageName(collectionItemInfo);
+                    if (collectionItemInfoPackage != null
+                            && packages.contains(collectionItemInfoPackage)) {
+                        collectionItems.add(collectionItemInfoPackage);
                     }
                 }
             }
@@ -137,13 +138,13 @@
         }
 
         if (DEBUG) {
-            printList(installerPackageName, "Folder item", folderItems);
+            printList(installerPackageName, "Collection item", collectionItems);
             printList(installerPackageName, "Workspace item", workspaceItems);
             printList(installerPackageName, "Hotseat item", hotseatItems);
             printList(installerPackageName, "Widget item", widgetItems);
         }
 
-        if (folderItems.isEmpty()
+        if (collectionItems.isEmpty()
                 && workspaceItems.isEmpty()
                 && hotseatItems.isEmpty()
                 && widgetItems.isEmpty()) {
@@ -152,7 +153,7 @@
         }
         context.sendBroadcast(new Intent(ACTION_FIRST_SCREEN_ACTIVE_INSTALLS)
                 .setPackage(installerPackageName)
-                .putStringArrayListExtra(FOLDER_ITEM_EXTRA, new ArrayList<>(folderItems))
+                .putStringArrayListExtra(COLLECTION_ITEM_EXTRA, new ArrayList<>(collectionItems))
                 .putStringArrayListExtra(WORKSPACE_ITEM_EXTRA, new ArrayList<>(workspaceItems))
                 .putStringArrayListExtra(HOTSEAT_ITEM_EXTRA, new ArrayList<>(hotseatItems))
                 .putStringArrayListExtra(WIDGET_ITEM_EXTRA, new ArrayList<>(widgetItems))
@@ -180,7 +181,7 @@
     }
 
     /**
-     * Clone the provided list on UI thread. This is used for {@link FolderInfo#contents} which
+     * Clone the provided list on UI thread. This is used for {@link FolderInfo#getContents()} which
      * is always modified on UI thread.
      */
     @AnyThread
diff --git a/src/com/android/launcher3/model/LoaderTask.java b/src/com/android/launcher3/model/LoaderTask.java
index f3d04b7..30cccd5 100644
--- a/src/com/android/launcher3/model/LoaderTask.java
+++ b/src/com/android/launcher3/model/LoaderTask.java
@@ -20,7 +20,6 @@
 import static com.android.launcher3.Flags.enableLauncherBrMetricsFixed;
 import static com.android.launcher3.LauncherPrefs.IS_FIRST_LOAD_AFTER_RESTORE;
 import static com.android.launcher3.LauncherPrefs.SHOULD_SHOW_SMARTSPACE;
-import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_APP_PAIR;
 import static com.android.launcher3.LauncherSettings.Favorites.TABLE_NAME;
 import static com.android.launcher3.config.FeatureFlags.ENABLE_SMARTSPACE_REMOVAL;
 import static com.android.launcher3.config.FeatureFlags.SMARTSPACE_AS_A_WIDGET;
@@ -77,9 +76,12 @@
 import com.android.launcher3.icons.cache.IconCacheUpdateHandler;
 import com.android.launcher3.logging.FileLog;
 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.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;
@@ -99,7 +101,6 @@
 import com.android.launcher3.widget.WidgetInflater;
 
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
@@ -234,6 +235,7 @@
             if (Objects.equals(mApp.getInvariantDeviceProfile().dbFile, mDbName)) {
                 verifyNotStopped();
                 sanitizeFolders(mItemsDeleted);
+                sanitizeAppPairs();
                 sanitizeWidgetsShortcutsAndPackages();
                 logASplit("sanitizeData");
             }
@@ -482,14 +484,20 @@
     }
 
     /**
-     * After all items have been processed and added to the BgDataModel, this method requests
-     * high-res icons for the items that are part of an app pair
+     * After all items have been processed and added to the BgDataModel, this method sorts and
+     * requests high-res icons for the items that are part of an app pair.
      */
     private void processAppPairItems() {
-        mBgDataModel.workspaceItems.stream()
-                .filter((itemInfo -> itemInfo.itemType == ITEM_TYPE_APP_PAIR))
-                .forEach(fi -> ((FolderInfo) fi).contents.forEach(item ->
-                        mIconCache.getTitleAndIcon(item, false /*useLowResIcon*/)));
+        for (CollectionInfo collection : mBgDataModel.collections) {
+            if (!(collection instanceof AppPairInfo appPair)) {
+                continue;
+            }
+
+            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));
+        }
     }
 
     /**
@@ -545,20 +553,21 @@
         // Sort the folder items, update ranks, and make sure all preview items are high res.
         List<FolderGridOrganizer> verifiers = mApp.getInvariantDeviceProfile().supportedProfiles
                 .stream().map(FolderGridOrganizer::new).toList();
-        for (FolderInfo folder : mBgDataModel.folders) {
-            Collections.sort(folder.contents, Folder.ITEM_POS_COMPARATOR);
+        for (CollectionInfo collection : mBgDataModel.collections) {
+            if (!(collection instanceof FolderInfo folder)) {
+                continue;
+            }
+
+            folder.getContents().sort(Folder.ITEM_POS_COMPARATOR);
             verifiers.forEach(verifier -> verifier.setFolderInfo(folder));
-            int size = folder.contents.size();
+            int size = folder.getContents().size();
 
             // Update ranks here to ensure there are no gaps caused by removed folder items.
             // 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.contents.get(rank);
-                // rank is used differently in app pairs, so don't reset
-                if (folder.itemType != ITEM_TYPE_APP_PAIR) {
-                    info.rank = rank;
-                }
+                WorkspaceItemInfo info = folder.getContents().get(rank);
+                info.rank = rank;
 
                 if (info.usingLowResIcon() && info.itemType == Favorites.ITEM_TYPE_APPLICATION
                         && verifiers.stream().anyMatch(it -> it.isItemInPreview(info.rank))) {
@@ -611,14 +620,32 @@
             IntArray deletedFolderIds = mApp.getModel().getModelDbController().deleteEmptyFolders();
             synchronized (mBgDataModel) {
                 for (int folderId : deletedFolderIds) {
-                    mBgDataModel.workspaceItems.remove(mBgDataModel.folders.get(folderId));
-                    mBgDataModel.folders.remove(folderId);
+                    mBgDataModel.workspaceItems.remove(mBgDataModel.collections.get(folderId));
+                    mBgDataModel.collections.remove(folderId);
                     mBgDataModel.itemsIdMap.remove(folderId);
                 }
             }
         }
     }
 
+    /** Cleans up app pairs if they don't have the right number of member apps (2). */
+    private void sanitizeAppPairs() {
+        IntArray deletedAppPairIds = mApp.getModel().getModelDbController().deleteBadAppPairs();
+        IntArray deletedAppIds = mApp.getModel().getModelDbController().deleteUnparentedApps();
+
+        IntArray deleted = new IntArray();
+        deleted.addAll(deletedAppPairIds);
+        deleted.addAll(deletedAppIds);
+
+        synchronized (mBgDataModel) {
+            for (int id : deleted) {
+                mBgDataModel.workspaceItems.remove(mBgDataModel.collections.get(id));
+                mBgDataModel.collections.remove(id);
+                mBgDataModel.itemsIdMap.remove(id);
+            }
+        }
+    }
+
     private void sanitizeWidgetsShortcutsAndPackages() {
         Context context = mApp.getContext();
 
@@ -754,16 +781,16 @@
 
     private void loadFolderNames() {
         FolderNameProvider provider = FolderNameProvider.newInstance(mApp.getContext(),
-                mBgAllAppsList.data, mBgDataModel.folders);
+                mBgAllAppsList.data, mBgDataModel.collections);
 
         synchronized (mBgDataModel) {
-            for (int i = 0; i < mBgDataModel.folders.size(); i++) {
+            for (int i = 0; i < mBgDataModel.collections.size(); i++) {
                 FolderNameInfos suggestionInfos = new FolderNameInfos();
-                FolderInfo info = mBgDataModel.folders.valueAt(i);
-                if (info.suggestedFolderNames == null) {
-                    provider.getSuggestedFolderName(mApp.getContext(), info.contents,
+                CollectionInfo info = mBgDataModel.collections.valueAt(i);
+                if (info instanceof FolderInfo fi && fi.suggestedFolderNames == null) {
+                    provider.getSuggestedFolderName(mApp.getContext(), fi.getContents(),
                             suggestionInfos);
-                    info.suggestedFolderNames = suggestionInfos;
+                    fi.suggestedFolderNames = suggestionInfos;
                 }
             }
         }
diff --git a/src/com/android/launcher3/model/ModelDbController.java b/src/com/android/launcher3/model/ModelDbController.java
index 8ed554a..7e1d40d 100644
--- a/src/com/android/launcher3/model/ModelDbController.java
+++ b/src/com/android/launcher3/model/ModelDbController.java
@@ -15,11 +15,15 @@
  */
 package com.android.launcher3.model;
 
+import static android.provider.BaseColumns._ID;
 import static android.util.Base64.NO_PADDING;
 import static android.util.Base64.NO_WRAP;
 
 import static com.android.launcher3.DefaultLayoutParser.RES_PARTNER_DEFAULT_LAYOUT;
+import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER;
 import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE;
+import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_APP_PAIR;
+import static com.android.launcher3.LauncherSettings.Favorites.TABLE_NAME;
 import static com.android.launcher3.LauncherSettings.Favorites.addTableToDb;
 import static com.android.launcher3.LauncherSettings.Settings.LAYOUT_DIGEST_KEY;
 import static com.android.launcher3.LauncherSettings.Settings.LAYOUT_DIGEST_LABEL;
@@ -391,6 +395,68 @@
         }
     }
 
+    /**
+     * Deletes any app pair that doesn't contain 2 member apps from the DB.
+     * @return Ids of deleted app pairs.
+     */
+    @WorkerThread
+    public IntArray deleteBadAppPairs() {
+        createDbIfNotExists();
+
+        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+        try (SQLiteTransaction t = new SQLiteTransaction(db)) {
+            // Select all entries with ITEM_TYPE = ITEM_TYPE_APP_PAIR whose id does not appear
+            // exactly twice in the CONTAINER column.
+            String selection =
+                    ITEM_TYPE + " = " + ITEM_TYPE_APP_PAIR
+                            + " AND " + _ID +  " NOT IN"
+                            + " (SELECT " + CONTAINER + " FROM " + TABLE_NAME
+                            + " GROUP BY " + CONTAINER + " HAVING COUNT(*) = 2)";
+
+            IntArray appPairIds = LauncherDbUtils.queryIntArray(false, db, TABLE_NAME,
+                    _ID, selection, null, null);
+            if (!appPairIds.isEmpty()) {
+                db.delete(TABLE_NAME, Utilities.createDbSelectionQuery(
+                        _ID, appPairIds), null);
+            }
+            t.commit();
+            return appPairIds;
+        } catch (SQLException ex) {
+            Log.e(TAG, ex.getMessage(), ex);
+            return new IntArray();
+        }
+    }
+
+    /**
+     * Deletes any app with a container id that doesn't exist.
+     * @return Ids of deleted apps.
+     */
+    @WorkerThread
+    public IntArray deleteUnparentedApps() {
+        createDbIfNotExists();
+
+        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+        try (SQLiteTransaction t = new SQLiteTransaction(db)) {
+            // Select all entries whose container id does not appear in the database.
+            String selection =
+                    CONTAINER + " >= 0"
+                            + " AND " + CONTAINER + " NOT IN"
+                            + " (SELECT " + _ID + " FROM " + TABLE_NAME + ")";
+
+            IntArray appIds = LauncherDbUtils.queryIntArray(false, db, TABLE_NAME,
+                    _ID, selection, null, null);
+            if (!appIds.isEmpty()) {
+                db.delete(TABLE_NAME, Utilities.createDbSelectionQuery(
+                        _ID, appIds), null);
+            }
+            t.commit();
+            return appIds;
+        } catch (SQLException ex) {
+            Log.e(TAG, ex.getMessage(), ex);
+            return new IntArray();
+        }
+    }
+
     private static void addModifiedTime(ContentValues values) {
         values.put(LauncherSettings.Favorites.MODIFIED, System.currentTimeMillis());
     }
diff --git a/src/com/android/launcher3/model/ModelWriter.java b/src/com/android/launcher3/model/ModelWriter.java
index 55093a3..b477cb1 100644
--- a/src/com/android/launcher3/model/ModelWriter.java
+++ b/src/com/android/launcher3/model/ModelWriter.java
@@ -37,7 +37,7 @@
 import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.logging.FileLog;
 import com.android.launcher3.model.BgDataModel.Callbacks;
-import com.android.launcher3.model.data.FolderInfo;
+import com.android.launcher3.model.data.CollectionInfo;
 import com.android.launcher3.model.data.ItemInfo;
 import com.android.launcher3.model.data.LauncherAppWidgetInfo;
 import com.android.launcher3.model.data.WorkspaceItemInfo;
@@ -275,7 +275,7 @@
     public void deleteItemsFromDatabase(@NonNull final Predicate<ItemInfo> matcher,
             @Nullable final String reason) {
         deleteItemsFromDatabase(StreamSupport.stream(mBgDataModel.itemsIdMap.spliterator(), false)
-                        .filter(matcher).collect(Collectors.toList()), reason);
+                .filter(matcher).collect(Collectors.toList()), reason);
     }
 
     /**
@@ -302,15 +302,15 @@
     /**
      * Remove the specified folder and all its contents from the database.
      */
-    public void deleteFolderAndContentsFromDatabase(final FolderInfo info) {
+    public void deleteCollectionAndContentsFromDatabase(final CollectionInfo info) {
         ModelVerifier verifier = new ModelVerifier();
         notifyDelete(Collections.singleton(info));
 
         enqueueDeleteRunnable(newModelTask(() -> {
             mModel.getModelDbController().delete(Favorites.TABLE_NAME,
                     Favorites.CONTAINER + "=" + info.id, null);
-            mBgDataModel.removeItem(mContext, info.contents);
-            info.contents.clear();
+            mBgDataModel.removeItem(mContext, info.getContents());
+            info.getContents().clear();
 
             mModel.getModelDbController().delete(Favorites.TABLE_NAME,
                     Favorites._ID + "=" + info.id, null);
@@ -458,12 +458,12 @@
 
                 if (item.container != Favorites.CONTAINER_DESKTOP &&
                         item.container != Favorites.CONTAINER_HOTSEAT) {
-                    // Item is in a folder, make sure this folder exists
-                    if (!mBgDataModel.folders.containsKey(item.container)) {
+                    // Item is in a collection, make sure this collection exists
+                    if (!mBgDataModel.collections.containsKey(item.container)) {
                         // An items container is being set to a that of an item which is not in
                         // the list of Folders.
                         String msg = "item: " + item + " container being set to: " +
-                                item.container + ", not in the list of folders";
+                                item.container + ", not in the list of collections";
                         Log.e(TAG, msg);
                     }
                 }
diff --git a/src/com/android/launcher3/model/PackageUpdatedTask.java b/src/com/android/launcher3/model/PackageUpdatedTask.java
index 0ba468d..ea1ae2e 100644
--- a/src/com/android/launcher3/model/PackageUpdatedTask.java
+++ b/src/com/android/launcher3/model/PackageUpdatedTask.java
@@ -361,17 +361,10 @@
         }
 
         if (!removedPackages.isEmpty() || !removedComponents.isEmpty()) {
-            // This predicate is used to mark an ItemInfo for removal if its package or component
-            // is marked for removal.
-            Predicate<ItemInfo> removeAppMatch =
+            Predicate<ItemInfo> removeMatch =
                     ItemInfoMatcher.ofPackages(removedPackages, mUser)
                             .or(ItemInfoMatcher.ofComponents(removedComponents, mUser))
                             .and(ItemInfoMatcher.ofItemIds(forceKeepShortcuts).negate());
-            // This predicate is used to mark an app pair for removal if it contains an app marked
-            // for removal.
-            Predicate<ItemInfo> removeAppPairMatch =
-                    ItemInfoMatcher.forAppPairMatch(removeAppMatch);
-            Predicate<ItemInfo> removeMatch = removeAppMatch.or(removeAppPairMatch);
             deleteAndBindComponentsRemoved(removeMatch,
                     "removed because the corresponding package or component is removed. "
                             + "mOp=" + mOp + " removedPackages=" + removedPackages.stream().collect(
diff --git a/src/com/android/launcher3/model/WorkspaceItemProcessor.kt b/src/com/android/launcher3/model/WorkspaceItemProcessor.kt
index 22e5eb4..aa29290 100644
--- a/src/com/android/launcher3/model/WorkspaceItemProcessor.kt
+++ b/src/com/android/launcher3/model/WorkspaceItemProcessor.kt
@@ -32,6 +32,8 @@
 import com.android.launcher3.Utilities
 import com.android.launcher3.backuprestore.LauncherRestoreEventLogger.RestoreError
 import com.android.launcher3.logging.FileLog
+import com.android.launcher3.model.data.AppPairInfo
+import com.android.launcher3.model.data.FolderInfo
 import com.android.launcher3.model.data.IconRequestInfo
 import com.android.launcher3.model.data.ItemInfoWithIcon
 import com.android.launcher3.model.data.LauncherAppWidgetInfo
@@ -360,25 +362,40 @@
     }
 
     /**
-     * Loads the folder information from the database and formats it into a FolderInfo. Some of the
-     * processing for folder content items is done in LoaderTask after all the items in the
-     * workspace have been loaded. The loaded FolderInfos are stored in the BgDataModel.
+     * Loads CollectionInfo information from the database and formats it. This function runs while
+     * LoaderTask is still active; some of the processing for folder content items is done after all
+     * the items in the workspace have been loaded. The loaded and formatted CollectionInfo is then
+     * stored in the BgDataModel.
      */
     private fun processFolderOrAppPair() {
-        val folderInfo =
-            bgDataModel.findOrMakeFolder(c.id).apply {
-                c.applyCommonProperties(this)
-                itemType = c.itemType
-                // Do not trim the folder label, as is was set by the user.
-                title = c.getString(c.mTitleIndex)
-                spanX = 1
-                spanY = 1
-                options = c.options
-            }
+        var collection = bgDataModel.findOrMakeFolder(c.id)
+        // 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) {
+            val folderInfo: FolderInfo = collection
+            val newAppPair = AppPairInfo()
+            // Move the placeholder's contents over to the new app pair.
+            folderInfo.contents.forEach(newAppPair::add)
+            collection = newAppPair
+            // Remove the placeholder and add the app pair into the data model.
+            bgDataModel.collections.remove(c.id)
+            bgDataModel.collections.put(c.id, collection)
+        }
 
-        // no special handling required for restored folders
+        c.applyCommonProperties(collection)
+        // Do not trim the folder label, as is was set by the user.
+        collection.title = c.getString(c.mTitleIndex)
+        collection.spanX = 1
+        collection.spanY = 1
+        if (collection is FolderInfo) {
+            collection.options = c.options
+        } else {
+            // An app pair may be inside another folder, so it needs to preserve rank information.
+            collection.rank = c.rank
+        }
+
         c.markRestored()
-        c.checkAndAddItem(folderInfo, bgDataModel, memoryLogger)
+        c.checkAndAddItem(collection, bgDataModel, memoryLogger)
     }
 
     /**
diff --git a/src/com/android/launcher3/model/data/AppPairInfo.kt b/src/com/android/launcher3/model/data/AppPairInfo.kt
new file mode 100644
index 0000000..4081316
--- /dev/null
+++ b/src/com/android/launcher3/model/data/AppPairInfo.kt
@@ -0,0 +1,65 @@
+/*
+ * 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.data
+
+import android.content.Context
+import com.android.launcher3.LauncherSettings
+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() {
+    init {
+        itemType = LauncherSettings.Favorites.ITEM_TYPE_APP_PAIR
+    }
+
+    /** Convenience constructor, calls primary constructor and init block */
+    constructor(app1: WorkspaceItemInfo, app2: WorkspaceItemInfo) : this() {
+        add(app1)
+        add(app2)
+    }
+
+    /** Adds an element to the contents array. */
+    override fun add(item: WorkspaceItemInfo) {
+        contents.add(item)
+    }
+
+    /** Returns the first app in the pair. */
+    fun getFirstApp() = contents[0]
+
+    /** Returns the second app in the pair. */
+    fun getSecondApp() = contents[1]
+
+    /** Returns if either of the app pair members is currently disabled. */
+    override fun isDisabled() = anyMatch { it.isDisabled }
+
+    /** 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) }
+
+    /** Generates an ItemInfo for logging. */
+    override fun buildProto(cInfo: CollectionInfo?): LauncherAtom.ItemInfo {
+        val appPairIcon = LauncherAtom.FolderIcon.newBuilder().setCardinality(contents.size)
+        appPairIcon.setLabelInfo(title.toString())
+        return getDefaultItemInfoBuilder()
+            .setFolderIcon(appPairIcon)
+            .setRank(rank)
+            .setContainerInfo(getContainerInfo())
+            .build()
+    }
+}
diff --git a/src/com/android/launcher3/model/data/CollectionInfo.kt b/src/com/android/launcher3/model/data/CollectionInfo.kt
new file mode 100644
index 0000000..2b865a5
--- /dev/null
+++ b/src/com/android/launcher3/model/data/CollectionInfo.kt
@@ -0,0 +1,48 @@
+/*
+ * 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.data
+
+import com.android.launcher3.LauncherSettings
+import com.android.launcher3.logger.LauncherAtom
+import com.android.launcher3.util.ContentWriter
+import java.util.function.Predicate
+
+abstract class CollectionInfo : ItemInfo() {
+    var contents: ArrayList<WorkspaceItemInfo> = ArrayList()
+
+    abstract fun add(item: 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)
+    }
+
+    override fun onAddToDatabase(writer: ContentWriter) {
+        super.onAddToDatabase(writer)
+        writer.put(LauncherSettings.Favorites.TITLE, title)
+    }
+
+    /** Returns the collection wrapped as {@link LauncherAtom.ItemInfo} for logging. */
+    override fun buildProto(): LauncherAtom.ItemInfo {
+        return buildProto(null)
+    }
+}
diff --git a/src/com/android/launcher3/model/data/FolderInfo.java b/src/com/android/launcher3/model/data/FolderInfo.java
index 83ba2b3..1bbb2fe 100644
--- a/src/com/android/launcher3/model/data/FolderInfo.java
+++ b/src/com/android/launcher3/model/data/FolderInfo.java
@@ -24,8 +24,6 @@
 import static com.android.launcher3.logger.LauncherAtom.Attribute.MANUAL_LABEL;
 import static com.android.launcher3.logger.LauncherAtom.Attribute.SUGGESTED_LABEL;
 
-import android.os.Process;
-
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 
@@ -49,7 +47,7 @@
 /**
  * Represents a folder containing shortcuts or apps.
  */
-public class FolderInfo extends ItemInfo {
+public class FolderInfo extends CollectionInfo {
 
     public static final int NO_FLAGS = 0x00000000;
 
@@ -100,27 +98,15 @@
 
     public FolderNameInfos suggestedFolderNames;
 
-    /**
-     * The apps and shortcuts
-     */
-    public ArrayList<WorkspaceItemInfo> contents = new ArrayList<>();
-
     private ArrayList<FolderListener> mListeners = new ArrayList<>();
 
     public FolderInfo() {
         itemType = LauncherSettings.Favorites.ITEM_TYPE_FOLDER;
-        user = Process.myUserHandle();
     }
 
-    /**
-     * Create an app pair, a type of app collection that launches multiple apps into split screen
-     */
-    public static FolderInfo createAppPair(WorkspaceItemInfo app1, WorkspaceItemInfo app2) {
-        FolderInfo newAppPair = new FolderInfo();
-        newAppPair.itemType = LauncherSettings.Favorites.ITEM_TYPE_APP_PAIR;
-        newAppPair.add(app1, /* animate */ false);
-        newAppPair.add(app2, /* animate */ false);
-        return newAppPair;
+    /** Adds a app or shortcut to the contents array without animation. */
+    public void add(@NonNull WorkspaceItemInfo item) {
+        add(item, false /* animate */);
     }
 
     /**
@@ -129,15 +115,15 @@
      * @param item
      */
     public void add(WorkspaceItemInfo item, boolean animate) {
-        add(item, contents.size(), animate);
+        add(item, getContents().size(), animate);
     }
 
     /**
      * Add an app or shortcut for a specified rank.
      */
     public void add(WorkspaceItemInfo item, int rank, boolean animate) {
-        rank = Utilities.boundToRange(rank, 0, contents.size());
-        contents.add(rank, item);
+        rank = Utilities.boundToRange(rank, 0, getContents().size());
+        getContents().add(rank, item);
         for (int i = 0; i < mListeners.size(); i++) {
             mListeners.get(i).onAdd(item, rank);
         }
@@ -157,7 +143,7 @@
      * Remove all matching app or shortcut. Does not change the DB.
      */
     public void removeAll(List<WorkspaceItemInfo> items, boolean animate) {
-        contents.removeAll(items);
+        getContents().removeAll(items);
         for (int i = 0; i < mListeners.size(); i++) {
             mListeners.get(i).onRemove(items);
         }
@@ -167,8 +153,7 @@
     @Override
     public void onAddToDatabase(@NonNull ContentWriter writer) {
         super.onAddToDatabase(writer);
-        writer.put(LauncherSettings.Favorites.TITLE, title)
-                .put(LauncherSettings.Favorites.OPTIONS, options);
+        writer.put(LauncherSettings.Favorites.OPTIONS, options);
     }
 
     public void addListener(FolderListener listener) {
@@ -219,9 +204,9 @@
 
     @NonNull
     @Override
-    public LauncherAtom.ItemInfo buildProto(@Nullable FolderInfo fInfo) {
+    public LauncherAtom.ItemInfo buildProto(@Nullable CollectionInfo cInfo) {
         FolderIcon.Builder folderIcon = FolderIcon.newBuilder()
-                .setCardinality(contents.size());
+                .setCardinality(getContents().size());
         if (LabelState.SUGGESTED.equals(getLabelState())) {
             folderIcon.setLabelInfo(title.toString());
         }
@@ -278,20 +263,11 @@
     public ItemInfo makeShallowCopy() {
         FolderInfo folderInfo = new FolderInfo();
         folderInfo.copyFrom(this);
-        folderInfo.contents = this.contents;
+        folderInfo.setContents(this.getContents());
         return folderInfo;
     }
 
     /**
-     * Returns {@link LauncherAtom.FolderIcon} wrapped as {@link LauncherAtom.ItemInfo} for logging.
-     */
-    @NonNull
-    @Override
-    public LauncherAtom.ItemInfo buildProto() {
-        return buildProto(null);
-    }
-
-    /**
      * Returns index of the accepted suggestion.
      */
     public OptionalInt getAcceptedSuggestionIndex() {
@@ -371,13 +347,4 @@
         }
         return LauncherAtom.ToState.TO_STATE_UNSPECIFIED;
     }
-
-    @Override
-    public boolean isDisabled() {
-        if (itemType == LauncherSettings.Favorites.ITEM_TYPE_APP_PAIR) {
-            return contents.stream().anyMatch((WorkspaceItemInfo::isDisabled));
-        }
-
-        return super.isDisabled();
-    }
 }
diff --git a/src/com/android/launcher3/model/data/ItemInfo.java b/src/com/android/launcher3/model/data/ItemInfo.java
index f7cff78..8c3efd7 100644
--- a/src/com/android/launcher3/model/data/ItemInfo.java
+++ b/src/com/android/launcher3/model/data/ItemInfo.java
@@ -349,10 +349,9 @@
 
     /**
      * Creates {@link LauncherAtom.ItemInfo} with important fields and parent container info.
-     * @param fInfo
      */
     @NonNull
-    public LauncherAtom.ItemInfo buildProto(@Nullable final FolderInfo fInfo) {
+    public LauncherAtom.ItemInfo buildProto(@Nullable final CollectionInfo cInfo) {
         LauncherAtom.ItemInfo.Builder itemBuilder = getDefaultItemInfoBuilder();
         Optional<ComponentName> nullableComponent = Optional.ofNullable(getTargetComponent());
         switch (itemType) {
@@ -398,21 +397,21 @@
             default:
                 break;
         }
-        if (fInfo != null) {
+        if (cInfo != null) {
             LauncherAtom.FolderContainer.Builder folderBuilder =
                     LauncherAtom.FolderContainer.newBuilder();
             folderBuilder.setGridX(cellX).setGridY(cellY).setPageIndex(screenId);
 
-            switch (fInfo.container) {
+            switch (cInfo.container) {
                 case CONTAINER_HOTSEAT:
                 case CONTAINER_HOTSEAT_PREDICTION:
                     folderBuilder.setHotseat(LauncherAtom.HotseatContainer.newBuilder()
-                            .setIndex(fInfo.screenId));
+                            .setIndex(cInfo.screenId));
                     break;
                 case CONTAINER_DESKTOP:
                     folderBuilder.setWorkspace(LauncherAtom.WorkspaceContainer.newBuilder()
-                            .setPageIndex(fInfo.screenId)
-                            .setGridX(fInfo.cellX).setGridY(fInfo.cellY));
+                            .setPageIndex(cInfo.screenId)
+                            .setGridX(cInfo.cellX).setGridY(cInfo.cellY));
                     break;
             }
             itemBuilder.setContainerInfo(ContainerInfo.newBuilder().setFolder(folderBuilder));
diff --git a/src/com/android/launcher3/model/data/LauncherAppWidgetInfo.java b/src/com/android/launcher3/model/data/LauncherAppWidgetInfo.java
index 6fa8c54..f4dda55 100644
--- a/src/com/android/launcher3/model/data/LauncherAppWidgetInfo.java
+++ b/src/com/android/launcher3/model/data/LauncherAppWidgetInfo.java
@@ -271,8 +271,8 @@
 
     @NonNull
     @Override
-    public LauncherAtom.ItemInfo buildProto(@Nullable FolderInfo folderInfo) {
-        LauncherAtom.ItemInfo info = super.buildProto(folderInfo);
+    public LauncherAtom.ItemInfo buildProto(@Nullable CollectionInfo collectionInfo) {
+        LauncherAtom.ItemInfo info = super.buildProto(collectionInfo);
         return info.toBuilder()
                 .setWidget(info.getWidget().toBuilder().setWidgetFeatures(widgetFeatures))
                 .addItemAttributes(getAttribute(sourceContainer))
diff --git a/src/com/android/launcher3/touch/ItemClickHandler.java b/src/com/android/launcher3/touch/ItemClickHandler.java
index 911568c..0c25e96 100644
--- a/src/com/android/launcher3/touch/ItemClickHandler.java
+++ b/src/com/android/launcher3/touch/ItemClickHandler.java
@@ -53,6 +53,7 @@
 import com.android.launcher3.logging.InstanceIdSequence;
 import com.android.launcher3.logging.StatsLogManager;
 import com.android.launcher3.model.data.AppInfo;
+import com.android.launcher3.model.data.AppPairInfo;
 import com.android.launcher3.model.data.FolderInfo;
 import com.android.launcher3.model.data.ItemInfo;
 import com.android.launcher3.model.data.ItemInfoWithIcon;
@@ -101,11 +102,9 @@
         if (tag instanceof WorkspaceItemInfo) {
             onClickAppShortcut(v, (WorkspaceItemInfo) tag, launcher);
         } else if (tag instanceof FolderInfo) {
-            if (v instanceof FolderIcon) {
-                onClickFolderIcon(v);
-            } else if (v instanceof AppPairIcon) {
-                onClickAppPairIcon(v);
-            }
+            onClickFolderIcon(v);
+        } else if (tag instanceof AppPairInfo) {
+            onClickAppPairIcon(v);
         } else if (tag instanceof AppInfo) {
             startAppShortcutOrInfoActivity(v, (AppInfo) tag, launcher);
         } else if (tag instanceof LauncherAppWidgetInfo) {
@@ -150,7 +149,7 @@
     private static void onClickAppPairIcon(View v) {
         Launcher launcher = Launcher.getLauncher(v.getContext());
         AppPairIcon appPairIcon = (AppPairIcon) v;
-        if (!appPairIcon.isLaunchableAtScreenSize()) {
+        if (!appPairIcon.getInfo().isLaunchable(launcher)) {
             // Display a message for app pairs that are disabled due to screen size
             boolean isFoldable = InvariantDeviceProfile.INSTANCE.get(launcher)
                     .supportedProfiles.stream().anyMatch(dp -> dp.isTwoPanels);
@@ -159,8 +158,8 @@
                             : R.string.app_pair_unlaunchable_at_screen_size,
                     Toast.LENGTH_SHORT).show();
         } else if (appPairIcon.getInfo().isDisabled()) {
-            WorkspaceItemInfo app1 = appPairIcon.getInfo().contents.get(0);
-            WorkspaceItemInfo app2 = appPairIcon.getInfo().contents.get(1);
+            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
diff --git a/src/com/android/launcher3/util/ItemInflater.kt b/src/com/android/launcher3/util/ItemInflater.kt
index 0f8311d..ebf4656 100644
--- a/src/com/android/launcher3/util/ItemInflater.kt
+++ b/src/com/android/launcher3/util/ItemInflater.kt
@@ -29,6 +29,7 @@
 import com.android.launcher3.apppairs.AppPairIcon
 import com.android.launcher3.folder.FolderIcon
 import com.android.launcher3.model.ModelWriter
+import com.android.launcher3.model.data.AppPairInfo
 import com.android.launcher3.model.data.FolderInfo
 import com.android.launcher3.model.data.ItemInfo
 import com.android.launcher3.model.data.LauncherAppWidgetInfo
@@ -81,7 +82,7 @@
                     R.layout.app_pair_icon,
                     context,
                     parent,
-                    item as FolderInfo,
+                    item as AppPairInfo,
                     BubbleTextView.DISPLAY_WORKSPACE
                 )
             Favorites.ITEM_TYPE_APPWIDGET,
diff --git a/src/com/android/launcher3/util/ItemInfoMatcher.java b/src/com/android/launcher3/util/ItemInfoMatcher.java
index 3074111..063313a 100644
--- a/src/com/android/launcher3/util/ItemInfoMatcher.java
+++ b/src/com/android/launcher3/util/ItemInfoMatcher.java
@@ -65,20 +65,11 @@
      * Returns a matcher for items within folders.
      */
     public static Predicate<ItemInfo> forFolderMatch(Predicate<ItemInfo> childOperator) {
-        return info -> info instanceof FolderInfo && ((FolderInfo) info).contents.stream()
+        return info -> info instanceof FolderInfo && ((FolderInfo) info).getContents().stream()
                 .anyMatch(childOperator);
     }
 
     /**
-     * Returns a matcher for items within app pairs.
-     */
-    public static Predicate<ItemInfo> forAppPairMatch(Predicate<ItemInfo> childOperator) {
-        Predicate<ItemInfo> isAppPair = info ->
-                info instanceof FolderInfo fi && fi.itemType == Favorites.ITEM_TYPE_APP_PAIR;
-        return isAppPair.and(forFolderMatch(childOperator));
-    }
-
-    /**
      * Returns a matcher for items with provided ids
      */
     public static Predicate<ItemInfo> ofItemIds(IntSet ids) {
diff --git a/src/com/android/launcher3/util/LauncherBindableItemsContainer.java b/src/com/android/launcher3/util/LauncherBindableItemsContainer.java
index 69786bb..02779ce 100644
--- a/src/com/android/launcher3/util/LauncherBindableItemsContainer.java
+++ b/src/com/android/launcher3/util/LauncherBindableItemsContainer.java
@@ -23,6 +23,7 @@
 import com.android.launcher3.folder.Folder;
 import com.android.launcher3.folder.FolderIcon;
 import com.android.launcher3.graphics.PreloadIconDrawable;
+import com.android.launcher3.model.data.AppPairInfo;
 import com.android.launcher3.model.data.FolderInfo;
 import com.android.launcher3.model.data.ItemInfo;
 import com.android.launcher3.model.data.LauncherAppWidgetInfo;
@@ -59,7 +60,7 @@
                                 : null);
             } else if (info instanceof FolderInfo && v instanceof FolderIcon) {
                 ((FolderIcon) v).updatePreviewItems(updates::contains);
-            } else if (info instanceof FolderInfo && v instanceof AppPairIcon appPairIcon) {
+            } else if (info instanceof AppPairInfo && v instanceof AppPairIcon appPairIcon) {
                 appPairIcon.maybeRedrawForWorkspaceUpdate(updates::contains);
             }
 
@@ -89,7 +90,7 @@
                 ((PendingAppWidgetHostView) v).applyState();
             } else if (v instanceof FolderIcon && info instanceof FolderInfo) {
                 ((FolderIcon) v).updatePreviewItems(updates::contains);
-            } else if (info instanceof FolderInfo && v instanceof AppPairIcon appPairIcon) {
+            } else if (info instanceof AppPairInfo && v instanceof AppPairIcon appPairIcon) {
                 appPairIcon.maybeRedrawForWorkspaceUpdate(updates::contains);
             }
             // process all the shortcuts
diff --git a/src/com/android/launcher3/widget/PendingAddWidgetInfo.java b/src/com/android/launcher3/widget/PendingAddWidgetInfo.java
index a501960..a916252 100644
--- a/src/com/android/launcher3/widget/PendingAddWidgetInfo.java
+++ b/src/com/android/launcher3/widget/PendingAddWidgetInfo.java
@@ -25,7 +25,7 @@
 import com.android.launcher3.LauncherSettings;
 import com.android.launcher3.PendingAddItemInfo;
 import com.android.launcher3.logger.LauncherAtom;
-import com.android.launcher3.model.data.FolderInfo;
+import com.android.launcher3.model.data.CollectionInfo;
 import com.android.launcher3.model.data.LauncherAppWidgetInfo;
 import com.android.launcher3.widget.picker.WidgetRecommendationCategory;
 import com.android.launcher3.widget.util.WidgetSizes;
@@ -82,8 +82,8 @@
 
     @NonNull
     @Override
-    public LauncherAtom.ItemInfo buildProto(@Nullable FolderInfo folderInfo) {
-        LauncherAtom.ItemInfo info = super.buildProto(folderInfo);
+    public LauncherAtom.ItemInfo buildProto(@Nullable CollectionInfo collectionInfo) {
+        LauncherAtom.ItemInfo info = super.buildProto(collectionInfo);
         return info.toBuilder()
                 .addItemAttributes(LauncherAppWidgetInfo.getAttribute(sourceContainer))
                 .build();
diff --git a/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java b/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java
index fcd2571..5cf8203 100644
--- a/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java
+++ b/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java
@@ -548,6 +548,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);
diff --git a/src/com/android/launcher3/widget/picker/WidgetsRecommendationTableLayout.java b/src/com/android/launcher3/widget/picker/WidgetsRecommendationTableLayout.java
index 7a2b4ef..563894d 100644
--- a/src/com/android/launcher3/widget/picker/WidgetsRecommendationTableLayout.java
+++ b/src/com/android/launcher3/widget/picker/WidgetsRecommendationTableLayout.java
@@ -109,7 +109,6 @@
                 WidgetCell widgetCell = addItemCell(tableRow);
                 widgetCell.applyFromCellItem(widgetItem);
                 widgetCell.showAppIconInWidgetTitle(true);
-                widgetCell.showBadge();
                 if (enableCategorizedWidgetSuggestions()) {
                     widgetCell.showDescription(false);
                     widgetCell.showDimensions(false);
diff --git a/tests/multivalentTests/src/com/android/launcher3/celllayout/FavoriteItemsTransaction.java b/tests/multivalentTests/src/com/android/launcher3/celllayout/FavoriteItemsTransaction.java
index b86333c..0c3081f 100644
--- a/tests/multivalentTests/src/com/android/launcher3/celllayout/FavoriteItemsTransaction.java
+++ b/tests/multivalentTests/src/com/android/launcher3/celllayout/FavoriteItemsTransaction.java
@@ -26,7 +26,7 @@
 import com.android.launcher3.LauncherModel;
 import com.android.launcher3.LauncherSettings;
 import com.android.launcher3.model.ModelDbController;
-import com.android.launcher3.model.data.FolderInfo;
+import com.android.launcher3.model.data.CollectionInfo;
 import com.android.launcher3.model.data.ItemInfo;
 import com.android.launcher3.provider.LauncherDbUtils.SQLiteTransaction;
 import com.android.launcher3.util.ContentWriter;
@@ -73,9 +73,8 @@
                     ContentWriter writer = new ContentWriter(mContext);
                     ItemInfo item = mItemsToSubmit.get(i).get();
 
-                    if (item.itemType == LauncherSettings.Favorites.ITEM_TYPE_FOLDER) {
-                        FolderInfo folderInfo = (FolderInfo) item;
-                        for (ItemInfo itemInfo : folderInfo.contents) {
+                    if (item instanceof CollectionInfo ci) {
+                        for (ItemInfo itemInfo : ci.getContents()) {
                             itemInfo.container = i;
                             containerItems.add(itemInfo);
                         }
diff --git a/tests/src/com/android/launcher3/folder/PreviewItemManagerTest.kt b/tests/src/com/android/launcher3/folder/PreviewItemManagerTest.kt
index 4ec5b0e..3a1883c 100644
--- a/tests/src/com/android/launcher3/folder/PreviewItemManagerTest.kt
+++ b/tests/src/com/android/launcher3/folder/PreviewItemManagerTest.kt
@@ -28,6 +28,7 @@
 import com.android.launcher3.icons.BaseIconFactory
 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.util.ActivityContextWrapper
 import com.android.launcher3.util.FlagOp
@@ -71,8 +72,8 @@
                     .build()
             )
             .loadModelSync()
-        folderItems = modelHelper.bgDataModel.folders.valueAt(0).contents
-        folderIcon.mInfo = modelHelper.bgDataModel.folders.valueAt(0)
+        folderItems = modelHelper.bgDataModel.collections.valueAt(0).contents
+        folderIcon.mInfo = modelHelper.bgDataModel.collections.valueAt(0) as FolderInfo
         folderIcon.mInfo.contents = folderItems
 
         // Set first icon to be themed.
diff --git a/tests/src/com/android/launcher3/model/CacheDataUpdatedTaskTest.java b/tests/src/com/android/launcher3/model/CacheDataUpdatedTaskTest.java
index 7a0b60a..abb0c39 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)).contents;
+        return ((FolderInfo) mModelHelper.getBgDataModel().itemsIdMap.get(1)).getContents();
     }
 }
diff --git a/tests/src/com/android/launcher3/model/DefaultLayoutProviderTest.java b/tests/src/com/android/launcher3/model/DefaultLayoutProviderTest.java
index 2b89321..10785f7 100644
--- a/tests/src/com/android/launcher3/model/DefaultLayoutProviderTest.java
+++ b/tests/src/com/android/launcher3/model/DefaultLayoutProviderTest.java
@@ -87,7 +87,7 @@
         assertEquals(1, mModelHelper.getBgDataModel().workspaceItems.size());
         ItemInfo info = mModelHelper.getBgDataModel().workspaceItems.get(0);
         assertEquals(LauncherSettings.Favorites.ITEM_TYPE_FOLDER, info.itemType);
-        assertEquals(3, ((FolderInfo) info).contents.size());
+        assertEquals(3, ((FolderInfo) info).getContents().size());
     }
 
     @Test
@@ -102,7 +102,7 @@
         assertEquals(1, mModelHelper.getBgDataModel().workspaceItems.size());
         ItemInfo info = mModelHelper.getBgDataModel().workspaceItems.get(0);
         assertEquals(LauncherSettings.Favorites.ITEM_TYPE_FOLDER, info.itemType);
-        assertEquals(3, ((FolderInfo) info).contents.size());
+        assertEquals(3, ((FolderInfo) info).getContents().size());
         assertEquals("CustomFolder", info.title.toString());
     }
 
@@ -154,11 +154,11 @@
         // Verify folder
         assertEquals(1, mModelHelper.getBgDataModel().workspaceItems.size());
         FolderInfo info = (FolderInfo) mModelHelper.getBgDataModel().workspaceItems.get(0);
-        assertEquals(3, info.contents.size());
+        assertEquals(3, info.getContents().size());
 
         // Verify last icon
         assertEquals(LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT,
-                info.contents.get(info.contents.size() - 1).itemType);
+                info.getContents().get(info.getContents().size() - 1).itemType);
     }
 
     private void writeLayoutAndLoad(LauncherLayoutBuilder builder) throws Exception {
diff --git a/tests/src/com/android/launcher3/model/FolderIconLoadTest.kt b/tests/src/com/android/launcher3/model/FolderIconLoadTest.kt
index 2118ed6..ed587a1 100644
--- a/tests/src/com/android/launcher3/model/FolderIconLoadTest.kt
+++ b/tests/src/com/android/launcher3/model/FolderIconLoadTest.kt
@@ -165,11 +165,11 @@
         // Reload again with correct icon state
         app.model.forceReload()
         modelHelper.loadModelSync()
-        val folders = modelHelper.getBgDataModel().folders
+        val collections = modelHelper.getBgDataModel().collections
 
-        assertThat(folders.size()).isEqualTo(1)
-        assertThat(folders.valueAt(0).contents.size).isEqualTo(itemCount)
-        return folders.valueAt(0).contents
+        assertThat(collections.size()).isEqualTo(1)
+        assertThat(collections.valueAt(0).contents.size).isEqualTo(itemCount)
+        return collections.valueAt(0).contents
     }
 
     private fun verifyHighRes(items: ArrayList<WorkspaceItemInfo>, vararg indices: Int) {
diff --git a/tests/src/com/android/launcher3/model/LoaderTaskTest.kt b/tests/src/com/android/launcher3/model/LoaderTaskTest.kt
index bbe8265..5731e2a 100644
--- a/tests/src/com/android/launcher3/model/LoaderTaskTest.kt
+++ b/tests/src/com/android/launcher3/model/LoaderTaskTest.kt
@@ -103,7 +103,7 @@
                 .runSyncOnBackgroundThread()
             Truth.assertThat(workspaceItems.size).isAtLeast(25)
             Truth.assertThat(appWidgets.size).isAtLeast(7)
-            Truth.assertThat(folders.size()).isAtLeast(8)
+            Truth.assertThat(collections.size()).isAtLeast(8)
             Truth.assertThat(itemsIdMap.size()).isAtLeast(40)
         }
 
diff --git a/tests/src/com/android/launcher3/util/ItemInflaterTest.kt b/tests/src/com/android/launcher3/util/ItemInflaterTest.kt
index efad899..0065527 100644
--- a/tests/src/com/android/launcher3/util/ItemInflaterTest.kt
+++ b/tests/src/com/android/launcher3/util/ItemInflaterTest.kt
@@ -36,6 +36,7 @@
 import com.android.launcher3.folder.FolderIcon
 import com.android.launcher3.model.ModelWriter
 import com.android.launcher3.model.data.AppInfo
+import com.android.launcher3.model.data.AppPairInfo
 import com.android.launcher3.model.data.FolderInfo
 import com.android.launcher3.model.data.LauncherAppWidgetInfo
 import com.android.launcher3.model.data.LauncherAppWidgetInfo.FLAG_ID_NOT_VALID
@@ -170,7 +171,7 @@
 
     @Test
     fun test_app_pair_inflated_on_UI() {
-        val itemInfo = FolderInfo()
+        val itemInfo = AppPairInfo()
         itemInfo.itemType = ITEM_TYPE_APP_PAIR
         itemInfo.contents.add(workspaceItemInfo())
         itemInfo.contents.add(workspaceItemInfo())
@@ -186,7 +187,7 @@
     fun test_app_pair_inflated_on_BG() {
         setFlagsRule.enableFlags(Flags.FLAG_ENABLE_WORKSPACE_INFLATION)
 
-        val itemInfo = FolderInfo()
+        val itemInfo = AppPairInfo()
         itemInfo.itemType = ITEM_TYPE_APP_PAIR
         itemInfo.contents.add(workspaceItemInfo())
         itemInfo.contents.add(workspaceItemInfo())