Merge "Fixing reverted order of accessibility scrolling in Recents" into ub-launcher3-edmonton
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index fde22eb..b7c5793 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -72,7 +72,7 @@
             android:stateNotNeeded="true"
             android:windowSoftInputMode="adjustPan"
             android:screenOrientation="unspecified"
-            android:configChanges="keyboard|keyboardHidden|navigation"
+            android:configChanges="keyboard|keyboardHidden|mcc|mnc|navigation|orientation|screenSize|screenLayout|smallestScreenSize"
             android:resizeableActivity="true"
             android:resumeWhilePausing="true"
             android:taskAffinity=""
diff --git a/go/res/values-ar/strings.xml b/go/res/values-ar/strings.xml
index 2b3b807..9888d0f 100644
--- a/go/res/values-ar/strings.xml
+++ b/go/res/values-ar/strings.xml
@@ -20,7 +20,7 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="long_press_widget_to_add" msgid="4001616142797446267">"المس مع الاستمرار لاختيار اختصار."</string>
-    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"يمكنك النقر نقرًا مزدوجًا مع الاستمرار لاختيار اختصار أو استخدام الإجراءات المخصصة."</string>
+    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"يمكنك النقر مرّتين مع الاستمرار لاختيار اختصار أو استخدام الإجراءات المخصصة."</string>
     <string name="widget_button_text" msgid="4221900832360456858">"الاختصارات"</string>
     <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"اختصارات <xliff:g id="NAME">%1$s</xliff:g>"</string>
 </resources>
diff --git a/protos/launcher_log.proto b/protos/launcher_log.proto
index 179f21d..065663d 100644
--- a/protos/launcher_log.proto
+++ b/protos/launcher_log.proto
@@ -55,6 +55,7 @@
   optional int32 span_y = 14 [default = 1];// Used for ItemType.WIDGET
   optional int32 predictedRank = 15;
   optional TargetExtension extension = 16;
+  optional TipType tip_type = 17;
 }
 
 // Used to define what type of item a Target would represent.
@@ -88,6 +89,8 @@
   NAVBAR = 11;
   TASKSWITCHER = 12; // Recents UI Container (QuickStep)
   APP = 13; // Foreground activity is another app (QuickStep)
+  TIP = 14; // Onboarding texts (QuickStep)
+  SIDELOADED_LAUNCHER = 15;
 }
 
 // Used to define what type of control a Target would represent.
@@ -109,14 +112,24 @@
   CANCEL_TARGET = 14;
 }
 
+enum TipType {
+  DEFAULT_NONE = 0;
+  BOUNCE = 1;
+  SWIPE_UP_TEXT = 2;
+  QUICK_SCRUB_TEXT = 3;
+  PREDICTION_TEXT = 4;
+}
+
 // Used to define the action component of the LauncherEvent.
 message Action {
   enum Type {
     TOUCH = 0;
     AUTOMATED = 1;
     COMMAND = 2;
+    TIP = 3;
     // SOFT_KEYBOARD, HARD_KEYBOARD, ASSIST
   }
+
   enum Touch {
     TAP = 0;
     LONGPRESS = 1;
@@ -125,7 +138,8 @@
     FLING = 4;
     PINCH = 5;
   }
- enum Direction {
+
+  enum Direction {
     NONE = 0;
     UP = 1;
     DOWN = 2;
@@ -135,11 +149,12 @@
   enum Command {
     HOME_INTENT = 0;
     BACK = 1;
-    ENTRY = 2;    // Indicates entry to one of Launcher container type target
-                  // not using the HOME_INTENT
-    CANCEL = 3;   // Indicates that a confirmation screen was cancelled
-    CONFIRM = 4;  // Indicates thata confirmation screen was accepted
-    STOP = 5;     // Indicates onStop() was called (screen time out, power off)
+    ENTRY = 2;          // Indicates entry to one of Launcher container type target
+                        // not using the HOME_INTENT
+    CANCEL = 3;         // Indicates that a confirmation screen was cancelled
+    CONFIRM = 4;        // Indicates thata confirmation screen was accepted
+    STOP = 5;           // Indicates onStop() was called (screen time out, power off)
+    RECENTS_BUTTON = 6; // Indicates that Recents button was pressed
   }
 
   optional Type type = 1;
diff --git a/quickstep/AndroidManifest.xml b/quickstep/AndroidManifest.xml
index ac38906..778866d 100644
--- a/quickstep/AndroidManifest.xml
+++ b/quickstep/AndroidManifest.xml
@@ -54,7 +54,7 @@
             android:stateNotNeeded="true"
             android:theme="@style/LauncherTheme"
             android:screenOrientation="unspecified"
-            android:configChanges="keyboard|keyboardHidden|navigation|orientation|screenSize|screenLayout|smallestScreenSize"
+            android:configChanges="keyboard|keyboardHidden|mcc|mnc|navigation|orientation|screenSize|screenLayout|smallestScreenSize"
             android:resizeableActivity="true"
             android:resumeWhilePausing="true"
             android:taskAffinity="" />
diff --git a/quickstep/libs/sysui_shared.jar b/quickstep/libs/sysui_shared.jar
index 398bd3c..53a6ceb 100644
--- a/quickstep/libs/sysui_shared.jar
+++ b/quickstep/libs/sysui_shared.jar
Binary files differ
diff --git a/quickstep/res/layout/drag_handle_indicator.xml b/quickstep/res/layout/drag_handle_indicator.xml
deleted file mode 100644
index 9ee05d5..0000000
--- a/quickstep/res/layout/drag_handle_indicator.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<com.android.quickstep.views.QuickstepDragIndicator
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/drag_indicator"
-    android:layout_width="wrap_content"
-    android:layout_height="wrap_content"
-    android:contentDescription="@string/accessibility_desc_recent_apps"
-    android:scaleType="centerInside"
-    android:tint="?attr/workspaceTextColor" />
diff --git a/res/layout/drag_handle_indicator.xml b/quickstep/res/layout/scrim_view.xml
similarity index 69%
copy from res/layout/drag_handle_indicator.xml
copy to quickstep/res/layout/scrim_view.xml
index d5a7b8a..2cc37f9 100644
--- a/res/layout/drag_handle_indicator.xml
+++ b/quickstep/res/layout/scrim_view.xml
@@ -13,11 +13,8 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<com.android.launcher3.views.LauncherDragIndicator
+<com.android.quickstep.views.ShelfScrimView
     xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/drag_indicator"
-    android:layout_width="wrap_content"
-    android:layout_height="wrap_content"
-    android:contentDescription="@string/all_apps_button_label"
-    android:scaleType="centerInside"
-    android:tint="?attr/workspaceTextColor" />
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:id="@+id/scrim_view" />
\ No newline at end of file
diff --git a/quickstep/res/values-af/strings.xml b/quickstep/res/values-af/strings.xml
index f9ffe4b..b33456d 100644
--- a/quickstep/res/values-af/strings.xml
+++ b/quickstep/res/values-af/strings.xml
@@ -25,4 +25,6 @@
     <string name="recents_empty_message" msgid="7040467240571714191">"Geen onlangse items nie"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Maak toe"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Vee alles uit"</string>
+    <!-- no translation found for accessibility_recent_apps (4058661986695117371) -->
+    <skip />
 </resources>
diff --git a/quickstep/res/values-am/strings.xml b/quickstep/res/values-am/strings.xml
index 428b46d..2f303c0 100644
--- a/quickstep/res/values-am/strings.xml
+++ b/quickstep/res/values-am/strings.xml
@@ -25,4 +25,6 @@
     <string name="recents_empty_message" msgid="7040467240571714191">"ምንም የቅርብ ጊዜ ንጥሎች የሉም"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"ዝጋ"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"ሁሉንም አጽዳ"</string>
+    <!-- no translation found for accessibility_recent_apps (4058661986695117371) -->
+    <skip />
 </resources>
diff --git a/quickstep/res/values-ar/strings.xml b/quickstep/res/values-ar/strings.xml
index a6011e7..e22bef4 100644
--- a/quickstep/res/values-ar/strings.xml
+++ b/quickstep/res/values-ar/strings.xml
@@ -25,4 +25,6 @@
     <string name="recents_empty_message" msgid="7040467240571714191">"ليست هناك عناصر تم استخدامها مؤخرًا"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"إغلاق"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"محو الكل"</string>
+    <!-- no translation found for accessibility_recent_apps (4058661986695117371) -->
+    <skip />
 </resources>
diff --git a/quickstep/res/values-as/strings.xml b/quickstep/res/values-as/strings.xml
index dad6102..7294f14 100644
--- a/quickstep/res/values-as/strings.xml
+++ b/quickstep/res/values-as/strings.xml
@@ -25,4 +25,6 @@
     <string name="recents_empty_message" msgid="7040467240571714191">"কোনো শেহতীয়া বস্তু নাই"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"বন্ধ কৰক"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"সকলো মচক"</string>
+    <!-- no translation found for accessibility_recent_apps (4058661986695117371) -->
+    <skip />
 </resources>
diff --git a/quickstep/res/values-az/strings.xml b/quickstep/res/values-az/strings.xml
index 0546f46..4c2f8ec 100644
--- a/quickstep/res/values-az/strings.xml
+++ b/quickstep/res/values-az/strings.xml
@@ -25,4 +25,6 @@
     <string name="recents_empty_message" msgid="7040467240571714191">"Son elementlər yoxdur"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Bağlayın"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Hamısını silin"</string>
+    <!-- no translation found for accessibility_recent_apps (4058661986695117371) -->
+    <skip />
 </resources>
diff --git a/quickstep/res/values-b+sr+Latn/strings.xml b/quickstep/res/values-b+sr+Latn/strings.xml
index 9a6edd1..bf66aef 100644
--- a/quickstep/res/values-b+sr+Latn/strings.xml
+++ b/quickstep/res/values-b+sr+Latn/strings.xml
@@ -25,4 +25,6 @@
     <string name="recents_empty_message" msgid="7040467240571714191">"Nema nedavnih stavki"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Zatvori"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Obriši sve"</string>
+    <!-- no translation found for accessibility_recent_apps (4058661986695117371) -->
+    <skip />
 </resources>
diff --git a/quickstep/res/values-be/strings.xml b/quickstep/res/values-be/strings.xml
index 1e60dd3..48ed4c5 100644
--- a/quickstep/res/values-be/strings.xml
+++ b/quickstep/res/values-be/strings.xml
@@ -25,4 +25,6 @@
     <string name="recents_empty_message" msgid="7040467240571714191">"Няма новых элементаў"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Закрыць"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Ачысціць усё"</string>
+    <!-- no translation found for accessibility_recent_apps (4058661986695117371) -->
+    <skip />
 </resources>
diff --git a/quickstep/res/values-bg/strings.xml b/quickstep/res/values-bg/strings.xml
index cfbc08d..30308ad 100644
--- a/quickstep/res/values-bg/strings.xml
+++ b/quickstep/res/values-bg/strings.xml
@@ -25,4 +25,6 @@
     <string name="recents_empty_message" msgid="7040467240571714191">"Няма скорошни елементи"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Затваряне"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Изчистване на всички"</string>
+    <!-- no translation found for accessibility_recent_apps (4058661986695117371) -->
+    <skip />
 </resources>
diff --git a/quickstep/res/values-bn/strings.xml b/quickstep/res/values-bn/strings.xml
index a0605d8..80eb639 100644
--- a/quickstep/res/values-bn/strings.xml
+++ b/quickstep/res/values-bn/strings.xml
@@ -25,4 +25,6 @@
     <string name="recents_empty_message" msgid="7040467240571714191">"কোনো সাম্প্রতিক আইটেম নেই"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"বন্ধ করুন"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"সবকিছু খালি করুন"</string>
+    <!-- no translation found for accessibility_recent_apps (4058661986695117371) -->
+    <skip />
 </resources>
diff --git a/quickstep/res/values-bs/strings.xml b/quickstep/res/values-bs/strings.xml
index 9ffa848..201f461 100644
--- a/quickstep/res/values-bs/strings.xml
+++ b/quickstep/res/values-bs/strings.xml
@@ -25,4 +25,6 @@
     <string name="recents_empty_message" msgid="7040467240571714191">"Nema nedavnih stavki"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Zatvaranje"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Obriši sve"</string>
+    <!-- no translation found for accessibility_recent_apps (4058661986695117371) -->
+    <skip />
 </resources>
diff --git a/quickstep/res/values-ca/strings.xml b/quickstep/res/values-ca/strings.xml
index b5f2bf1..c6b93e3 100644
--- a/quickstep/res/values-ca/strings.xml
+++ b/quickstep/res/values-ca/strings.xml
@@ -25,4 +25,6 @@
     <string name="recents_empty_message" msgid="7040467240571714191">"No hi ha cap element recent"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Tanca"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Esborra-ho tot"</string>
+    <!-- no translation found for accessibility_recent_apps (4058661986695117371) -->
+    <skip />
 </resources>
diff --git a/quickstep/res/values-cs/strings.xml b/quickstep/res/values-cs/strings.xml
index 25c8f81..023244c 100644
--- a/quickstep/res/values-cs/strings.xml
+++ b/quickstep/res/values-cs/strings.xml
@@ -25,4 +25,6 @@
     <string name="recents_empty_message" msgid="7040467240571714191">"Žádné nedávné položky"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Zavřít"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Vymazat vše"</string>
+    <!-- no translation found for accessibility_recent_apps (4058661986695117371) -->
+    <skip />
 </resources>
diff --git a/quickstep/res/values-da/strings.xml b/quickstep/res/values-da/strings.xml
index de5529f..5d1e763 100644
--- a/quickstep/res/values-da/strings.xml
+++ b/quickstep/res/values-da/strings.xml
@@ -25,4 +25,6 @@
     <string name="recents_empty_message" msgid="7040467240571714191">"Ingen nye elementer"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Luk"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Ryd alt"</string>
+    <!-- no translation found for accessibility_recent_apps (4058661986695117371) -->
+    <skip />
 </resources>
diff --git a/quickstep/res/values-de/strings.xml b/quickstep/res/values-de/strings.xml
index 63483d9..cf2f194 100644
--- a/quickstep/res/values-de/strings.xml
+++ b/quickstep/res/values-de/strings.xml
@@ -25,4 +25,6 @@
     <string name="recents_empty_message" msgid="7040467240571714191">"Keine kürzlich verwendeten Elemente"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Schließen"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Alle Apps schließen"</string>
+    <!-- no translation found for accessibility_recent_apps (4058661986695117371) -->
+    <skip />
 </resources>
diff --git a/quickstep/res/values-el/strings.xml b/quickstep/res/values-el/strings.xml
index e5dd604..9cf0576 100644
--- a/quickstep/res/values-el/strings.xml
+++ b/quickstep/res/values-el/strings.xml
@@ -25,4 +25,6 @@
     <string name="recents_empty_message" msgid="7040467240571714191">"Δεν υπάρχουν πρόσφατα στοιχεία"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Κλείσιμο"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Διαγραφή όλων"</string>
+    <!-- no translation found for accessibility_recent_apps (4058661986695117371) -->
+    <skip />
 </resources>
diff --git a/quickstep/res/values-es-rUS/strings.xml b/quickstep/res/values-es-rUS/strings.xml
index 642fe4c..320892a 100644
--- a/quickstep/res/values-es-rUS/strings.xml
+++ b/quickstep/res/values-es-rUS/strings.xml
@@ -25,4 +25,6 @@
     <string name="recents_empty_message" msgid="7040467240571714191">"No hay elementos recientes"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Cerrar"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Borrar todo"</string>
+    <!-- no translation found for accessibility_recent_apps (4058661986695117371) -->
+    <skip />
 </resources>
diff --git a/quickstep/res/values-es/strings.xml b/quickstep/res/values-es/strings.xml
index 4f74a38..abccec8 100644
--- a/quickstep/res/values-es/strings.xml
+++ b/quickstep/res/values-es/strings.xml
@@ -25,4 +25,6 @@
     <string name="recents_empty_message" msgid="7040467240571714191">"No hay elementos recientes"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Cerrar"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Borrar todo"</string>
+    <!-- no translation found for accessibility_recent_apps (4058661986695117371) -->
+    <skip />
 </resources>
diff --git a/quickstep/res/values-et/strings.xml b/quickstep/res/values-et/strings.xml
index efa68f9..5143406 100644
--- a/quickstep/res/values-et/strings.xml
+++ b/quickstep/res/values-et/strings.xml
@@ -25,4 +25,6 @@
     <string name="recents_empty_message" msgid="7040467240571714191">"Hiljutisi üksusi pole"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Sule"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Sule kõik"</string>
+    <!-- no translation found for accessibility_recent_apps (4058661986695117371) -->
+    <skip />
 </resources>
diff --git a/quickstep/res/values-eu/strings.xml b/quickstep/res/values-eu/strings.xml
index d22242e..879aa28 100644
--- a/quickstep/res/values-eu/strings.xml
+++ b/quickstep/res/values-eu/strings.xml
@@ -25,4 +25,6 @@
     <string name="recents_empty_message" msgid="7040467240571714191">"Ez dago azkenaldi honetako ezer"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Itxi"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Garbitu guztiak"</string>
+    <!-- no translation found for accessibility_recent_apps (4058661986695117371) -->
+    <skip />
 </resources>
diff --git a/quickstep/res/values-fa/strings.xml b/quickstep/res/values-fa/strings.xml
index fa610a2..b76e9a5 100644
--- a/quickstep/res/values-fa/strings.xml
+++ b/quickstep/res/values-fa/strings.xml
@@ -25,4 +25,6 @@
     <string name="recents_empty_message" msgid="7040467240571714191">"بدون موارد اخیر"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"بستن"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"پاک کردن همه"</string>
+    <!-- no translation found for accessibility_recent_apps (4058661986695117371) -->
+    <skip />
 </resources>
diff --git a/quickstep/res/values-fi/strings.xml b/quickstep/res/values-fi/strings.xml
index 2c4aa04..bbfaa11 100644
--- a/quickstep/res/values-fi/strings.xml
+++ b/quickstep/res/values-fi/strings.xml
@@ -25,4 +25,6 @@
     <string name="recents_empty_message" msgid="7040467240571714191">"Ei viimeaikaisia kohteita"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Sulje"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Poista kaikki"</string>
+    <!-- no translation found for accessibility_recent_apps (4058661986695117371) -->
+    <skip />
 </resources>
diff --git a/quickstep/res/values-fr-rCA/strings.xml b/quickstep/res/values-fr-rCA/strings.xml
index 892c43f..7cad9fc 100644
--- a/quickstep/res/values-fr-rCA/strings.xml
+++ b/quickstep/res/values-fr-rCA/strings.xml
@@ -25,4 +25,6 @@
     <string name="recents_empty_message" msgid="7040467240571714191">"Aucun élément récent"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Fermer"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Tout effacer"</string>
+    <!-- no translation found for accessibility_recent_apps (4058661986695117371) -->
+    <skip />
 </resources>
diff --git a/quickstep/res/values-fr/strings.xml b/quickstep/res/values-fr/strings.xml
index 4930449..078ab2b 100644
--- a/quickstep/res/values-fr/strings.xml
+++ b/quickstep/res/values-fr/strings.xml
@@ -25,4 +25,6 @@
     <string name="recents_empty_message" msgid="7040467240571714191">"Aucun élément récent"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Fermer"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Tout effacer"</string>
+    <!-- no translation found for accessibility_recent_apps (4058661986695117371) -->
+    <skip />
 </resources>
diff --git a/quickstep/res/values-gl/strings.xml b/quickstep/res/values-gl/strings.xml
index 8efc773..549d804 100644
--- a/quickstep/res/values-gl/strings.xml
+++ b/quickstep/res/values-gl/strings.xml
@@ -25,4 +25,6 @@
     <string name="recents_empty_message" msgid="7040467240571714191">"Non hai elementos recentes"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Pecha a aplicación"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Borrar todo"</string>
+    <!-- no translation found for accessibility_recent_apps (4058661986695117371) -->
+    <skip />
 </resources>
diff --git a/quickstep/res/values-gu/strings.xml b/quickstep/res/values-gu/strings.xml
index cdae86f..27235f2 100644
--- a/quickstep/res/values-gu/strings.xml
+++ b/quickstep/res/values-gu/strings.xml
@@ -25,4 +25,6 @@
     <string name="recents_empty_message" msgid="7040467240571714191">"તાજેતરની કોઈ આઇટમ નથી"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"બંધ કરો"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"બધું સાફ કરો"</string>
+    <!-- no translation found for accessibility_recent_apps (4058661986695117371) -->
+    <skip />
 </resources>
diff --git a/quickstep/res/values-hi/strings.xml b/quickstep/res/values-hi/strings.xml
index 06d0ab1..46b404f 100644
--- a/quickstep/res/values-hi/strings.xml
+++ b/quickstep/res/values-hi/strings.xml
@@ -25,4 +25,6 @@
     <string name="recents_empty_message" msgid="7040467240571714191">"हाल ही में इस्तेमाल किया गया कोई ऐप्लिकेशन नहीं है"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"बंद करें"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"सभी ऐप्लिकेशन बंद करें"</string>
+    <!-- no translation found for accessibility_recent_apps (4058661986695117371) -->
+    <skip />
 </resources>
diff --git a/quickstep/res/values-hr/strings.xml b/quickstep/res/values-hr/strings.xml
index aacc6dd..b868260 100644
--- a/quickstep/res/values-hr/strings.xml
+++ b/quickstep/res/values-hr/strings.xml
@@ -25,4 +25,6 @@
     <string name="recents_empty_message" msgid="7040467240571714191">"Nema nedavnih stavki"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Zatvori"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Izbriši sve"</string>
+    <!-- no translation found for accessibility_recent_apps (4058661986695117371) -->
+    <skip />
 </resources>
diff --git a/quickstep/res/values-hu/strings.xml b/quickstep/res/values-hu/strings.xml
index d033741..60cd6a1 100644
--- a/quickstep/res/values-hu/strings.xml
+++ b/quickstep/res/values-hu/strings.xml
@@ -25,4 +25,6 @@
     <string name="recents_empty_message" msgid="7040467240571714191">"Nincsenek mostanában használt elemek"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Bezárás"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Összes törlése"</string>
+    <!-- no translation found for accessibility_recent_apps (4058661986695117371) -->
+    <skip />
 </resources>
diff --git a/quickstep/res/values-hy/strings.xml b/quickstep/res/values-hy/strings.xml
index 4afae7d..c908263 100644
--- a/quickstep/res/values-hy/strings.xml
+++ b/quickstep/res/values-hy/strings.xml
@@ -25,4 +25,6 @@
     <string name="recents_empty_message" msgid="7040467240571714191">"Վերջին տարրեր չկան"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Փակել"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Փակել բոլորը"</string>
+    <!-- no translation found for accessibility_recent_apps (4058661986695117371) -->
+    <skip />
 </resources>
diff --git a/quickstep/res/values-in/strings.xml b/quickstep/res/values-in/strings.xml
index 7adc31e..ff6267c 100644
--- a/quickstep/res/values-in/strings.xml
+++ b/quickstep/res/values-in/strings.xml
@@ -25,4 +25,6 @@
     <string name="recents_empty_message" msgid="7040467240571714191">"Tidak ada item yang baru dibuka"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Tutup"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Hapus semua"</string>
+    <!-- no translation found for accessibility_recent_apps (4058661986695117371) -->
+    <skip />
 </resources>
diff --git a/quickstep/res/values-is/strings.xml b/quickstep/res/values-is/strings.xml
index 88a92ed..bbb4607 100644
--- a/quickstep/res/values-is/strings.xml
+++ b/quickstep/res/values-is/strings.xml
@@ -25,4 +25,6 @@
     <string name="recents_empty_message" msgid="7040467240571714191">"Engin nýleg atriði"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Loka"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Hreinsa allt"</string>
+    <!-- no translation found for accessibility_recent_apps (4058661986695117371) -->
+    <skip />
 </resources>
diff --git a/quickstep/res/values-it/strings.xml b/quickstep/res/values-it/strings.xml
index e95faf8..6175a47 100644
--- a/quickstep/res/values-it/strings.xml
+++ b/quickstep/res/values-it/strings.xml
@@ -25,4 +25,6 @@
     <string name="recents_empty_message" msgid="7040467240571714191">"Nessun elemento recente"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Chiudi"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Cancella tutto"</string>
+    <!-- no translation found for accessibility_recent_apps (4058661986695117371) -->
+    <skip />
 </resources>
diff --git a/quickstep/res/values-iw/strings.xml b/quickstep/res/values-iw/strings.xml
index ee4f040..9afb842 100644
--- a/quickstep/res/values-iw/strings.xml
+++ b/quickstep/res/values-iw/strings.xml
@@ -25,4 +25,6 @@
     <string name="recents_empty_message" msgid="7040467240571714191">"אין פריטים אחרונים"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"סגירה"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"ניקוי הכול"</string>
+    <!-- no translation found for accessibility_recent_apps (4058661986695117371) -->
+    <skip />
 </resources>
diff --git a/quickstep/res/values-ja/strings.xml b/quickstep/res/values-ja/strings.xml
index f32e2e6..e478d4a 100644
--- a/quickstep/res/values-ja/strings.xml
+++ b/quickstep/res/values-ja/strings.xml
@@ -25,4 +25,6 @@
     <string name="recents_empty_message" msgid="7040467240571714191">"最近のアイテムはありません"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"閉じる"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"すべてクリア"</string>
+    <!-- no translation found for accessibility_recent_apps (4058661986695117371) -->
+    <skip />
 </resources>
diff --git a/quickstep/res/values-ka/strings.xml b/quickstep/res/values-ka/strings.xml
index 6de8ed9..3d9726c 100644
--- a/quickstep/res/values-ka/strings.xml
+++ b/quickstep/res/values-ka/strings.xml
@@ -25,4 +25,6 @@
     <string name="recents_empty_message" msgid="7040467240571714191">"ბოლოს გამოყენებული ერთეულები არ არის"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"დახურვა"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"ყველას გასუფთავება"</string>
+    <!-- no translation found for accessibility_recent_apps (4058661986695117371) -->
+    <skip />
 </resources>
diff --git a/quickstep/res/values-kk/strings.xml b/quickstep/res/values-kk/strings.xml
index ddd4a77..80cab46 100644
--- a/quickstep/res/values-kk/strings.xml
+++ b/quickstep/res/values-kk/strings.xml
@@ -25,4 +25,6 @@
     <string name="recents_empty_message" msgid="7040467240571714191">"Соңғы элементтер жоқ"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Жабу"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Барлығын өшіру"</string>
+    <!-- no translation found for accessibility_recent_apps (4058661986695117371) -->
+    <skip />
 </resources>
diff --git a/quickstep/res/values-km/strings.xml b/quickstep/res/values-km/strings.xml
index 65c1dcc..36a9ad9 100644
--- a/quickstep/res/values-km/strings.xml
+++ b/quickstep/res/values-km/strings.xml
@@ -25,4 +25,6 @@
     <string name="recents_empty_message" msgid="7040467240571714191">"មិនមានធាតុថ្មីៗទេ"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"បិទ"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"សម្អាត​ទាំងអស់"</string>
+    <!-- no translation found for accessibility_recent_apps (4058661986695117371) -->
+    <skip />
 </resources>
diff --git a/quickstep/res/values-kn/strings.xml b/quickstep/res/values-kn/strings.xml
index 55ccbb0..314638c 100644
--- a/quickstep/res/values-kn/strings.xml
+++ b/quickstep/res/values-kn/strings.xml
@@ -25,4 +25,6 @@
     <string name="recents_empty_message" msgid="7040467240571714191">"ಯಾವುದೇ ಇತ್ತೀಚಿನ ಐಟಂಗಳಿಲ್ಲ"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"ಮುಚ್ಚಿ"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"ಎಲ್ಲವನ್ನೂ ತೆರವುಗೊಳಿಸಿ"</string>
+    <!-- no translation found for accessibility_recent_apps (4058661986695117371) -->
+    <skip />
 </resources>
diff --git a/quickstep/res/values-ko/strings.xml b/quickstep/res/values-ko/strings.xml
index 54b86a8..557ee4a 100644
--- a/quickstep/res/values-ko/strings.xml
+++ b/quickstep/res/values-ko/strings.xml
@@ -25,4 +25,6 @@
     <string name="recents_empty_message" msgid="7040467240571714191">"최근 항목이 없습니다."</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"닫기"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"모두 삭제"</string>
+    <!-- no translation found for accessibility_recent_apps (4058661986695117371) -->
+    <skip />
 </resources>
diff --git a/quickstep/res/values-ky/strings.xml b/quickstep/res/values-ky/strings.xml
index b788693..1575af6 100644
--- a/quickstep/res/values-ky/strings.xml
+++ b/quickstep/res/values-ky/strings.xml
@@ -25,4 +25,6 @@
     <string name="recents_empty_message" msgid="7040467240571714191">"Акыркы колдонмолор жок"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Жабуу"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Баарын тазалоо"</string>
+    <!-- no translation found for accessibility_recent_apps (4058661986695117371) -->
+    <skip />
 </resources>
diff --git a/quickstep/res/values-lo/strings.xml b/quickstep/res/values-lo/strings.xml
index a83743a..3e332be 100644
--- a/quickstep/res/values-lo/strings.xml
+++ b/quickstep/res/values-lo/strings.xml
@@ -25,4 +25,6 @@
     <string name="recents_empty_message" msgid="7040467240571714191">"ບໍ່ມີລາຍການຫຼ້າສຸດ"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"ປິດ"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"ລຶບລ້າງທັງໝົດ"</string>
+    <!-- no translation found for accessibility_recent_apps (4058661986695117371) -->
+    <skip />
 </resources>
diff --git a/quickstep/res/values-lt/strings.xml b/quickstep/res/values-lt/strings.xml
index 689cf94..4dd2680 100644
--- a/quickstep/res/values-lt/strings.xml
+++ b/quickstep/res/values-lt/strings.xml
@@ -25,4 +25,6 @@
     <string name="recents_empty_message" msgid="7040467240571714191">"Nėra jokių naujausių elementų"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Uždaryti"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Išvalyti viską"</string>
+    <!-- no translation found for accessibility_recent_apps (4058661986695117371) -->
+    <skip />
 </resources>
diff --git a/quickstep/res/values-lv/strings.xml b/quickstep/res/values-lv/strings.xml
index 0aac222..7eb385f 100644
--- a/quickstep/res/values-lv/strings.xml
+++ b/quickstep/res/values-lv/strings.xml
@@ -25,4 +25,6 @@
     <string name="recents_empty_message" msgid="7040467240571714191">"Nav nesenu vienumu."</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Aizvērt"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Notīrīt visu"</string>
+    <!-- no translation found for accessibility_recent_apps (4058661986695117371) -->
+    <skip />
 </resources>
diff --git a/quickstep/res/values-mk/strings.xml b/quickstep/res/values-mk/strings.xml
index e428b4e..9e959d3 100644
--- a/quickstep/res/values-mk/strings.xml
+++ b/quickstep/res/values-mk/strings.xml
@@ -25,4 +25,6 @@
     <string name="recents_empty_message" msgid="7040467240571714191">"Нема неодамнешни ставки"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Затвори"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Исчисти ги сите"</string>
+    <!-- no translation found for accessibility_recent_apps (4058661986695117371) -->
+    <skip />
 </resources>
diff --git a/quickstep/res/values-ml/strings.xml b/quickstep/res/values-ml/strings.xml
index 4cca447..1d7b927 100644
--- a/quickstep/res/values-ml/strings.xml
+++ b/quickstep/res/values-ml/strings.xml
@@ -25,4 +25,6 @@
     <string name="recents_empty_message" msgid="7040467240571714191">"സമീപകാല ഇനങ്ങൾ ഒന്നുമില്ല"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"അവസാനിപ്പിക്കുക"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"എല്ലാം മായ്‌ക്കുക"</string>
+    <!-- no translation found for accessibility_recent_apps (4058661986695117371) -->
+    <skip />
 </resources>
diff --git a/quickstep/res/values-mn/strings.xml b/quickstep/res/values-mn/strings.xml
index f40f69e..5031388 100644
--- a/quickstep/res/values-mn/strings.xml
+++ b/quickstep/res/values-mn/strings.xml
@@ -25,4 +25,6 @@
     <string name="recents_empty_message" msgid="7040467240571714191">"Сүүлийн үеийн зүйл алга"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Хаах"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Бүгдийг устгах"</string>
+    <!-- no translation found for accessibility_recent_apps (4058661986695117371) -->
+    <skip />
 </resources>
diff --git a/quickstep/res/values-mr/strings.xml b/quickstep/res/values-mr/strings.xml
index 938363d..939963e 100644
--- a/quickstep/res/values-mr/strings.xml
+++ b/quickstep/res/values-mr/strings.xml
@@ -25,4 +25,6 @@
     <string name="recents_empty_message" msgid="7040467240571714191">"कोणतेही अलीकडील आयटम नाहीत"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"बंद"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"सर्व साफ करा"</string>
+    <!-- no translation found for accessibility_recent_apps (4058661986695117371) -->
+    <skip />
 </resources>
diff --git a/quickstep/res/values-ms/strings.xml b/quickstep/res/values-ms/strings.xml
index 236fab2..0e93bf6 100644
--- a/quickstep/res/values-ms/strings.xml
+++ b/quickstep/res/values-ms/strings.xml
@@ -25,4 +25,6 @@
     <string name="recents_empty_message" msgid="7040467240571714191">"Tiada item terbaharu"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Tutup"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Kosongkan semua"</string>
+    <!-- no translation found for accessibility_recent_apps (4058661986695117371) -->
+    <skip />
 </resources>
diff --git a/quickstep/res/values-my/strings.xml b/quickstep/res/values-my/strings.xml
index e44b904..ebffc3c 100644
--- a/quickstep/res/values-my/strings.xml
+++ b/quickstep/res/values-my/strings.xml
@@ -25,4 +25,6 @@
     <string name="recents_empty_message" msgid="7040467240571714191">"မကြာမီကဖွင့်ထားသည်များ မရှိပါ"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"ပိတ်ရန်"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"အားလုံးကို ရှင်းရန်"</string>
+    <!-- no translation found for accessibility_recent_apps (4058661986695117371) -->
+    <skip />
 </resources>
diff --git a/quickstep/res/values-nb/strings.xml b/quickstep/res/values-nb/strings.xml
index 423b7c1..97870b1 100644
--- a/quickstep/res/values-nb/strings.xml
+++ b/quickstep/res/values-nb/strings.xml
@@ -25,4 +25,6 @@
     <string name="recents_empty_message" msgid="7040467240571714191">"Ingen nylige elementer"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Lukk"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Fjern alt"</string>
+    <!-- no translation found for accessibility_recent_apps (4058661986695117371) -->
+    <skip />
 </resources>
diff --git a/quickstep/res/values-ne/strings.xml b/quickstep/res/values-ne/strings.xml
index bf52604..c9a6c6b 100644
--- a/quickstep/res/values-ne/strings.xml
+++ b/quickstep/res/values-ne/strings.xml
@@ -25,4 +25,6 @@
     <string name="recents_empty_message" msgid="7040467240571714191">"हालसालैको कुनै पनि वस्तु छैन"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"बन्द गर्नुहोस्"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"सबै खाली गर्नुहोस्"</string>
+    <!-- no translation found for accessibility_recent_apps (4058661986695117371) -->
+    <skip />
 </resources>
diff --git a/quickstep/res/values-nl/strings.xml b/quickstep/res/values-nl/strings.xml
index 96319a4..e3acf0d 100644
--- a/quickstep/res/values-nl/strings.xml
+++ b/quickstep/res/values-nl/strings.xml
@@ -25,4 +25,6 @@
     <string name="recents_empty_message" msgid="7040467240571714191">"Geen recente items"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Sluiten"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Alles wissen"</string>
+    <!-- no translation found for accessibility_recent_apps (4058661986695117371) -->
+    <skip />
 </resources>
diff --git a/quickstep/res/values-or/strings.xml b/quickstep/res/values-or/strings.xml
index 08e38c0..5e5e420 100644
--- a/quickstep/res/values-or/strings.xml
+++ b/quickstep/res/values-or/strings.xml
@@ -25,4 +25,6 @@
     <string name="recents_empty_message" msgid="7040467240571714191">"କୌଣସି ସାମ୍ପ୍ରତିକ ଆଇଟମ୍ ନାହିଁ"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"ବନ୍ଦ କରନ୍ତୁ"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"ସବୁ ଖାଲି କରନ୍ତୁ"</string>
+    <!-- no translation found for accessibility_recent_apps (4058661986695117371) -->
+    <skip />
 </resources>
diff --git a/quickstep/res/values-pa/strings.xml b/quickstep/res/values-pa/strings.xml
index bc044c8..fec9f03 100644
--- a/quickstep/res/values-pa/strings.xml
+++ b/quickstep/res/values-pa/strings.xml
@@ -25,4 +25,6 @@
     <string name="recents_empty_message" msgid="7040467240571714191">"ਕੋਈ ਹਾਲੀਆ ਆਈਟਮਾਂ ਨਹੀਂ"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"ਬੰਦ ਕਰੋ"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"ਸਭ ਕਲੀਅਰ ਕਰੋ"</string>
+    <!-- no translation found for accessibility_recent_apps (4058661986695117371) -->
+    <skip />
 </resources>
diff --git a/quickstep/res/values-pl/strings.xml b/quickstep/res/values-pl/strings.xml
index 4f865d7..54196e8 100644
--- a/quickstep/res/values-pl/strings.xml
+++ b/quickstep/res/values-pl/strings.xml
@@ -25,4 +25,6 @@
     <string name="recents_empty_message" msgid="7040467240571714191">"Brak ostatnich elementów"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Zamknij"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Wyczyść wszystko"</string>
+    <!-- no translation found for accessibility_recent_apps (4058661986695117371) -->
+    <skip />
 </resources>
diff --git a/quickstep/res/values-pt-rPT/strings.xml b/quickstep/res/values-pt-rPT/strings.xml
index e0a9372..afc6295 100644
--- a/quickstep/res/values-pt-rPT/strings.xml
+++ b/quickstep/res/values-pt-rPT/strings.xml
@@ -25,4 +25,6 @@
     <string name="recents_empty_message" msgid="7040467240571714191">"Nenhum item recente"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Fechar"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Limpar tudo"</string>
+    <!-- no translation found for accessibility_recent_apps (4058661986695117371) -->
+    <skip />
 </resources>
diff --git a/quickstep/res/values-pt/strings.xml b/quickstep/res/values-pt/strings.xml
index d4be221..9e43cd7 100644
--- a/quickstep/res/values-pt/strings.xml
+++ b/quickstep/res/values-pt/strings.xml
@@ -25,4 +25,6 @@
     <string name="recents_empty_message" msgid="7040467240571714191">"Nenhum item recente"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Fechar"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Limpar tudo"</string>
+    <!-- no translation found for accessibility_recent_apps (4058661986695117371) -->
+    <skip />
 </resources>
diff --git a/quickstep/res/values-ru/strings.xml b/quickstep/res/values-ru/strings.xml
index 2d7fc78..832aa0a 100644
--- a/quickstep/res/values-ru/strings.xml
+++ b/quickstep/res/values-ru/strings.xml
@@ -25,4 +25,6 @@
     <string name="recents_empty_message" msgid="7040467240571714191">"Здесь пока ничего нет."</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Закрыть"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Очистить все"</string>
+    <!-- no translation found for accessibility_recent_apps (4058661986695117371) -->
+    <skip />
 </resources>
diff --git a/quickstep/res/values-sk/strings.xml b/quickstep/res/values-sk/strings.xml
index fc173b7..da4585b 100644
--- a/quickstep/res/values-sk/strings.xml
+++ b/quickstep/res/values-sk/strings.xml
@@ -25,4 +25,6 @@
     <string name="recents_empty_message" msgid="7040467240571714191">"Žiadne nedávne položky"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Zavrieť"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Vymazať všetko"</string>
+    <!-- no translation found for accessibility_recent_apps (4058661986695117371) -->
+    <skip />
 </resources>
diff --git a/quickstep/res/values-sl/strings.xml b/quickstep/res/values-sl/strings.xml
index b03978c..6a25e9d 100644
--- a/quickstep/res/values-sl/strings.xml
+++ b/quickstep/res/values-sl/strings.xml
@@ -25,4 +25,6 @@
     <string name="recents_empty_message" msgid="7040467240571714191">"Ni nedavnih elementov"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Zapri"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Počisti vse"</string>
+    <!-- no translation found for accessibility_recent_apps (4058661986695117371) -->
+    <skip />
 </resources>
diff --git a/quickstep/res/values-sq/strings.xml b/quickstep/res/values-sq/strings.xml
index a0c3d78..521b8c7 100644
--- a/quickstep/res/values-sq/strings.xml
+++ b/quickstep/res/values-sq/strings.xml
@@ -25,4 +25,6 @@
     <string name="recents_empty_message" msgid="7040467240571714191">"Nuk ka asnjë artikull të fundit"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Mbyll"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Pastroji të gjitha"</string>
+    <!-- no translation found for accessibility_recent_apps (4058661986695117371) -->
+    <skip />
 </resources>
diff --git a/quickstep/res/values-sr/strings.xml b/quickstep/res/values-sr/strings.xml
index c51ca1c..054cda5 100644
--- a/quickstep/res/values-sr/strings.xml
+++ b/quickstep/res/values-sr/strings.xml
@@ -25,4 +25,6 @@
     <string name="recents_empty_message" msgid="7040467240571714191">"Нема недавних ставки"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Затвори"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Обриши све"</string>
+    <!-- no translation found for accessibility_recent_apps (4058661986695117371) -->
+    <skip />
 </resources>
diff --git a/quickstep/res/values-sv/strings.xml b/quickstep/res/values-sv/strings.xml
index 29b4e45..1a0ecc1 100644
--- a/quickstep/res/values-sv/strings.xml
+++ b/quickstep/res/values-sv/strings.xml
@@ -25,4 +25,6 @@
     <string name="recents_empty_message" msgid="7040467240571714191">"Listan med de senaste åtgärderna är tom"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Stäng"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Rensa alla"</string>
+    <!-- no translation found for accessibility_recent_apps (4058661986695117371) -->
+    <skip />
 </resources>
diff --git a/quickstep/res/values-sw/strings.xml b/quickstep/res/values-sw/strings.xml
index e41c2bb..be26e8b 100644
--- a/quickstep/res/values-sw/strings.xml
+++ b/quickstep/res/values-sw/strings.xml
@@ -25,4 +25,6 @@
     <string name="recents_empty_message" msgid="7040467240571714191">"Hakuna vipengee vya hivi karibuni"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Funga"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Ondoa zote"</string>
+    <!-- no translation found for accessibility_recent_apps (4058661986695117371) -->
+    <skip />
 </resources>
diff --git a/quickstep/res/values-ta/strings.xml b/quickstep/res/values-ta/strings.xml
index 0c800ca..886b017 100644
--- a/quickstep/res/values-ta/strings.xml
+++ b/quickstep/res/values-ta/strings.xml
@@ -25,4 +25,6 @@
     <string name="recents_empty_message" msgid="7040467240571714191">"சமீபத்தியவை எதுவுமில்லை"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"மூடும்"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"எல்லாம் அழி"</string>
+    <!-- no translation found for accessibility_recent_apps (4058661986695117371) -->
+    <skip />
 </resources>
diff --git a/quickstep/res/values-te/strings.xml b/quickstep/res/values-te/strings.xml
index 416fbb8..a0a818c 100644
--- a/quickstep/res/values-te/strings.xml
+++ b/quickstep/res/values-te/strings.xml
@@ -25,4 +25,6 @@
     <string name="recents_empty_message" msgid="7040467240571714191">"ఇటీవలి అంశాలు ఏవీ లేవు"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"మూసివేయండి"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"అన్నీ తీసివేయండి"</string>
+    <!-- no translation found for accessibility_recent_apps (4058661986695117371) -->
+    <skip />
 </resources>
diff --git a/quickstep/res/values-th/strings.xml b/quickstep/res/values-th/strings.xml
index ccca5ad..5a162b7 100644
--- a/quickstep/res/values-th/strings.xml
+++ b/quickstep/res/values-th/strings.xml
@@ -25,4 +25,6 @@
     <string name="recents_empty_message" msgid="7040467240571714191">"ไม่มีรายการล่าสุด"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"ปิด"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"ล้างทั้งหมด"</string>
+    <!-- no translation found for accessibility_recent_apps (4058661986695117371) -->
+    <skip />
 </resources>
diff --git a/quickstep/res/values-tl/strings.xml b/quickstep/res/values-tl/strings.xml
index 4b29694..af7ff97 100644
--- a/quickstep/res/values-tl/strings.xml
+++ b/quickstep/res/values-tl/strings.xml
@@ -25,4 +25,6 @@
     <string name="recents_empty_message" msgid="7040467240571714191">"Walang kamakailang item"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Isara"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"I-clear lahat"</string>
+    <!-- no translation found for accessibility_recent_apps (4058661986695117371) -->
+    <skip />
 </resources>
diff --git a/quickstep/res/values-tr/strings.xml b/quickstep/res/values-tr/strings.xml
index 3c7463a..760a61f 100644
--- a/quickstep/res/values-tr/strings.xml
+++ b/quickstep/res/values-tr/strings.xml
@@ -25,4 +25,6 @@
     <string name="recents_empty_message" msgid="7040467240571714191">"Yeni öğe yok"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Kapat"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Tümünü temizle"</string>
+    <!-- no translation found for accessibility_recent_apps (4058661986695117371) -->
+    <skip />
 </resources>
diff --git a/quickstep/res/values-uk/strings.xml b/quickstep/res/values-uk/strings.xml
index f11bd6b..41babaa 100644
--- a/quickstep/res/values-uk/strings.xml
+++ b/quickstep/res/values-uk/strings.xml
@@ -25,4 +25,6 @@
     <string name="recents_empty_message" msgid="7040467240571714191">"Немає нещодавніх додатків"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Закрити"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Очистити все"</string>
+    <!-- no translation found for accessibility_recent_apps (4058661986695117371) -->
+    <skip />
 </resources>
diff --git a/quickstep/res/values-ur/strings.xml b/quickstep/res/values-ur/strings.xml
index 0a546fd..9dd7b8d 100644
--- a/quickstep/res/values-ur/strings.xml
+++ b/quickstep/res/values-ur/strings.xml
@@ -25,4 +25,6 @@
     <string name="recents_empty_message" msgid="7040467240571714191">"کوئی حالیہ آئٹم نہیں"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"بند کریں"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"سبھی کو صاف کریں"</string>
+    <!-- no translation found for accessibility_recent_apps (4058661986695117371) -->
+    <skip />
 </resources>
diff --git a/quickstep/res/values-uz/strings.xml b/quickstep/res/values-uz/strings.xml
index efea341..c78f000 100644
--- a/quickstep/res/values-uz/strings.xml
+++ b/quickstep/res/values-uz/strings.xml
@@ -25,4 +25,6 @@
     <string name="recents_empty_message" msgid="7040467240571714191">"Yaqinda ishlatilgan ilovalar yo‘q"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Yopish"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Hammasini tozalash"</string>
+    <!-- no translation found for accessibility_recent_apps (4058661986695117371) -->
+    <skip />
 </resources>
diff --git a/quickstep/res/values-vi/strings.xml b/quickstep/res/values-vi/strings.xml
index d4012f3..4b1d1c0 100644
--- a/quickstep/res/values-vi/strings.xml
+++ b/quickstep/res/values-vi/strings.xml
@@ -25,4 +25,6 @@
     <string name="recents_empty_message" msgid="7040467240571714191">"Không có mục gần đây nào"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Đóng"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Xóa tất cả"</string>
+    <!-- no translation found for accessibility_recent_apps (4058661986695117371) -->
+    <skip />
 </resources>
diff --git a/quickstep/res/values-zh-rCN/strings.xml b/quickstep/res/values-zh-rCN/strings.xml
index ec02632..17cf6c3 100644
--- a/quickstep/res/values-zh-rCN/strings.xml
+++ b/quickstep/res/values-zh-rCN/strings.xml
@@ -25,4 +25,6 @@
     <string name="recents_empty_message" msgid="7040467240571714191">"近期没有任何内容"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"关闭"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"全部清除"</string>
+    <!-- no translation found for accessibility_recent_apps (4058661986695117371) -->
+    <skip />
 </resources>
diff --git a/quickstep/res/values-zh-rHK/strings.xml b/quickstep/res/values-zh-rHK/strings.xml
index 152f894..1203cf0 100644
--- a/quickstep/res/values-zh-rHK/strings.xml
+++ b/quickstep/res/values-zh-rHK/strings.xml
@@ -25,4 +25,6 @@
     <string name="recents_empty_message" msgid="7040467240571714191">"最近沒有任何項目"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"關閉"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"全部清除"</string>
+    <!-- no translation found for accessibility_recent_apps (4058661986695117371) -->
+    <skip />
 </resources>
diff --git a/quickstep/res/values-zh-rTW/strings.xml b/quickstep/res/values-zh-rTW/strings.xml
index 44a16c9..ed708b4 100644
--- a/quickstep/res/values-zh-rTW/strings.xml
+++ b/quickstep/res/values-zh-rTW/strings.xml
@@ -25,4 +25,6 @@
     <string name="recents_empty_message" msgid="7040467240571714191">"最近沒有任何項目"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"關閉"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"全部清除"</string>
+    <!-- no translation found for accessibility_recent_apps (4058661986695117371) -->
+    <skip />
 </resources>
diff --git a/quickstep/res/values-zu/strings.xml b/quickstep/res/values-zu/strings.xml
index 847c547..1aa34b6 100644
--- a/quickstep/res/values-zu/strings.xml
+++ b/quickstep/res/values-zu/strings.xml
@@ -25,4 +25,6 @@
     <string name="recents_empty_message" msgid="7040467240571714191">"Azikho izinto zakamuva"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Vala"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Sula konke"</string>
+    <!-- no translation found for accessibility_recent_apps (4058661986695117371) -->
+    <skip />
 </resources>
diff --git a/quickstep/res/values/dimens.xml b/quickstep/res/values/dimens.xml
index 9e4d60c..ad5f767 100644
--- a/quickstep/res/values/dimens.xml
+++ b/quickstep/res/values/dimens.xml
@@ -30,8 +30,9 @@
     <dimen name="quickstep_fling_min_velocity">250dp</dimen>
 
     <!-- Launcher app transition -->
-    <dimen name="content_trans_y">25dp</dimen>
-    <dimen name="workspace_trans_y">80dp</dimen>
+    <dimen name="content_trans_y">50dp</dimen>
+    <dimen name="workspace_trans_y">50dp</dimen>
+    <dimen name="closing_window_trans_y">115dp</dimen>
 
     <dimen name="recents_empty_message_text_size">16sp</dimen>
     <dimen name="recents_empty_message_text_padding">16dp</dimen>
@@ -50,5 +51,4 @@
     <dimen name="clear_all_container_width">168dp</dimen>
 
     <dimen name="shelf_surface_radius">16dp</dimen>
-    <dimen name="shelf_surface_top_padding">4dp</dimen>
 </resources>
diff --git a/quickstep/src/com/android/launcher3/LauncherAnimationRunner.java b/quickstep/src/com/android/launcher3/LauncherAnimationRunner.java
index 29399142..e346310 100644
--- a/quickstep/src/com/android/launcher3/LauncherAnimationRunner.java
+++ b/quickstep/src/com/android/launcher3/LauncherAnimationRunner.java
@@ -118,6 +118,7 @@
                 finish();
             } else if (mFinished) {
                 // Animation callback was already finished, skip the animation.
+                mAnimator.start();
                 mAnimator.end();
             } else {
                 // Start the animation
diff --git a/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java b/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java
index 4963f5d..2e31ef2 100644
--- a/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java
+++ b/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java
@@ -19,13 +19,15 @@
 import static com.android.launcher3.BaseActivity.INVISIBLE_ALL;
 import static com.android.launcher3.BaseActivity.INVISIBLE_BY_APP_TRANSITIONS;
 import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY;
+import static com.android.launcher3.LauncherState.ALL_APPS;
 import static com.android.launcher3.LauncherState.NORMAL;
+import static com.android.launcher3.LauncherState.OVERVIEW;
 import static com.android.launcher3.Utilities.postAsyncCallback;
 import static com.android.launcher3.allapps.AllAppsTransitionController.ALL_APPS_PROGRESS;
 import static com.android.launcher3.anim.Interpolators.AGGRESSIVE_EASE;
-import static com.android.launcher3.anim.Interpolators.AGGRESSIVE_EASE_IN_OUT;
-import static com.android.launcher3.anim.Interpolators.APP_CLOSE_ALPHA;
+import static com.android.launcher3.anim.Interpolators.DEACCEL_1_7;
 import static com.android.launcher3.anim.Interpolators.LINEAR;
+import static com.android.launcher3.dragndrop.DragLayer.ALPHA_INDEX_TRANSITIONS;
 import static com.android.quickstep.TaskUtils.findTaskViewToLaunch;
 import static com.android.quickstep.TaskUtils.getRecentsWindowAnimator;
 import static com.android.quickstep.TaskUtils.taskIsATargetWithMode;
@@ -64,6 +66,8 @@
 import com.android.launcher3.dragndrop.DragLayer;
 import com.android.launcher3.graphics.DrawableFactory;
 import com.android.launcher3.shortcuts.DeepShortcutView;
+import com.android.launcher3.util.MultiValueAlpha;
+import com.android.launcher3.util.MultiValueAlpha.AlphaProperty;
 import com.android.quickstep.util.ClipAnimationHelper;
 import com.android.quickstep.util.MultiValueUpdateListener;
 import com.android.quickstep.util.RemoteAnimationProvider;
@@ -102,33 +106,27 @@
 
     public static final int RECENTS_LAUNCH_DURATION = 336;
     private static final int LAUNCHER_RESUME_START_DELAY = 100;
-    private static final int CLOSING_TRANSITION_DURATION_MS = 350;
+    private static final int CLOSING_TRANSITION_DURATION_MS = 250;
 
     // Progress = 0: All apps is fully pulled up, Progress = 1: All apps is fully pulled down.
     public static final float ALL_APPS_PROGRESS_OFF_SCREEN = 1.3059858f;
-    public static final float ALL_APPS_PROGRESS_OVERSHOOT = 0.99581414f;
 
-    private final DragLayer mDragLayer;
     private final Launcher mLauncher;
+    private final DragLayer mDragLayer;
+    private final AlphaProperty mDragLayerAlpha;
 
     private final Handler mHandler;
     private final boolean mIsRtl;
 
     private final float mContentTransY;
     private final float mWorkspaceTransY;
+    private final float mClosingWindowTransY;
 
     private DeviceProfile mDeviceProfile;
     private View mFloatingView;
 
     private RemoteAnimationProvider mRemoteAnimationProvider;
 
-    private final AnimatorListenerAdapter mReapplyStateListener = new AnimatorListenerAdapter() {
-        @Override
-        public void onAnimationEnd(Animator animation) {
-            mLauncher.getStateManager().reapplyState();
-        }
-    };
-
     private final AnimatorListenerAdapter mForceInvisibleListener = new AnimatorListenerAdapter() {
         @Override
         public void onAnimationStart(Animator animation) {
@@ -144,6 +142,7 @@
     public LauncherAppTransitionManagerImpl(Context context) {
         mLauncher = Launcher.getLauncher(context);
         mDragLayer = mLauncher.getDragLayer();
+        mDragLayerAlpha = mDragLayer.getAlphaProperty(ALPHA_INDEX_TRANSITIONS);
         mHandler = new Handler(Looper.getMainLooper());
         mIsRtl = Utilities.isRtl(mLauncher.getResources());
         mDeviceProfile = mLauncher.getDeviceProfile();
@@ -151,6 +150,7 @@
         Resources res = mLauncher.getResources();
         mContentTransY = res.getDimensionPixelSize(R.dimen.content_trans_y);
         mWorkspaceTransY = res.getDimensionPixelSize(R.dimen.workspace_trans_y);
+        mClosingWindowTransY = res.getDimensionPixelSize(R.dimen.closing_window_trans_y);
 
         mLauncher.addOnDeviceProfileChangeListener(this);
         registerRemoteAnimations();
@@ -187,7 +187,7 @@
                         anim.play(getIconAnimator(v));
                         if (launcherClosing) {
                             Pair<AnimatorSet, Runnable> launcherContentAnimator =
-                                    getLauncherContentAnimator(false /* show */);
+                                    getLauncherContentAnimator(true /* isAppOpening */);
                             anim.play(launcherContentAnimator.first);
                             anim.addListener(new AnimatorListenerAdapter() {
                                 @Override
@@ -253,7 +253,13 @@
             launcherAnim.setDuration(RECENTS_LAUNCH_DURATION);
 
             // Make sure recents gets fixed up by resetting task alphas and scales, etc.
-            windowAnimEndListener = mReapplyStateListener;
+            windowAnimEndListener = new AnimatorListenerAdapter() {
+                @Override
+                public void onAnimationEnd(Animator animation) {
+                    mLauncher.getStateManager().moveToRestState();
+                    mLauncher.getStateManager().reapplyState();
+                }
+            };
         } else {
             AnimatorPlaybackController controller =
                     mLauncher.getStateManager()
@@ -281,21 +287,21 @@
     /**
      * Content is everything on screen except the background and the floating view (if any).
      *
-     * @param show If true: Animate the content so that it moves upwards and fades in.
-     *             Else: Animate the content so that it moves downwards and fades out.
+     * @param isAppOpening True when this is called when an app is opening.
+     *                     False when this is called when an app is closing.
      */
-    private Pair<AnimatorSet, Runnable> getLauncherContentAnimator(boolean show) {
+    private Pair<AnimatorSet, Runnable> getLauncherContentAnimator(boolean isAppOpening) {
         AnimatorSet launcherAnimator = new AnimatorSet();
         Runnable endListener;
 
-        float[] alphas = show
-                ? new float[] {0, 1}
-                : new float[] {1, 0};
-        float[] trans = show
-                ? new float[] {mContentTransY, 0,}
-                : new float[] {0, mContentTransY};
+        float[] alphas = isAppOpening
+                ? new float[] {1, 0}
+                : new float[] {0, 1};
+        float[] trans = isAppOpening
+                ? new float[] {0, mContentTransY}
+                : new float[] {-mContentTransY, 0};
 
-        if (mLauncher.isInState(LauncherState.ALL_APPS) && !mDeviceProfile.isVerticalBarLayout()) {
+        if (mLauncher.isInState(ALL_APPS)) {
             // All Apps in portrait mode is full screen, so we only animate AllAppsContainerView.
             final View appsView = mLauncher.getAppsView();
             final float startAlpha = appsView.getAlpha();
@@ -325,30 +331,50 @@
                 appsView.setTranslationY(startY);
                 appsView.setLayerType(View.LAYER_TYPE_NONE, null);
             };
+        } else if (mLauncher.isInState(OVERVIEW)) {
+            AllAppsTransitionController allAppsController = mLauncher.getAllAppsController();
+            launcherAnimator.play(ObjectAnimator.ofFloat(allAppsController, ALL_APPS_PROGRESS,
+                    allAppsController.getProgress(), ALL_APPS_PROGRESS_OFF_SCREEN));
+
+            View overview = mLauncher.getOverviewPanelContainer();
+            ObjectAnimator alpha = ObjectAnimator.ofFloat(overview, View.ALPHA, alphas);
+            alpha.setDuration(217);
+            alpha.setInterpolator(LINEAR);
+            launcherAnimator.play(alpha);
+
+            ObjectAnimator transY = ObjectAnimator.ofFloat(overview, View.TRANSLATION_Y, trans);
+            transY.setInterpolator(AGGRESSIVE_EASE);
+            transY.setDuration(350);
+            launcherAnimator.play(transY);
+
+            overview.setLayerType(View.LAYER_TYPE_HARDWARE, null);
+
+            endListener = () -> {
+                overview.setLayerType(View.LAYER_TYPE_NONE, null);
+                overview.setAlpha(1f);
+                overview.setTranslationY(0f);
+                mLauncher.getStateManager().reapplyState();
+            };
         } else {
-            mDragLayer.setAlpha(alphas[0]);
+            mDragLayerAlpha.setValue(alphas[0]);
+            ObjectAnimator alpha =
+                    ObjectAnimator.ofFloat(mDragLayerAlpha, MultiValueAlpha.VALUE, alphas);
+            alpha.setDuration(217);
+            alpha.setInterpolator(LINEAR);
+            launcherAnimator.play(alpha);
+
             mDragLayer.setTranslationY(trans[0]);
+            ObjectAnimator transY = ObjectAnimator.ofFloat(mDragLayer, View.TRANSLATION_Y, trans);
+            transY.setInterpolator(AGGRESSIVE_EASE);
+            transY.setDuration(350);
+            launcherAnimator.play(transY);
 
-            ObjectAnimator dragLayerAlpha = ObjectAnimator.ofFloat(mDragLayer, View.ALPHA, alphas);
-            dragLayerAlpha.setDuration(217);
-            dragLayerAlpha.setInterpolator(LINEAR);
-            ObjectAnimator dragLayerTransY = ObjectAnimator.ofFloat(mDragLayer, View.TRANSLATION_Y,
-                    trans);
-            dragLayerTransY.setInterpolator(AGGRESSIVE_EASE);
-            dragLayerTransY.setDuration(350);
-
-            launcherAnimator.play(dragLayerAlpha);
-            launcherAnimator.play(dragLayerTransY);
-            mDragLayer.setLayerType(View.LAYER_TYPE_HARDWARE, null);
-
+            mDragLayer.getScrim().hideSysUiScrim(true);
             // Pause page indicator animations as they lead to layer trashing.
             mLauncher.getWorkspace().getPageIndicator().pauseAnimations();
-            endListener = () -> {
-                mDragLayer.setLayerType(View.LAYER_TYPE_NONE, null);
-                mDragLayer.setAlpha(1);
-                mDragLayer.setTranslationY(0);
-                mLauncher.getWorkspace().getPageIndicator().skipAnimationsToEnd();
-            };
+            mDragLayer.setLayerType(View.LAYER_TYPE_HARDWARE, null);
+
+            endListener = this::resetContentView;
         }
         return new Pair<>(launcherAnimator, endListener);
     }
@@ -646,16 +672,13 @@
      */
     private Animator getClosingWindowAnimators(RemoteAnimationTargetCompat[] targets) {
         Matrix matrix = new Matrix();
-        float height = mLauncher.getDeviceProfile().heightPx;
-        float width = mLauncher.getDeviceProfile().widthPx;
-        float endX = (mLauncher.<RecentsView>getOverviewPanel().isRtl() ? -width : width) * 1.16f;
-
         ValueAnimator closingAnimator = ValueAnimator.ofFloat(0, 1);
-        closingAnimator.setDuration(CLOSING_TRANSITION_DURATION_MS);
+        int duration = CLOSING_TRANSITION_DURATION_MS;
+        closingAnimator.setDuration(duration);
         closingAnimator.addUpdateListener(new MultiValueUpdateListener() {
-            FloatProp mDx = new FloatProp(0, endX, 0, 350, AGGRESSIVE_EASE_IN_OUT);
-            FloatProp mScale = new FloatProp(1f, 0.8f, 0, 267, AGGRESSIVE_EASE);
-            FloatProp mAlpha = new FloatProp(1f, 0f, 0, 350, APP_CLOSE_ALPHA);
+            FloatProp mDy = new FloatProp(0, mClosingWindowTransY, 0, duration, DEACCEL_1_7);
+            FloatProp mScale = new FloatProp(1f, 1f, 0, duration, DEACCEL_1_7);
+            FloatProp mAlpha = new FloatProp(1f, 0f, 25, 125, LINEAR);
 
             boolean isFirstFrame = true;
 
@@ -672,7 +695,7 @@
                         matrix.setScale(mScale.value, mScale.value,
                                 app.sourceContainerBounds.centerX(),
                                 app.sourceContainerBounds.centerY());
-                        matrix.postTranslate(mDx.value, 0);
+                        matrix.postTranslate(0, mDy.value);
                         matrix.postTranslate(app.position.x, app.position.y);
                         t.setMatrix(app.leash, matrix);
                     }
@@ -691,10 +714,9 @@
      * Creates an animator that modifies Launcher as a result from {@link #getWallpaperOpenRunner}.
      */
     private void createLauncherResumeAnimation(AnimatorSet anim) {
-        if (mLauncher.isInState(LauncherState.ALL_APPS)
-                || mLauncher.getDeviceProfile().isVerticalBarLayout()) {
+        if (mLauncher.isInState(LauncherState.ALL_APPS)) {
             Pair<AnimatorSet, Runnable> contentAnimator =
-                    getLauncherContentAnimator(true /* show */);
+                    getLauncherContentAnimator(false /* isAppOpening */);
             contentAnimator.first.setStartDelay(LAUNCHER_RESUME_START_DELAY);
             anim.play(contentAnimator.first);
             anim.addListener(new AnimatorListenerAdapter() {
@@ -706,53 +728,42 @@
         } else {
             AnimatorSet workspaceAnimator = new AnimatorSet();
 
-            mLauncher.getWorkspace().setTranslationY(mWorkspaceTransY);
-            workspaceAnimator.play(ObjectAnimator.ofFloat(mLauncher.getWorkspace(),
-                    View.TRANSLATION_Y, mWorkspaceTransY, 0));
+            mDragLayer.setTranslationY(-mWorkspaceTransY);;
+            workspaceAnimator.play(ObjectAnimator.ofFloat(mDragLayer, View.TRANSLATION_Y,
+                    -mWorkspaceTransY, 0));
 
-            View currentPage = ((CellLayout) mLauncher.getWorkspace()
-                    .getChildAt(mLauncher.getWorkspace().getCurrentPage()))
-                    .getShortcutsAndWidgets();
-            currentPage.setAlpha(0f);
-            workspaceAnimator.play(ObjectAnimator.ofFloat(currentPage, View.ALPHA, 0, 1f));
+            mDragLayerAlpha.setValue(0);
+            workspaceAnimator.play(ObjectAnimator.ofFloat(
+                    mDragLayerAlpha, MultiValueAlpha.VALUE, 0, 1f));
 
             workspaceAnimator.setStartDelay(LAUNCHER_RESUME_START_DELAY);
             workspaceAnimator.setDuration(333);
-            workspaceAnimator.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
-            currentPage.setLayerType(View.LAYER_TYPE_HARDWARE, null);
+            workspaceAnimator.setInterpolator(Interpolators.DEACCEL_1_7);
+
+            mDragLayer.getScrim().hideSysUiScrim(true);
+
+            // Pause page indicator animations as they lead to layer trashing.
+            mLauncher.getWorkspace().getPageIndicator().pauseAnimations();
+            mDragLayer.setLayerType(View.LAYER_TYPE_HARDWARE, null);
+
             workspaceAnimator.addListener(new AnimatorListenerAdapter() {
                 @Override
                 public void onAnimationEnd(Animator animation) {
-                    currentPage.setLayerType(View.LAYER_TYPE_NONE, null);
+                    resetContentView();
                 }
             });
-
-            // Animate the shelf in two parts: slide in, and overeshoot.
-            AllAppsTransitionController allAppsController = mLauncher.getAllAppsController();
-            // The shelf will start offscreen
-            final float startY = ALL_APPS_PROGRESS_OFF_SCREEN;
-            // And will end slightly pulled up, so that there is something to overshoot back to 1f.
-            final float slideEnd = ALL_APPS_PROGRESS_OVERSHOOT;
-
-            allAppsController.setProgress(startY);
-
-            Animator allAppsSlideIn =
-                    ObjectAnimator.ofFloat(allAppsController, ALL_APPS_PROGRESS, startY, slideEnd);
-            allAppsSlideIn.setStartDelay(LAUNCHER_RESUME_START_DELAY);
-            allAppsSlideIn.setDuration(317);
-            allAppsSlideIn.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
-
-            Animator allAppsOvershoot =
-                    ObjectAnimator.ofFloat(allAppsController, ALL_APPS_PROGRESS, slideEnd, 1f);
-            allAppsOvershoot.setDuration(153);
-            allAppsOvershoot.setInterpolator(Interpolators.OVERSHOOT_0);
-
             anim.play(workspaceAnimator);
-            anim.playSequentially(allAppsSlideIn, allAppsOvershoot);
-            anim.addListener(mReapplyStateListener);
         }
     }
 
+    private void resetContentView() {
+        mLauncher.getWorkspace().getPageIndicator().skipAnimationsToEnd();
+        mDragLayerAlpha.setValue(1f);
+        mDragLayer.setLayerType(View.LAYER_TYPE_NONE, null);
+        mDragLayer.setTranslationY(0f);
+        mDragLayer.getScrim().hideSysUiScrim(false);
+    }
+
     private boolean hasControlRemoteAppTransitionPermission() {
         return mLauncher.checkSelfPermission(CONTROL_REMOTE_APP_TRANSITION_PERMISSION)
                 == PackageManager.PERMISSION_GRANTED;
diff --git a/quickstep/src/com/android/launcher3/uioverrides/AllAppsScrim.java b/quickstep/src/com/android/launcher3/uioverrides/AllAppsScrim.java
deleted file mode 100644
index 3c741b3..0000000
--- a/quickstep/src/com/android/launcher3/uioverrides/AllAppsScrim.java
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.launcher3.uioverrides;
-
-import static com.android.launcher3.anim.Interpolators.ACCEL_2;
-import static com.android.launcher3.anim.Interpolators.DEACCEL_2;
-
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.Paint;
-import android.support.v4.graphics.ColorUtils;
-
-import com.android.launcher3.DeviceProfile;
-import com.android.launcher3.Launcher;
-import com.android.launcher3.R;
-import com.android.launcher3.Utilities;
-import com.android.launcher3.allapps.AllAppsContainerView;
-import com.android.launcher3.graphics.ViewScrim;
-import com.android.launcher3.util.Themes;
-
-/**
- * Scrim used for all-apps and shelf in Overview
- * In transposed layout, it behaves as a simple color scrim.
- * In portrait layout, it draws a rounded rect such that
- *    From normal state to overview state, the shelf just fades in and does not move
- *    From overview state to all-apps state the self moves up and fades in to cover the screen
- */
-public class AllAppsScrim extends ViewScrim<AllAppsContainerView> {
-
-    private static final int THRESHOLD_ALPHA_DARK = 102;
-    private static final int THRESHOLD_ALPHA_LIGHT = 46;
-
-    private final Launcher mLauncher;
-    private final int mEndColor;
-
-    private int mProgressColor;
-
-    // In transposed layout, we simply draw a flat color.
-    private boolean mDrawingFlatColor;
-
-    private final Paint mVerticalPaint;
-    private float mVerticalProgress;
-
-    private final int mEndAlpha;
-    private final int mThresholdAlpha;
-    private final float mRadius;
-    private final float mTopPadding;
-
-    // Max vertical progress after which the scrim stops moving.
-    private float mMoveThreshold;
-    // Minimum visible size of the scrim.
-    private int mMinSize;
-    private float mDrawFactor = 0;
-
-    public AllAppsScrim(AllAppsContainerView view) {
-        super(view);
-        mLauncher = Launcher.getLauncher(view.getContext());
-        mEndColor = Themes.getAttrColor(mLauncher, R.attr.allAppsScrimColor);
-        mProgressColor = mEndColor;
-
-        mEndAlpha = Color.alpha(mEndColor);
-        mThresholdAlpha = Themes.getAttrBoolean(mLauncher, R.attr.isMainColorDark)
-                ? THRESHOLD_ALPHA_DARK : THRESHOLD_ALPHA_LIGHT;
-        mRadius = mLauncher.getResources().getDimension(R.dimen.shelf_surface_radius);
-        mTopPadding = mLauncher.getResources().getDimension(R.dimen.shelf_surface_top_padding);
-
-        mVerticalPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
-        mVerticalPaint.setColor(ColorUtils.setAlphaComponent(mEndColor, 255));
-
-        // Just assume the easiest UI for now, until we have the proper layout information.
-        mDrawingFlatColor = true;
-    }
-
-    @Override
-    protected void onProgressChanged() {
-        mProgressColor = ColorUtils.setAlphaComponent(mEndColor,
-                Math.round(DEACCEL_2.getInterpolation(mProgress) * Color.alpha(mEndColor)));
-    }
-
-    @Override
-    public void draw(Canvas canvas, int width, int height) {
-        if (mDrawingFlatColor) {
-            if (mProgress > 0) {
-                canvas.drawColor(mProgressColor);
-            }
-            return;
-        }
-
-        if (mVerticalPaint.getAlpha() == 0) {
-            return;
-        } else if (mDrawFactor <= 0) {
-            canvas.drawPaint(mVerticalPaint);
-        } else {
-            float top = (height - mMinSize) * mDrawFactor - mTopPadding;
-            canvas.drawRoundRect(0, top - mRadius, width, height + mRadius,
-                    mRadius, mRadius, mVerticalPaint);
-        }
-    }
-
-    public void reInitUi() {
-        DeviceProfile dp = mLauncher.getDeviceProfile();
-        mDrawingFlatColor = dp.isVerticalBarLayout();
-
-        if (!mDrawingFlatColor) {
-            float swipeLength = OverviewState.getDefaultSwipeHeight(mLauncher);
-            mMoveThreshold = 1 - swipeLength / mLauncher.getAllAppsController().getShiftRange();
-            mMinSize = dp.hotseatBarSizePx + dp.getInsets().bottom;
-            onVerticalProgress(mVerticalProgress);
-        }
-        invalidate();
-    }
-
-    public void onVerticalProgress(float progress) {
-        mVerticalProgress = progress;
-        if (mDrawingFlatColor) {
-            return;
-        }
-
-        float drawFactor;
-        int alpha;
-        if (mVerticalProgress >= mMoveThreshold) {
-            drawFactor = 1;
-            alpha = mVerticalProgress >= 1 ? 0 : Math.round(mThresholdAlpha
-                    * ACCEL_2.getInterpolation((1 - mVerticalProgress) / (1 - mMoveThreshold)));
-        } else if (mVerticalProgress <= 0) {
-            drawFactor = 0;
-            alpha = mEndAlpha;
-        } else {
-            drawFactor = mVerticalProgress / mMoveThreshold;
-            alpha = mEndAlpha - Math.round((mEndAlpha - mThresholdAlpha) * drawFactor);
-        }
-        alpha = Utilities.boundToRange(alpha, 0, 255);
-        if (alpha != mVerticalPaint.getAlpha() || drawFactor != mDrawFactor) {
-            mVerticalPaint.setAlpha(alpha);
-            mDrawFactor = drawFactor;
-            invalidate();
-        }
-    }
-
-}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/AllAppsState.java b/quickstep/src/com/android/launcher3/uioverrides/AllAppsState.java
index 5a216f6..d86ba6a 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/AllAppsState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/AllAppsState.java
@@ -31,7 +31,7 @@
  */
 public class AllAppsState extends LauncherState {
 
-    private static final int STATE_FLAGS = FLAG_DISABLE_ACCESSIBILITY | FLAG_ALL_APPS_SCRIM;
+    private static final int STATE_FLAGS = FLAG_DISABLE_ACCESSIBILITY;
 
     private static final PageAlphaProvider PAGE_ALPHA_PROVIDER = new PageAlphaProvider(DEACCEL_2) {
         @Override
@@ -68,8 +68,10 @@
 
     @Override
     public float[] getWorkspaceScaleAndTranslation(Launcher launcher) {
-        // TODO: interpolate
-        return LauncherState.OVERVIEW.getWorkspaceScaleAndTranslation(launcher);
+        float[] scaleAndTranslation = LauncherState.OVERVIEW.getWorkspaceScaleAndTranslation(
+                launcher);
+        scaleAndTranslation[0] = 1;
+        return scaleAndTranslation;
     }
 
     @Override
@@ -84,7 +86,7 @@
 
     @Override
     public float[] getOverviewScaleAndTranslationYFactor(Launcher launcher) {
-        return new float[] {1f, -0.2f};
+        return new float[] {0.9f, -0.2f};
     }
 
     @Override
diff --git a/quickstep/src/com/android/launcher3/uioverrides/DisplayRotationListener.java b/quickstep/src/com/android/launcher3/uioverrides/DisplayRotationListener.java
new file mode 100644
index 0000000..2d9a161
--- /dev/null
+++ b/quickstep/src/com/android/launcher3/uioverrides/DisplayRotationListener.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.launcher3.uioverrides;
+
+import android.content.Context;
+import android.os.Handler;
+
+import com.android.systemui.shared.system.RotationWatcher;
+
+/**
+ * Utility class for listening for rotation changes
+ */
+public class DisplayRotationListener extends RotationWatcher {
+
+    private final Runnable mCallback;
+    private Handler mHandler;
+
+    public DisplayRotationListener(Context context, Runnable callback) {
+        super(context);
+        mCallback = callback;
+    }
+
+    @Override
+    public void enable() {
+        if (mHandler == null) {
+            mHandler = new Handler();
+        }
+        super.enable();
+    }
+
+    @Override
+    protected void onRotationChanged(int i) {
+        mHandler.post(mCallback);
+    }
+}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/FastOverviewState.java b/quickstep/src/com/android/launcher3/uioverrides/FastOverviewState.java
index 89dd879..a11625a 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/FastOverviewState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/FastOverviewState.java
@@ -24,12 +24,11 @@
  */
 public class FastOverviewState extends OverviewState {
 
-    private static final int STATE_FLAGS = FLAG_SHOW_SCRIM | FLAG_DISABLE_RESTORE
-            | FLAG_DISABLE_INTERACTION | FLAG_OVERVIEW_UI | FLAG_HIDE_BACK_BUTTON
-            | FLAG_DISABLE_ACCESSIBILITY;
+    private static final int STATE_FLAGS = FLAG_DISABLE_RESTORE | FLAG_DISABLE_INTERACTION
+            | FLAG_OVERVIEW_UI | FLAG_HIDE_BACK_BUTTON | FLAG_DISABLE_ACCESSIBILITY;
 
     public FastOverviewState(int id) {
-        super(id, QuickScrubController.QUICK_SCRUB_START_DURATION, STATE_FLAGS);
+        super(id, QuickScrubController.QUICK_SCRUB_FROM_HOME_START_DURATION, STATE_FLAGS);
     }
 
     @Override
diff --git a/quickstep/src/com/android/launcher3/uioverrides/LandscapeEdgeSwipeController.java b/quickstep/src/com/android/launcher3/uioverrides/LandscapeEdgeSwipeController.java
index 42f6c74..68773b4 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/LandscapeEdgeSwipeController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/LandscapeEdgeSwipeController.java
@@ -9,12 +9,12 @@
 import com.android.launcher3.AbstractFloatingView;
 import com.android.launcher3.Launcher;
 import com.android.launcher3.LauncherState;
+import com.android.launcher3.LauncherStateManager.AnimationComponents;
 import com.android.launcher3.touch.AbstractStateChangeTouchController;
 import com.android.launcher3.touch.SwipeDetector;
 import com.android.launcher3.userevent.nano.LauncherLogProto;
 import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction;
 import com.android.quickstep.RecentsModel;
-import com.android.quickstep.util.SysuiEventLogger;
 
 /**
  * Touch controller for handling edge swipes in landscape/seascape UI
@@ -56,11 +56,11 @@
     }
 
     @Override
-    protected float initCurrentAnimation() {
+    protected float initCurrentAnimation(@AnimationComponents int animComponent) {
         float range = getShiftRange();
         long maxAccuracy = (long) (2 * range);
-        mCurrentAnimation = mLauncher.getStateManager()
-                .createAnimationToNewWorkspace(mToState, maxAccuracy);
+        mCurrentAnimation = mLauncher.getStateManager().createAnimationToNewWorkspace(mToState,
+                maxAccuracy, animComponent);
         return (mLauncher.getDeviceProfile().isSeascape() ? 2 : -2) / range;
     }
 
@@ -74,7 +74,6 @@
         super.onSwipeInteractionCompleted(targetState, logAction);
         if (mFromState == NORMAL && targetState == OVERVIEW) {
             RecentsModel.getInstance(mLauncher).onOverviewShown(true, TAG);
-            SysuiEventLogger.writeDummyRecentsTransition(0);
         }
     }
 }
diff --git a/quickstep/src/com/android/launcher3/uioverrides/OverviewState.java b/quickstep/src/com/android/launcher3/uioverrides/OverviewState.java
index 5bdf1b5..3a49294 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/OverviewState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/OverviewState.java
@@ -25,6 +25,7 @@
 import com.android.launcher3.DeviceProfile;
 import com.android.launcher3.Launcher;
 import com.android.launcher3.LauncherState;
+import com.android.launcher3.Workspace;
 import com.android.launcher3.allapps.DiscoveryBounce;
 import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
 import com.android.quickstep.views.RecentsView;
@@ -34,7 +35,7 @@
  */
 public class OverviewState extends LauncherState {
 
-    private static final int STATE_FLAGS = FLAG_SHOW_SCRIM | FLAG_WORKSPACE_ICONS_CAN_BE_DRAGGED
+    private static final int STATE_FLAGS = FLAG_WORKSPACE_ICONS_CAN_BE_DRAGGED
             | FLAG_DISABLE_RESTORE | FLAG_OVERVIEW_UI | FLAG_DISABLE_ACCESSIBILITY;
 
     public OverviewState(int id) {
@@ -47,8 +48,15 @@
 
     @Override
     public float[] getWorkspaceScaleAndTranslation(Launcher launcher) {
-        // TODO: provide a valid value
-        return new float[]{1, 0, -launcher.getDeviceProfile().hotseatBarSizePx / 2};
+        RecentsView recentsView = launcher.getOverviewPanel();
+        Workspace workspace = launcher.getWorkspace();
+        View workspacePage = workspace.getPageAt(workspace.getCurrentPage());
+        float workspacePageWidth = workspacePage != null && workspacePage.getWidth() != 0
+                ? workspacePage.getWidth() : launcher.getDeviceProfile().availableWidthPx;
+        recentsView.getTaskSize(sTempRect);
+        float scale = (float) sTempRect.width() / workspacePageWidth;
+        float parallaxFactor = 0.5f;
+        return new float[]{scale, 0, -getDefaultSwipeHeight(launcher) * parallaxFactor};
     }
 
     @Override
@@ -92,15 +100,20 @@
     @Override
     public int getVisibleElements(Launcher launcher) {
         if (launcher.getDeviceProfile().isVerticalBarLayout()) {
-            return DRAG_HANDLE_INDICATOR;
+            return 0;
         } else {
-            return HOTSEAT_SEARCH_BOX | DRAG_HANDLE_INDICATOR |
+            return HOTSEAT_SEARCH_BOX |
                     (launcher.getAppsView().getFloatingHeaderView().hasVisibleContent()
                             ? ALL_APPS_HEADER_EXTRA : HOTSEAT_ICONS);
         }
     }
 
     @Override
+    public float getWorkspaceScrimAlpha(Launcher launcher) {
+        return 0.5f;
+    }
+
+    @Override
     public float getVerticalProgress(Launcher launcher) {
         if ((getVisibleElements(launcher) & ALL_APPS_HEADER_EXTRA) == 0) {
             // We have no all apps content, so we're still at the fully down progress.
diff --git a/quickstep/src/com/android/launcher3/uioverrides/PortraitStatesTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/PortraitStatesTouchController.java
index 2f0bdc6..987f952 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/PortraitStatesTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/PortraitStatesTouchController.java
@@ -18,20 +18,20 @@
 import static com.android.launcher3.LauncherState.ALL_APPS;
 import static com.android.launcher3.LauncherState.NORMAL;
 import static com.android.launcher3.LauncherState.OVERVIEW;
-import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_OVERVIEW_TRANSLATION;
 import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_VERTICAL_PROGRESS;
-import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN;
 import static com.android.launcher3.anim.Interpolators.LINEAR;
 
 import android.animation.TimeInterpolator;
 import android.animation.ValueAnimator;
 import android.view.MotionEvent;
 import android.view.animation.Interpolator;
+import android.view.animation.OvershootInterpolator;
 
 import com.android.launcher3.AbstractFloatingView;
 import com.android.launcher3.DeviceProfile;
 import com.android.launcher3.Launcher;
 import com.android.launcher3.LauncherState;
+import com.android.launcher3.LauncherStateManager.AnimationComponents;
 import com.android.launcher3.anim.AnimatorPlaybackController;
 import com.android.launcher3.anim.AnimatorSetBuilder;
 import com.android.launcher3.anim.Interpolators;
@@ -41,7 +41,6 @@
 import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
 import com.android.quickstep.RecentsModel;
 import com.android.quickstep.TouchInteractionService;
-import com.android.quickstep.util.SysuiEventLogger;
 import com.android.quickstep.views.RecentsView;
 import com.android.quickstep.views.TaskView;
 
@@ -52,43 +51,11 @@
 
     private static final String TAG = "PortraitStatesTouchCtrl";
 
-    private static final float TOTAL_DISTANCE_MULTIPLIER = 3f;
-    private static final float LINEAR_SCALE_LIMIT = 1 / TOTAL_DISTANCE_MULTIPLIER;
-
-    // Must be greater than LINEAR_SCALE_LIMIT;
-    private static final float MAXIMUM_DISTANCE_FACTOR = 0.9f;
-
-    // Maximum amount to overshoot.
-    private static final float MAX_OVERSHOOT = 0.3f;
-
-    private static final double PI_BY_2 = Math.PI / 2;
-
     private InterpolatorWrapper mAllAppsInterpolatorWrapper = new InterpolatorWrapper();
 
     // If true, we will finish the current animation instantly on second touch.
     private boolean mFinishFastOnSecondTouch;
 
-    private final Interpolator mAllAppsDampedInterpolator = new Interpolator() {
-
-        private final double mAngleMultiplier = Math.PI /
-                (2 * (MAXIMUM_DISTANCE_FACTOR - LINEAR_SCALE_LIMIT));
-
-        @Override
-        public float getInterpolation(float v) {
-            if (v <= LINEAR_SCALE_LIMIT) {
-                return v * TOTAL_DISTANCE_MULTIPLIER;
-            }
-            float overshoot = (v - LINEAR_SCALE_LIMIT);
-            return (float) (1 + MAX_OVERSHOOT * Math.sin(overshoot * mAngleMultiplier));
-        }
-    };
-
-    private final Interpolator mOverviewBoundInterpolator = (v) -> {
-            if (v >= MAXIMUM_DISTANCE_FACTOR) {
-                return 1;
-            }
-            return FAST_OUT_SLOW_IN.getInterpolation(v / MAXIMUM_DISTANCE_FACTOR);
-    };
 
     public PortraitStatesTouchController(Launcher l) {
         super(l, SwipeDetector.VERTICAL);
@@ -144,17 +111,16 @@
     }
 
     private AnimatorSetBuilder getNormalToOverviewAnimation() {
-        mAllAppsInterpolatorWrapper.baseInterpolator = mAllAppsDampedInterpolator;
+        mAllAppsInterpolatorWrapper.baseInterpolator = LINEAR;
 
         AnimatorSetBuilder builder = new AnimatorSetBuilder();
         builder.setInterpolator(ANIM_VERTICAL_PROGRESS, mAllAppsInterpolatorWrapper);
 
-        builder.setInterpolator(ANIM_OVERVIEW_TRANSLATION, mOverviewBoundInterpolator);
         return builder;
     }
 
     @Override
-    protected float initCurrentAnimation() {
+    protected float initCurrentAnimation(@AnimationComponents int animComponents) {
         float range = getShiftRange();
         long maxAccuracy = (long) (2 * range);
 
@@ -167,7 +133,6 @@
 
         if (mFromState == NORMAL && mToState == OVERVIEW && totalShift != 0) {
             builder = getNormalToOverviewAnimation();
-            totalShift = totalShift * TOTAL_DISTANCE_MULTIPLIER;
         } else {
             builder = new AnimatorSetBuilder();
         }
@@ -190,7 +155,8 @@
             mLauncher.getStateManager().setCurrentUserControlledAnimation(mCurrentAnimation);
         } else {
             mCurrentAnimation = mLauncher.getStateManager()
-                    .createAnimationToNewWorkspace(mToState, builder, maxAccuracy, this::clearState);
+                    .createAnimationToNewWorkspace(mToState, builder, maxAccuracy, this::clearState,
+                            animComponents);
         }
 
         if (totalShift == 0) {
@@ -210,9 +176,9 @@
     @Override
     protected void updateSwipeCompleteAnimation(ValueAnimator animator, long expectedDuration,
             LauncherState targetState, float velocity, boolean isFling) {
-        handleFirstSwipeToOverview(animator, expectedDuration, targetState, velocity, isFling);
         super.updateSwipeCompleteAnimation(animator, expectedDuration, targetState,
                 velocity, isFling);
+        handleFirstSwipeToOverview(animator, expectedDuration, targetState, velocity, isFling);
     }
 
     private void handleFirstSwipeToOverview(final ValueAnimator animator,
@@ -220,62 +186,17 @@
             final boolean isFling) {
         if (mFromState == NORMAL && mToState == OVERVIEW && targetState == OVERVIEW) {
             mFinishFastOnSecondTouch = true;
-
-            // Update all apps interpolator
-            float currentFraction = mCurrentAnimation.getProgressFraction();
-            float absVelocity = Math.abs(velocity);
-            float currentValue = mAllAppsDampedInterpolator.getInterpolation(currentFraction);
-
-            if (isFling && absVelocity > 1 && currentFraction < LINEAR_SCALE_LIMIT) {
-
-                // TODO: Clean up these magic calculations
-                // Linearly interpolate the max value based on the velocity.
-                float maxValue = Math.max(absVelocity > 4 ? 1 + MAX_OVERSHOOT :
-                                1 + (absVelocity - 1) * MAX_OVERSHOOT / 3,
-                        currentValue);
-                double angleToPeak = PI_BY_2 - Math.asin(currentValue / maxValue);
-
-                if (expectedDuration != 0 && angleToPeak != 0) {
-
-                    float distanceLeft = 1 - currentFraction;
-                    mAllAppsInterpolatorWrapper.baseInterpolator = (f) -> {
-                        float scaledF = (f - currentFraction) / distanceLeft;
-
-                        if (scaledF < 0.5f) {
-                            double angle = PI_BY_2 - angleToPeak + scaledF * angleToPeak / 0.5f;
-                            return (float) (maxValue * Math.sin(angle));
-                        }
-
-                        scaledF = ((scaledF - .5f) / .5f);
-                        double angle = PI_BY_2 + 3 * scaledF * PI_BY_2;
-                        float amplitude = (1 - scaledF) * (1 - scaledF) * (maxValue - 1);
-                        return 1 + (float) (amplitude * Math.sin(angle));
-                    };
-
-                    animator.setDuration(expectedDuration).setInterpolator(LINEAR);
-                    return;
-                }
+            if (isFling && expectedDuration != 0) {
+                // Update all apps interpolator to add a bit of overshoot starting from currFraction
+                final float currFraction = mCurrentAnimation.getProgressFraction();
+                mAllAppsInterpolatorWrapper.baseInterpolator = Interpolators.clampToProgress(
+                        new OvershootInterpolator(Math.min(Math.abs(velocity), 3f)), currFraction, 1);
+                animator.setDuration(Math.min(expectedDuration, ATOMIC_DURATION))
+                        .setInterpolator(LINEAR);
             }
-
-            if (currentFraction < LINEAR_SCALE_LIMIT) {
-                mAllAppsInterpolatorWrapper.baseInterpolator = LINEAR;
-                return;
-            }
-            float extraValue = mAllAppsDampedInterpolator.getInterpolation(currentFraction) - 1;
-            float distanceLeft = 1 - currentFraction;
-
-            animator.setFloatValues(currentFraction, 1);
-            mAllAppsInterpolatorWrapper.baseInterpolator = (f) -> {
-                float scaledF = (f - currentFraction) / distanceLeft;
-
-                double angle = scaledF * 1.5 * Math.PI;
-                float amplitude = (1 - scaledF) * (1 - scaledF) * extraValue;
-                return 1 + (float) (amplitude * Math.sin(angle));
-            };
-            animator.setDuration(200).setInterpolator(LINEAR);
-            return;
+        } else {
+            mFinishFastOnSecondTouch = false;
         }
-        mFinishFastOnSecondTouch = false;
     }
 
     @Override
@@ -283,7 +204,6 @@
         super.onSwipeInteractionCompleted(targetState, logAction);
         if (mFromState == NORMAL && targetState == OVERVIEW) {
             RecentsModel.getInstance(mLauncher).onOverviewShown(true, TAG);
-            SysuiEventLogger.writeDummyRecentsTransition(0);
         }
     }
 
diff --git a/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java b/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java
index 2579bc2..e43b24a 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java
@@ -15,9 +15,14 @@
  */
 package com.android.launcher3.uioverrides;
 
-import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_OVERVIEW_TRANSLATION;
+import static com.android.launcher3.LauncherState.FAST_OVERVIEW;
+import static com.android.launcher3.LauncherState.OVERVIEW;
+import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_OVERVIEW_FADE;
+import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_OVERVIEW_SCALE;
 import static com.android.launcher3.anim.Interpolators.AGGRESSIVE_EASE_IN_OUT;
 import static com.android.launcher3.anim.Interpolators.LINEAR;
+import static com.android.quickstep.QuickScrubController.QUICK_SCRUB_START_INTERPOLATOR;
+import static com.android.quickstep.QuickScrubController.QUICK_SCRUB_TRANSLATION_Y_FACTOR;
 import static com.android.quickstep.views.LauncherRecentsView.TRANSLATION_Y_FACTOR;
 import static com.android.quickstep.views.RecentsView.ADJACENT_SCALE;
 import static com.android.quickstep.views.RecentsViewContainer.CONTENT_ALPHA;
@@ -25,12 +30,14 @@
 import android.animation.ValueAnimator;
 import android.annotation.TargetApi;
 import android.os.Build;
+import android.view.animation.Interpolator;
 
 import com.android.launcher3.Launcher;
 import com.android.launcher3.LauncherState;
 import com.android.launcher3.LauncherStateManager.AnimationConfig;
 import com.android.launcher3.LauncherStateManager.StateHandler;
 import com.android.launcher3.anim.AnimatorSetBuilder;
+import com.android.launcher3.anim.Interpolators;
 import com.android.launcher3.anim.PropertySetter;
 import com.android.quickstep.views.LauncherRecentsView;
 import com.android.quickstep.views.RecentsViewContainer;
@@ -63,14 +70,23 @@
     @Override
     public void setStateWithAnimation(final LauncherState toState,
             AnimatorSetBuilder builder, AnimationConfig config) {
+        if (!config.playAtomicComponent()) {
+            // The entire recents animation is played atomically.
+            return;
+        }
         PropertySetter setter = config.getPropertySetter(builder);
         float[] scaleTranslationYFactor = toState.getOverviewScaleAndTranslationYFactor(mLauncher);
-        setter.setFloat(mRecentsView, ADJACENT_SCALE, scaleTranslationYFactor[0],
-                builder.getInterpolator(ANIM_OVERVIEW_TRANSLATION, LINEAR));
+        Interpolator scaleInterpolator = builder.getInterpolator(ANIM_OVERVIEW_SCALE, LINEAR);
+        setter.setFloat(mRecentsView, ADJACENT_SCALE, scaleTranslationYFactor[0], scaleInterpolator);
+        Interpolator transYInterpolator = scaleInterpolator;
+        if (mLauncher.getStateManager().getState() == OVERVIEW && toState == FAST_OVERVIEW) {
+            transYInterpolator = Interpolators.clampToProgress(QUICK_SCRUB_START_INTERPOLATOR, 0,
+                    QUICK_SCRUB_TRANSLATION_Y_FACTOR);
+        }
         setter.setFloat(mRecentsView, TRANSLATION_Y_FACTOR, scaleTranslationYFactor[1],
-                builder.getInterpolator(ANIM_OVERVIEW_TRANSLATION, LINEAR));
+                transYInterpolator);
         setter.setFloat(mRecentsViewContainer, CONTENT_ALPHA, toState.overviewUi ? 1 : 0,
-                AGGRESSIVE_EASE_IN_OUT);
+                builder.getInterpolator(ANIM_OVERVIEW_FADE, AGGRESSIVE_EASE_IN_OUT));
 
         if (!toState.overviewUi) {
             builder.addOnFinishRunnable(mRecentsView::resetTaskVisuals);
diff --git a/quickstep/src/com/android/launcher3/uioverrides/TaskViewTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/TaskViewTouchController.java
index dc3f79c..a405735 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/TaskViewTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/TaskViewTouchController.java
@@ -21,16 +21,17 @@
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.animation.ValueAnimator;
-import android.util.Log;
 import android.view.MotionEvent;
 
 import com.android.launcher3.AbstractFloatingView;
 import com.android.launcher3.BaseDraggingActivity;
+import com.android.launcher3.LauncherAnimUtils;
 import com.android.launcher3.Utilities;
 import com.android.launcher3.anim.AnimatorPlaybackController;
 import com.android.launcher3.anim.Interpolators;
 import com.android.launcher3.touch.SwipeDetector;
 import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch;
+import com.android.launcher3.util.FlingBlockCheck;
 import com.android.launcher3.util.PendingAnimation;
 import com.android.launcher3.util.TouchController;
 import com.android.launcher3.views.BaseDragLayer;
@@ -46,8 +47,6 @@
 
     private static final String TAG = "OverviewSwipeController";
 
-    private static final float ALLOWED_FLING_DIRECTION_CHANGE_PROGRESS = 0.1f;
-
     // Progress after which the transition is assumed to be a success in case user does not fling
     private static final float SUCCESS_TRANSITION_PROGRESS = 0.5f;
 
@@ -65,6 +64,7 @@
     private float mDisplacementShift;
     private float mProgressMultiplier;
     private float mEndDisplacement;
+    private FlingBlockCheck mFlingBlockCheck = new FlingBlockCheck();
 
     private TaskView mTaskBeingDragged;
 
@@ -93,7 +93,6 @@
     @Override
     public void onAnimationCancel(Animator animation) {
         if (mCurrentAnimation != null && animation == mCurrentAnimation.getTarget()) {
-            Log.e(TAG, "Who dare cancel the animation when I am in control", new Exception());
             clearState();
         }
     }
@@ -158,16 +157,16 @@
         return mDetector.onTouchEvent(ev);
     }
 
-    private boolean reInitAnimationController(boolean goingUp) {
+    private void reInitAnimationController(boolean goingUp) {
         if (mCurrentAnimation != null && mCurrentAnimationIsGoingUp == goingUp) {
             // No need to init
-            return false;
+            return;
         }
         int scrollDirections = mDetector.getScrollDirections();
         if (goingUp && ((scrollDirections & SwipeDetector.DIRECTION_POSITIVE) == 0)
                 || !goingUp && ((scrollDirections & SwipeDetector.DIRECTION_NEGATIVE) == 0)) {
             // Trying to re-init in an unsupported direction.
-            return false;
+            return;
         }
         if (mCurrentAnimation != null) {
             mCurrentAnimation.setPlayFraction(0);
@@ -205,7 +204,6 @@
         mCurrentAnimation.getTarget().addListener(this);
         mCurrentAnimation.dispatchOnStart();
         mProgressMultiplier = 1 / mEndDisplacement;
-        return true;
     }
 
     @Override
@@ -217,6 +215,7 @@
             mDisplacementShift = mCurrentAnimation.getProgressFraction() / mProgressMultiplier;
             mCurrentAnimation.pause();
         }
+        mFlingBlockCheck.unblockFling();
     }
 
     @Override
@@ -226,6 +225,9 @@
                 totalDisplacement == 0 ? mCurrentAnimationIsGoingUp : totalDisplacement < 0;
         if (isGoingUp != mCurrentAnimationIsGoingUp) {
             reInitAnimationController(isGoingUp);
+            mFlingBlockCheck.blockFling();
+        } else {
+            mFlingBlockCheck.onEvent();
         }
         mCurrentAnimation.setPlayFraction(totalDisplacement * mProgressMultiplier);
         return true;
@@ -235,22 +237,14 @@
     public void onDragEnd(float velocity, boolean fling) {
         final boolean goingToEnd;
         final int logAction;
+        boolean blockedFling = fling && mFlingBlockCheck.isBlocked();
+        if (blockedFling) {
+            fling = false;
+        }
         if (fling) {
             logAction = Touch.FLING;
             boolean goingUp = velocity < 0;
-            if (goingUp != mCurrentAnimationIsGoingUp) {
-                // In case the fling is in opposite direction, make sure if is close enough
-                // from the start position
-                if (mCurrentAnimation.getProgressFraction()
-                        >= ALLOWED_FLING_DIRECTION_CHANGE_PROGRESS) {
-                    // Not allowed
-                    goingToEnd = false;
-                } else {
-                    goingToEnd = reInitAnimationController(goingUp);
-                }
-            } else {
-                goingToEnd = true;
-            }
+            goingToEnd = goingUp == mCurrentAnimationIsGoingUp;
         } else {
             logAction = Touch.SWIPE;
             goingToEnd = mCurrentAnimation.getProgressFraction() > SUCCESS_TRANSITION_PROGRESS;
@@ -259,6 +253,9 @@
         float progress = mCurrentAnimation.getProgressFraction();
         long animationDuration = SwipeDetector.calculateDuration(
                 velocity, goingToEnd ? (1 - progress) : progress);
+        if (blockedFling && !goingToEnd) {
+            animationDuration *= LauncherAnimUtils.blockedFlingDurationFactor(velocity);
+        }
 
         float nextFrameProgress = Utilities.boundToRange(
                 progress + velocity * SINGLE_FRAME_MS / Math.abs(mEndDisplacement), 0f, 1f);
diff --git a/quickstep/src/com/android/launcher3/uioverrides/UiFactory.java b/quickstep/src/com/android/launcher3/uioverrides/UiFactory.java
index 06099b9..b371677 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/UiFactory.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/UiFactory.java
@@ -16,6 +16,7 @@
 
 package com.android.launcher3.uioverrides;
 
+import static android.view.View.VISIBLE;
 import static com.android.launcher3.AbstractFloatingView.TYPE_ALL;
 import static com.android.launcher3.AbstractFloatingView.TYPE_HIDE_BACK_BUTTON;
 import static com.android.launcher3.LauncherState.ALL_APPS;
@@ -24,7 +25,9 @@
 import static com.android.launcher3.allapps.DiscoveryBounce.HOME_BOUNCE_SEEN;
 import static com.android.launcher3.allapps.DiscoveryBounce.SHELF_BOUNCE_SEEN;
 
+import android.app.Activity;
 import android.content.Context;
+import android.util.Base64;
 
 import com.android.launcher3.AbstractFloatingView;
 import com.android.launcher3.DeviceProfile;
@@ -32,13 +35,19 @@
 import com.android.launcher3.LauncherState;
 import com.android.launcher3.LauncherStateManager;
 import com.android.launcher3.LauncherStateManager.StateHandler;
+import com.android.launcher3.Utilities;
 import com.android.launcher3.anim.AnimatorPlaybackController;
 import com.android.launcher3.util.TouchController;
 import com.android.quickstep.OverviewInteractionState;
 import com.android.quickstep.RecentsModel;
 import com.android.quickstep.views.RecentsView;
+import com.android.systemui.shared.system.ActivityCompat;
 import com.android.systemui.shared.system.WindowManagerWrapper;
 
+import java.io.ByteArrayOutputStream;
+import java.io.PrintWriter;
+import java.util.zip.Deflater;
+
 public class UiFactory {
 
     public static TouchController[] createTouchControllers(Launcher launcher) {
@@ -84,7 +93,11 @@
                     TYPE_ALL & ~TYPE_HIDE_BACK_BUTTON) == null;
         }
         OverviewInteractionState.getInstance(launcher)
-                .setBackButtonVisible(!shouldBackButtonBeHidden);
+                .setBackButtonAlpha(shouldBackButtonBeHidden ? 0 : 1, true /* animate */);
+    }
+
+    public static void setBackButtonAlpha(Launcher launcher, float alpha, boolean animate) {
+         OverviewInteractionState.getInstance(launcher).setBackButtonAlpha(alpha,animate);
     }
 
     public static void resetOverview(Launcher launcher) {
@@ -167,6 +180,39 @@
         }
     }
 
+    public static boolean dumpActivity(Activity activity, PrintWriter writer) {
+        if (!Utilities.IS_DEBUG_DEVICE) {
+            return false;
+        }
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        if (!(new ActivityCompat(activity).encodeViewHierarchy(out))) {
+            return false;
+        }
+
+        Deflater deflater = new Deflater();
+        deflater.setInput(out.toByteArray());
+        deflater.finish();
+
+        out.reset();
+        byte[] buffer = new byte[1024];
+        while (!deflater.finished()) {
+            int count = deflater.deflate(buffer); // returns the generated code... index
+            out.write(buffer, 0, count);
+        }
+
+        writer.println("--encoded-view-dump-v0--");
+        writer.println(Base64.encodeToString(
+                out.toByteArray(), Base64.NO_WRAP | Base64.NO_PADDING));
+        return true;
+    }
+
+    public static void prepareToShowOverview(Launcher launcher) {
+        RecentsView overview = launcher.getOverviewPanel();
+        if (overview.getVisibility() != VISIBLE || overview.getContentAlpha() == 0) {
+            overview.setAdjacentScale(1.33f);
+        }
+    }
+
     private static class LauncherTaskViewController extends TaskViewTouchController<Launcher> {
 
         public LauncherTaskViewController(Launcher activity) {
diff --git a/quickstep/src/com/android/quickstep/ActivityControlHelper.java b/quickstep/src/com/android/quickstep/ActivityControlHelper.java
index 85106ba..ae0affe 100644
--- a/quickstep/src/com/android/quickstep/ActivityControlHelper.java
+++ b/quickstep/src/com/android/quickstep/ActivityControlHelper.java
@@ -15,18 +15,25 @@
  */
 package com.android.quickstep;
 
+import static com.android.launcher3.LauncherAnimUtils.OVERVIEW_TRANSITION_MS;
 import static com.android.launcher3.LauncherState.FAST_OVERVIEW;
 import static com.android.launcher3.LauncherState.OVERVIEW;
 import static com.android.launcher3.allapps.AllAppsTransitionController.ALL_APPS_PROGRESS;
 import static com.android.launcher3.anim.Interpolators.LINEAR;
 import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_BACK;
+import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_ROTATION;
 
 import android.animation.AnimatorSet;
 import android.animation.ObjectAnimator;
+import android.annotation.TargetApi;
+import android.app.ActivityManager.RunningTaskInfo;
+import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.graphics.Rect;
+import android.os.Build;
 import android.os.Handler;
+import android.os.Looper;
 import android.support.annotation.Nullable;
 import android.support.annotation.UiThread;
 import android.view.View;
@@ -40,6 +47,9 @@
 import com.android.launcher3.allapps.AllAppsTransitionController;
 import com.android.launcher3.allapps.DiscoveryBounce;
 import com.android.launcher3.anim.AnimatorPlaybackController;
+import com.android.launcher3.dragndrop.DragLayer;
+import com.android.launcher3.userevent.nano.LauncherLogProto;
+import com.android.launcher3.util.MultiValueAlpha.AlphaProperty;
 import com.android.quickstep.util.LayoutUtils;
 import com.android.quickstep.util.RemoteAnimationProvider;
 import com.android.quickstep.util.RemoteAnimationTargetSet;
@@ -49,21 +59,23 @@
 import com.android.quickstep.views.RecentsViewContainer;
 import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
 
+import java.util.Objects;
 import java.util.function.BiPredicate;
 import java.util.function.Consumer;
 
 /**
  * Utility class which abstracts out the logical differences between Launcher and RecentsActivity.
  */
+@TargetApi(Build.VERSION_CODES.P)
 public interface ActivityControlHelper<T extends BaseDraggingActivity> {
 
     LayoutListener createLayoutListener(T activity);
 
     /**
      * Updates the UI to indicate quick interaction.
-     * @return true if there any any UI change as a result of this
      */
-    boolean onQuickInteractionStart(T activity, boolean activityVisible);
+    void onQuickInteractionStart(T activity, @Nullable RunningTaskInfo taskInfo,
+            boolean activityVisible);
 
     float getTranslationYForQuickScrub(T activity);
 
@@ -88,7 +100,7 @@
     RecentsView getVisibleRecentsView();
 
     @UiThread
-    boolean switchToRecentsIfVisible();
+    boolean switchToRecentsIfVisible(boolean fromRecentsButton);
 
     Rect getOverviewWindowBounds(Rect homeBounds, RemoteAnimationTargetCompat target);
 
@@ -102,11 +114,18 @@
 
     boolean supportsLongSwipe(T activity);
 
+    AlphaProperty getAlphaProperty(T activity);
+
     /**
      * Must return a non-null controller is supportsLongSwipe was true.
      */
     LongSwipeHelper getLongSwipeController(T activity, RemoteAnimationTargetSet targetSet);
 
+    /**
+     * Used for containerType in {@link com.android.launcher3.logging.UserEventDispatcher}
+     */
+    int getContainerType();
+
     class LauncherActivityControllerHelper implements ActivityControlHelper<Launcher> {
 
         @Override
@@ -115,10 +134,14 @@
         }
 
         @Override
-        public boolean onQuickInteractionStart(Launcher activity, boolean activityVisible) {
+        public void onQuickInteractionStart(Launcher activity, RunningTaskInfo taskInfo,
+                boolean activityVisible) {
             LauncherState fromState = activity.getStateManager().getState();
             activity.getStateManager().goToState(FAST_OVERVIEW, activityVisible);
-            return !fromState.overviewUi;
+
+            QuickScrubController controller = activity.<RecentsView>getOverviewPanel()
+                    .getQuickScrubController();
+            controller.onQuickScrubStart(activityVisible && !fromState.overviewUi, this);
         }
 
         @Override
@@ -260,9 +283,15 @@
         }
 
         @Override
-        public boolean switchToRecentsIfVisible() {
+        public boolean switchToRecentsIfVisible(boolean fromRecentsButton) {
             Launcher launcher = getVisibleLaucher();
             if (launcher != null) {
+                if (fromRecentsButton) {
+                    launcher.getUserEventDispatcher().logActionCommand(
+                            LauncherLogProto.Action.Command.RECENTS_BUTTON,
+                            getContainerType(),
+                            LauncherLogProto.ContainerType.TASKSWITCHER);
+                }
                 launcher.getStateManager().goToState(OVERVIEW);
                 return true;
             }
@@ -271,7 +300,7 @@
 
         @Override
         public boolean deferStartingActivity(int downHitTarget) {
-            return downHitTarget == HIT_TARGET_BACK;
+            return downHitTarget == HIT_TARGET_BACK || downHitTarget == HIT_TARGET_ROTATION;
         }
 
         @Override
@@ -297,14 +326,43 @@
             }
             return new LongSwipeHelper(activity, targetSet);
         }
+
+        @Override
+        public AlphaProperty getAlphaProperty(Launcher activity) {
+            return activity.getDragLayer().getAlphaProperty(DragLayer.ALPHA_INDEX_SWIPE_UP);
+        }
+
+        @Override
+        public int getContainerType() {
+            final Launcher launcher = getVisibleLaucher();
+            return launcher != null ? launcher.getStateManager().getState().containerType
+                    : LauncherLogProto.ContainerType.APP;
+        }
     }
 
     class FallbackActivityControllerHelper implements ActivityControlHelper<RecentsActivity> {
 
+        private final ComponentName mHomeComponent;
+        private final Handler mUiHandler = new Handler(Looper.getMainLooper());
+
+        public FallbackActivityControllerHelper(ComponentName homeComponent) {
+            mHomeComponent = homeComponent;
+        }
+
         @Override
-        public boolean onQuickInteractionStart(RecentsActivity activity, boolean activityVisible) {
-            // Activity does not need any UI change for quickscrub.
-            return false;
+        public void onQuickInteractionStart(RecentsActivity activity, RunningTaskInfo taskInfo,
+                boolean activityVisible) {
+            QuickScrubController controller = activity.<RecentsView>getOverviewPanel()
+                    .getQuickScrubController();
+
+            // TODO: match user is as well
+            boolean startingFromHome = !activityVisible &&
+                    (taskInfo == null || Objects.equals(taskInfo.topActivity, mHomeComponent));
+            controller.onQuickScrubStart(startingFromHome, this);
+            if (activityVisible) {
+                mUiHandler.postDelayed(controller::onFinishedTransitionToQuickScrub,
+                        OVERVIEW_TRANSITION_MS);
+            }
         }
 
         @Override
@@ -418,7 +476,7 @@
         }
 
         @Override
-        public boolean switchToRecentsIfVisible() {
+        public boolean switchToRecentsIfVisible(boolean fromRecentsButton) {
             return false;
         }
 
@@ -450,6 +508,16 @@
                 RemoteAnimationTargetSet targetSet) {
             return null;
         }
+
+        @Override
+        public AlphaProperty getAlphaProperty(RecentsActivity activity) {
+            return activity.getDragLayer().getAlphaProperty(0);
+        }
+
+        @Override
+        public int getContainerType() {
+            return LauncherLogProto.ContainerType.SIDELOADED_LAUNCHER;
+        }
     }
 
     interface LayoutListener {
diff --git a/quickstep/src/com/android/quickstep/LongSwipeHelper.java b/quickstep/src/com/android/quickstep/LongSwipeHelper.java
index edc7457..fbcde8b 100644
--- a/quickstep/src/com/android/quickstep/LongSwipeHelper.java
+++ b/quickstep/src/com/android/quickstep/LongSwipeHelper.java
@@ -15,6 +15,7 @@
  */
 package com.android.quickstep;
 
+import static com.android.launcher3.LauncherAnimUtils.MIN_PROGRESS_TO_ALL_APPS;
 import static com.android.launcher3.LauncherState.ALL_APPS;
 import static com.android.launcher3.LauncherState.OVERVIEW;
 import static com.android.launcher3.anim.Interpolators.DEACCEL;
@@ -26,6 +27,7 @@
 import android.view.Surface;
 
 import com.android.launcher3.Launcher;
+import com.android.launcher3.LauncherAnimUtils;
 import com.android.launcher3.R;
 import com.android.launcher3.allapps.AllAppsTransitionController;
 import com.android.launcher3.allapps.DiscoveryBounce;
@@ -33,7 +35,9 @@
 import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction;
 import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch;
 import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
+import com.android.launcher3.util.FlingBlockCheck;
 import com.android.quickstep.util.RemoteAnimationTargetSet;
+import com.android.quickstep.views.RecentsView;
 import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
 import com.android.systemui.shared.system.TransactionCompat;
 
@@ -44,7 +48,6 @@
  */
 public class LongSwipeHelper {
 
-    private static final float MIN_PROGRESS_TO_ALL_APPS = 0.35f;
     private static final float SWIPE_DURATION_MULTIPLIER =
             Math.min(1 / MIN_PROGRESS_TO_ALL_APPS, 1 / (1 - MIN_PROGRESS_TO_ALL_APPS));
 
@@ -53,6 +56,7 @@
 
     private float mMaxSwipeDistance = 1;
     private AnimatorPlaybackController mAnimator;
+    private FlingBlockCheck mFlingBlockCheck = new FlingBlockCheck();
 
     LongSwipeHelper(Launcher launcher, RemoteAnimationTargetSet targetSet) {
         mLauncher = launcher;
@@ -62,6 +66,7 @@
 
     private void init() {
         setTargetAlpha(0, true);
+        mFlingBlockCheck.blockFling();
 
         // Init animations
         AllAppsTransitionController controller = mLauncher.getAllAppsController();
@@ -74,6 +79,7 @@
 
     public void onMove(float displacement) {
         mAnimator.setPlayFraction(displacement / mMaxSwipeDistance);
+        mFlingBlockCheck.onEvent();
     }
 
     public void destroy() {
@@ -90,6 +96,11 @@
         final boolean toAllApps;
         float endProgress;
 
+        boolean blockedFling = isFling && mFlingBlockCheck.isBlocked();
+        if (blockedFling) {
+            isFling = false;
+        }
+
         if (!isFling) {
             toAllApps = currentFraction > MIN_PROGRESS_TO_ALL_APPS;
             endProgress = toAllApps ? 1 : 0;
@@ -114,7 +125,11 @@
             }
         }
 
-        mAnimator.setEndAction(() -> onSwipeAnimationComplete(toAllApps, isFling, callback));
+        if (blockedFling && !toAllApps) {
+            duration *= LauncherAnimUtils.blockedFlingDurationFactor(0);
+        }
+        final boolean finalIsFling = isFling;
+        mAnimator.setEndAction(() -> onSwipeAnimationComplete(toAllApps, finalIsFling, callback));
         ValueAnimator animator = mAnimator.getAnimationPlayer();
         animator.setDuration(duration).setInterpolator(DEACCEL);
         animator.setFloatValues(currentFraction, endProgress);
@@ -150,6 +165,7 @@
         mLauncher.getStateManager().goToState(toAllApps ? ALL_APPS : OVERVIEW, false);
         if (!toAllApps) {
             DiscoveryBounce.showForOverviewIfNeeded(mLauncher);
+            mLauncher.<RecentsView>getOverviewPanel().setSwipeDownShouldLaunchApp(true);
         }
 
         mLauncher.getUserEventDispatcher().logStateChangeAction(
diff --git a/quickstep/src/com/android/quickstep/MotionEventQueue.java b/quickstep/src/com/android/quickstep/MotionEventQueue.java
index 538e23c..15f5aa5 100644
--- a/quickstep/src/com/android/quickstep/MotionEventQueue.java
+++ b/quickstep/src/com/android/quickstep/MotionEventQueue.java
@@ -163,7 +163,7 @@
                             mConsumer.updateTouchTracking(INTERACTION_QUICK_SCRUB);
                             break;
                         case ACTION_QUICK_STEP:
-                            mConsumer.onQuickStep(event.getX(), event.getY(), event.getEventTime());
+                            mConsumer.onQuickStep(event);
                             break;
                         default:
                             Log.e(TAG, "Invalid virtual event: " + event.getAction());
diff --git a/quickstep/src/com/android/quickstep/OtherActivityTouchConsumer.java b/quickstep/src/com/android/quickstep/OtherActivityTouchConsumer.java
index 2d41a5b..23738fb 100644
--- a/quickstep/src/com/android/quickstep/OtherActivityTouchConsumer.java
+++ b/quickstep/src/com/android/quickstep/OtherActivityTouchConsumer.java
@@ -82,6 +82,7 @@
     private final PointF mLastPos = new PointF();
     private int mActivePointerId = INVALID_POINTER_ID;
     private boolean mPassedInitialSlop;
+    // Used for non-deferred gestures to determine when to start dragging
     private int mQuickStepDragSlop;
     private float mStartDisplacement;
     private WindowTransformSwipeHandler mInteractionHandler;
@@ -160,15 +161,14 @@
                 }
                 mLastPos.set(ev.getX(pointerIndex), ev.getY(pointerIndex));
                 float displacement = getDisplacement(ev);
-                if (!mPassedInitialSlop
-                        && Math.abs(displacement) > mQuickStepDragSlop) {
-                    mPassedInitialSlop = true;
-                    mStartDisplacement = displacement;
-
-                    // If we deferred starting the window animation on touch down, then
-                    // start tracking now
-                    if (mIsDeferredDownTarget) {
-                        startTouchTrackingForWindowAnimation(ev.getEventTime());
+                if (!mPassedInitialSlop) {
+                    if (!mIsDeferredDownTarget) {
+                        // Normal gesture, ensure we pass the drag slop before we start tracking
+                        // the gesture
+                        if (Math.abs(displacement) > mQuickStepDragSlop) {
+                            mPassedInitialSlop = true;
+                            mStartDisplacement = displacement;
+                        }
                     }
                 }
 
@@ -353,7 +353,14 @@
     }
 
     @Override
-    public void onQuickStep(float eventX, float eventY, long eventTime) {
+    public void onQuickStep(MotionEvent ev) {
+        if (mIsDeferredDownTarget) {
+            // Deferred gesture, start the animation and gesture tracking once we pass the actual
+            // touch slop
+            startTouchTrackingForWindowAnimation(ev.getEventTime());
+            mPassedInitialSlop = true;
+            mStartDisplacement = getDisplacement(ev);
+        }
         notifyGestureStarted();
     }
 
diff --git a/quickstep/src/com/android/quickstep/OverviewCommandHelper.java b/quickstep/src/com/android/quickstep/OverviewCommandHelper.java
index 43772fb..7b29323 100644
--- a/quickstep/src/com/android/quickstep/OverviewCommandHelper.java
+++ b/quickstep/src/com/android/quickstep/OverviewCommandHelper.java
@@ -18,10 +18,13 @@
 import static android.content.Intent.ACTION_PACKAGE_ADDED;
 import static android.content.Intent.ACTION_PACKAGE_CHANGED;
 import static android.content.Intent.ACTION_PACKAGE_REMOVED;
+
 import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN;
 import static com.android.launcher3.anim.Interpolators.TOUCH_RESPONSE_INTERPOLATOR;
-import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_RECENTS;
-import static com.android.systemui.shared.system.PackageManagerWrapper.ACTION_PREFERRED_ACTIVITY_CHANGED;
+import static com.android.systemui.shared.system.ActivityManagerWrapper
+        .CLOSE_SYSTEM_WINDOWS_REASON_RECENTS;
+import static com.android.systemui.shared.system.PackageManagerWrapper
+        .ACTION_PREFERRED_ACTIVITY_CHANGED;
 import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_CLOSING;
 import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_OPENING;
 
@@ -42,22 +45,28 @@
 import android.util.Log;
 import android.view.View;
 import android.view.ViewConfiguration;
+
 import com.android.launcher3.AbstractFloatingView;
 import com.android.launcher3.BaseDraggingActivity;
+import com.android.launcher3.InvariantDeviceProfile;
 import com.android.launcher3.MainThreadExecutor;
 import com.android.launcher3.anim.AnimationSuccessListener;
+import com.android.launcher3.logging.UserEventDispatcher;
+import com.android.launcher3.userevent.nano.LauncherLogProto.Action;
+import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
 import com.android.quickstep.ActivityControlHelper.ActivityInitListener;
 import com.android.quickstep.ActivityControlHelper.AnimationFactory;
 import com.android.quickstep.ActivityControlHelper.FallbackActivityControllerHelper;
 import com.android.quickstep.ActivityControlHelper.LauncherActivityControllerHelper;
 import com.android.quickstep.util.ClipAnimationHelper;
 import com.android.quickstep.util.RemoteAnimationTargetSet;
-import com.android.quickstep.util.SysuiEventLogger;
 import com.android.quickstep.views.RecentsView;
 import com.android.systemui.shared.system.ActivityManagerWrapper;
+import com.android.systemui.shared.system.LatencyTrackerCompat;
 import com.android.systemui.shared.system.PackageManagerWrapper;
 import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
 import com.android.systemui.shared.system.TransactionCompat;
+
 import java.util.ArrayList;
 
 /**
@@ -132,7 +141,7 @@
         } else {
             // The default home app is a different launcher. Use the fallback Overview instead.
             overviewComponent = new ComponentName(mContext, RecentsActivity.class);
-            mActivityControlHelper = new FallbackActivityControllerHelper();
+            mActivityControlHelper = new FallbackActivityControllerHelper(defaultHome);
             overviewIntentCategory = Intent.CATEGORY_DEFAULT;
 
             // User's default home app can change as a result of package updates of this app (such
@@ -184,6 +193,17 @@
         mMainThreadExecutor.execute(new ShowRecentsCommand());
     }
 
+    public void onTip(int actionType, int viewType) {
+        mMainThreadExecutor.execute(new Runnable() {
+            @Override
+            public void run() {
+                UserEventDispatcher.newInstance(mContext,
+                        new InvariantDeviceProfile(mContext).getDeviceProfile(mContext))
+                        .logActionTip(actionType, viewType);
+            }
+        });
+    }
+
     public ActivityControlHelper getActivityControlHelper() {
         return mActivityControlHelper;
     }
@@ -205,6 +225,8 @@
         private ActivityInitListener mListener;
         private T mActivity;
         private RecentsView mRecentsView;
+        private final long mToggleClickedTime = SystemClock.uptimeMillis();
+        private boolean mUserEventLogged;
 
         public RecentsActivityCommand() {
             mHelper = getActivityControlHelper();
@@ -222,10 +244,7 @@
 
             if (!handleCommand(elapsedTime)) {
                 // Start overview
-                if (mHelper.switchToRecentsIfVisible()) {
-                    SysuiEventLogger.writeDummyRecentsTransition(0);
-                    // Do nothing
-                } else {
+                if (!mHelper.switchToRecentsIfVisible(true)) {
                     mListener = mHelper.createActivityInitListener(this::onActivityReady);
                     mListener.registerAndStartActivity(overviewIntent, this::createWindowAnimation,
                             mContext, mMainThreadExecutor.getHandler(), RECENTS_LAUNCH_DURATION);
@@ -267,11 +286,21 @@
             }
             mActivity = activity;
             mRecentsView = mActivity.getOverviewPanel();
-            mRecentsView.setFirstTaskIconScaledDown(true /* isScaledDown */, false /* animate */);
+            mRecentsView.setRunningTaskIconScaledDown(true /* isScaledDown */, false /* animate */);
+            if (!mUserEventLogged) {
+                activity.getUserEventDispatcher().logActionCommand(Action.Command.RECENTS_BUTTON,
+                        mHelper.getContainerType(), ContainerType.TASKSWITCHER);
+                mUserEventLogged = true;
+            }
             return false;
         }
 
         private AnimatorSet createWindowAnimation(RemoteAnimationTargetCompat[] targetCompats) {
+            if (LatencyTrackerCompat.isEnabled(mContext)) {
+                LatencyTrackerCompat.logToggleRecents(
+                        (int) (SystemClock.uptimeMillis() - mToggleClickedTime));
+            }
+
             if (mListener != null) {
                 mListener.unregister();
             }
@@ -280,7 +309,7 @@
                 @Override
                 public void onAnimationSuccess(Animator animator) {
                     if (mRecentsView != null) {
-                        mRecentsView.setFirstTaskIconScaledDown(false /* isScaledDown */,
+                        mRecentsView.setRunningTaskIconScaledDown(false /* isScaledDown */,
                                 true /* animate */);
                     }
                 }
diff --git a/quickstep/src/com/android/quickstep/OverviewInteractionState.java b/quickstep/src/com/android/quickstep/OverviewInteractionState.java
index 8923608..d605746 100644
--- a/quickstep/src/com/android/quickstep/OverviewInteractionState.java
+++ b/quickstep/src/com/android/quickstep/OverviewInteractionState.java
@@ -17,12 +17,12 @@
 
 import static com.android.systemui.shared.system.NavigationBarCompat.FLAG_DISABLE_QUICK_SCRUB;
 import static com.android.systemui.shared.system.NavigationBarCompat.FLAG_DISABLE_SWIPE_UP;
-import static com.android.systemui.shared.system.NavigationBarCompat.FLAG_HIDE_BACK_BUTTON;
 import static com.android.systemui.shared.system.NavigationBarCompat.FLAG_SHOW_OVERVIEW_BUTTON;
 import static com.android.systemui.shared.system.SettingsCompat.SWIPE_UP_SETTING_NAME;
 
 import android.content.ContentResolver;
 import android.content.Context;
+import android.content.res.Resources;
 import android.database.ContentObserver;
 import android.os.Handler;
 import android.os.Looper;
@@ -33,6 +33,8 @@
 import android.util.Log;
 
 import com.android.launcher3.MainThreadExecutor;
+import com.android.launcher3.Utilities;
+import com.android.launcher3.allapps.DiscoveryBounce;
 import com.android.launcher3.util.UiThreadHelper;
 import com.android.systemui.shared.recents.ISystemUiProxy;
 
@@ -43,7 +45,6 @@
  *
  *   - FLAG_DISABLE_QUICK_SCRUB
  *   - FLAG_DISABLE_SWIPE_UP
- *   - FLAG_HIDE_BACK_BUTTON
  *   - FLAG_SHOW_OVERVIEW_BUTTON
  *
  * @see com.android.systemui.shared.system.NavigationBarCompat.InteractionType and associated flags.
@@ -52,6 +53,12 @@
 
     private static final String TAG = "OverviewFlags";
 
+    private static final String HAS_ENABLED_QUICKSTEP_ONCE = "launcher.has_enabled_quickstep_once";
+    private static final String SWIPE_UP_SETTING_AVAILABLE_RES_NAME =
+            "config_swipe_up_gesture_setting_available";
+    private static final String SWIPE_UP_ENABLED_DEFAULT_RES_NAME =
+            "config_swipe_up_gesture_default";
+
     // We do not need any synchronization for this variable as its only written on UI thread.
     private static OverviewInteractionState INSTANCE;
 
@@ -72,37 +79,47 @@
     }
 
     private static final int MSG_SET_PROXY = 200;
-    private static final int MSG_SET_BACK_BUTTON_VISIBLE = 201;
+    private static final int MSG_SET_BACK_BUTTON_ALPHA = 201;
     private static final int MSG_SET_SWIPE_UP_ENABLED = 202;
 
     private final SwipeUpGestureEnabledSettingObserver mSwipeUpSettingObserver;
 
+    private final Context mContext;
     private final Handler mUiHandler;
     private final Handler mBgHandler;
 
     // These are updated on the background thread
     private ISystemUiProxy mISystemUiProxy;
-    private boolean mBackButtonVisible = true;
     private boolean mSwipeUpEnabled = true;
 
     private Runnable mOnSwipeUpSettingChangedListener;
 
     private OverviewInteractionState(Context context) {
+        mContext = context;
+
+        // Data posted to the uihandler will be sent to the bghandler. Data is sent to uihandler
+        // because of its high send frequency and data may be very different than the previous value
+        // For example, send back alpha on uihandler to avoid flickering when setting its visibility
         mUiHandler = new Handler(this::handleUiMessage);
         mBgHandler = new Handler(UiThreadHelper.getBackgroundLooper(), this::handleBgMessage);
 
-        mSwipeUpSettingObserver = new SwipeUpGestureEnabledSettingObserver(mUiHandler,
-                context.getContentResolver());
-        mSwipeUpSettingObserver.register();
+        if (getSystemBooleanRes(SWIPE_UP_SETTING_AVAILABLE_RES_NAME)) {
+            mSwipeUpSettingObserver = new SwipeUpGestureEnabledSettingObserver(mUiHandler,
+                    context.getContentResolver());
+            mSwipeUpSettingObserver.register();
+        } else {
+            mSwipeUpSettingObserver = null;
+            mSwipeUpEnabled = getSystemBooleanRes(SWIPE_UP_ENABLED_DEFAULT_RES_NAME);
+        }
     }
 
     public boolean isSwipeUpGestureEnabled() {
         return mSwipeUpEnabled;
     }
 
-    public void setBackButtonVisible(boolean visible) {
-        mUiHandler.removeMessages(MSG_SET_BACK_BUTTON_VISIBLE);
-        mUiHandler.obtainMessage(MSG_SET_BACK_BUTTON_VISIBLE, visible ? 1 : 0, 0)
+    public void setBackButtonAlpha(float alpha, boolean animate) {
+        mUiHandler.removeMessages(MSG_SET_BACK_BUTTON_ALPHA);
+        mUiHandler.obtainMessage(MSG_SET_BACK_BUTTON_ALPHA, animate ? 1 : 0, 0, alpha)
                 .sendToTarget();
     }
 
@@ -111,7 +128,7 @@
     }
 
     private boolean handleUiMessage(Message msg) {
-        mBgHandler.obtainMessage(msg.what, msg.arg1, msg.arg2).sendToTarget();
+        mBgHandler.obtainMessage(msg.what, msg.arg1, msg.arg2, msg.obj).sendToTarget();
         return true;
     }
 
@@ -120,11 +137,13 @@
             case MSG_SET_PROXY:
                 mISystemUiProxy = (ISystemUiProxy) msg.obj;
                 break;
-            case MSG_SET_BACK_BUTTON_VISIBLE:
-                mBackButtonVisible = msg.arg1 != 0;
-                break;
+            case MSG_SET_BACK_BUTTON_ALPHA:
+                applyBackButtonAlpha((float) msg.obj, msg.arg1 == 1);
+                return true;
             case MSG_SET_SWIPE_UP_ENABLED:
                 mSwipeUpEnabled = msg.arg1 != 0;
+                resetHomeBounceSeenOnQuickstepEnabledFirstTime();
+
                 if (mOnSwipeUpSettingChangedListener != null) {
                     mOnSwipeUpSettingChangedListener.run();
                 }
@@ -144,10 +163,8 @@
             return;
         }
 
-        int flags;
-        if (mSwipeUpEnabled) {
-            flags = mBackButtonVisible ? 0 : FLAG_HIDE_BACK_BUTTON;
-        } else {
+        int flags = 0;
+        if (!mSwipeUpEnabled) {
             flags = FLAG_DISABLE_SWIPE_UP | FLAG_DISABLE_QUICK_SCRUB | FLAG_SHOW_OVERVIEW_BUTTON;
         }
         try {
@@ -157,20 +174,35 @@
         }
     }
 
+    @WorkerThread
+    private void applyBackButtonAlpha(float alpha, boolean animate) {
+        if (mISystemUiProxy == null) {
+            return;
+        }
+        try {
+            mISystemUiProxy.setBackButtonAlpha(alpha, animate);
+        } catch (RemoteException e) {
+            Log.w(TAG, "Unable to update overview back button alpha", e);
+        }
+    }
+
     private class SwipeUpGestureEnabledSettingObserver extends ContentObserver {
         private Handler mHandler;
         private ContentResolver mResolver;
+        private final int defaultValue;
 
         SwipeUpGestureEnabledSettingObserver(Handler handler, ContentResolver resolver) {
             super(handler);
             mHandler = handler;
             mResolver = resolver;
+            defaultValue = getSystemBooleanRes(SWIPE_UP_ENABLED_DEFAULT_RES_NAME) ? 1 : 0;
         }
 
         public void register() {
             mResolver.registerContentObserver(Settings.Secure.getUriFor(SWIPE_UP_SETTING_NAME),
                     false, this);
             mSwipeUpEnabled = getValue();
+            resetHomeBounceSeenOnQuickstepEnabledFirstTime();
         }
 
         @Override
@@ -181,7 +213,29 @@
         }
 
         private boolean getValue() {
-            return Settings.Secure.getInt(mResolver, SWIPE_UP_SETTING_NAME, 0) == 1;
+            return Settings.Secure.getInt(mResolver, SWIPE_UP_SETTING_NAME, defaultValue) == 1;
+        }
+    }
+
+    private boolean getSystemBooleanRes(String resName) {
+        Resources res = Resources.getSystem();
+        int resId = res.getIdentifier(resName, "bool", "android");
+
+        if (resId != 0) {
+            return res.getBoolean(resId);
+        } else {
+            Log.e(TAG, "Failed to get system resource ID. Incompatible framework version?");
+            return false;
+        }
+    }
+
+    private void resetHomeBounceSeenOnQuickstepEnabledFirstTime() {
+        if (mSwipeUpEnabled && !Utilities.getPrefs(mContext).getBoolean(
+                HAS_ENABLED_QUICKSTEP_ONCE, true)) {
+            Utilities.getPrefs(mContext).edit()
+                    .putBoolean(HAS_ENABLED_QUICKSTEP_ONCE, true)
+                    .putBoolean(DiscoveryBounce.HOME_BOUNCE_SEEN, false)
+                    .apply();
         }
     }
 }
diff --git a/quickstep/src/com/android/quickstep/QuickScrubController.java b/quickstep/src/com/android/quickstep/QuickScrubController.java
index ae7de87..abb479d 100644
--- a/quickstep/src/com/android/quickstep/QuickScrubController.java
+++ b/quickstep/src/com/android/quickstep/QuickScrubController.java
@@ -16,16 +16,18 @@
 
 package com.android.quickstep;
 
+import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN;
+
 import android.util.Log;
 import android.view.HapticFeedbackConstants;
+import android.view.animation.Interpolator;
 
 import com.android.launcher3.Alarm;
 import com.android.launcher3.BaseActivity;
 import com.android.launcher3.OnAlarmListener;
 import com.android.launcher3.Utilities;
+import com.android.launcher3.userevent.nano.LauncherLogProto;
 import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch;
-import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
-import com.android.launcher3.userevent.nano.LauncherLogProto.ControlType;
 import com.android.quickstep.views.RecentsView;
 import com.android.quickstep.views.TaskView;
 
@@ -37,7 +39,11 @@
  */
 public class QuickScrubController implements OnAlarmListener {
 
-    public static final int QUICK_SCRUB_START_DURATION = 210;
+    public static final int QUICK_SCRUB_FROM_APP_START_DURATION = 240;
+    public static final int QUICK_SCRUB_FROM_HOME_START_DURATION = 150;
+    // We want the translation y to finish faster than the rest of the animation.
+    public static final float QUICK_SCRUB_TRANSLATION_Y_FACTOR = 5f / 6;
+    public static final Interpolator QUICK_SCRUB_START_INTERPOLATOR = FAST_OUT_SLOW_IN;
 
     /**
      * Snap to a new page when crossing these thresholds. The first and last auto-advance.
@@ -57,6 +63,7 @@
     private final BaseActivity mActivity;
 
     private boolean mInQuickScrub;
+    private boolean mWaitingForTaskLaunch;
     private int mQuickScrubSection;
     private boolean mStartedFromHome;
     private boolean mFinishedTransitionToQuickScrub;
@@ -73,11 +80,11 @@
     }
 
     public void onQuickScrubStart(boolean startingFromHome, ActivityControlHelper controlHelper) {
+        prepareQuickScrub(TAG);
         mInQuickScrub = true;
         mStartedFromHome = startingFromHome;
         mQuickScrubSection = 0;
         mFinishedTransitionToQuickScrub = false;
-        mOnFinishedTransitionToQuickScrubRunnable = null;
         mActivityControlHelper = controlHelper;
 
         snapToNextTaskIfAvailable();
@@ -93,11 +100,17 @@
         Runnable launchTaskRunnable = () -> {
             TaskView taskView = mRecentsView.getPageAt(page);
             if (taskView != null) {
+                mWaitingForTaskLaunch = true;
                 taskView.launchTask(true, (result) -> {
                     if (!result) {
                         taskView.notifyTaskLaunchFailed(TAG);
                         breakOutOfQuickScrub();
+                    } else {
+                        mActivity.getUserEventDispatcher().logTaskLaunchOrDismiss(Touch.DRAGDROP,
+                                LauncherLogProto.Action.Direction.NONE, page,
+                                TaskUtils.getComponentKeyForTask(taskView.getTask().key));
                     }
+                    mWaitingForTaskLaunch = false;
                 }, taskView.getHandler());
             } else {
                 breakOutOfQuickScrub();
@@ -117,9 +130,19 @@
                 mOnFinishedTransitionToQuickScrubRunnable = launchTaskRunnable;
             }
         }
-        mActivity.getUserEventDispatcher().logActionOnControl(Touch.DRAGDROP,
-                ControlType.QUICK_SCRUB_BUTTON, null, mStartedFromHome ?
-                        ContainerType.WORKSPACE : ContainerType.APP);
+    }
+
+    /**
+     * Initializes the UI for quick scrub, returns true if success.
+     */
+    public boolean prepareQuickScrub(String tag) {
+        if (mWaitingForTaskLaunch || mInQuickScrub) {
+            Log.d(tag, "Waiting for last scrub to finish, will skip this interaction");
+            return false;
+        }
+        mOnFinishedTransitionToQuickScrubRunnable = null;
+        mRecentsView.setNextPageSwitchRunnable(null);
+        return true;
     }
 
     /**
@@ -127,7 +150,7 @@
      */
     private void breakOutOfQuickScrub() {
         if (mRecentsView.getChildCount() == 0 || mActivityControlHelper == null
-                || !mActivityControlHelper.switchToRecentsIfVisible()) {
+                || !mActivityControlHelper.switchToRecentsIfVisible(false)) {
             mActivity.onBackPressed();
         }
     }
@@ -160,31 +183,37 @@
 
     public void onFinishedTransitionToQuickScrub() {
         mFinishedTransitionToQuickScrub = true;
-        if (mOnFinishedTransitionToQuickScrubRunnable != null) {
-            mOnFinishedTransitionToQuickScrubRunnable.run();
-            mOnFinishedTransitionToQuickScrubRunnable = null;
+        Runnable action = mOnFinishedTransitionToQuickScrubRunnable;
+        // Clear the runnable before executing it, to prevent potential recursion.
+        mOnFinishedTransitionToQuickScrubRunnable = null;
+        if (action != null) {
+            action.run();
         }
     }
 
     public void snapToNextTaskIfAvailable() {
         if (mInQuickScrub && mRecentsView.getChildCount() > 0) {
+            int duration = mStartedFromHome ? QUICK_SCRUB_FROM_HOME_START_DURATION
+                    : QUICK_SCRUB_FROM_APP_START_DURATION;
             int pageToGoTo = mStartedFromHome ? 0 : mRecentsView.getNextPage() + 1;
-            goToPageWithHaptic(pageToGoTo, QUICK_SCRUB_START_DURATION, true /* forceHaptic */);
+            goToPageWithHaptic(pageToGoTo, duration, true /* forceHaptic */,
+                    QUICK_SCRUB_START_INTERPOLATOR);
         }
     }
 
     private void goToPageWithHaptic(int pageToGoTo) {
-        goToPageWithHaptic(pageToGoTo, -1 /* overrideDuration */, false /* forceHaptic */);
+        goToPageWithHaptic(pageToGoTo, -1 /* overrideDuration */, false /* forceHaptic */, null);
     }
 
-    private void goToPageWithHaptic(int pageToGoTo, int overrideDuration, boolean forceHaptic) {
+    private void goToPageWithHaptic(int pageToGoTo, int overrideDuration, boolean forceHaptic,
+            Interpolator interpolator) {
         pageToGoTo = Utilities.boundToRange(pageToGoTo, 0, mRecentsView.getPageCount() - 1);
         boolean snappingToPage = pageToGoTo != mRecentsView.getNextPage();
         if (snappingToPage) {
             int duration = overrideDuration > -1 ? overrideDuration
                     : Math.abs(pageToGoTo - mRecentsView.getNextPage())
                             * QUICKSCRUB_SNAP_DURATION_PER_PAGE;
-            mRecentsView.snapToPage(pageToGoTo, duration);
+            mRecentsView.snapToPage(pageToGoTo, duration, interpolator);
         }
         if (snappingToPage || forceHaptic) {
             mRecentsView.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY,
diff --git a/quickstep/src/com/android/quickstep/RecentsActivity.java b/quickstep/src/com/android/quickstep/RecentsActivity.java
index 1359b3a..b472d61 100644
--- a/quickstep/src/com/android/quickstep/RecentsActivity.java
+++ b/quickstep/src/com/android/quickstep/RecentsActivity.java
@@ -59,6 +59,9 @@
 import com.android.systemui.shared.system.RemoteAnimationRunnerCompat;
 import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
 
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+
 /**
  * A simple activity to show the recently launched tasks
  */
@@ -121,6 +124,11 @@
         dispatchDeviceProfileChanged();
 
         mRecentsRootView.setup();
+        reapplyUi();
+    }
+
+    @Override
+    protected void reapplyUi() {
         mRecentsRootView.dispatchInsets();
     }
 
@@ -140,6 +148,7 @@
                     ? new InvariantDeviceProfile(this).getDeviceProfile(this)
                     : appState.getInvariantDeviceProfile().getDeviceProfile(this).copy(this);
         }
+        onDeviceProfileInitiated();
     }
 
     @Override
@@ -265,4 +274,11 @@
                 .addCategory(Intent.CATEGORY_HOME)
                 .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
     }
+
+    @Override
+    public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {
+        super.dump(prefix, fd, writer, args);
+        writer.println(prefix + "Misc:");
+        dumpMisc(writer);
+    }
 }
diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationWrapper.java b/quickstep/src/com/android/quickstep/RecentsAnimationWrapper.java
index 730984c..30b10b0 100644
--- a/quickstep/src/com/android/quickstep/RecentsAnimationWrapper.java
+++ b/quickstep/src/com/android/quickstep/RecentsAnimationWrapper.java
@@ -15,27 +15,32 @@
  */
 package com.android.quickstep;
 
+import com.android.launcher3.util.LooperExecutor;
 import com.android.launcher3.util.TraceHelper;
+import com.android.launcher3.util.UiThreadHelper;
 import com.android.quickstep.util.RemoteAnimationTargetSet;
-import com.android.systemui.shared.system.BackgroundExecutor;
 import com.android.systemui.shared.system.RecentsAnimationControllerCompat;
+import java.util.concurrent.ExecutorService;
 
 /**
  * Wrapper around RecentsAnimationController to help with some synchronization
  */
 public class RecentsAnimationWrapper {
 
-    public RecentsAnimationControllerCompat controller;
     public RemoteAnimationTargetSet targetSet;
 
+    private RecentsAnimationControllerCompat mController;
     private boolean mInputConsumerEnabled = false;
     private boolean mBehindSystemBars = true;
     private boolean mSplitScreenMinimized = false;
 
+    private final ExecutorService mExecutorService =
+            new LooperExecutor(UiThreadHelper.getBackgroundLooper());
+
     public synchronized void setController(
             RecentsAnimationControllerCompat controller, RemoteAnimationTargetSet targetSet) {
         TraceHelper.partitionSection("RecentsController", "Set controller " + controller);
-        this.controller = controller;
+        this.mController = controller;
         this.targetSet = targetSet;
 
         if (mInputConsumerEnabled) {
@@ -48,17 +53,16 @@
      *                         on the background thread.
      */
     public void finish(boolean toHome, Runnable onFinishComplete) {
-        BackgroundExecutor.get().submit(() -> {
-            synchronized (this) {
-                TraceHelper.endSection("RecentsController",
-                        "Finish " + controller + ", toHome=" + toHome);
-                if (controller != null) {
-                    controller.setInputConsumerEnabled(false);
-                    controller.finish(toHome);
-                    if (onFinishComplete != null) {
-                        onFinishComplete.run();
-                    }
-                    controller = null;
+        mExecutorService.submit(() -> {
+            RecentsAnimationControllerCompat controller = mController;
+            mController = null;
+            TraceHelper.endSection("RecentsController",
+                    "Finish " + controller + ", toHome=" + toHome);
+            if (controller != null) {
+                controller.setInputConsumerEnabled(false);
+                controller.finish(toHome);
+                if (onFinishComplete != null) {
+                    onFinishComplete.run();
                 }
             }
         });
@@ -67,13 +71,12 @@
     public void enableInputConsumer() {
         mInputConsumerEnabled = true;
         if (mInputConsumerEnabled) {
-            BackgroundExecutor.get().submit(() -> {
-                synchronized (this) {
-                    TraceHelper.partitionSection("RecentsController",
-                            "Enabling consumer on " + controller);
-                    if (controller != null) {
-                        controller.setInputConsumerEnabled(true);
-                    }
+            mExecutorService.submit(() -> {
+                RecentsAnimationControllerCompat controller = mController;
+                TraceHelper.partitionSection("RecentsController",
+                        "Enabling consumer on " + controller);
+                if (controller != null) {
+                    controller.setInputConsumerEnabled(true);
                 }
             });
         }
@@ -84,13 +87,12 @@
             return;
         }
         mBehindSystemBars = behindSystemBars;
-        BackgroundExecutor.get().submit(() -> {
-            synchronized (this) {
-                TraceHelper.partitionSection("RecentsController",
-                        "Setting behind system bars on " + controller);
-                if (controller != null) {
-                    controller.setAnimationTargetsBehindSystemBars(behindSystemBars);
-                }
+        mExecutorService.submit(() -> {
+            RecentsAnimationControllerCompat controller = mController;
+            TraceHelper.partitionSection("RecentsController",
+                    "Setting behind system bars on " + controller);
+            if (controller != null) {
+                controller.setAnimationTargetsBehindSystemBars(behindSystemBars);
             }
         });
     }
@@ -106,25 +108,28 @@
             return;
         }
         mSplitScreenMinimized = minimized;
-        BackgroundExecutor.get().submit(() -> {
-            synchronized (this) {
-                TraceHelper.partitionSection("RecentsController",
-                        "Setting minimize dock on " + controller);
-                if (controller != null) {
-                    controller.setSplitScreenMinimized(minimized);
-                }
+        mExecutorService.submit(() -> {
+            RecentsAnimationControllerCompat controller = mController;
+            TraceHelper.partitionSection("RecentsController",
+                    "Setting minimize dock on " + controller);
+            if (controller != null) {
+                controller.setSplitScreenMinimized(minimized);
             }
         });
     }
 
     public void hideCurrentInputMethod() {
-        BackgroundExecutor.get().submit(() -> {
-            synchronized (this) {
-                TraceHelper.partitionSection("RecentsController", "Hiding currentinput method");
-                if (controller != null) {
-                    controller.hideCurrentInputMethod();
-                }
+        mExecutorService.submit(() -> {
+            RecentsAnimationControllerCompat controller = mController;
+            TraceHelper.partitionSection("RecentsController",
+                    "Hiding currentinput method on " + controller);
+            if (controller != null) {
+                controller.hideCurrentInputMethod();
             }
         });
     }
+
+    public RecentsAnimationControllerCompat getController() {
+        return mController;
+    }
 }
diff --git a/quickstep/src/com/android/quickstep/RecentsModel.java b/quickstep/src/com/android/quickstep/RecentsModel.java
index 7676a70..9c2c8b3 100644
--- a/quickstep/src/com/android/quickstep/RecentsModel.java
+++ b/quickstep/src/com/android/quickstep/RecentsModel.java
@@ -15,6 +15,8 @@
  */
 package com.android.quickstep;
 
+import static com.android.quickstep.TaskUtils.checkCurrentOrManagedUserId;
+
 import android.annotation.TargetApi;
 import android.app.ActivityManager;
 import android.content.ComponentCallbacks2;
@@ -190,7 +192,7 @@
     @Override
     public void onTaskStackChangedBackground() {
         int userId = UserHandle.myUserId();
-        if (!mPreloadTasksInBackground || !checkCurrentUserId(userId, false /* debug */)) {
+        if (!mPreloadTasksInBackground || !checkCurrentOrManagedUserId(userId, mContext)) {
             // TODO: Only register this for the current user
             return;
         }
diff --git a/quickstep/src/com/android/quickstep/TaskUtils.java b/quickstep/src/com/android/quickstep/TaskUtils.java
index f9628d7..2b0c98f 100644
--- a/quickstep/src/com/android/quickstep/TaskUtils.java
+++ b/quickstep/src/com/android/quickstep/TaskUtils.java
@@ -47,6 +47,8 @@
 import com.android.systemui.shared.recents.model.Task;
 import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
 
+import java.util.List;
+
 /**
  * Contains helpful methods for retrieving data from {@link Task}s.
  */
@@ -96,12 +98,13 @@
         if (v.getTag() instanceof ItemInfo) {
             ItemInfo itemInfo = (ItemInfo) v.getTag();
             ComponentName componentName = itemInfo.getTargetComponent();
+            int userId = itemInfo.user.getIdentifier();
             if (componentName != null) {
                 for (int i = 0; i < recentsView.getChildCount(); i++) {
                     TaskView taskView = recentsView.getPageAt(i);
                     if (recentsView.isTaskViewVisible(taskView)) {
-                        Task task = taskView.getTask();
-                        if (componentName.equals(task.key.getComponent())) {
+                        Task.TaskKey key = taskView.getTask().key;
+                        if (componentName.equals(key.getComponent()) && userId == key.userId) {
                             return taskView;
                         }
                     }
@@ -207,4 +210,17 @@
         }
         return false;
     }
+
+    public static boolean checkCurrentOrManagedUserId(int currentUserId, Context context) {
+        if (currentUserId == UserHandle.myUserId()) {
+            return true;
+        }
+        List<UserHandle> allUsers = UserManagerCompat.getInstance(context).getUserProfiles();
+        for (int i = allUsers.size() - 1; i >= 0; i--) {
+            if (currentUserId == allUsers.get(i).getIdentifier()) {
+                return true;
+            }
+        }
+        return false;
+    }
 }
diff --git a/quickstep/src/com/android/quickstep/TouchConsumer.java b/quickstep/src/com/android/quickstep/TouchConsumer.java
index 1290ec3..aa844d8 100644
--- a/quickstep/src/com/android/quickstep/TouchConsumer.java
+++ b/quickstep/src/com/android/quickstep/TouchConsumer.java
@@ -46,7 +46,7 @@
 
     default void onQuickScrubProgress(float progress) { }
 
-    default void onQuickStep(float eventX, float eventY, long eventTime) { }
+    default void onQuickStep(MotionEvent ev) { }
 
     /**
      * Called on the binder thread to allow the consumer to process the motion event before it is
diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java
index 3babd1f..aecb66c 100644
--- a/quickstep/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java
@@ -147,6 +147,11 @@
             TraceHelper.endSection("SysUiBinder", "onQuickStep");
 
         }
+
+        @Override
+        public void onTip(int actionType, int viewType) {
+            mOverviewCommandHelper.onTip(actionType, viewType);
+        }
     };
 
     private final TouchConsumer mNoOpTouchConsumer = (ev) -> {};
@@ -329,7 +334,7 @@
         }
 
         @Override
-        public void onQuickStep(float eventX, float eventY, long eventTime) {
+        public void onQuickStep(MotionEvent ev) {
             if (mInvalidated) {
                 return;
             }
@@ -344,14 +349,21 @@
                 return;
             }
             if (interactionType == INTERACTION_QUICK_SCRUB) {
+                if (!mQuickScrubController.prepareQuickScrub(TAG)) {
+                    mInvalidated = true;
+                    return;
+                }
                 OverviewCallbacks.get(mActivity).closeAllWindows();
                 ActivityManagerWrapper.getInstance()
                         .closeSystemWindows(CLOSE_SYSTEM_WINDOWS_REASON_RECENTS);
 
                 mStartPending = true;
                 Runnable action = () -> {
-                    mQuickScrubController.onQuickScrubStart(mActivityHelper.onQuickInteractionStart(
-                            mActivity, true), mActivityHelper);
+                    if (!mQuickScrubController.prepareQuickScrub(TAG)) {
+                        mInvalidated = true;
+                        return;
+                    }
+                    mActivityHelper.onQuickInteractionStart(mActivity, null, true);
                     mQuickScrubController.onQuickScrubProgress(mLastProgress);
                     mStartPending = false;
 
@@ -380,7 +392,7 @@
         @Override
         public void onQuickScrubProgress(float progress) {
             mLastProgress = progress;
-            if (mInvalidated || mEndPending) {
+            if (mInvalidated || mStartPending) {
                 return;
             }
             mQuickScrubController.onQuickScrubProgress(progress);
diff --git a/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java b/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java
index 614ba6e..84b2176 100644
--- a/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java
+++ b/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java
@@ -17,15 +17,14 @@
 
 import static com.android.launcher3.BaseActivity.INVISIBLE_BY_STATE_HANDLER;
 import static com.android.launcher3.Utilities.postAsyncCallback;
-import static com.android.launcher3.anim.Interpolators.ACCEL_2;
 import static com.android.launcher3.anim.Interpolators.DEACCEL;
 import static com.android.launcher3.anim.Interpolators.LINEAR;
-import static com.android.launcher3.anim.Interpolators.TOUCH_RESPONSE_INTERPOLATOR;
-import static com.android.quickstep.QuickScrubController.QUICK_SCRUB_START_DURATION;
+import static com.android.quickstep.QuickScrubController.QUICK_SCRUB_FROM_APP_START_DURATION;
 import static com.android.quickstep.TouchConsumer.INTERACTION_NORMAL;
 import static com.android.quickstep.TouchConsumer.INTERACTION_QUICK_SCRUB;
 
 import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
 import android.animation.ObjectAnimator;
 import android.annotation.TargetApi;
 import android.app.ActivityManager.RunningTaskInfo;
@@ -43,6 +42,7 @@
 import android.util.Log;
 import android.view.View;
 import android.view.ViewTreeObserver.OnDrawListener;
+import android.view.WindowManager;
 import android.view.animation.Interpolator;
 
 import com.android.launcher3.AbstractFloatingView;
@@ -57,6 +57,8 @@
 import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction;
 import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch;
 import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
+import com.android.launcher3.util.MultiValueAlpha;
+import com.android.launcher3.util.MultiValueAlpha.AlphaProperty;
 import com.android.launcher3.util.TraceHelper;
 import com.android.quickstep.ActivityControlHelper.ActivityInitListener;
 import com.android.quickstep.ActivityControlHelper.AnimationFactory;
@@ -64,7 +66,6 @@
 import com.android.quickstep.TouchConsumer.InteractionType;
 import com.android.quickstep.util.ClipAnimationHelper;
 import com.android.quickstep.util.RemoteAnimationTargetSet;
-import com.android.quickstep.util.SysuiEventLogger;
 import com.android.quickstep.views.RecentsView;
 import com.android.quickstep.views.TaskView;
 import com.android.systemui.shared.recents.model.ThumbnailData;
@@ -108,6 +109,8 @@
     private static final int STATE_CAPTURE_SCREENSHOT = 1 << 14;
     private static final int STATE_SCREENSHOT_CAPTURED = 1 << 15;
 
+    private static final int STATE_RESUME_LAST_TASK = 1 << 16;
+
     private static final int LAUNCHER_UI_STATES =
             STATE_LAUNCHER_PRESENT | STATE_LAUNCHER_DRAWN | STATE_ACTIVITY_MULTIPLIER_COMPLETE
             | STATE_LAUNCHER_STARTED;
@@ -138,6 +141,7 @@
             "STATE_QUICK_SCRUB_END",
             "STATE_CAPTURE_SCREENSHOT",
             "STATE_SCREENSHOT_CAPTURED",
+            "STATE_RESUME_LAST_TASK",
     };
 
     public static final long MAX_SWIPE_DURATION = 350;
@@ -167,6 +171,7 @@
     private final ActivityInitListener mActivityInitListener;
 
     private final int mRunningTaskId;
+    private final RunningTaskInfo mRunningTaskInfo;
     private ThumbnailData mTaskSnapshot;
 
     private MultiStateCallback mStateCallback;
@@ -185,6 +190,7 @@
     private boolean mGestureStarted;
     private int mLogAction = Touch.SWIPE;
     private float mCurrentQuickScrubProgress;
+    private boolean mQuickScrubBlocked;
 
     private @InteractionType int mInteractionType = INTERACTION_NORMAL;
 
@@ -203,6 +209,7 @@
     WindowTransformSwipeHandler(RunningTaskInfo runningTaskInfo, Context context, long touchTimeMs,
             ActivityControlHelper<T> controller) {
         mContext = context;
+        mRunningTaskInfo = runningTaskInfo;
         mRunningTaskId = runningTaskInfo.id;
         mTouchTimeMs = touchTimeMs;
         mActivityControlHelper = controller;
@@ -236,9 +243,12 @@
 
         mStateCallback.addCallback(STATE_LAUNCHER_STARTED | STATE_APP_CONTROLLER_RECEIVED,
                 this::sendRemoteAnimationsToAnimationFactory);
-        mStateCallback.addCallback(STATE_LAUNCHER_PRESENT | STATE_APP_CONTROLLER_RECEIVED
-                        | STATE_SCALED_CONTROLLER_APP,
+
+        mStateCallback.addCallback(STATE_LAUNCHER_PRESENT | STATE_SCALED_CONTROLLER_APP,
+                this::resumeLastTaskForQuickstep);
+        mStateCallback.addCallback(STATE_RESUME_LAST_TASK | STATE_APP_CONTROLLER_RECEIVED,
                 this::resumeLastTask);
+
         mStateCallback.addCallback(STATE_LAUNCHER_PRESENT | STATE_APP_CONTROLLER_RECEIVED
                         | STATE_ACTIVITY_MULTIPLIER_COMPLETE
                         | STATE_CAPTURE_SCREENSHOT,
@@ -255,9 +265,6 @@
                         | STATE_GESTURE_COMPLETED,
                 this::setupLauncherUiAfterSwipeUpAnimation);
 
-        mStateCallback.addCallback(STATE_LAUNCHER_PRESENT | STATE_SCALED_CONTROLLER_APP,
-                this::reset);
-
         mStateCallback.addCallback(STATE_HANDLER_INVALIDATED, this::invalidateHandler);
         mStateCallback.addCallback(STATE_LAUNCHER_PRESENT | STATE_HANDLER_INVALIDATED,
                 this::invalidateHandlerWithLauncher);
@@ -367,15 +374,15 @@
             mStateCallback.setState(STATE_ACTIVITY_MULTIPLIER_COMPLETE | STATE_LAUNCHER_DRAWN);
         } else {
             TraceHelper.beginSection("WTS-init");
-            View rootView = activity.getRootView();
-            rootView.setAlpha(0);
-            rootView.getViewTreeObserver().addOnDrawListener(new OnDrawListener() {
+            View dragLayer = activity.getDragLayer();
+            mActivityControlHelper.getAlphaProperty(activity).setValue(0);
+            dragLayer.getViewTreeObserver().addOnDrawListener(new OnDrawListener() {
 
                 @Override
                 public void onDraw() {
                     TraceHelper.endSection("WTS-init", "Launcher frame is drawn");
-                    rootView.post(() ->
-                            rootView.getViewTreeObserver().removeOnDrawListener(this));
+                    dragLayer.post(() ->
+                            dragLayer.getViewTreeObserver().removeOnDrawListener(this));
                     if (activity != mActivity) {
                         return;
                     }
@@ -387,7 +394,7 @@
 
         mRecentsView.showTask(mRunningTaskId);
         mRecentsView.setRunningTaskHidden(true);
-        mRecentsView.setFirstTaskIconScaledDown(true /* isScaledDown */, false /* animate */);
+        mRecentsView.setRunningTaskIconScaledDown(true /* isScaledDown */, false /* animate */);
         mLayoutListener.open();
         mStateCallback.setState(STATE_LAUNCHER_STARTED);
     }
@@ -397,15 +404,22 @@
     }
 
     private void launcherFrameDrawn() {
-        View rootView = mActivity.getRootView();
-        if (rootView.getAlpha() < 1) {
+        AlphaProperty property = mActivityControlHelper.getAlphaProperty(mActivity);
+        if (property.getValue() < 1) {
             if (mGestureStarted) {
                 final MultiStateCallback callback = mStateCallback;
-                rootView.animate().alpha(1)
-                        .setDuration(getFadeInDuration())
-                        .withEndAction(() -> callback.setState(STATE_ACTIVITY_MULTIPLIER_COMPLETE));
+                ObjectAnimator animator = ObjectAnimator.ofFloat(
+                        property, MultiValueAlpha.VALUE, 1);
+                animator.setDuration(getFadeInDuration()).addListener(
+                        new AnimatorListenerAdapter() {
+                            @Override
+                            public void onAnimationEnd(Animator animation) {
+                                callback.setState(STATE_ACTIVITY_MULTIPLIER_COMPLETE);
+                            }
+                        });
+                animator.start();
             } else {
-                rootView.setAlpha(1);
+                property.setValue(1);
                 mStateCallback.setState(STATE_ACTIVITY_MULTIPLIER_COMPLETE);
             }
         }
@@ -423,11 +437,8 @@
         mLayoutListener.setHandler(this);
         buildAnimationController();
 
-        final long transitionDelay = mLauncherFrameDrawnTime - mTouchTimeMs;
-        SysuiEventLogger.writeDummyRecentsTransition(transitionDelay);
-
         if (LatencyTrackerCompat.isEnabled(mContext)) {
-            LatencyTrackerCompat.logToggleRecents((int) transitionDelay);
+            LatencyTrackerCompat.logToggleRecents((int) (mLauncherFrameDrawnTime - mTouchTimeMs));
         }
     }
 
@@ -445,7 +456,7 @@
         setStateOnUiThread(STATE_QUICK_SCRUB_START | STATE_GESTURE_COMPLETED);
 
         // Start the window animation without waiting for launcher.
-        animateToProgress(1f, QUICK_SCRUB_START_DURATION, TOUCH_RESPONSE_INTERPOLATOR);
+        animateToProgress(1f, QUICK_SCRUB_FROM_APP_START_DURATION, LINEAR);
     }
 
     @WorkerThread
@@ -490,21 +501,15 @@
     private void updateFinalShift() {
         float shift = mCurrentShift.value;
 
-        synchronized (mRecentsAnimationWrapper) {
-            if (mRecentsAnimationWrapper.controller != null) {
-                Interpolator interpolator = mInteractionType == INTERACTION_QUICK_SCRUB
-                        ? ACCEL_2 : LINEAR;
-                float interpolated = interpolator.getInterpolation(shift);
-                mClipAnimationHelper.applyTransform(
-                        mRecentsAnimationWrapper.targetSet, interpolated);
+        RecentsAnimationControllerCompat controller = mRecentsAnimationWrapper.getController();
+        if (controller != null) {
+            mClipAnimationHelper.applyTransform(mRecentsAnimationWrapper.targetSet, shift);
 
-                // TODO: This logic is spartanic!
-                boolean passedThreshold = shift > 0.12f;
-                mRecentsAnimationWrapper.setAnimationTargetsBehindSystemBars(!passedThreshold);
-                if (mActivityControlHelper.shouldMinimizeSplitScreen()) {
-                    mRecentsAnimationWrapper
-                            .setSplitScreenMinimizedForTransaction(passedThreshold);
-                }
+            // TODO: This logic is spartanic!
+            boolean passedThreshold = shift > 0.12f;
+            mRecentsAnimationWrapper.setAnimationTargetsBehindSystemBars(!passedThreshold);
+            if (mActivityControlHelper.shouldMinimizeSplitScreen()) {
+                mRecentsAnimationWrapper.setSplitScreenMinimizedForTransaction(passedThreshold);
             }
         }
 
@@ -541,6 +546,7 @@
             dp = dp.copy(mContext);
             dp.updateInsets(insets);
         }
+        dp.updateIsSeascape(mContext.getSystemService(WindowManager.class));
 
         if (runningTaskTarget != null) {
             mClipAnimationHelper.updateSource(overviewStackBounds, runningTaskTarget);
@@ -655,9 +661,15 @@
     }
 
     @UiThread
+    private void resumeLastTaskForQuickstep() {
+        setStateOnUiThread(STATE_RESUME_LAST_TASK);
+        doLogGesture(false /* toLauncher */);
+        reset();
+    }
+
+    @UiThread
     private void resumeLastTask() {
         mRecentsAnimationWrapper.finish(false /* toHome */, null);
-        doLogGesture(false /* toLauncher */);
     }
 
     public void reset() {
@@ -683,9 +695,10 @@
     private void invalidateHandlerWithLauncher() {
         mLauncherTransitionController = null;
         mLayoutListener.finish();
+        mActivityControlHelper.getAlphaProperty(mActivity).setValue(1);
 
         mRecentsView.setRunningTaskHidden(false);
-        mRecentsView.setFirstTaskIconScaledDown(false /* isScaledDown */, false /* animate */);
+        mRecentsView.setRunningTaskIconScaledDown(false /* isScaledDown */, false /* animate */);
     }
 
     private void notifyTransitionCancelled() {
@@ -705,27 +718,25 @@
 
     private void switchToScreenshot() {
         boolean finishTransitionPosted = false;
-        synchronized (mRecentsAnimationWrapper) {
-            if (mRecentsAnimationWrapper.controller != null) {
-                // Update the screenshot of the task
-                if (mTaskSnapshot == null) {
-                    mTaskSnapshot = mRecentsAnimationWrapper.controller
-                            .screenshotTask(mRunningTaskId);
-                }
-                TaskView taskView = mRecentsView.updateThumbnail(mRunningTaskId, mTaskSnapshot);
-                mRecentsView.setRunningTaskHidden(false);
-                if (taskView != null) {
-                    // Defer finishing the animation until the next launcher frame with the
-                    // new thumbnail
-                    finishTransitionPosted = new WindowCallbacksCompat(taskView) {
+        RecentsAnimationControllerCompat controller = mRecentsAnimationWrapper.getController();
+        if (controller != null) {
+            // Update the screenshot of the task
+            if (mTaskSnapshot == null) {
+                mTaskSnapshot = controller.screenshotTask(mRunningTaskId);
+            }
+            TaskView taskView = mRecentsView.updateThumbnail(mRunningTaskId, mTaskSnapshot);
+            mRecentsView.setRunningTaskHidden(false);
+            if (taskView != null) {
+                // Defer finishing the animation until the next launcher frame with the
+                // new thumbnail
+                finishTransitionPosted = new WindowCallbacksCompat(taskView) {
 
-                        @Override
-                        public void onPostDraw(Canvas canvas) {
-                            setStateOnUiThread(STATE_SCREENSHOT_CAPTURED);
-                            detach();
-                        }
-                    }.attach();
-                }
+                    @Override
+                    public void onPostDraw(Canvas canvas) {
+                        setStateOnUiThread(STATE_SCREENSHOT_CAPTURED);
+                        detach();
+                    }
+                }.attach();
             }
         }
         if (!finishTransitionPosted) {
@@ -749,7 +760,7 @@
         mActivityControlHelper.onSwipeUpComplete(mActivity);
 
         // Animate the first icon.
-        mRecentsView.setFirstTaskIconScaledDown(false /* isScaledDown */, true /* animate */);
+        mRecentsView.setRunningTaskIconScaledDown(false /* isScaledDown */, true /* animate */);
         mRecentsView.setSwipeDownShouldLaunchApp(true);
 
         RecentsModel.getInstance(mContext).onOverviewShown(false, TAG);
@@ -759,13 +770,17 @@
     }
 
     private void onQuickScrubStart() {
+        if (!mQuickScrubController.prepareQuickScrub(TAG)) {
+            mQuickScrubBlocked = true;
+            setStateOnUiThread(STATE_RESUME_LAST_TASK | STATE_HANDLER_INVALIDATED);
+            return;
+        }
         if (mLauncherTransitionController != null) {
             mLauncherTransitionController.getAnimationPlayer().end();
             mLauncherTransitionController = null;
         }
 
-        mActivityControlHelper.onQuickInteractionStart(mActivity, false);
-        mQuickScrubController.onQuickScrubStart(false, mActivityControlHelper);
+        mActivityControlHelper.onQuickInteractionStart(mActivity, mRunningTaskInfo, false);
 
         // Inform the last progress in case we skipped before.
         mQuickScrubController.onQuickScrubProgress(mCurrentQuickScrubProgress);
@@ -787,17 +802,22 @@
             }
             mClipAnimationHelper.offsetTarget(
                     firstTask.getCurveScaleForInterpolation(interpolation), offsetFromFirstTask,
-                    mActivityControlHelper.getTranslationYForQuickScrub(mActivity));
+                    mActivityControlHelper.getTranslationYForQuickScrub(mActivity),
+                    QuickScrubController.QUICK_SCRUB_START_INTERPOLATOR);
         }
     }
 
     private void onFinishedTransitionToQuickScrub() {
+        if (mQuickScrubBlocked) {
+            return;
+        }
         mQuickScrubController.onFinishedTransitionToQuickScrub();
     }
 
     public void onQuickScrubProgress(float progress) {
         mCurrentQuickScrubProgress = progress;
-        if (Looper.myLooper() != Looper.getMainLooper() || mQuickScrubController == null) {
+        if (Looper.myLooper() != Looper.getMainLooper() || mQuickScrubController == null
+                || mQuickScrubBlocked) {
             return;
         }
         mQuickScrubController.onQuickScrubProgress(progress);
@@ -808,6 +828,9 @@
     }
 
     private void switchToFinalAppAfterQuickScrub() {
+        if (mQuickScrubBlocked) {
+            return;
+        }
         mQuickScrubController.onQuickScrubEnd();
 
         // Normally this is handled in reset(), but since we are still scrubbing after the
@@ -883,6 +906,13 @@
             return;
         }
 
+        RemoteAnimationTargetSet targetSet = mRecentsAnimationWrapper.targetSet;
+        if (targetSet == null) {
+            // This can happen when cancelAnimation comes on the background thread, while we are
+            // processing the long swipe on the UI thread.
+            return;
+        }
+
         mLongSwipeController = mActivityControlHelper.getLongSwipeController(
                 mActivity, mRecentsAnimationWrapper.targetSet);
         onLongSwipeDisplacementUpdated();
diff --git a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
index fb4aa02..9e2de33 100644
--- a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
+++ b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
@@ -35,6 +35,7 @@
     public FallbackRecentsView(Context context, AttributeSet attrs, int defStyleAttr) {
         super(context, attrs, defStyleAttr);
         setOverviewStateEnabled(true);
+        getQuickScrubController().onFinishedTransitionToQuickScrub();
     }
 
     @Override
diff --git a/quickstep/src/com/android/quickstep/fallback/RecentsRootView.java b/quickstep/src/com/android/quickstep/fallback/RecentsRootView.java
index 878a593..ca8c252 100644
--- a/quickstep/src/com/android/quickstep/fallback/RecentsRootView.java
+++ b/quickstep/src/com/android/quickstep/fallback/RecentsRootView.java
@@ -35,7 +35,7 @@
     private final Point mLastKnownSize = new Point(10, 10);
 
     public RecentsRootView(Context context, AttributeSet attrs) {
-        super(context, attrs);
+        super(context, attrs, 1 /* alphaChannelCount */);
         mActivity = (RecentsActivity) BaseActivity.fromContext(context);
         setSystemUiVisibility(SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                 | SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
diff --git a/quickstep/src/com/android/quickstep/logging/UserEventDispatcherExtension.java b/quickstep/src/com/android/quickstep/logging/UserEventDispatcherExtension.java
index d4cdd35..04153cc 100644
--- a/quickstep/src/com/android/quickstep/logging/UserEventDispatcherExtension.java
+++ b/quickstep/src/com/android/quickstep/logging/UserEventDispatcherExtension.java
@@ -15,15 +15,32 @@
  */
 package com.android.quickstep.logging;
 
+import android.util.Log;
+
+import static com.android.launcher3.logging.LoggerUtils.newAction;
+import static com.android.launcher3.logging.LoggerUtils.newContainerTarget;
+import static com.android.launcher3.logging.LoggerUtils.newLauncherEvent;
+import static com.android.launcher3.userevent.nano.LauncherLogProto.ControlType.CANCEL_TARGET;
+import static com.android.systemui.shared.system.LauncherEventUtil.VISIBLE;
+import static com.android.systemui.shared.system.LauncherEventUtil.DISMISS;
+import static com.android.systemui.shared.system.LauncherEventUtil.RECENTS_QUICK_SCRUB_ONBOARDING_TIP;
+import static com.android.systemui.shared.system.LauncherEventUtil.RECENTS_SWIPE_UP_ONBOARDING_TIP;
+
 import com.android.launcher3.logging.UserEventDispatcher;
+import com.android.launcher3.model.nano.LauncherDumpProto;
+import com.android.launcher3.userevent.nano.LauncherLogExtensions;
 import com.android.launcher3.userevent.nano.LauncherLogProto;
+import com.android.systemui.shared.system.LauncherEventUtil;
 import com.android.systemui.shared.system.MetricsLoggerCompat;
 
 /**
- * This class handles AOSP MetricsLogger function calls.
+ * This class handles AOSP MetricsLogger function calls and logging around
+ * quickstep interactions.
  */
 public class UserEventDispatcherExtension extends UserEventDispatcher {
 
+    private static final String TAG = "UserEventDispatcher";
+
     public void logStateChangeAction(int action, int dir, int srcChildTargetType,
                                      int srcParentContainerType, int dstContainerType,
                                      int pageIndex) {
@@ -32,4 +49,37 @@
         super.logStateChangeAction(action, dir, srcChildTargetType, srcParentContainerType,
                 dstContainerType, pageIndex);
     }
+
+    public void logActionTip(int actionType, int viewType) {
+        LauncherLogProto.Action action = new LauncherLogProto.Action();
+        LauncherLogProto.Target target = new LauncherLogProto.Target();
+        switch(actionType) {
+            case VISIBLE:
+                action.type = LauncherLogProto.Action.Type.TIP;
+                target.type = LauncherLogProto.Target.Type.CONTAINER;
+                target.containerType = LauncherLogProto.ContainerType.TIP;
+                break;
+            case DISMISS:
+                action.type = LauncherLogProto.Action.Type.TOUCH;
+                action.touch = LauncherLogProto.Action.Touch.TAP;
+                target.type = LauncherLogProto.Target.Type.CONTROL;
+                target.controlType = CANCEL_TARGET;
+                break;
+            default:
+                Log.e(TAG, "Unexpected action type = " + actionType);
+        }
+
+        switch(viewType) {
+            case RECENTS_QUICK_SCRUB_ONBOARDING_TIP:
+                target.tipType = LauncherLogProto.TipType.QUICK_SCRUB_TEXT;
+                break;
+            case RECENTS_SWIPE_UP_ONBOARDING_TIP:
+                target.tipType = LauncherLogProto.TipType.SWIPE_UP_TEXT;
+                break;
+            default:
+                Log.e(TAG, "Unexpected viewType = " + viewType);
+        }
+        LauncherLogProto.LauncherEvent event = newLauncherEvent(action, target);
+        dispatchUserEvent(event, null);
+    }
 }
diff --git a/quickstep/src/com/android/quickstep/util/ClipAnimationHelper.java b/quickstep/src/com/android/quickstep/util/ClipAnimationHelper.java
index 14b4046..8c7f104 100644
--- a/quickstep/src/com/android/quickstep/util/ClipAnimationHelper.java
+++ b/quickstep/src/com/android/quickstep/util/ClipAnimationHelper.java
@@ -16,7 +16,7 @@
 package com.android.quickstep.util;
 
 import static com.android.launcher3.anim.Interpolators.LINEAR;
-import static com.android.launcher3.anim.Interpolators.SCROLL;
+import static com.android.quickstep.QuickScrubController.QUICK_SCRUB_TRANSLATION_Y_FACTOR;
 import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_CLOSING;
 import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_OPENING;
 
@@ -30,11 +30,13 @@
 import android.os.Build;
 import android.os.RemoteException;
 import android.support.annotation.Nullable;
+import android.view.animation.Interpolator;
 
 import com.android.launcher3.BaseDraggingActivity;
 import com.android.launcher3.DeviceProfile;
 import com.android.launcher3.R;
 import com.android.launcher3.Utilities;
+import com.android.launcher3.anim.Interpolators;
 import com.android.launcher3.views.BaseDragLayer;
 import com.android.quickstep.RecentsModel;
 import com.android.quickstep.views.RecentsView;
@@ -78,6 +80,9 @@
     private final RectF mTmpRectF = new RectF();
 
     private float mTargetScale = 1f;
+    private Interpolator mInterpolator = LINEAR;
+    // We translate y slightly faster than the rest of the animation for quick scrub.
+    private Interpolator mOffsetYInterpolator = LINEAR;
 
     // Whether to boost the opening animation target layers, or the closing
     private int mBoostModeTargetLayers = -1;
@@ -134,12 +139,13 @@
         RectF currentRect;
         mTmpRectF.set(mTargetRect);
         Utilities.scaleRectFAboutCenter(mTmpRectF, mTargetScale);
+        float offsetYProgress = mOffsetYInterpolator.getInterpolation(progress);
+        progress = mInterpolator.getInterpolation(progress);
         currentRect =  mRectFEvaluator.evaluate(progress, mSourceRect, mTmpRectF);
 
         synchronized (mTargetOffset) {
             // Stay lined up with the center of the target, since it moves for quick scrub.
-            currentRect.offset(mTargetOffset.x * SCROLL.getInterpolation(progress),
-                    mTargetOffset.y  * LINEAR.getInterpolation(progress));
+            currentRect.offset(mTargetOffset.x * progress, mTargetOffset.y  * offsetYProgress);
         }
 
         mClipRect.left = (int) (mSourceWindowClipInsets.left * progress);
@@ -180,11 +186,14 @@
         mTaskTransformCallback = callback;
     }
 
-    public void offsetTarget(float scale, float offsetX, float offsetY) {
+    public void offsetTarget(float scale, float offsetX, float offsetY, Interpolator interpolator) {
         synchronized (mTargetOffset) {
-            mTargetScale = scale;
             mTargetOffset.set(offsetX, offsetY);
         }
+        mTargetScale = scale;
+        mInterpolator = interpolator;
+        mOffsetYInterpolator = Interpolators.clampToProgress(mInterpolator, 0,
+                QUICK_SCRUB_TRANSLATION_Y_FACTOR);
     }
 
     public void fromTaskThumbnailView(TaskThumbnailView ttv, RecentsView rv) {
@@ -250,10 +259,11 @@
             taskHeight = taskHeight / 2 - halfDividerSize;
         }
 
+        // Align the task to bottom left/right edge (closer to nav bar).
+        int left = activity.getDeviceProfile().isSeascape() ? insets.left
+                : (insets.left + fullDp.availableWidthPx - taskWidth);
         mSourceStackBounds.set(0, 0, taskWidth, taskHeight);
-        // Align the task to bottom right (probably not true for seascape).
-        mSourceStackBounds.offset(insets.left + fullDp.availableWidthPx - taskWidth,
-                insets.top + fullDp.availableHeightPx - taskHeight);
+        mSourceStackBounds.offset(left, insets.top + fullDp.availableHeightPx - taskHeight);
     }
 
     public void drawForProgress(TaskThumbnailView ttv, Canvas canvas, float progress) {
diff --git a/quickstep/src/com/android/quickstep/util/LayoutUtils.java b/quickstep/src/com/android/quickstep/util/LayoutUtils.java
index b1fa5e2..ec9c7ea 100644
--- a/quickstep/src/com/android/quickstep/util/LayoutUtils.java
+++ b/quickstep/src/com/android/quickstep/util/LayoutUtils.java
@@ -42,9 +42,7 @@
         if (dp.isVerticalBarLayout()) {
             extraSpace = 0;
         } else {
-            Resources res = context.getResources();
-            extraSpace = dp.hotseatBarSizePx + res.getDimension(R.dimen.shelf_surface_top_padding)
-                    + res.getDimension(R.dimen.shelf_surface_radius);
+            extraSpace = dp.hotseatBarSizePx + dp.verticalDragHandleSizePx;
         }
         calculateTaskSize(context, dp, extraSpace, MULTI_WINDOW_STRATEGY_HALF_SCREEN, outRect);
     }
@@ -106,7 +104,7 @@
         float outHeight = scale * taskHeight;
 
         // Center in the visible space
-        float x = insets.left + (taskWidth - outWidth) / 2;
+        float x = insets.left + (launcherVisibleWidth - outWidth) / 2;
         float y = insets.top + Math.max(topIconMargin,
                 (launcherVisibleHeight - extraVerticalSpace - outHeight) / 2);
         outRect.set(Math.round(x), Math.round(y),
diff --git a/quickstep/src/com/android/quickstep/util/SysuiEventLogger.java b/quickstep/src/com/android/quickstep/util/SysuiEventLogger.java
deleted file mode 100644
index d474ded..0000000
--- a/quickstep/src/com/android/quickstep/util/SysuiEventLogger.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.quickstep.util;
-
-import android.metrics.LogMaker;
-import android.util.EventLog;
-
-/**
- * Utility class for writing logs on behalf of systemUI
- */
-public class SysuiEventLogger {
-
-    /** 524292 sysui_multi_action (content|4) */
-    public static final int SYSUI_MULTI_ACTION = 524292;
-
-    private static void write(LogMaker content) {
-        if (content.getType() == 0/*MetricsEvent.TYPE_UNKNOWN*/) {
-            content.setType(4/*MetricsEvent.TYPE_ACTION*/);
-        }
-        EventLog.writeEvent(SYSUI_MULTI_ACTION, content.serialize());
-    }
-
-    public static void writeDummyRecentsTransition(long transitionDelay) {
-        // Mimic ActivityMetricsLogger.logAppTransitionMultiEvents() logging for
-        // "Recents" activity for app transition tests for the app-to-recents case.
-        final LogMaker builder = new LogMaker(761/*APP_TRANSITION*/);
-        builder.setPackageName("com.android.systemui");
-        builder.addTaggedData(871/*FIELD_CLASS_NAME*/,
-                "com.android.systemui.recents.RecentsActivity");
-        builder.addTaggedData(319/*APP_TRANSITION_DELAY_MS*/,
-                transitionDelay);
-        write(builder);
-    }
-}
diff --git a/quickstep/src/com/android/quickstep/util/TaskViewDrawable.java b/quickstep/src/com/android/quickstep/util/TaskViewDrawable.java
index 34f580b..48b07a7 100644
--- a/quickstep/src/com/android/quickstep/util/TaskViewDrawable.java
+++ b/quickstep/src/com/android/quickstep/util/TaskViewDrawable.java
@@ -15,7 +15,9 @@
  */
 package com.android.quickstep.util;
 
-import android.animation.TimeInterpolator;
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ValueAnimator;
 import android.graphics.Canvas;
 import android.graphics.ColorFilter;
 import android.graphics.PixelFormat;
@@ -30,7 +32,7 @@
 
 public class TaskViewDrawable extends Drawable {
 
-    public static FloatProperty<TaskViewDrawable> PROGRESS =
+    public static final FloatProperty<TaskViewDrawable> PROGRESS =
             new FloatProperty<TaskViewDrawable>("progress") {
                 @Override
                 public void setValue(TaskViewDrawable taskViewDrawable, float v) {
@@ -43,8 +45,10 @@
                 }
             };
 
-    private static final TimeInterpolator ICON_SIZE_INTERPOLATOR =
-            (t) -> (Math.max(t, 0.3f) - 0.3f) / 0.7f;
+    /**
+     * The progress at which we play the atomic icon scale animation.
+     */
+    private static final float ICON_SCALE_THRESHOLD = 0.95f;
 
     private final RecentsView mParent;
     private final View mIconView;
@@ -55,11 +59,15 @@
     private final ClipAnimationHelper mClipAnimationHelper;
 
     private float mProgress = 1;
+    private boolean mPassedIconScaleThreshold;
+    private ValueAnimator mIconScaleAnimator;
+    private float mIconScale;
 
     public TaskViewDrawable(TaskView tv, RecentsView parent) {
         mParent = parent;
         mIconView = tv.getIconView();
         mIconPos = new int[2];
+        mIconScale = mIconView.getScaleX();
         Utilities.getDescendantCoordRelativeToAncestor(mIconView, parent, mIconPos, true);
 
         mThumbnailView = tv.getThumbnail();
@@ -70,6 +78,37 @@
     public void setProgress(float progress) {
         mProgress = progress;
         mParent.invalidate();
+        boolean passedIconScaleThreshold = progress <= ICON_SCALE_THRESHOLD;
+        if (mPassedIconScaleThreshold != passedIconScaleThreshold) {
+            mPassedIconScaleThreshold = passedIconScaleThreshold;
+            animateIconScale(mPassedIconScaleThreshold ? 0 : 1);
+        }
+    }
+
+    private void animateIconScale(float toScale) {
+        if (mIconScaleAnimator != null) {
+            mIconScaleAnimator.cancel();
+        }
+        mIconScaleAnimator = ValueAnimator.ofFloat(mIconScale, toScale);
+        mIconScaleAnimator.addUpdateListener(valueAnimator -> {
+            mIconScale = (float) valueAnimator.getAnimatedValue();
+            if (mProgress > ICON_SCALE_THRESHOLD) {
+                // Speed up the icon scale to ensure it is 1 when progress is 1.
+                float iconProgress = (mProgress - ICON_SCALE_THRESHOLD) / (1 - ICON_SCALE_THRESHOLD);
+                if (iconProgress > mIconScale) {
+                    mIconScale = iconProgress;
+                }
+            }
+            invalidateSelf();
+        });
+        mIconScaleAnimator.addListener(new AnimatorListenerAdapter() {
+            @Override
+            public void onAnimationEnd(Animator animation) {
+                mIconScaleAnimator = null;
+            }
+        });
+        mIconScaleAnimator.setDuration(TaskView.SCALE_ICON_DURATION);
+        mIconScaleAnimator.start();
     }
 
     @Override
@@ -81,8 +120,7 @@
 
         canvas.save();
         canvas.translate(mIconPos[0], mIconPos[1]);
-        float scale = ICON_SIZE_INTERPOLATOR.getInterpolation(mProgress);
-        canvas.scale(scale, scale, mIconView.getWidth() / 2, mIconView.getHeight() / 2);
+        canvas.scale(mIconScale, mIconScale, mIconView.getWidth() / 2, mIconView.getHeight() / 2);
         mIconView.draw(canvas);
         canvas.restore();
     }
diff --git a/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java b/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
index e237500..950f7fb 100644
--- a/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
@@ -148,6 +148,9 @@
     protected void onTaskLaunched(boolean success) {
         if (success) {
             mActivity.getStateManager().goToState(NORMAL, false /* animate */);
+        } else {
+            LauncherState state = mActivity.getStateManager().getState();
+            mActivity.getAllAppsController().setProgress(state.getVerticalProgress(mActivity));
         }
         super.onTaskLaunched(success);
     }
diff --git a/quickstep/src/com/android/quickstep/views/QuickstepDragIndicator.java b/quickstep/src/com/android/quickstep/views/QuickstepDragIndicator.java
deleted file mode 100644
index 5e9cd6e..0000000
--- a/quickstep/src/com/android/quickstep/views/QuickstepDragIndicator.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.quickstep.views;
-
-import static com.android.launcher3.LauncherState.ALL_APPS;
-import static com.android.launcher3.LauncherState.OVERVIEW;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.view.View;
-import android.view.accessibility.AccessibilityNodeInfo;
-
-import com.android.launcher3.R;
-import com.android.launcher3.userevent.nano.LauncherLogProto.Action;
-import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
-import com.android.launcher3.userevent.nano.LauncherLogProto.ControlType;
-import com.android.launcher3.views.LauncherDragIndicator;
-
-public class QuickstepDragIndicator extends LauncherDragIndicator {
-
-    public QuickstepDragIndicator(Context context) {
-        super(context);
-    }
-
-    public QuickstepDragIndicator(Context context, AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    public QuickstepDragIndicator(Context context, AttributeSet attrs, int defStyleAttr) {
-        super(context, attrs, defStyleAttr);
-    }
-
-    private boolean isInOverview() {
-        return mLauncher.isInState(OVERVIEW);
-    }
-
-    @Override
-    public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
-        super.onInitializeAccessibilityNodeInfo(info);
-        info.setContentDescription(getContext().getString(R.string.all_apps_button_label));
-    }
-
-    @Override
-    protected void initCustomActions(AccessibilityNodeInfo info) {
-        if (!isInOverview()) {
-            super.initCustomActions(info);
-        }
-    }
-
-    @Override
-    public void onClick(View view) {
-        mLauncher.getUserEventDispatcher().logActionOnControl(Action.Touch.TAP,
-                ControlType.ALL_APPS_BUTTON,
-                isInOverview() ? ContainerType.TASKSWITCHER : ContainerType.WORKSPACE);
-        mLauncher.getStateManager().goToState(ALL_APPS);
-    }
-}
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index 525e074..dfa25b8 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -21,7 +21,10 @@
 import static com.android.launcher3.anim.Interpolators.ACCEL_2;
 import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN;
 import static com.android.launcher3.anim.Interpolators.LINEAR;
+import static com.android.launcher3.util.SystemUiController.UI_STATE_OVERVIEW;
+import static com.android.quickstep.TaskUtils.checkCurrentOrManagedUserId;
 
+import android.animation.Animator;
 import android.animation.AnimatorSet;
 import android.animation.ObjectAnimator;
 import android.animation.TimeInterpolator;
@@ -36,6 +39,8 @@
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
 import android.os.Build;
+import android.os.Handler;
+import android.os.UserHandle;
 import android.text.Layout;
 import android.text.StaticLayout;
 import android.text.TextPaint;
@@ -75,6 +80,8 @@
 import com.android.systemui.shared.recents.model.TaskStack;
 import com.android.systemui.shared.recents.model.ThumbnailData;
 import com.android.systemui.shared.system.ActivityManagerWrapper;
+import com.android.systemui.shared.system.BackgroundExecutor;
+import com.android.systemui.shared.system.PackageManagerWrapper;
 import com.android.systemui.shared.system.TaskStackChangeListener;
 
 import java.util.ArrayList;
@@ -104,6 +111,8 @@
     };
     public static final boolean FLIP_RECENTS = true;
     private static final int DISMISS_TASK_DURATION = 300;
+    // The threshold at which we update the SystemUI flags when animating from the task into the app
+    private static final float UPDATE_SYSUI_FLAGS_THRESHOLD = 0.6f;
 
     private static final float[] sTempFloatArray = new float[3];
 
@@ -116,19 +125,27 @@
     // Keeps track of the previously known visible tasks for purposes of loading/unloading task data
     private final SparseBooleanArray mHasVisibleTaskData = new SparseBooleanArray();
 
+    private boolean mIsClearAllButtonFullyRevealed;
+
     /**
      * TODO: Call reloadIdNeeded in onTaskStackChanged.
      */
     private final TaskStackChangeListener mTaskStackListener = new TaskStackChangeListener() {
         @Override
         public void onTaskSnapshotChanged(int taskId, ThumbnailData snapshot) {
+            if (!mHandleTaskStackChanges) {
+                return;
+            }
             updateThumbnail(taskId, snapshot);
         }
 
         @Override
         public void onActivityPinned(String packageName, int userId, int taskId, int stackId) {
+            if (!mHandleTaskStackChanges) {
+                return;
+            }
             // Check this is for the right user
-            if (!checkCurrentUserId(userId, false /* debug */)) {
+            if (!checkCurrentOrManagedUserId(userId, getContext())) {
                 return;
             }
 
@@ -141,20 +158,52 @@
 
         @Override
         public void onActivityUnpinned() {
+            if (!mHandleTaskStackChanges) {
+                return;
+            }
             // TODO: Re-enable layout transitions for addition of the unpinned task
             reloadIfNeeded();
         }
 
         @Override
         public void onTaskRemoved(int taskId) {
-            TaskView taskView = getTaskView(taskId);
-            if (taskView != null) {
-                dismissTask(taskView, true /* animate */, false /* removeTask */);
+            if (!mHandleTaskStackChanges) {
+                return;
             }
-        }
-    };
+            BackgroundExecutor.get().submit(() -> {
+                TaskView taskView = getTaskView(taskId);
+                if (taskView == null) {
+                    return;
+                }
+                Handler handler = taskView.getHandler();
+                if (handler == null) {
+                    return;
+                }
 
-    private TaskStackChangeListener mTaskStackClearFlagListener = new TaskStackChangeListener() {
+                // TODO: Add callbacks from AM reflecting adding/removing from the recents list, and
+                //       remove all these checks
+                Task.TaskKey taskKey = taskView.getTask().key;
+                if (PackageManagerWrapper.getInstance().getActivityInfo(taskKey.getComponent(),
+                        taskKey.userId) == null) {
+                    // The package was uninstalled
+                    handler.post(() ->
+                            dismissTask(taskView, true /* animate */, false /* removeTask */));
+                } else {
+                    RecentsTaskLoadPlan loadPlan = new RecentsTaskLoadPlan(getContext());
+                    RecentsTaskLoadPlan.PreloadOptions opts =
+                            new RecentsTaskLoadPlan.PreloadOptions();
+                    opts.loadTitles = false;
+                    loadPlan.preloadPlan(opts, mModel.getRecentsTaskLoader(), -1,
+                            UserHandle.myUserId());
+                    if (loadPlan.getTaskStack().findTaskWithId(taskId) == null) {
+                        // The task was removed from the recents list
+                        handler.post(() ->
+                                dismissTask(taskView, true /* animate */, false /* removeTask */));
+                    }
+                }
+            });
+        }
+
         @Override
         public void onPinnedStackAnimationStarted() {
             // Needed for activities that auto-enter PiP, which will not trigger a remote
@@ -170,10 +219,10 @@
     private boolean mRunningTaskTileHidden;
     private Task mTmpRunningTask;
 
-    private boolean mFirstTaskIconScaledDown = false;
+    private boolean mRunningTaskIconScaledDown = false;
 
     private boolean mOverviewStateEnabled;
-    private boolean mTaskStackListenerRegistered;
+    private boolean mHandleTaskStackChanges;
     private Runnable mNextPageSwitchRunnable;
     private boolean mSwipeDownShouldLaunchApp;
 
@@ -260,7 +309,7 @@
         super.onAttachedToWindow();
         updateTaskStackListenerState();
         mActivity.addMultiWindowModeChangedListener(mMultiWindowModeChangedListener);
-        ActivityManagerWrapper.getInstance().registerTaskStackListener(mTaskStackClearFlagListener);
+        ActivityManagerWrapper.getInstance().registerTaskStackListener(mTaskStackListener);
     }
 
     @Override
@@ -268,8 +317,7 @@
         super.onDetachedFromWindow();
         updateTaskStackListenerState();
         mActivity.removeMultiWindowModeChangedListener(mMultiWindowModeChangedListener);
-        ActivityManagerWrapper.getInstance().unregisterTaskStackListener(
-                mTaskStackClearFlagListener);
+        ActivityManagerWrapper.getInstance().unregisterTaskStackListener(mTaskStackListener);
     }
 
     @Override
@@ -323,34 +371,34 @@
         }
     }
 
+    private int getScrollEnd() {
+        return mIsRtl ? 0 : mMaxScrollX;
+    }
+
     private float calculateClearAllButtonAlpha() {
         final int childCount = getChildCount();
-        if (mShowEmptyMessage || childCount == 0) return 0;
+        if (mShowEmptyMessage || childCount == 0 || mPageScrolls == null
+                || childCount != mPageScrolls.length) {
+            return 0;
+        }
 
-        final View lastChild = getChildAt(childCount - 1);
+        final int scrollEnd = getScrollEnd();
+        final int oldestChildScroll = getScrollForPage(childCount - 1);
 
-        // Current visible coordinate of the end of the oldest task.
-        final int carouselCurrentEnd =
-                (mIsRtl ? lastChild.getLeft() : lastChild.getRight()) - getScrollX();
+        final int clearAllButtonMotionRange = scrollEnd - oldestChildScroll;
+        if (clearAllButtonMotionRange == 0) return 0;
 
-        // Visible button-facing end of a centered task.
-        final int centeredTaskEnd = mIsRtl ?
-                getPaddingLeft() + mInsets.left :
-                getWidth() - getPaddingRight() - mInsets.right;
+        final float alphaUnbound = ((float) (getScrollX() - oldestChildScroll)) /
+                clearAllButtonMotionRange;
+        if (alphaUnbound > 1) return 0;
 
-        // The distance of the carousel travel during which the alpha changes from 0 to 1. This
-        // is the motion between the oldest task in its centered position and the oldest task
-        // scrolled to the end.
-        final int alphaChangeRange = (mIsRtl ? 0 : mMaxScrollX) - getScrollForPage(childCount - 1);
-
-        return Utilities.boundToRange(
-                ((float) (centeredTaskEnd - carouselCurrentEnd)) /
-                        alphaChangeRange, 0, 1);
+        return Math.max(alphaUnbound, 0);
     }
 
     private void updateClearAllButtonAlpha() {
         if (mClearAllButton != null) {
             final float alpha = calculateClearAllButtonAlpha();
+            mIsClearAllButtonFullyRevealed = alpha == 1;
             mClearAllButton.setAlpha(alpha * mContentAlpha);
         }
     }
@@ -362,9 +410,18 @@
     }
 
     @Override
+    protected void restoreScrollOnLayout() {
+        if (mIsClearAllButtonFullyRevealed) {
+            scrollAndForceFinish(getScrollEnd());
+        } else {
+            super.restoreScrollOnLayout();
+        }
+    }
+
+    @Override
     public boolean onTouchEvent(MotionEvent ev) {
         if (ev.getAction() == MotionEvent.ACTION_DOWN && mTouchState == TOUCH_STATE_REST
-                && mScroller.isFinished() && mClearAllButton.getAlpha() > 0) {
+                && mScroller.isFinished() && mIsClearAllButtonFullyRevealed) {
             mClearAllButton.getHitRect(mTempRect);
             mTempRect.offset(-getLeft(), -getTop());
             if (mTempRect.contains((int) ev.getX(), (int) ev.getY())) {
@@ -419,7 +476,6 @@
             taskView.bind(task);
         }
         resetTaskVisuals();
-        applyIconScale(false /* animate */);
 
         if (oldChildCount != getChildCount()) {
             mQuickScrubController.snapToNextTaskIfAvailable();
@@ -439,6 +495,7 @@
         if (mRunningTaskTileHidden) {
             setRunningTaskHidden(mRunningTaskTileHidden);
         }
+        applyIconScale(false /* animate */);
 
         updateCurveProperties();
         // Update the set of visible task's data
@@ -446,18 +503,13 @@
     }
 
     private void updateTaskStackListenerState() {
-        boolean registerStackListener = mOverviewStateEnabled && isAttachedToWindow()
+        boolean handleTaskStackChanges = mOverviewStateEnabled && isAttachedToWindow()
                 && getWindowVisibility() == VISIBLE;
-        if (registerStackListener != mTaskStackListenerRegistered) {
-            if (registerStackListener) {
-                ActivityManagerWrapper.getInstance()
-                        .registerTaskStackListener(mTaskStackListener);
+        if (handleTaskStackChanges != mHandleTaskStackChanges) {
+            mHandleTaskStackChanges = handleTaskStackChanges;
+            if (handleTaskStackChanges) {
                 reloadIfNeeded();
-            } else {
-                ActivityManagerWrapper.getInstance()
-                        .unregisterTaskStackListener(mTaskStackListener);
             }
-            mTaskStackListenerRegistered = registerStackListener;
         }
     }
 
@@ -638,13 +690,15 @@
      * Similar to {@link #showTask(int)} but does not put any restrictions on the first tile.
      */
     public void setCurrentTask(int runningTaskId) {
-        if (mRunningTaskTileHidden) {
-            setRunningTaskHidden(false);
-            mRunningTaskId = runningTaskId;
-            setRunningTaskHidden(true);
-        } else {
-            mRunningTaskId = runningTaskId;
-        }
+        boolean runningTaskTileHidden = mRunningTaskTileHidden;
+        boolean runningTaskIconScaledDown = mRunningTaskIconScaledDown;
+
+        setRunningTaskIconScaledDown(false, false);
+        setRunningTaskHidden(false);
+        mRunningTaskId = runningTaskId;
+        setRunningTaskIconScaledDown(runningTaskIconScaledDown, false);
+        setRunningTaskHidden(runningTaskTileHidden);
+
         setCurrentPage(0);
 
         // Load the tasks (if the loading is already
@@ -672,17 +726,17 @@
         return mQuickScrubController;
     }
 
-    public void setFirstTaskIconScaledDown(boolean isScaledDown, boolean animate) {
-        if (mFirstTaskIconScaledDown == isScaledDown) {
+    public void setRunningTaskIconScaledDown(boolean isScaledDown, boolean animate) {
+        if (mRunningTaskIconScaledDown == isScaledDown) {
             return;
         }
-        mFirstTaskIconScaledDown = isScaledDown;
+        mRunningTaskIconScaledDown = isScaledDown;
         applyIconScale(animate);
     }
 
     private void applyIconScale(boolean animate) {
-        float scale = mFirstTaskIconScaledDown ? 0 : 1;
-        TaskView firstTask = (TaskView) getChildAt(0);
+        float scale = mRunningTaskIconScaledDown ? 0 : 1;
+        TaskView firstTask = getTaskView(mRunningTaskId);
         if (firstTask != null) {
             if (animate) {
                 firstTask.animateIconToScaleAndDim(scale);
@@ -731,13 +785,13 @@
                 duration, LINEAR, anim);
     }
 
-    private void removeTask(Task task, PendingAnimation.OnEndListener onEndListener,
-            boolean shouldLog) {
+    private void removeTask(Task task, int index, PendingAnimation.OnEndListener onEndListener,
+                            boolean shouldLog) {
         if (task != null) {
             ActivityManagerWrapper.getInstance().removeTask(task.key.id);
             if (shouldLog) {
                 mActivity.getUserEventDispatcher().logTaskLaunchOrDismiss(
-                        onEndListener.logAction, Direction.UP,
+                        onEndListener.logAction, Direction.UP, index,
                         TaskUtils.getComponentKeyForTask(task.key));
             }
         }
@@ -822,7 +876,7 @@
         mPendingAnimation.addEndListener((onEndListener) -> {
            if (onEndListener.isSuccess) {
                if (shouldRemoveTask) {
-                   removeTask(taskView.getTask(), onEndListener, true);
+                   removeTask(taskView.getTask(), draggedIndex, onEndListener, true);
                }
                int pageToSnapTo = mCurrentPage;
                if (draggedIndex < pageToSnapTo) {
@@ -831,7 +885,7 @@
                removeView(taskView);
                if (getChildCount() == 0) {
                    onAllTasksRemoved();
-               } else {
+               } else if (!mIsClearAllButtonFullyRevealed) {
                    snapToPageImmediately(pageToSnapTo);
                }
            }
@@ -858,7 +912,7 @@
             if (onEndListener.isSuccess) {
                 while (getChildCount() != 0) {
                     TaskView taskView = getPageAt(getChildCount() - 1);
-                    removeTask(taskView.getTask(), onEndListener, false);
+                    removeTask(taskView.getTask(), -1, onEndListener, false);
                     removeView(taskView);
                 }
                 onAllTasksRemoved();
@@ -971,15 +1025,13 @@
         if (currTask == null) {
             return;
         }
-        currTask.setScaleX(mAdjacentScale);
-        currTask.setScaleY(mAdjacentScale);
+        currTask.setZoomScale(mAdjacentScale);
 
         if (mCurrentPage - 1 >= 0) {
             TaskView adjacentTask = getPageAt(mCurrentPage - 1);
             float[] scaleAndTranslation = getAdjacentScaleAndTranslation(currTask, adjacentTask,
                     mAdjacentScale, 0);
-            adjacentTask.setScaleX(scaleAndTranslation[0]);
-            adjacentTask.setScaleY(scaleAndTranslation[0]);
+            adjacentTask.setZoomScale(scaleAndTranslation[0]);
             adjacentTask.setTranslationX(-scaleAndTranslation[1]);
             adjacentTask.setTranslationY(scaleAndTranslation[2]);
         }
@@ -987,8 +1039,7 @@
             TaskView adjacentTask = getPageAt(mCurrentPage + 1);
             float[] scaleAndTranslation = getAdjacentScaleAndTranslation(currTask, adjacentTask,
                     mAdjacentScale, 0);
-            adjacentTask.setScaleX(scaleAndTranslation[0]);
-            adjacentTask.setScaleY(scaleAndTranslation[0]);
+            adjacentTask.setZoomScale(scaleAndTranslation[0]);
             adjacentTask.setTranslationX(scaleAndTranslation[1]);
             adjacentTask.setTranslationY(scaleAndTranslation[2]);
         }
@@ -997,7 +1048,7 @@
     private float[] getAdjacentScaleAndTranslation(TaskView currTask, TaskView adjacentTask,
             float currTaskToScale, float currTaskToTranslationY) {
         float displacement = currTask.getWidth() * (currTaskToScale - currTask.getCurveScale());
-        sTempFloatArray[0] = currTaskToScale * adjacentTask.getCurveScale();
+        sTempFloatArray[0] = currTaskToScale;
         sTempFloatArray[1] = mIsRtl ? -displacement : displacement;
         sTempFloatArray[2] = currTaskToTranslationY;
         return sTempFloatArray;
@@ -1043,14 +1094,7 @@
         }
         updateClearAllButtonAlpha();
 
-        if (!mShowEmptyMessage) return;
-
-        // The icon needs to be centered. Need to scoll to horizontal 0 because with Clear-All
-        // space on the right, it's not guaranteed that after deleting all tasks, the horizontal
-        // scroll position will be zero.
-        scrollTo(0, 0);
-
-        if (hasValidSize && mEmptyTextLayout == null) {
+        if (mShowEmptyMessage && hasValidSize && mEmptyTextLayout == null) {
             int availableWidth = mLastMeasureSize.x - mEmptyMessagePadding - mEmptyMessagePadding;
             mEmptyTextLayout = StaticLayout.Builder.obtain(mEmptyMessage, 0, mEmptyMessage.length(),
                     mEmptyMessagePaint, availableWidth)
@@ -1077,7 +1121,7 @@
             mTempRect.set(mInsets.left + getPaddingLeft(), mInsets.top + getPaddingTop(),
                     mInsets.right + getPaddingRight(), mInsets.bottom + getPaddingBottom());
             canvas.save();
-            canvas.translate((mTempRect.left - mTempRect.right) / 2,
+            canvas.translate(getScrollX() + (mTempRect.left - mTempRect.right) / 2,
                     (mTempRect.top - mTempRect.bottom) / 2);
             mEmptyIcon.draw(canvas);
             canvas.translate(mEmptyMessagePadding,
@@ -1138,13 +1182,15 @@
         return anim;
     }
 
-    private ObjectAnimator createAnimForChild(View child, float[] toScaleAndTranslation) {
-        return ObjectAnimator.ofPropertyValuesHolder(child,
+    private Animator createAnimForChild(TaskView child, float[] toScaleAndTranslation) {
+        AnimatorSet anim = new AnimatorSet();
+        anim.play(ObjectAnimator.ofFloat(child, TaskView.ZOOM_SCALE, toScaleAndTranslation[0]));
+        anim.play(ObjectAnimator.ofPropertyValuesHolder(child,
                         new PropertyListBuilder()
-                                .scale(child.getScaleX() * toScaleAndTranslation[0])
                                 .translationX(toScaleAndTranslation[1])
                                 .translationY(toScaleAndTranslation[2])
-                                .build());
+                                .build()));
+        return anim;
     }
 
     public PendingAnimation createTaskLauncherAnimation(TaskView tv, long duration) {
@@ -1158,12 +1204,21 @@
         }
 
         tv.setVisibility(INVISIBLE);
+        int targetSysUiFlags = tv.getThumbnail().getSysUiStatusNavFlags();
         TaskViewDrawable drawable = new TaskViewDrawable(tv, this);
         getOverlay().add(drawable);
 
         ObjectAnimator drawableAnim =
                 ObjectAnimator.ofFloat(drawable, TaskViewDrawable.PROGRESS, 1, 0);
         drawableAnim.setInterpolator(LINEAR);
+        drawableAnim.addUpdateListener((animator) -> {
+            // Once we pass a certain threshold, update the sysui flags to match the target tasks'
+            // flags
+            mActivity.getSystemUiController().updateUiState(UI_STATE_OVERVIEW,
+                    animator.getAnimatedFraction() > UPDATE_SYSUI_FLAGS_THRESHOLD
+                            ? targetSysUiFlags
+                            : 0);
+        });
 
         AnimatorSet anim = createAdjacentPageAnimForTaskLaunch(tv,
                 drawable.getClipAnimationHelper());
@@ -1189,7 +1244,7 @@
                 Task task = tv.getTask();
                 if (task != null) {
                     mActivity.getUserEventDispatcher().logTaskLaunchOrDismiss(
-                            onEndListener.logAction, Direction.DOWN,
+                            onEndListener.logAction, Direction.DOWN, indexOfChild(tv),
                             TaskUtils.getComponentKeyForTask(task.key));
                 }
             } else {
@@ -1213,6 +1268,7 @@
         if (currChild != null) {
             currChild.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED);
         }
+        loadVisibleTaskData();
     }
 
     @Override
diff --git a/quickstep/src/com/android/quickstep/views/RecentsViewContainer.java b/quickstep/src/com/android/quickstep/views/RecentsViewContainer.java
index a951de9..429432b 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsViewContainer.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsViewContainer.java
@@ -75,8 +75,8 @@
     }
 
     @Override
-    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+        super.onLayout(changed, left, top, right, bottom);
 
         mRecentsView.getTaskSize(mTempRect);
 
diff --git a/quickstep/src/com/android/quickstep/views/ShelfScrimView.java b/quickstep/src/com/android/quickstep/views/ShelfScrimView.java
new file mode 100644
index 0000000..24afd48
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/views/ShelfScrimView.java
@@ -0,0 +1,259 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.quickstep.views;
+
+import static android.support.v4.graphics.ColorUtils.compositeColors;
+import static android.support.v4.graphics.ColorUtils.setAlphaComponent;
+
+import static com.android.launcher3.LauncherState.OVERVIEW;
+import static com.android.launcher3.anim.Interpolators.ACCEL_2;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.Path;
+import android.graphics.Path.Direction;
+import android.graphics.Path.Op;
+import android.os.Bundle;
+import android.support.annotation.NonNull;
+import android.support.v4.view.accessibility.AccessibilityNodeInfoCompat;
+import android.util.AttributeSet;
+
+import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.R;
+import com.android.launcher3.uioverrides.OverviewState;
+import com.android.launcher3.util.Themes;
+import com.android.launcher3.views.ScrimView;
+
+/**
+ * Scrim used for all-apps and shelf in Overview
+ * In transposed layout, it behaves as a simple color scrim.
+ * In portrait layout, it draws a rounded rect such that
+ *    From normal state to overview state, the shelf just fades in and does not move
+ *    From overview state to all-apps state the shelf moves up and fades in to cover the screen
+ */
+public class ShelfScrimView extends ScrimView {
+
+    private static final int THRESHOLD_ALPHA_DARK = 102;
+    private static final int THRESHOLD_ALPHA_LIGHT = 46;
+    private static final int THRESHOLD_ALPHA_SUPER_LIGHT = 128;
+    private static final int CLEAR_ALL_TASKS = R.string.recents_clear_all;
+
+    // In transposed layout, we simply draw a flat color.
+    private boolean mDrawingFlatColor;
+
+    // For shelf mode
+    private final int mEndAlpha;
+    private final int mThresholdAlpha;
+    private final float mRadius;
+    private final float mMaxScrimAlpha;
+    private final Paint mPaint;
+
+    // Max vertical progress after which the scrim stops moving.
+    private float mMoveThreshold;
+    // Minimum visible size of the scrim.
+    private int mMinSize;
+
+    private float mScrimMoveFactor = 0;
+    private int mShelfColor;
+    private int mRemainingScreenColor;
+
+    private final Path mTempPath = new Path();
+    private final Path mRemainingScreenPath = new Path();
+    private boolean mRemainingScreenPathValid = false;
+
+    public ShelfScrimView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        mMaxScrimAlpha = OVERVIEW.getWorkspaceScrimAlpha(mLauncher);
+
+        mEndAlpha = Color.alpha(mEndScrim);
+        if (Themes.getAttrBoolean(mLauncher, R.attr.isMainColorDark)) {
+            mThresholdAlpha = THRESHOLD_ALPHA_DARK;
+        } else if (Themes.getAttrBoolean(mLauncher, R.attr.isWorkspaceDarkText)) {
+            mThresholdAlpha = THRESHOLD_ALPHA_SUPER_LIGHT;
+        } else {
+            mThresholdAlpha = THRESHOLD_ALPHA_LIGHT;
+        }
+        mRadius = mLauncher.getResources().getDimension(R.dimen.shelf_surface_radius);
+        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+
+        // Just assume the easiest UI for now, until we have the proper layout information.
+        mDrawingFlatColor = true;
+    }
+
+    @Override
+    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+        super.onSizeChanged(w, h, oldw, oldh);
+        mRemainingScreenPathValid = false;
+    }
+
+    @Override
+    public void reInitUi() {
+        DeviceProfile dp = mLauncher.getDeviceProfile();
+        mDrawingFlatColor = dp.isVerticalBarLayout();
+
+        if (!mDrawingFlatColor) {
+            float swipeLength = OverviewState.getDefaultSwipeHeight(mLauncher);
+            mMoveThreshold = 1 - swipeLength / mLauncher.getAllAppsController().getShiftRange();
+            mMinSize = dp.hotseatBarSizePx + dp.getInsets().bottom;
+            mRemainingScreenPathValid = false;
+            updateColors();
+        }
+        updateDragHandleAlpha();
+        invalidate();
+    }
+
+    @Override
+    public void updateColors() {
+        super.updateColors();
+        if (mDrawingFlatColor) {
+            return;
+        }
+
+        if (mProgress >= mMoveThreshold) {
+            mScrimMoveFactor = 1;
+
+            if (mProgress >= 1) {
+                mShelfColor = 0;
+            } else {
+                int alpha = Math.round(mThresholdAlpha * ACCEL_2.getInterpolation(
+                        (1 - mProgress) / (1 - mMoveThreshold)));
+                mShelfColor = setAlphaComponent(mEndScrim, alpha);
+            }
+
+            mRemainingScreenColor = 0;
+        } else if (mProgress <= 0) {
+            mScrimMoveFactor = 0;
+            mShelfColor = mCurrentFlatColor;
+            mRemainingScreenColor = 0;
+
+        } else {
+            mScrimMoveFactor = mProgress / mMoveThreshold;
+            mRemainingScreenColor = setAlphaComponent(mScrimColor,
+                    Math.round((1 - mScrimMoveFactor) * mMaxScrimAlpha * 255));
+
+            // Merge the remainingScreenColor and shelfColor in one to avoid overdraw.
+            int alpha = mEndAlpha - Math.round((mEndAlpha - mThresholdAlpha) * mScrimMoveFactor);
+            mShelfColor = compositeColors(setAlphaComponent(mEndScrim, alpha),
+                    mRemainingScreenColor);
+        }
+    }
+
+    @Override
+    protected void updateDragHandleAlpha() {
+        if (mDrawingFlatColor) {
+            super.updateDragHandleAlpha();
+        } else if (mDragHandle != null) {
+            mDragHandle.setAlpha(255);
+        }
+    }
+
+    @Override
+    protected void onDraw(Canvas canvas) {
+        float translate = drawBackground(canvas);
+
+        if (mDragHandle != null) {
+            canvas.translate(0, -translate);
+            mDragHandle.draw(canvas);
+            canvas.translate(0, translate);
+        }
+    }
+
+    private float drawBackground(Canvas canvas) {
+        if (mDrawingFlatColor) {
+            if (mCurrentFlatColor != 0) {
+                canvas.drawColor(mCurrentFlatColor);
+            }
+            return 0;
+        }
+
+        if (mShelfColor == 0) {
+            return 0;
+        } else if (mScrimMoveFactor <= 0) {
+            canvas.drawColor(mShelfColor);
+            return getHeight();
+        }
+
+        float minTop = getHeight() - mMinSize;
+        float top = minTop * mScrimMoveFactor - mDragHandleSize;
+
+        // Draw the scrim over the remaining screen if needed.
+        if (mRemainingScreenColor != 0) {
+            if (!mRemainingScreenPathValid) {
+                mTempPath.reset();
+                // Using a arbitrary '+10' in the bottom to avoid any left-overs at the
+                // corners due to rounding issues.
+                mTempPath.addRoundRect(0, minTop, getWidth(), getHeight() + mRadius + 10,
+                        mRadius, mRadius, Direction.CW);
+
+                mRemainingScreenPath.reset();
+                mRemainingScreenPath.addRect(0, 0, getWidth(), getHeight(), Direction.CW);
+                mRemainingScreenPath.op(mTempPath, Op.DIFFERENCE);
+            }
+
+            float offset = minTop - top;
+            canvas.translate(0, -offset);
+            mPaint.setColor(mRemainingScreenColor);
+            canvas.drawPath(mRemainingScreenPath, mPaint);
+            canvas.translate(0, offset);
+        }
+
+        mPaint.setColor(mShelfColor);
+        canvas.drawRoundRect(0, top, getWidth(), getHeight() + mRadius,
+                mRadius, mRadius, mPaint);
+        return minTop - mDragHandleSize - top;
+    }
+
+    @NonNull
+    @Override
+    protected AccessibilityHelper createAccessibilityHelper() {
+        return new ShelfScrimAccessibilityHelper();
+    }
+
+    protected class ShelfScrimAccessibilityHelper extends AccessibilityHelper {
+        @Override
+        protected void onPopulateNodeForVirtualView(int virtualViewId,
+                AccessibilityNodeInfoCompat node) {
+            super.onPopulateNodeForVirtualView(virtualViewId, node);
+
+            if (mLauncher.isInState(OVERVIEW)) {
+                final RecentsView overviewPanel = mLauncher.getOverviewPanel();
+                if (overviewPanel.getChildCount() != 0) {
+                    node.addAction(
+                            new AccessibilityNodeInfoCompat.AccessibilityActionCompat(
+                                    CLEAR_ALL_TASKS,
+                                    getContext().getText(CLEAR_ALL_TASKS)));
+                }
+            }
+        }
+
+        @Override
+        protected boolean onPerformActionForVirtualView(
+                int virtualViewId, int action, Bundle arguments) {
+            if (super.onPerformActionForVirtualView(virtualViewId, action, arguments)) return true;
+
+            if (action == CLEAR_ALL_TASKS) {
+                if (mLauncher.isInState(OVERVIEW)) {
+                    mLauncher.<RecentsView>getOverviewPanel().dismissAllTasks();
+                }
+                return true;
+            }
+
+            return false;
+        }
+    }
+}
diff --git a/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java b/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java
index c724930..128a19e 100644
--- a/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java
@@ -38,6 +38,7 @@
 import com.android.launcher3.DeviceProfile;
 import com.android.launcher3.R;
 import com.android.launcher3.config.FeatureFlags;
+import com.android.launcher3.util.SystemUiController;
 import com.android.quickstep.TaskOverlayFactory;
 import com.android.quickstep.TaskOverlayFactory.TaskOverlay;
 import com.android.systemui.shared.recents.model.Task;
@@ -50,16 +51,16 @@
 
     private static final LightingColorFilter[] sDimFilterCache = new LightingColorFilter[256];
 
-    public static final Property<TaskThumbnailView, Float> DIM_ALPHA =
-            new FloatProperty<TaskThumbnailView>("dimAlpha") {
+    public static final Property<TaskThumbnailView, Float> DIM_ALPHA_MULTIPLIER =
+            new FloatProperty<TaskThumbnailView>("dimAlphaMultiplier") {
                 @Override
-                public void setValue(TaskThumbnailView thumbnail, float dimAlpha) {
-                    thumbnail.setDimAlpha(dimAlpha);
+                public void setValue(TaskThumbnailView thumbnail, float dimAlphaMultiplier) {
+                    thumbnail.setDimAlphaMultipler(dimAlphaMultiplier);
                 }
 
                 @Override
                 public Float get(TaskThumbnailView thumbnailView) {
-                    return thumbnailView.mDimAlpha;
+                    return thumbnailView.mDimAlphaMultiplier;
                 }
             };
 
@@ -79,6 +80,7 @@
     protected BitmapShader mBitmapShader;
 
     private float mDimAlpha = 1f;
+    private float mDimAlphaMultiplier = 1f;
 
     public TaskThumbnailView(Context context) {
         this(context, null);
@@ -126,6 +128,11 @@
         updateThumbnailPaintFilter();
     }
 
+    public void setDimAlphaMultipler(float dimAlphaMultipler) {
+        mDimAlphaMultiplier = dimAlphaMultipler;
+        setDimAlpha(mDimAlpha);
+    }
+
     /**
      * Sets the alpha of the dim layer on top of this view.
      *
@@ -143,6 +150,20 @@
         return new Rect();
     }
 
+    public int getSysUiStatusNavFlags() {
+        if (mThumbnailData != null) {
+            int flags = 0;
+            flags |= (mThumbnailData.systemUiVisibility & SYSTEM_UI_FLAG_LIGHT_STATUS_BAR) != 0
+                    ? SystemUiController.FLAG_LIGHT_STATUS
+                    : SystemUiController.FLAG_DARK_STATUS;
+            flags |= (mThumbnailData.systemUiVisibility & SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR) != 0
+                    ? SystemUiController.FLAG_LIGHT_NAV
+                    : SystemUiController.FLAG_DARK_NAV;
+            return flags;
+        }
+        return 0;
+    }
+
     @Override
     protected void onDraw(Canvas canvas) {
         drawOnCanvas(canvas, 0, 0, getMeasuredWidth(), getMeasuredHeight(), mCornerRadius);
@@ -154,25 +175,28 @@
 
     public void drawOnCanvas(Canvas canvas, float x, float y, float width, float height,
             float cornerRadius) {
-        // Always draw the background since the snapshots may be translucent
-        canvas.drawRoundRect(x, y, width, height, cornerRadius, cornerRadius, mBackgroundPaint);
-        if (mTask == null) {
-            return;
-        }
-        if (!mTask.isLocked) {
-            if (mClipBottom > 0) {
-                canvas.save();
-                canvas.clipRect(x, y, width, mClipBottom);
-                canvas.drawRoundRect(x, y, width, height, cornerRadius, cornerRadius, mPaint);
-                canvas.restore();
-            } else {
-                canvas.drawRoundRect(x, y, width, height, cornerRadius, cornerRadius, mPaint);
+        // Draw the background in all cases, except when the thumbnail data is opaque
+        final boolean drawBackgroundOnly = mTask == null || mTask.isLocked || mBitmapShader == null
+                || mThumbnailData == null;
+        if (drawBackgroundOnly || mClipBottom > 0 || mThumbnailData.isTranslucent) {
+            canvas.drawRoundRect(x, y, width, height, cornerRadius, cornerRadius, mBackgroundPaint);
+            if (drawBackgroundOnly) {
+                return;
             }
         }
+
+        if (mClipBottom > 0) {
+            canvas.save();
+            canvas.clipRect(x, y, width, mClipBottom);
+            canvas.drawRoundRect(x, y, width, height, cornerRadius, cornerRadius, mPaint);
+            canvas.restore();
+        } else {
+            canvas.drawRoundRect(x, y, width, height, cornerRadius, cornerRadius, mPaint);
+        }
     }
 
     private void updateThumbnailPaintFilter() {
-        int mul = (int) ((1 - mDimAlpha) * 255);
+        int mul = (int) ((1 - mDimAlpha * mDimAlphaMultiplier) * 255);
         if (mBitmapShader != null) {
             LightingColorFilter filter = getLightingColorFilter(mul);
             mPaint.setColorFilter(filter);
diff --git a/quickstep/src/com/android/quickstep/views/TaskView.java b/quickstep/src/com/android/quickstep/views/TaskView.java
index 5fffb50..82aa45a 100644
--- a/quickstep/src/com/android/quickstep/views/TaskView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskView.java
@@ -17,7 +17,7 @@
 package com.android.quickstep.views;
 
 import static android.widget.Toast.LENGTH_SHORT;
-import static com.android.quickstep.views.TaskThumbnailView.DIM_ALPHA;
+import static com.android.quickstep.views.TaskThumbnailView.DIM_ALPHA_MULTIPLIER;
 
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
@@ -30,14 +30,15 @@
 import android.os.Bundle;
 import android.os.Handler;
 import android.util.AttributeSet;
+import android.util.FloatProperty;
 import android.util.Log;
+import android.util.Property;
 import android.view.View;
 import android.view.ViewOutlineProvider;
 import android.view.accessibility.AccessibilityNodeInfo;
 import android.widget.FrameLayout;
-import android.widget.ImageView;
-
 import android.widget.Toast;
+
 import com.android.launcher3.BaseActivity;
 import com.android.launcher3.BaseDraggingActivity;
 import com.android.launcher3.R;
@@ -76,13 +77,27 @@
      */
     private static final float EDGE_SCALE_DOWN_FACTOR = 0.03f;
 
-    private static final long SCALE_ICON_DURATION = 120;
+    public static final long SCALE_ICON_DURATION = 120;
+    private static final long DIM_ANIM_DURATION = 700;
+
+    public static final Property<TaskView, Float> ZOOM_SCALE =
+            new FloatProperty<TaskView>("zoomScale") {
+                @Override
+                public void setValue(TaskView taskView, float v) {
+                    taskView.setZoomScale(v);
+                }
+
+                @Override
+                public Float get(TaskView taskView) {
+                    return taskView.mZoomScale;
+                }
+            };
 
     private Task mTask;
     private TaskThumbnailView mSnapshotView;
     private IconView mIconView;
     private float mCurveScale;
-    private float mCurveDimAlpha;
+    private float mZoomScale;
     private Animator mDimAlphaAnim;
 
     public TaskView(Context context) {
@@ -96,11 +111,13 @@
     public TaskView(Context context, AttributeSet attrs, int defStyleAttr) {
         super(context, attrs, defStyleAttr);
         setOnClickListener((view) -> {
-            if (mTask != null) {
-                launchTask(true /* animate */);
-                BaseActivity.fromContext(context).getUserEventDispatcher().logTaskLaunchOrDismiss(
-                        Touch.TAP, Direction.NONE, TaskUtils.getComponentKeyForTask(mTask.key));
+            if (getTask() == null) {
+                return;
             }
+            launchTask(true /* animate */);
+            BaseActivity.fromContext(context).getUserEventDispatcher().logTaskLaunchOrDismiss(
+                    Touch.TAP, Direction.NONE, ((RecentsView) getParent()).indexOfChild(this),
+                    TaskUtils.getComponentKeyForTask(getTask().key));
         });
         setOutlineProvider(new TaskOutlineProvider(getResources()));
     }
@@ -185,8 +202,9 @@
 
     public void animateIconToScaleAndDim(float scale) {
         mIconView.animate().scaleX(scale).scaleY(scale).setDuration(SCALE_ICON_DURATION).start();
-        mDimAlphaAnim = ObjectAnimator.ofFloat(mSnapshotView, DIM_ALPHA, scale * mCurveDimAlpha);
-        mDimAlphaAnim.setDuration(SCALE_ICON_DURATION);
+        mDimAlphaAnim = ObjectAnimator.ofFloat(mSnapshotView, DIM_ALPHA_MULTIPLIER, 1 - scale,
+                scale);
+        mDimAlphaAnim.setDuration(DIM_ANIM_DURATION);
         mDimAlphaAnim.addListener(new AnimatorListenerAdapter() {
             @Override
             public void onAnimationEnd(Animator animation) {
@@ -203,16 +221,16 @@
         if (mDimAlphaAnim != null) {
             mDimAlphaAnim.cancel();
         }
-        mSnapshotView.setDimAlpha(iconScale * mCurveDimAlpha);
+        mSnapshotView.setDimAlphaMultipler(iconScale);
     }
 
     public void resetVisualProperties() {
-        setScaleX(1f);
-        setScaleY(1f);
+        setZoomScale(1);
         setTranslationX(0f);
         setTranslationY(0f);
         setTranslationZ(0);
         setAlpha(1f);
+        setIconScaleAndDim(1);
     }
 
     @Override
@@ -220,14 +238,8 @@
         float curveInterpolation =
                 CURVE_INTERPOLATOR.getInterpolation(scrollState.linearInterpolation);
 
-        mCurveDimAlpha = curveInterpolation * MAX_PAGE_SCRIM_ALPHA;
-        if (mDimAlphaAnim == null && mIconView.getScaleX() > 0) {
-            mSnapshotView.setDimAlpha(mCurveDimAlpha);
-        }
-
-        mCurveScale = getCurveScaleForCurveInterpolation(curveInterpolation);
-        setScaleX(mCurveScale);
-        setScaleY(mCurveScale);
+        mSnapshotView.setDimAlpha(curveInterpolation * MAX_PAGE_SCRIM_ALPHA);
+        setCurveScale(getCurveScaleForCurveInterpolation(curveInterpolation));
     }
 
     @Override
@@ -246,10 +258,26 @@
         return 1 - curveInterpolation * EDGE_SCALE_DOWN_FACTOR;
     }
 
+    private void setCurveScale(float curveScale) {
+        mCurveScale = curveScale;
+        onScaleChanged();
+    }
+
     public float getCurveScale() {
         return mCurveScale;
     }
 
+    public void setZoomScale(float adjacentScale) {
+        mZoomScale = adjacentScale;
+        onScaleChanged();
+    }
+
+    private void onScaleChanged() {
+        float scale = mCurveScale * mZoomScale;
+        setScaleX(scale);
+        setScaleY(scale);
+    }
+
     @Override
     public boolean hasOverlappingRendering() {
         // TODO: Clip-out the icon region from the thumbnail, since they are overlapping.
diff --git a/res/animator-v23/discovery_bounce.xml b/res/animator-v23/discovery_bounce.xml
index 8d0e8fd..f554853 100644
--- a/res/animator-v23/discovery_bounce.xml
+++ b/res/animator-v23/discovery_bounce.xml
@@ -26,14 +26,14 @@
             android:fraction="0"
             android:value="1f" />
         <keyframe
-            android:fraction="0.346"
+            android:fraction="0.246"
             android:value="1f" />
         <keyframe
             android:fraction=".423"
             android:interpolator="@interpolator/disco_bounce"
-            android:value="0.9438f" />
+            android:value="0.9738f" />
         <keyframe
-            android:fraction="0.654"
+            android:fraction="0.754"
             android:interpolator="@interpolator/disco_bounce"
             android:value="1f" />
         <keyframe
diff --git a/res/drawable/all_apps_handle_landscape.xml b/res/drawable/drag_handle_indicator.xml
similarity index 77%
rename from res/drawable/all_apps_handle_landscape.xml
rename to res/drawable/drag_handle_indicator.xml
index 15518ff..b01b84a 100644
--- a/res/drawable/all_apps_handle_landscape.xml
+++ b/res/drawable/drag_handle_indicator.xml
@@ -15,25 +15,25 @@
 -->
 
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:width="@dimen/dynamic_grid_min_page_indicator_size"
-    android:height="@dimen/dynamic_grid_min_page_indicator_size"
-    android:viewportWidth="48.0"
-    android:viewportHeight="48.0" >
+    android:width="@dimen/vertical_drag_handle_size"
+    android:height="@dimen/vertical_drag_handle_size"
+    android:viewportWidth="36.0"
+    android:viewportHeight="36.0" >
 
     <group
-        android:translateX="17.5"
-        android:translateY="17.5">
+        android:translateX="11.5"
+        android:translateY="11.5">
         <path
             android:pathData="M2 8.5L6.5 4L11 8.5"
             android:strokeColor="?attr/workspaceAmbientShadowColor"
-            android:strokeWidth="4"
+            android:strokeWidth="3.6"
             android:strokeLineCap="round"
             android:strokeLineJoin="round" />
 
         <path
             android:pathData="M2 8.5L6.5 4L11 8.5"
             android:strokeColor="?attr/workspaceTextColor"
-            android:strokeWidth="2"
+            android:strokeWidth="1.8"
             android:strokeLineCap="round"
             android:strokeLineJoin="round" />
         </group>
diff --git a/res/drawable/ic_drag_indicator.xml b/res/drawable/ic_drag_indicator.xml
deleted file mode 100644
index d50bdd3..0000000
--- a/res/drawable/ic_drag_indicator.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2018 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:height="2dp"
-        android:width="16dp"
-        android:viewportHeight="2.0"
-        android:viewportWidth="16.0">
-    <path
-        android:fillColor="@android:color/white"
-        android:pathData="M1,0h14c0.55,0,1,0.45,1,1s-0.45,1-1,1H1C0.45,2,0,1.55,0,1S0.45,0,1,0z"/>
-</vector>
\ No newline at end of file
diff --git a/res/layout/launcher.xml b/res/layout/launcher.xml
index 6556adf..da17b2b 100644
--- a/res/layout/launcher.xml
+++ b/res/layout/launcher.xml
@@ -18,7 +18,6 @@
     android:id="@+id/launcher"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
-    android:background="?attr/workspaceStatusBarScrim"
     android:fitsSystemWindows="true">
 
     <com.android.launcher3.dragndrop.DragLayer
@@ -57,6 +56,9 @@
             android:id="@+id/drop_target_bar"
             layout="@layout/drop_target_bar" />
 
+        <include android:id="@+id/scrim_view"
+            layout="@layout/scrim_view" />
+
         <include
             android:id="@+id/apps_view"
             layout="@layout/all_apps"
@@ -64,9 +66,6 @@
             android:layout_height="match_parent"
             android:visibility="invisible" />
 
-        <include android:id="@+id/drag_indicator"
-            layout="@layout/drag_handle_indicator" />
-
         <!-- DO NOT CHANGE THE ID -->
         <include
             android:id="@+id/hotseat"
diff --git a/res/layout/drag_handle_indicator.xml b/res/layout/scrim_view.xml
similarity index 69%
rename from res/layout/drag_handle_indicator.xml
rename to res/layout/scrim_view.xml
index d5a7b8a..a604d56 100644
--- a/res/layout/drag_handle_indicator.xml
+++ b/res/layout/scrim_view.xml
@@ -13,11 +13,8 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<com.android.launcher3.views.LauncherDragIndicator
+<com.android.launcher3.views.ScrimView
     xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/drag_indicator"
-    android:layout_width="wrap_content"
-    android:layout_height="wrap_content"
-    android:contentDescription="@string/all_apps_button_label"
-    android:scaleType="centerInside"
-    android:tint="?attr/workspaceTextColor" />
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:id="@+id/scrim_view" />
\ No newline at end of file
diff --git a/res/values-af/strings.xml b/res/values-af/strings.xml
index 9b0ed47..87924e7 100644
--- a/res/values-af/strings.xml
+++ b/res/values-af/strings.xml
@@ -130,8 +130,8 @@
     <string name="action_decrease_height" msgid="282377193880900022">"Verminder hoogte"</string>
     <string name="widget_resized" msgid="9130327887929620">"Legstukgrootte is verander na breedte <xliff:g id="NUMBER_0">%1$s</xliff:g> hoogte <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
     <string name="action_deep_shortcut" msgid="2864038805849372848">"Kortpaaie"</string>
-    <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> kortpaaie vir <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
-    <string name="shortcuts_menu_with_notifications_description" msgid="8985659504915468840">"<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> kortpaaie en <xliff:g id="NUMBER_OF_NOTIFICATIONS">%2$d</xliff:g> kennisgewings vir <xliff:g id="APP_NAME">%3$s</xliff:g>"</string>
+    <!-- no translation found for shortcuts_menu_with_notifications_description (2676582286544232849) -->
+    <skip />
     <string name="action_dismiss_notification" msgid="5909461085055959187">"Maak toe"</string>
     <string name="notification_dismissed" msgid="6002233469409822874">"Kennisgewing is toegemaak"</string>
     <string name="all_apps_personal_tab" msgid="4190252696685155002">"Persoonlik"</string>
diff --git a/res/values-am/strings.xml b/res/values-am/strings.xml
index 0db7a53..46647c6 100644
--- a/res/values-am/strings.xml
+++ b/res/values-am/strings.xml
@@ -130,8 +130,8 @@
     <string name="action_decrease_height" msgid="282377193880900022">"ቁመት ይቀንሱ"</string>
     <string name="widget_resized" msgid="9130327887929620">"የመግብር መጠን ወደ ስፋት <xliff:g id="NUMBER_0">%1$s</xliff:g> ቁመት <xliff:g id="NUMBER_1">%2$s</xliff:g> ተለውጧል"</string>
     <string name="action_deep_shortcut" msgid="2864038805849372848">"አቋራጮች"</string>
-    <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> የ<xliff:g id="APP_NAME">%2$s</xliff:g> አቋራጮች"</string>
-    <string name="shortcuts_menu_with_notifications_description" msgid="8985659504915468840">"<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> አቋራጮች እና <xliff:g id="NUMBER_OF_NOTIFICATIONS">%2$d</xliff:g> ማሳወቂያዎች ለ<xliff:g id="APP_NAME">%3$s</xliff:g>"</string>
+    <!-- no translation found for shortcuts_menu_with_notifications_description (2676582286544232849) -->
+    <skip />
     <string name="action_dismiss_notification" msgid="5909461085055959187">"አሰናብት"</string>
     <string name="notification_dismissed" msgid="6002233469409822874">"ማሳወቂያ ተሰናብቷል"</string>
     <string name="all_apps_personal_tab" msgid="4190252696685155002">"የግል"</string>
diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml
index 9962bd7..c094c3a 100644
--- a/res/values-ar/strings.xml
+++ b/res/values-ar/strings.xml
@@ -30,7 +30,7 @@
     <string name="home_screen" msgid="806512411299847073">"الشاشة الرئيسية"</string>
     <string name="custom_actions" msgid="3747508247759093328">"الإجراءات المخصّصة"</string>
     <string name="long_press_widget_to_add" msgid="7699152356777458215">"المس مع الاستمرار لاختيار إحدى الأدوات."</string>
-    <string name="long_accessible_way_to_add" msgid="4289502106628154155">"انقر نقرًا مزدوجًا مع الاستمرار لاختيار أداة أو استخدم الإجراءات المخصصة."</string>
+    <string name="long_accessible_way_to_add" msgid="4289502106628154155">"انقر مرّتين مع الاستمرار لاختيار أداة أو استخدم الإجراءات المخصصة."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"‏العرض %1$d الطول %2$d"</string>
     <string name="add_item_request_drag_hint" msgid="5899764264480397019">"انقر مع الاستمرار لإضافة العنصر يدويًا"</string>
@@ -41,7 +41,7 @@
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"البحث عن مزيد من التطبيقات"</string>
     <string name="notifications_header" msgid="1404149926117359025">"الإشعارات"</string>
     <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"انقر مع الاستمرار لاختيار اختصار."</string>
-    <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"يمكنك النقر نقرًا مزدوجًا مع الاستمرار لاختيار اختصار أو استخدام الإجراءات المخصصة."</string>
+    <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"يمكنك النقر مرّتين مع الاستمرار لاختيار اختصار أو استخدام الإجراءات المخصصة."</string>
     <string name="out_of_space" msgid="4691004494942118364">"ليس هناك مساحة أخرى في هذه الشاشة الرئيسية."</string>
     <string name="hotseat_out_of_space" msgid="7448809638125333693">"لا يوجد المزيد من الحقول في علبة المفضلة"</string>
     <string name="all_apps_button_label" msgid="8130441508702294465">"قائمة التطبيقات"</string>
@@ -134,8 +134,8 @@
     <string name="action_decrease_height" msgid="282377193880900022">"تقليل الارتفاع"</string>
     <string name="widget_resized" msgid="9130327887929620">"تم تغيير حجم الأداة إلى العرض <xliff:g id="NUMBER_0">%1$s</xliff:g> والارتفاع <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
     <string name="action_deep_shortcut" msgid="2864038805849372848">"الاختصارات"</string>
-    <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> اختصار لتطبيق <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
-    <string name="shortcuts_menu_with_notifications_description" msgid="8985659504915468840">"هناك <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> اختصار و<xliff:g id="NUMBER_OF_NOTIFICATIONS">%2$d</xliff:g> إشعار عن <xliff:g id="APP_NAME">%3$s</xliff:g>"</string>
+    <!-- no translation found for shortcuts_menu_with_notifications_description (2676582286544232849) -->
+    <skip />
     <string name="action_dismiss_notification" msgid="5909461085055959187">"تجاهل"</string>
     <string name="notification_dismissed" msgid="6002233469409822874">"تم تجاهل الإشعار"</string>
     <string name="all_apps_personal_tab" msgid="4190252696685155002">"شخصية"</string>
diff --git a/res/values-as/strings.xml b/res/values-as/strings.xml
index 6f45c10..41deec3 100644
--- a/res/values-as/strings.xml
+++ b/res/values-as/strings.xml
@@ -130,8 +130,8 @@
     <string name="action_decrease_height" msgid="282377193880900022">"উচ্চতা হ্ৰাস কৰক"</string>
     <string name="widget_resized" msgid="9130327887929620">"ৱিজেটৰ আকাৰ সলনি কৰি প্ৰস্থ <xliff:g id="NUMBER_0">%1$s</xliff:g> আৰু উচ্চতা <xliff:g id="NUMBER_1">%2$s</xliff:g> কৰা হ\'ল"</string>
     <string name="action_deep_shortcut" msgid="2864038805849372848">"শ্বৰ্টকাটসমূহ"</string>
-    <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="APP_NAME">%2$s</xliff:g>ৰ <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g>টা শ্বৰ্টকাট"</string>
-    <string name="shortcuts_menu_with_notifications_description" msgid="8985659504915468840">"<xliff:g id="APP_NAME">%3$s</xliff:g>ৰ <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g>টা শ্বৰ্টকাট আৰু <xliff:g id="NUMBER_OF_NOTIFICATIONS">%2$d</xliff:g>টা জাননী"</string>
+    <!-- no translation found for shortcuts_menu_with_notifications_description (2676582286544232849) -->
+    <skip />
     <string name="action_dismiss_notification" msgid="5909461085055959187">"অগ্ৰাহ্য কৰক"</string>
     <string name="notification_dismissed" msgid="6002233469409822874">"জাননী অগ্ৰাহ্য কৰা হৈছে"</string>
     <string name="all_apps_personal_tab" msgid="4190252696685155002">"ব্যক্তিগত"</string>
diff --git a/res/values-az/strings.xml b/res/values-az/strings.xml
index ed86f91..dd0f022 100644
--- a/res/values-az/strings.xml
+++ b/res/values-az/strings.xml
@@ -130,8 +130,8 @@
     <string name="action_decrease_height" msgid="282377193880900022">"Hündürlüyü azaldın"</string>
     <string name="widget_resized" msgid="9130327887929620">"Vidcetin eni <xliff:g id="NUMBER_0">%1$s</xliff:g> hündürlüyü <xliff:g id="NUMBER_1">%2$s</xliff:g> kimi ölçüləndirildi"</string>
     <string name="action_deep_shortcut" msgid="2864038805849372848">"Qısa yollar"</string>
-    <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> üçün <xliff:g id="APP_NAME">%2$s</xliff:g> qısa yolu"</string>
-    <string name="shortcuts_menu_with_notifications_description" msgid="8985659504915468840">"<xliff:g id="APP_NAME">%3$s</xliff:g> üçün <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> qısayol və  <xliff:g id="NUMBER_OF_NOTIFICATIONS">%2$d</xliff:g> bildiriş"</string>
+    <!-- no translation found for shortcuts_menu_with_notifications_description (2676582286544232849) -->
+    <skip />
     <string name="action_dismiss_notification" msgid="5909461085055959187">"Rədd edin"</string>
     <string name="notification_dismissed" msgid="6002233469409822874">"Bildiriş rədd edildi"</string>
     <string name="all_apps_personal_tab" msgid="4190252696685155002">"Şəxsi"</string>
diff --git a/res/values-b+sr+Latn/strings.xml b/res/values-b+sr+Latn/strings.xml
index b06178e..9a2062f 100644
--- a/res/values-b+sr+Latn/strings.xml
+++ b/res/values-b+sr+Latn/strings.xml
@@ -131,8 +131,8 @@
     <string name="action_decrease_height" msgid="282377193880900022">"Smanji visinu"</string>
     <string name="widget_resized" msgid="9130327887929620">"Veličina vidžeta je promenjena na širinu <xliff:g id="NUMBER_0">%1$s</xliff:g> i visinu <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
     <string name="action_deep_shortcut" msgid="2864038805849372848">"Prečice"</string>
-    <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> prečice(a) za <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
-    <string name="shortcuts_menu_with_notifications_description" msgid="8985659504915468840">"Prečice (<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g>) i obaveštenja (<xliff:g id="NUMBER_OF_NOTIFICATIONS">%2$d</xliff:g>) za <xliff:g id="APP_NAME">%3$s</xliff:g>"</string>
+    <!-- no translation found for shortcuts_menu_with_notifications_description (2676582286544232849) -->
+    <skip />
     <string name="action_dismiss_notification" msgid="5909461085055959187">"Odbaci"</string>
     <string name="notification_dismissed" msgid="6002233469409822874">"Obaveštenje je odbačeno"</string>
     <string name="all_apps_personal_tab" msgid="4190252696685155002">"Lične"</string>
diff --git a/res/values-be/strings.xml b/res/values-be/strings.xml
index 399ae76..ea312e7 100644
--- a/res/values-be/strings.xml
+++ b/res/values-be/strings.xml
@@ -132,8 +132,8 @@
     <string name="action_decrease_height" msgid="282377193880900022">"Паменшыць вышыню"</string>
     <string name="widget_resized" msgid="9130327887929620">"Памеры віджэта зменены на: шырыня <xliff:g id="NUMBER_0">%1$s</xliff:g>, вышыня <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
     <string name="action_deep_shortcut" msgid="2864038805849372848">"Ярлыкі"</string>
-    <string name="shortcuts_menu_description" msgid="406159963824238648">"Ярлыкі (<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g>) для <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
-    <string name="shortcuts_menu_with_notifications_description" msgid="8985659504915468840">"Ярлыкі (<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g>) і апавяшчэнні (<xliff:g id="NUMBER_OF_NOTIFICATIONS">%2$d</xliff:g>) для <xliff:g id="APP_NAME">%3$s</xliff:g>"</string>
+    <!-- no translation found for shortcuts_menu_with_notifications_description (2676582286544232849) -->
+    <skip />
     <string name="action_dismiss_notification" msgid="5909461085055959187">"Адхіліць"</string>
     <string name="notification_dismissed" msgid="6002233469409822874">"Апавяшчэнне адхілена"</string>
     <string name="all_apps_personal_tab" msgid="4190252696685155002">"Асабістыя"</string>
diff --git a/res/values-bg/strings.xml b/res/values-bg/strings.xml
index 4eb109a..9200049 100644
--- a/res/values-bg/strings.xml
+++ b/res/values-bg/strings.xml
@@ -130,8 +130,8 @@
     <string name="action_decrease_height" msgid="282377193880900022">"Намаляване на височината"</string>
     <string name="widget_resized" msgid="9130327887929620">"Приспособлението е преоразмерено към ширина <xliff:g id="NUMBER_0">%1$s</xliff:g> и височина <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
     <string name="action_deep_shortcut" msgid="2864038805849372848">"Преки пътища"</string>
-    <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> преки пътища за <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
-    <string name="shortcuts_menu_with_notifications_description" msgid="8985659504915468840">"<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> преки пътища и <xliff:g id="NUMBER_OF_NOTIFICATIONS">%2$d</xliff:g> известия за <xliff:g id="APP_NAME">%3$s</xliff:g>"</string>
+    <!-- no translation found for shortcuts_menu_with_notifications_description (2676582286544232849) -->
+    <skip />
     <string name="action_dismiss_notification" msgid="5909461085055959187">"Отхвърляне"</string>
     <string name="notification_dismissed" msgid="6002233469409822874">"Известието е отхвърлено"</string>
     <string name="all_apps_personal_tab" msgid="4190252696685155002">"Лични"</string>
diff --git a/res/values-bn/strings.xml b/res/values-bn/strings.xml
index ffeeed7..b11fae9 100644
--- a/res/values-bn/strings.xml
+++ b/res/values-bn/strings.xml
@@ -130,8 +130,8 @@
     <string name="action_decrease_height" msgid="282377193880900022">"উচ্চতা কমান"</string>
     <string name="widget_resized" msgid="9130327887929620">"উইজেটের আকার প্রস্থ <xliff:g id="NUMBER_0">%1$s</xliff:g> উচ্চতা <xliff:g id="NUMBER_1">%2$s</xliff:g> তে পরিবর্তন করা হয়েছে"</string>
     <string name="action_deep_shortcut" msgid="2864038805849372848">"শর্টকাট"</string>
-    <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="APP_NAME">%2$s</xliff:g> এর <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g>টি শর্টকার্ট"</string>
-    <string name="shortcuts_menu_with_notifications_description" msgid="8985659504915468840">"<xliff:g id="APP_NAME">%3$s</xliff:g> এর জন্য <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g>টি শর্টকাট এবং <xliff:g id="NUMBER_OF_NOTIFICATIONS">%2$d</xliff:g>টি বিজ্ঞপ্তি"</string>
+    <!-- no translation found for shortcuts_menu_with_notifications_description (2676582286544232849) -->
+    <skip />
     <string name="action_dismiss_notification" msgid="5909461085055959187">"খারিজ করুন"</string>
     <string name="notification_dismissed" msgid="6002233469409822874">"বিজ্ঞপ্তি খারিজ করা হয়েছে"</string>
     <string name="all_apps_personal_tab" msgid="4190252696685155002">"ব্যক্তিগত"</string>
diff --git a/res/values-bs/strings.xml b/res/values-bs/strings.xml
index 40c8866..94d3ca0 100644
--- a/res/values-bs/strings.xml
+++ b/res/values-bs/strings.xml
@@ -131,8 +131,8 @@
     <string name="action_decrease_height" msgid="282377193880900022">"Smanji visinu"</string>
     <string name="widget_resized" msgid="9130327887929620">"Veličina vidžeta je promijenjena na širinu <xliff:g id="NUMBER_0">%1$s</xliff:g> visinu <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
     <string name="action_deep_shortcut" msgid="2864038805849372848">"Prečice"</string>
-    <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> prečica za aplikaciju <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
-    <string name="shortcuts_menu_with_notifications_description" msgid="8985659504915468840">"Za aplikaciju <xliff:g id="APP_NAME">%3$s</xliff:g> broj prečica je <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g>, a broj obavještenja je <xliff:g id="NUMBER_OF_NOTIFICATIONS">%2$d</xliff:g>"</string>
+    <!-- no translation found for shortcuts_menu_with_notifications_description (2676582286544232849) -->
+    <skip />
     <string name="action_dismiss_notification" msgid="5909461085055959187">"Odbaci"</string>
     <string name="notification_dismissed" msgid="6002233469409822874">"Obavještenje je odbačeno"</string>
     <string name="all_apps_personal_tab" msgid="4190252696685155002">"Lične"</string>
diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml
index 2041319..2364e72 100644
--- a/res/values-ca/strings.xml
+++ b/res/values-ca/strings.xml
@@ -130,8 +130,8 @@
     <string name="action_decrease_height" msgid="282377193880900022">"Redueix l\'alçada"</string>
     <string name="widget_resized" msgid="9130327887929620">"S\'ha canviat la mida del widget a l\'amplada <xliff:g id="NUMBER_0">%1$s</xliff:g> i l\'alçada <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
     <string name="action_deep_shortcut" msgid="2864038805849372848">"Dreceres"</string>
-    <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> dreceres per a l\'aplicació <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
-    <string name="shortcuts_menu_with_notifications_description" msgid="8985659504915468840">"<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> dreceres i <xliff:g id="NUMBER_OF_NOTIFICATIONS">%2$d</xliff:g> notificacions per a <xliff:g id="APP_NAME">%3$s</xliff:g>"</string>
+    <!-- no translation found for shortcuts_menu_with_notifications_description (2676582286544232849) -->
+    <skip />
     <string name="action_dismiss_notification" msgid="5909461085055959187">"Ignora"</string>
     <string name="notification_dismissed" msgid="6002233469409822874">"S\'ha ignorat la notificació"</string>
     <string name="all_apps_personal_tab" msgid="4190252696685155002">"Personal"</string>
diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml
index 7f1a4c6..f84e437 100644
--- a/res/values-cs/strings.xml
+++ b/res/values-cs/strings.xml
@@ -132,8 +132,8 @@
     <string name="action_decrease_height" msgid="282377193880900022">"Snížit výšku"</string>
     <string name="widget_resized" msgid="9130327887929620">"Velikost widgetu upravena: šířka <xliff:g id="NUMBER_0">%1$s</xliff:g>, výška <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
     <string name="action_deep_shortcut" msgid="2864038805849372848">"Zkratky"</string>
-    <string name="shortcuts_menu_description" msgid="406159963824238648">"Počet zkratek pro aplikaci <xliff:g id="APP_NAME">%2$s</xliff:g>: <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g>"</string>
-    <string name="shortcuts_menu_with_notifications_description" msgid="8985659504915468840">"Zkratky (<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g>) a oznámení (<xliff:g id="NUMBER_OF_NOTIFICATIONS">%2$d</xliff:g>) aplikace <xliff:g id="APP_NAME">%3$s</xliff:g>"</string>
+    <!-- no translation found for shortcuts_menu_with_notifications_description (2676582286544232849) -->
+    <skip />
     <string name="action_dismiss_notification" msgid="5909461085055959187">"Zavřít"</string>
     <string name="notification_dismissed" msgid="6002233469409822874">"Oznámení bylo zavřeno"</string>
     <string name="all_apps_personal_tab" msgid="4190252696685155002">"Osobní"</string>
diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml
index cff300c..1d6984c 100644
--- a/res/values-da/strings.xml
+++ b/res/values-da/strings.xml
@@ -130,8 +130,8 @@
     <string name="action_decrease_height" msgid="282377193880900022">"Reducer højden"</string>
     <string name="widget_resized" msgid="9130327887929620">"Størrelsen for widgetten er ændret til bredde <xliff:g id="NUMBER_0">%1$s</xliff:g> og højde <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
     <string name="action_deep_shortcut" msgid="2864038805849372848">"Genveje"</string>
-    <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> genveje til <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
-    <string name="shortcuts_menu_with_notifications_description" msgid="8985659504915468840">"<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> genveje og <xliff:g id="NUMBER_OF_NOTIFICATIONS">%2$d</xliff:g> underretninger for <xliff:g id="APP_NAME">%3$s</xliff:g>"</string>
+    <!-- no translation found for shortcuts_menu_with_notifications_description (2676582286544232849) -->
+    <skip />
     <string name="action_dismiss_notification" msgid="5909461085055959187">"Afvis"</string>
     <string name="notification_dismissed" msgid="6002233469409822874">"Underretningen blev afvist"</string>
     <string name="all_apps_personal_tab" msgid="4190252696685155002">"Personlige"</string>
diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml
index 2ee7c11..af07f1c 100644
--- a/res/values-de/strings.xml
+++ b/res/values-de/strings.xml
@@ -130,8 +130,8 @@
     <string name="action_decrease_height" msgid="282377193880900022">"Höhe verringern"</string>
     <string name="widget_resized" msgid="9130327887929620">"Größe des Widgets zu Breite <xliff:g id="NUMBER_0">%1$s</xliff:g> und Höhe <xliff:g id="NUMBER_1">%2$s</xliff:g> geändert"</string>
     <string name="action_deep_shortcut" msgid="2864038805849372848">"Verknüpfungen"</string>
-    <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> Verknüpfungen für <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
-    <string name="shortcuts_menu_with_notifications_description" msgid="8985659504915468840">"<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> Verknüpfungen und <xliff:g id="NUMBER_OF_NOTIFICATIONS">%2$d</xliff:g> Benachrichtigungen für <xliff:g id="APP_NAME">%3$s</xliff:g>"</string>
+    <!-- no translation found for shortcuts_menu_with_notifications_description (2676582286544232849) -->
+    <skip />
     <string name="action_dismiss_notification" msgid="5909461085055959187">"Schließen"</string>
     <string name="notification_dismissed" msgid="6002233469409822874">"Benachrichtigung geschlossen"</string>
     <string name="all_apps_personal_tab" msgid="4190252696685155002">"Privat"</string>
diff --git a/res/values-el/strings.xml b/res/values-el/strings.xml
index db9ac80..3de0aaf 100644
--- a/res/values-el/strings.xml
+++ b/res/values-el/strings.xml
@@ -130,8 +130,8 @@
     <string name="action_decrease_height" msgid="282377193880900022">"Μείωση του ύψους"</string>
     <string name="widget_resized" msgid="9130327887929620">"Έγινε προσαρμογή του μεγέθους του γραφικού στοιχείου σε <xliff:g id="NUMBER_0">%1$s</xliff:g> πλάτος και <xliff:g id="NUMBER_1">%2$s</xliff:g> ύψος"</string>
     <string name="action_deep_shortcut" msgid="2864038805849372848">"Συντομεύσεις"</string>
-    <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> συντομεύσεις για <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
-    <string name="shortcuts_menu_with_notifications_description" msgid="8985659504915468840">"<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> συντομεύσεις και <xliff:g id="NUMBER_OF_NOTIFICATIONS">%2$d</xliff:g> ειδοποιήσεις για την εφαρμογή <xliff:g id="APP_NAME">%3$s</xliff:g>"</string>
+    <!-- no translation found for shortcuts_menu_with_notifications_description (2676582286544232849) -->
+    <skip />
     <string name="action_dismiss_notification" msgid="5909461085055959187">"Παράβλεψη"</string>
     <string name="notification_dismissed" msgid="6002233469409822874">"Η ειδοποίηση παραβλέφθηκε"</string>
     <string name="all_apps_personal_tab" msgid="4190252696685155002">"Προσωπικές"</string>
diff --git a/res/values-es-rUS/strings.xml b/res/values-es-rUS/strings.xml
index 7ee1bdd..f991da7 100644
--- a/res/values-es-rUS/strings.xml
+++ b/res/values-es-rUS/strings.xml
@@ -130,8 +130,8 @@
     <string name="action_decrease_height" msgid="282377193880900022">"Reducir la altura"</string>
     <string name="widget_resized" msgid="9130327887929620">"Se cambió la dimensión del widget a <xliff:g id="NUMBER_0">%1$s</xliff:g> de ancho y <xliff:g id="NUMBER_1">%2$s</xliff:g> de alto."</string>
     <string name="action_deep_shortcut" msgid="2864038805849372848">"Accesos directos"</string>
-    <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> accesos directos para <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
-    <string name="shortcuts_menu_with_notifications_description" msgid="8985659504915468840">"<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> accesos directos y <xliff:g id="NUMBER_OF_NOTIFICATIONS">%2$d</xliff:g> notificaciones de <xliff:g id="APP_NAME">%3$s</xliff:g>"</string>
+    <!-- no translation found for shortcuts_menu_with_notifications_description (2676582286544232849) -->
+    <skip />
     <string name="action_dismiss_notification" msgid="5909461085055959187">"Descartar"</string>
     <string name="notification_dismissed" msgid="6002233469409822874">"Se descartó la notificación"</string>
     <string name="all_apps_personal_tab" msgid="4190252696685155002">"Personales"</string>
diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml
index aa30967..1dbe8e9 100644
--- a/res/values-es/strings.xml
+++ b/res/values-es/strings.xml
@@ -85,7 +85,7 @@
     <string name="allow_rotation_desc" msgid="8662546029078692509">"Al girar el teléfono"</string>
     <string name="icon_badging_title" msgid="874121399231955394">"Burbujas de notificación"</string>
     <string name="icon_badging_desc_on" msgid="2627952638544674079">"Activado"</string>
-    <string name="icon_badging_desc_off" msgid="5503319969924580241">"Desactivada"</string>
+    <string name="icon_badging_desc_off" msgid="5503319969924580241">"Desactivado"</string>
     <string name="title_missing_notification_access" msgid="7503287056163941064">"Se necesita acceso a las notificaciones"</string>
     <string name="msg_missing_notification_access" msgid="281113995110910548">"Para mostrar burbujas de notificación, activa las notificaciones de <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="title_change_settings" msgid="1376365968844349552">"Cambiar ajustes"</string>
@@ -130,8 +130,8 @@
     <string name="action_decrease_height" msgid="282377193880900022">"Reducir altura"</string>
     <string name="widget_resized" msgid="9130327887929620">"Se ha modificado el tamaño del widget a <xliff:g id="NUMBER_0">%1$s</xliff:g> de ancho y <xliff:g id="NUMBER_1">%2$s</xliff:g> de alto"</string>
     <string name="action_deep_shortcut" msgid="2864038805849372848">"Accesos directos"</string>
-    <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> accesos directos de <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
-    <string name="shortcuts_menu_with_notifications_description" msgid="8985659504915468840">"<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> accesos directos y <xliff:g id="NUMBER_OF_NOTIFICATIONS">%2$d</xliff:g> notificaciones de <xliff:g id="APP_NAME">%3$s</xliff:g>"</string>
+    <!-- no translation found for shortcuts_menu_with_notifications_description (2676582286544232849) -->
+    <skip />
     <string name="action_dismiss_notification" msgid="5909461085055959187">"Ignorar"</string>
     <string name="notification_dismissed" msgid="6002233469409822874">"Notificación ignorada"</string>
     <string name="all_apps_personal_tab" msgid="4190252696685155002">"Personal"</string>
diff --git a/res/values-et/strings.xml b/res/values-et/strings.xml
index 1bde8aa..94b0103 100644
--- a/res/values-et/strings.xml
+++ b/res/values-et/strings.xml
@@ -130,8 +130,8 @@
     <string name="action_decrease_height" msgid="282377193880900022">"Vähenda kõrgust"</string>
     <string name="widget_resized" msgid="9130327887929620">"Vidina suurust muudeti. Laius: <xliff:g id="NUMBER_0">%1$s</xliff:g>. Kõrgus: <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
     <string name="action_deep_shortcut" msgid="2864038805849372848">"Otseteed"</string>
-    <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> otseteed rakenduse <xliff:g id="APP_NAME">%2$s</xliff:g> jaoks"</string>
-    <string name="shortcuts_menu_with_notifications_description" msgid="8985659504915468840">"<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> otseteed ja <xliff:g id="NUMBER_OF_NOTIFICATIONS">%2$d</xliff:g> märguannet rakendusele <xliff:g id="APP_NAME">%3$s</xliff:g>"</string>
+    <!-- no translation found for shortcuts_menu_with_notifications_description (2676582286544232849) -->
+    <skip />
     <string name="action_dismiss_notification" msgid="5909461085055959187">"Loobu"</string>
     <string name="notification_dismissed" msgid="6002233469409822874">"Märguandest loobuti"</string>
     <string name="all_apps_personal_tab" msgid="4190252696685155002">"Isiklik"</string>
diff --git a/res/values-eu/strings.xml b/res/values-eu/strings.xml
index 128c6f4..a13c493 100644
--- a/res/values-eu/strings.xml
+++ b/res/values-eu/strings.xml
@@ -130,8 +130,8 @@
     <string name="action_decrease_height" msgid="282377193880900022">"Txikitu altuera"</string>
     <string name="widget_resized" msgid="9130327887929620">"Aldatu da widgetaren tamaina. Zabalera: <xliff:g id="NUMBER_0">%1$s</xliff:g>. Altuera: <xliff:g id="NUMBER_1">%2$s</xliff:g>."</string>
     <string name="action_deep_shortcut" msgid="2864038805849372848">"Lasterbideak"</string>
-    <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="APP_NAME">%2$s</xliff:g> aplikazioaren <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> lasterbide"</string>
-    <string name="shortcuts_menu_with_notifications_description" msgid="8985659504915468840">"<xliff:g id="APP_NAME">%3$s</xliff:g> aplikazioaren <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> lasterbide eta <xliff:g id="NUMBER_OF_NOTIFICATIONS">%2$d</xliff:g> jakinarazpen"</string>
+    <!-- no translation found for shortcuts_menu_with_notifications_description (2676582286544232849) -->
+    <skip />
     <string name="action_dismiss_notification" msgid="5909461085055959187">"Baztertu"</string>
     <string name="notification_dismissed" msgid="6002233469409822874">"Baztertu egin da jakinarazpena"</string>
     <string name="all_apps_personal_tab" msgid="4190252696685155002">"Pertsonalak"</string>
diff --git a/res/values-fa/strings.xml b/res/values-fa/strings.xml
index c301752..da12ebe 100644
--- a/res/values-fa/strings.xml
+++ b/res/values-fa/strings.xml
@@ -130,8 +130,8 @@
     <string name="action_decrease_height" msgid="282377193880900022">"کاهش ارتفاع"</string>
     <string name="widget_resized" msgid="9130327887929620">"اندازه ابزارک به عرض <xliff:g id="NUMBER_0">%1$s</xliff:g> ارتفاع <xliff:g id="NUMBER_1">%2$s</xliff:g> تغییر کرد"</string>
     <string name="action_deep_shortcut" msgid="2864038805849372848">"میان‌برها"</string>
-    <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> میانبر برای <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
-    <string name="shortcuts_menu_with_notifications_description" msgid="8985659504915468840">"<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> میان‌بر و <xliff:g id="NUMBER_OF_NOTIFICATIONS">%2$d</xliff:g> اعلان برای <xliff:g id="APP_NAME">%3$s</xliff:g>"</string>
+    <!-- no translation found for shortcuts_menu_with_notifications_description (2676582286544232849) -->
+    <skip />
     <string name="action_dismiss_notification" msgid="5909461085055959187">"رد کردن"</string>
     <string name="notification_dismissed" msgid="6002233469409822874">"اعلان رد شد"</string>
     <string name="all_apps_personal_tab" msgid="4190252696685155002">"شخصی"</string>
diff --git a/res/values-fi/strings.xml b/res/values-fi/strings.xml
index 6b568f6..96214d3 100644
--- a/res/values-fi/strings.xml
+++ b/res/values-fi/strings.xml
@@ -130,8 +130,8 @@
     <string name="action_decrease_height" msgid="282377193880900022">"Vähennä korkeutta"</string>
     <string name="widget_resized" msgid="9130327887929620">"Widgetin kokoa muutettiin. Sen leveys on nyt <xliff:g id="NUMBER_0">%1$s</xliff:g> ja korkeus <xliff:g id="NUMBER_1">%2$s</xliff:g>."</string>
     <string name="action_deep_shortcut" msgid="2864038805849372848">"Pikakuvakkeet"</string>
-    <string name="shortcuts_menu_description" msgid="406159963824238648">"Sovelluksella <xliff:g id="APP_NAME">%2$s</xliff:g> on <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> pikakuvaketta."</string>
-    <string name="shortcuts_menu_with_notifications_description" msgid="8985659504915468840">"<xliff:g id="APP_NAME">%3$s</xliff:g>: <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> pikakuvaketta ja <xliff:g id="NUMBER_OF_NOTIFICATIONS">%2$d</xliff:g> ilmoitusta"</string>
+    <!-- no translation found for shortcuts_menu_with_notifications_description (2676582286544232849) -->
+    <skip />
     <string name="action_dismiss_notification" msgid="5909461085055959187">"Hylkää"</string>
     <string name="notification_dismissed" msgid="6002233469409822874">"Ilmoitus hylätty"</string>
     <string name="all_apps_personal_tab" msgid="4190252696685155002">"Henkilökohtaiset"</string>
diff --git a/res/values-fr-rCA/strings.xml b/res/values-fr-rCA/strings.xml
index cef238c..aebb42d 100644
--- a/res/values-fr-rCA/strings.xml
+++ b/res/values-fr-rCA/strings.xml
@@ -130,8 +130,8 @@
     <string name="action_decrease_height" msgid="282377193880900022">"Diminuer la hauteur"</string>
     <string name="widget_resized" msgid="9130327887929620">"Le widget a été redimensionné (largeur : <xliff:g id="NUMBER_0">%1$s</xliff:g>, hauteur : <xliff:g id="NUMBER_1">%2$s</xliff:g>)"</string>
     <string name="action_deep_shortcut" msgid="2864038805849372848">"Raccourcis"</string>
-    <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> raccourcis pour <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
-    <string name="shortcuts_menu_with_notifications_description" msgid="8985659504915468840">"<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> raccourcis et <xliff:g id="NUMBER_OF_NOTIFICATIONS">%2$d</xliff:g> notifications pour <xliff:g id="APP_NAME">%3$s</xliff:g>"</string>
+    <!-- no translation found for shortcuts_menu_with_notifications_description (2676582286544232849) -->
+    <skip />
     <string name="action_dismiss_notification" msgid="5909461085055959187">"Ignorer"</string>
     <string name="notification_dismissed" msgid="6002233469409822874">"Notification ignorée"</string>
     <string name="all_apps_personal_tab" msgid="4190252696685155002">"Personnel"</string>
diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml
index 0e6ae57..6c5c120 100644
--- a/res/values-fr/strings.xml
+++ b/res/values-fr/strings.xml
@@ -130,8 +130,8 @@
     <string name="action_decrease_height" msgid="282377193880900022">"Diminuer la hauteur"</string>
     <string name="widget_resized" msgid="9130327887929620">"Le widget a bien été redimensionné (largeur : <xliff:g id="NUMBER_0">%1$s</xliff:g>, hauteur : <xliff:g id="NUMBER_1">%2$s</xliff:g>)."</string>
     <string name="action_deep_shortcut" msgid="2864038805849372848">"Raccourcis"</string>
-    <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> raccourcis pour <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
-    <string name="shortcuts_menu_with_notifications_description" msgid="8985659504915468840">"<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> raccourcis et <xliff:g id="NUMBER_OF_NOTIFICATIONS">%2$d</xliff:g> notifications pour <xliff:g id="APP_NAME">%3$s</xliff:g>"</string>
+    <!-- no translation found for shortcuts_menu_with_notifications_description (2676582286544232849) -->
+    <skip />
     <string name="action_dismiss_notification" msgid="5909461085055959187">"Ignorer"</string>
     <string name="notification_dismissed" msgid="6002233469409822874">"Notification ignorée"</string>
     <string name="all_apps_personal_tab" msgid="4190252696685155002">"Personnelles"</string>
diff --git a/res/values-gl/strings.xml b/res/values-gl/strings.xml
index 1efa5ce..4dd7ae7 100644
--- a/res/values-gl/strings.xml
+++ b/res/values-gl/strings.xml
@@ -130,8 +130,8 @@
     <string name="action_decrease_height" msgid="282377193880900022">"Reducir altura"</string>
     <string name="widget_resized" msgid="9130327887929620">"Cambiouse o tamaño do widget polo ancho <xliff:g id="NUMBER_0">%1$s</xliff:g> e a altura <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
     <string name="action_deep_shortcut" msgid="2864038805849372848">"Atallos"</string>
-    <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> atallos para <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
-    <string name="shortcuts_menu_with_notifications_description" msgid="8985659504915468840">"<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> atallos e <xliff:g id="NUMBER_OF_NOTIFICATIONS">%2$d</xliff:g> notificacións para a aplicación <xliff:g id="APP_NAME">%3$s</xliff:g>"</string>
+    <!-- no translation found for shortcuts_menu_with_notifications_description (2676582286544232849) -->
+    <skip />
     <string name="action_dismiss_notification" msgid="5909461085055959187">"Ignorar"</string>
     <string name="notification_dismissed" msgid="6002233469409822874">"Ignorouse a notificación"</string>
     <string name="all_apps_personal_tab" msgid="4190252696685155002">"Persoal"</string>
diff --git a/res/values-gu/strings.xml b/res/values-gu/strings.xml
index 234fada..aa0b3af 100644
--- a/res/values-gu/strings.xml
+++ b/res/values-gu/strings.xml
@@ -130,8 +130,8 @@
     <string name="action_decrease_height" msgid="282377193880900022">"ઊંચાઈ ઘટાડો"</string>
     <string name="widget_resized" msgid="9130327887929620">"વિજેટનો આકાર બદલીને <xliff:g id="NUMBER_0">%1$s</xliff:g> પહોળાઈ <xliff:g id="NUMBER_1">%2$s</xliff:g> ઊંચાઈ કર્યો"</string>
     <string name="action_deep_shortcut" msgid="2864038805849372848">"શૉર્ટકટ્સ"</string>
-    <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="APP_NAME">%2$s</xliff:g> માટે <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> શૉર્ટકટ"</string>
-    <string name="shortcuts_menu_with_notifications_description" msgid="8985659504915468840">"<xliff:g id="APP_NAME">%3$s</xliff:g> માટે <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> શૉર્ટકટ અને <xliff:g id="NUMBER_OF_NOTIFICATIONS">%2$d</xliff:g> સૂચનાઓ"</string>
+    <!-- no translation found for shortcuts_menu_with_notifications_description (2676582286544232849) -->
+    <skip />
     <string name="action_dismiss_notification" msgid="5909461085055959187">"છોડી દો"</string>
     <string name="notification_dismissed" msgid="6002233469409822874">"સૂચના છોડી દીધી"</string>
     <string name="all_apps_personal_tab" msgid="4190252696685155002">"મનગમતી ઍપ"</string>
diff --git a/res/values-hi/strings.xml b/res/values-hi/strings.xml
index e4f4dfe..1b47fcb 100644
--- a/res/values-hi/strings.xml
+++ b/res/values-hi/strings.xml
@@ -130,8 +130,8 @@
     <string name="action_decrease_height" msgid="282377193880900022">"ऊंचाई घटाएं"</string>
     <string name="widget_resized" msgid="9130327887929620">"विजेट का आकार बदलकर उसकी चौड़ाई <xliff:g id="NUMBER_0">%1$s</xliff:g> और ऊंचाई <xliff:g id="NUMBER_1">%2$s</xliff:g> कर दी गई"</string>
     <string name="action_deep_shortcut" msgid="2864038805849372848">"शॉर्टकट"</string>
-    <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="APP_NAME">%2$s</xliff:g> के लिए <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> शॉर्टकट"</string>
-    <string name="shortcuts_menu_with_notifications_description" msgid="8985659504915468840">"<xliff:g id="APP_NAME">%3$s</xliff:g> के लिए <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> शॉर्टकट और <xliff:g id="NUMBER_OF_NOTIFICATIONS">%2$d</xliff:g> सूचनाएं हैं"</string>
+    <!-- no translation found for shortcuts_menu_with_notifications_description (2676582286544232849) -->
+    <skip />
     <string name="action_dismiss_notification" msgid="5909461085055959187">"खारिज करें"</string>
     <string name="notification_dismissed" msgid="6002233469409822874">"सूचना को खारिज किया गया"</string>
     <string name="all_apps_personal_tab" msgid="4190252696685155002">"निजी ऐप"</string>
diff --git a/res/values-hr/strings.xml b/res/values-hr/strings.xml
index 7a8d639..077da67 100644
--- a/res/values-hr/strings.xml
+++ b/res/values-hr/strings.xml
@@ -131,8 +131,8 @@
     <string name="action_decrease_height" msgid="282377193880900022">"Smanjenje visine"</string>
     <string name="widget_resized" msgid="9130327887929620">"Širina widgeta promijenjena je na <xliff:g id="NUMBER_0">%1$s</xliff:g>, a visina na <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
     <string name="action_deep_shortcut" msgid="2864038805849372848">"Prečaci"</string>
-    <string name="shortcuts_menu_description" msgid="406159963824238648">"Prečaca za aplikaciju <xliff:g id="APP_NAME">%2$s</xliff:g>: <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g>"</string>
-    <string name="shortcuts_menu_with_notifications_description" msgid="8985659504915468840">"Za aplikaciju <xliff:g id="APP_NAME">%3$s</xliff:g> ima prečaca (ukupno <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g>) i obavijesti (ukupno <xliff:g id="NUMBER_OF_NOTIFICATIONS">%2$d</xliff:g>)"</string>
+    <!-- no translation found for shortcuts_menu_with_notifications_description (2676582286544232849) -->
+    <skip />
     <string name="action_dismiss_notification" msgid="5909461085055959187">"Odbaci"</string>
     <string name="notification_dismissed" msgid="6002233469409822874">"Obavijest je odbačena"</string>
     <string name="all_apps_personal_tab" msgid="4190252696685155002">"Osobno"</string>
diff --git a/res/values-hu/strings.xml b/res/values-hu/strings.xml
index 24b29a0..797bde4 100644
--- a/res/values-hu/strings.xml
+++ b/res/values-hu/strings.xml
@@ -130,8 +130,8 @@
     <string name="action_decrease_height" msgid="282377193880900022">"Magasság csökkentése"</string>
     <string name="widget_resized" msgid="9130327887929620">"Modul átméretezve <xliff:g id="NUMBER_0">%1$s</xliff:g> szélességre és <xliff:g id="NUMBER_1">%2$s</xliff:g> magasságra"</string>
     <string name="action_deep_shortcut" msgid="2864038805849372848">"Gyorsparancsok"</string>
-    <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> gyorsparancs a(z) <xliff:g id="APP_NAME">%2$s</xliff:g> számára"</string>
-    <string name="shortcuts_menu_with_notifications_description" msgid="8985659504915468840">"<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> parancsikon és <xliff:g id="NUMBER_OF_NOTIFICATIONS">%2$d</xliff:g> értesítés a következő alkalmazásnál: <xliff:g id="APP_NAME">%3$s</xliff:g>"</string>
+    <!-- no translation found for shortcuts_menu_with_notifications_description (2676582286544232849) -->
+    <skip />
     <string name="action_dismiss_notification" msgid="5909461085055959187">"Elvetés"</string>
     <string name="notification_dismissed" msgid="6002233469409822874">"Értesítés elvetve"</string>
     <string name="all_apps_personal_tab" msgid="4190252696685155002">"Személyes"</string>
diff --git a/res/values-hy/strings.xml b/res/values-hy/strings.xml
index 6844a27..79210f3 100644
--- a/res/values-hy/strings.xml
+++ b/res/values-hy/strings.xml
@@ -130,8 +130,8 @@
     <string name="action_decrease_height" msgid="282377193880900022">"Նվազեցնել բարձրությունը"</string>
     <string name="widget_resized" msgid="9130327887929620">"Վիջեթի լայնությունը փոխվել է <xliff:g id="NUMBER_0">%1$s</xliff:g>-ի, իսկ բարձրությունը՝ <xliff:g id="NUMBER_1">%2$s</xliff:g>-ի"</string>
     <string name="action_deep_shortcut" msgid="2864038805849372848">"Դյուրանցումներ"</string>
-    <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> դյուրանցումներ <xliff:g id="APP_NAME">%2$s</xliff:g> հավելվածի համար"</string>
-    <string name="shortcuts_menu_with_notifications_description" msgid="8985659504915468840">"<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> դյուրացում և <xliff:g id="NUMBER_OF_NOTIFICATIONS">%2$d</xliff:g> ծանուցում <xliff:g id="APP_NAME">%3$s</xliff:g>-ի համար"</string>
+    <!-- no translation found for shortcuts_menu_with_notifications_description (2676582286544232849) -->
+    <skip />
     <string name="action_dismiss_notification" msgid="5909461085055959187">"Անտեսել"</string>
     <string name="notification_dismissed" msgid="6002233469409822874">"Ծանուցումը մերժված է"</string>
     <string name="all_apps_personal_tab" msgid="4190252696685155002">"Անձնական"</string>
diff --git a/res/values-in/strings.xml b/res/values-in/strings.xml
index 457efce..6e8f46a 100644
--- a/res/values-in/strings.xml
+++ b/res/values-in/strings.xml
@@ -130,8 +130,8 @@
     <string name="action_decrease_height" msgid="282377193880900022">"Kurangi tinggi"</string>
     <string name="widget_resized" msgid="9130327887929620">"Widget diubah ukurannya menjadi lebar <xliff:g id="NUMBER_0">%1$s</xliff:g> tinggi <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
     <string name="action_deep_shortcut" msgid="2864038805849372848">"Pintasan"</string>
-    <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> pintasan untuk <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
-    <string name="shortcuts_menu_with_notifications_description" msgid="8985659504915468840">"<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> pintasan dan <xliff:g id="NUMBER_OF_NOTIFICATIONS">%2$d</xliff:g> notifikasi untuk <xliff:g id="APP_NAME">%3$s</xliff:g>"</string>
+    <!-- no translation found for shortcuts_menu_with_notifications_description (2676582286544232849) -->
+    <skip />
     <string name="action_dismiss_notification" msgid="5909461085055959187">"Tutup"</string>
     <string name="notification_dismissed" msgid="6002233469409822874">"Notifikasi ditutup"</string>
     <string name="all_apps_personal_tab" msgid="4190252696685155002">"Pribadi"</string>
diff --git a/res/values-is/strings.xml b/res/values-is/strings.xml
index 3b5daba..49843b6 100644
--- a/res/values-is/strings.xml
+++ b/res/values-is/strings.xml
@@ -130,8 +130,8 @@
     <string name="action_decrease_height" msgid="282377193880900022">"Minnka hæð"</string>
     <string name="widget_resized" msgid="9130327887929620">"Stærð græju breytt í <xliff:g id="NUMBER_0">%1$s</xliff:g> á breidd og <xliff:g id="NUMBER_1">%2$s</xliff:g> á hæð"</string>
     <string name="action_deep_shortcut" msgid="2864038805849372848">"Flýtileiðir"</string>
-    <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> flýtileiðir fyrir <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
-    <string name="shortcuts_menu_with_notifications_description" msgid="8985659504915468840">"<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> flýtileiðir og <xliff:g id="NUMBER_OF_NOTIFICATIONS">%2$d</xliff:g> tilkynningar fyrir <xliff:g id="APP_NAME">%3$s</xliff:g>"</string>
+    <!-- no translation found for shortcuts_menu_with_notifications_description (2676582286544232849) -->
+    <skip />
     <string name="action_dismiss_notification" msgid="5909461085055959187">"Hunsa"</string>
     <string name="notification_dismissed" msgid="6002233469409822874">"Tilkynningu lokað"</string>
     <string name="all_apps_personal_tab" msgid="4190252696685155002">"Persónulegt"</string>
diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml
index 5d05f91..5fc68a5 100644
--- a/res/values-it/strings.xml
+++ b/res/values-it/strings.xml
@@ -130,8 +130,8 @@
     <string name="action_decrease_height" msgid="282377193880900022">"Riduci altezza"</string>
     <string name="widget_resized" msgid="9130327887929620">"Widget ridimensionato a larghezza <xliff:g id="NUMBER_0">%1$s</xliff:g>, altezza <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
     <string name="action_deep_shortcut" msgid="2864038805849372848">"Scorciatoie"</string>
-    <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> scorciatoie per <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
-    <string name="shortcuts_menu_with_notifications_description" msgid="8985659504915468840">"<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> scorciatoie e <xliff:g id="NUMBER_OF_NOTIFICATIONS">%2$d</xliff:g> notifiche relative a <xliff:g id="APP_NAME">%3$s</xliff:g>"</string>
+    <!-- no translation found for shortcuts_menu_with_notifications_description (2676582286544232849) -->
+    <skip />
     <string name="action_dismiss_notification" msgid="5909461085055959187">"Ignora"</string>
     <string name="notification_dismissed" msgid="6002233469409822874">"Notifica ignorata"</string>
     <string name="all_apps_personal_tab" msgid="4190252696685155002">"Personali"</string>
diff --git a/res/values-iw/strings.xml b/res/values-iw/strings.xml
index ad6aec6..806aeef 100644
--- a/res/values-iw/strings.xml
+++ b/res/values-iw/strings.xml
@@ -132,8 +132,8 @@
     <string name="action_decrease_height" msgid="282377193880900022">"הקטן גובה"</string>
     <string name="widget_resized" msgid="9130327887929620">"גודל הווידג\'ט שונה - רוחב <xliff:g id="NUMBER_0">%1$s</xliff:g> גובה <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
     <string name="action_deep_shortcut" msgid="2864038805849372848">"קיצורי דרך"</string>
-    <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> קיצורי דרך עבור <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
-    <string name="shortcuts_menu_with_notifications_description" msgid="8985659504915468840">"<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> קיצורי דרך ו-<xliff:g id="NUMBER_OF_NOTIFICATIONS">%2$d</xliff:g> הודעות של <xliff:g id="APP_NAME">%3$s</xliff:g>"</string>
+    <!-- no translation found for shortcuts_menu_with_notifications_description (2676582286544232849) -->
+    <skip />
     <string name="action_dismiss_notification" msgid="5909461085055959187">"סגור"</string>
     <string name="notification_dismissed" msgid="6002233469409822874">"ההודעה נסגרה"</string>
     <string name="all_apps_personal_tab" msgid="4190252696685155002">"אישיות"</string>
diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml
index 8e3022b..baa59ab 100644
--- a/res/values-ja/strings.xml
+++ b/res/values-ja/strings.xml
@@ -130,8 +130,8 @@
     <string name="action_decrease_height" msgid="282377193880900022">"高さを低くする"</string>
     <string name="widget_resized" msgid="9130327887929620">"ウィジェットのサイズを幅<xliff:g id="NUMBER_0">%1$s</xliff:g>、高さ<xliff:g id="NUMBER_1">%2$s</xliff:g>に変更しました"</string>
     <string name="action_deep_shortcut" msgid="2864038805849372848">"ショートカット"</string>
-    <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="APP_NAME">%2$s</xliff:g>用の <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> 件のショートカット"</string>
-    <string name="shortcuts_menu_with_notifications_description" msgid="8985659504915468840">"<xliff:g id="APP_NAME">%3$s</xliff:g>: <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> 個のショートカットと <xliff:g id="NUMBER_OF_NOTIFICATIONS">%2$d</xliff:g> 件の通知"</string>
+    <!-- no translation found for shortcuts_menu_with_notifications_description (2676582286544232849) -->
+    <skip />
     <string name="action_dismiss_notification" msgid="5909461085055959187">"表示しない"</string>
     <string name="notification_dismissed" msgid="6002233469409822874">"通知を非表示にしました"</string>
     <string name="all_apps_personal_tab" msgid="4190252696685155002">"個人用"</string>
diff --git a/res/values-ka/strings.xml b/res/values-ka/strings.xml
index 521ec80..64c8573 100644
--- a/res/values-ka/strings.xml
+++ b/res/values-ka/strings.xml
@@ -130,8 +130,8 @@
     <string name="action_decrease_height" msgid="282377193880900022">"სიმაღლის შემცირება"</string>
     <string name="widget_resized" msgid="9130327887929620">"ვიჯეტის ზომები შეიცვალა: სიგანე <xliff:g id="NUMBER_0">%1$s</xliff:g> სიმაღლე <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
     <string name="action_deep_shortcut" msgid="2864038805849372848">"მალსახმობები"</string>
-    <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="APP_NAME">%2$s</xliff:g>-ს აქვს <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> მალსახმობი"</string>
-    <string name="shortcuts_menu_with_notifications_description" msgid="8985659504915468840">"<xliff:g id="APP_NAME">%3$s</xliff:g>-ის <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> მალსახმობი და <xliff:g id="NUMBER_OF_NOTIFICATIONS">%2$d</xliff:g> შეტყობინება"</string>
+    <!-- no translation found for shortcuts_menu_with_notifications_description (2676582286544232849) -->
+    <skip />
     <string name="action_dismiss_notification" msgid="5909461085055959187">"დახურვა"</string>
     <string name="notification_dismissed" msgid="6002233469409822874">"შეტყობინება დაიხურა"</string>
     <string name="all_apps_personal_tab" msgid="4190252696685155002">"პირადი"</string>
diff --git a/res/values-kk/strings.xml b/res/values-kk/strings.xml
index 7ab73d9..2ad5954 100644
--- a/res/values-kk/strings.xml
+++ b/res/values-kk/strings.xml
@@ -130,8 +130,8 @@
     <string name="action_decrease_height" msgid="282377193880900022">"Биіктігін азайту"</string>
     <string name="widget_resized" msgid="9130327887929620">"Виджет өлшемінің ені <xliff:g id="NUMBER_0">%1$s</xliff:g>, биіктігі <xliff:g id="NUMBER_1">%2$s</xliff:g> болып өзгертілді"</string>
     <string name="action_deep_shortcut" msgid="2864038805849372848">"Таңбашалар"</string>
-    <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="APP_NAME">%2$s</xliff:g> қолданбасына арналған <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> таңбаша"</string>
-    <string name="shortcuts_menu_with_notifications_description" msgid="8985659504915468840">"<xliff:g id="APP_NAME">%3$s</xliff:g> қолданбасының <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> таңбашасы мен <xliff:g id="NUMBER_OF_NOTIFICATIONS">%2$d</xliff:g> хабарландыруы"</string>
+    <!-- no translation found for shortcuts_menu_with_notifications_description (2676582286544232849) -->
+    <skip />
     <string name="action_dismiss_notification" msgid="5909461085055959187">"Бас тарту"</string>
     <string name="notification_dismissed" msgid="6002233469409822874">"Хабарландырудан бас тартылды"</string>
     <string name="all_apps_personal_tab" msgid="4190252696685155002">"Жеке"</string>
diff --git a/res/values-km/strings.xml b/res/values-km/strings.xml
index 582bb33..e3659c9 100644
--- a/res/values-km/strings.xml
+++ b/res/values-km/strings.xml
@@ -130,8 +130,8 @@
     <string name="action_decrease_height" msgid="282377193880900022">"បន្ថយកម្ពស់"</string>
     <string name="widget_resized" msgid="9130327887929620">"ធាតុក្រាហ្វិកដែលបានប្តូរទំហំទៅទទឹងប្រវែង <xliff:g id="NUMBER_0">%1$s</xliff:g> កម្ពស់ប្រវែង <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
     <string name="action_deep_shortcut" msgid="2864038805849372848">"ផ្លូវកាត់"</string>
-    <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> ផ្លូវកាត់សម្រាប់ <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
-    <string name="shortcuts_menu_with_notifications_description" msgid="8985659504915468840">"ផ្លូវកាត់ចំនួន <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> និង​ការជូនដំណឹងចំនួន <xliff:g id="NUMBER_OF_NOTIFICATIONS">%2$d</xliff:g> សម្រាប់ <xliff:g id="APP_NAME">%3$s</xliff:g>"</string>
+    <!-- no translation found for shortcuts_menu_with_notifications_description (2676582286544232849) -->
+    <skip />
     <string name="action_dismiss_notification" msgid="5909461085055959187">"បដិសេធ"</string>
     <string name="notification_dismissed" msgid="6002233469409822874">"បាន​បដិសេធ​ការជូនដំណឹង"</string>
     <string name="all_apps_personal_tab" msgid="4190252696685155002">"ផ្ទាល់ខ្លួន"</string>
diff --git a/res/values-kn/strings.xml b/res/values-kn/strings.xml
index 56ebe0a..7a68378d 100644
--- a/res/values-kn/strings.xml
+++ b/res/values-kn/strings.xml
@@ -130,8 +130,8 @@
     <string name="action_decrease_height" msgid="282377193880900022">"ಎತ್ತರವನ್ನು ಕಡಿಮೆ ಮಾಡಿ"</string>
     <string name="widget_resized" msgid="9130327887929620">"ವಿಜೆಟ್ ಅನ್ನು <xliff:g id="NUMBER_0">%1$s</xliff:g> ಅಗಲ <xliff:g id="NUMBER_1">%2$s</xliff:g> ಎತ್ತರಕ್ಕೆ ಮರುಗಾತ್ರಗೊಳಿಸಲಾಗಿದೆ"</string>
     <string name="action_deep_shortcut" msgid="2864038805849372848">"ಶಾರ್ಟ್‌ಕಟ್‌ಗಳು"</string>
-    <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="APP_NAME">%2$s</xliff:g> ಗೆ <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> ಶಾರ್ಟ್‌ಕಟ್‌ಗಳು"</string>
-    <string name="shortcuts_menu_with_notifications_description" msgid="8985659504915468840">"<xliff:g id="APP_NAME">%3$s</xliff:g> ಗಾಗಿ <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> ಶಾರ್ಟ್‌ಕಟ್‌ಗಳು ಮತ್ತು <xliff:g id="NUMBER_OF_NOTIFICATIONS">%2$d</xliff:g> ಅಧಿಸೂಚನೆಗಳು"</string>
+    <!-- no translation found for shortcuts_menu_with_notifications_description (2676582286544232849) -->
+    <skip />
     <string name="action_dismiss_notification" msgid="5909461085055959187">"ವಜಾಗೊಳಿಸಿ"</string>
     <string name="notification_dismissed" msgid="6002233469409822874">"ಅಧಿಸೂಚನೆಯನ್ನು ವಜಾಗೊಳಿಸಲಾಗಿದೆ"</string>
     <string name="all_apps_personal_tab" msgid="4190252696685155002">"ವೈಯಕ್ತಿಕ"</string>
diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml
index 4ec01d8..4a6f3fa 100644
--- a/res/values-ko/strings.xml
+++ b/res/values-ko/strings.xml
@@ -130,8 +130,8 @@
     <string name="action_decrease_height" msgid="282377193880900022">"높이 줄이기"</string>
     <string name="widget_resized" msgid="9130327887929620">"폭 <xliff:g id="NUMBER_0">%1$s</xliff:g>, 높이 <xliff:g id="NUMBER_1">%2$s</xliff:g>로 위젯 크기 조정됨"</string>
     <string name="action_deep_shortcut" msgid="2864038805849372848">"바로가기"</string>
-    <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="APP_NAME">%2$s</xliff:g>에 사용 가능한 단축키 <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g>개"</string>
-    <string name="shortcuts_menu_with_notifications_description" msgid="8985659504915468840">"바로가기 <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g>개 및 <xliff:g id="APP_NAME">%3$s</xliff:g> 알림 <xliff:g id="NUMBER_OF_NOTIFICATIONS">%2$d</xliff:g>개"</string>
+    <!-- no translation found for shortcuts_menu_with_notifications_description (2676582286544232849) -->
+    <skip />
     <string name="action_dismiss_notification" msgid="5909461085055959187">"닫기"</string>
     <string name="notification_dismissed" msgid="6002233469409822874">"알림이 해제되었습니다."</string>
     <string name="all_apps_personal_tab" msgid="4190252696685155002">"개인"</string>
diff --git a/res/values-ky/strings.xml b/res/values-ky/strings.xml
index 502a08a..ce0dc3f 100644
--- a/res/values-ky/strings.xml
+++ b/res/values-ky/strings.xml
@@ -130,8 +130,8 @@
     <string name="action_decrease_height" msgid="282377193880900022">"Жапыздатуу"</string>
     <string name="widget_resized" msgid="9130327887929620">"Виджеттин кеңдиги <xliff:g id="NUMBER_0">%1$s</xliff:g> бийиктиги <xliff:g id="NUMBER_1">%2$s</xliff:g> болду"</string>
     <string name="action_deep_shortcut" msgid="2864038805849372848">"Кыска жолдор"</string>
-    <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="APP_NAME">%2$s</xliff:g> колдонмосуна <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> кыска жол бар"</string>
-    <string name="shortcuts_menu_with_notifications_description" msgid="8985659504915468840">"<xliff:g id="APP_NAME">%3$s</xliff:g> колдонмосу үчүн <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> кыска жол жана <xliff:g id="NUMBER_OF_NOTIFICATIONS">%2$d</xliff:g> эскертме бар"</string>
+    <!-- no translation found for shortcuts_menu_with_notifications_description (2676582286544232849) -->
+    <skip />
     <string name="action_dismiss_notification" msgid="5909461085055959187">"Этибарга албоо"</string>
     <string name="notification_dismissed" msgid="6002233469409822874">"Эскертме көз жаздымда калтырылды"</string>
     <string name="all_apps_personal_tab" msgid="4190252696685155002">"Жеке колдонмолор"</string>
diff --git a/res/values-land/dimens.xml b/res/values-land/dimens.xml
index 7b52529..f002195 100644
--- a/res/values-land/dimens.xml
+++ b/res/values-land/dimens.xml
@@ -25,7 +25,6 @@
     <dimen name="fastscroll_popup_text_size">24dp</dimen>
 
     <!-- Dynamic grid -->
-    <dimen name="dynamic_grid_min_page_indicator_size">48dp</dimen>
     <dimen name="dynamic_grid_icon_drawable_padding">4dp</dimen>
 
     <dimen name="dynamic_grid_cell_layout_padding">0dp</dimen>
diff --git a/res/values-lo/strings.xml b/res/values-lo/strings.xml
index cd2c933..a195eaf 100644
--- a/res/values-lo/strings.xml
+++ b/res/values-lo/strings.xml
@@ -130,8 +130,8 @@
     <string name="action_decrease_height" msgid="282377193880900022">"ຫຼຸດ​ລວງ​ສູງ​ລົງ"</string>
     <string name="widget_resized" msgid="9130327887929620">"ປ່ຽນ​ຂະ​ໜາດ​ວິດ​ເຈັດ​ເປັນ​ລວງ​ກ້​ວາງ <xliff:g id="NUMBER_0">%1$s</xliff:g> ລວງ​ສູງ <xliff:g id="NUMBER_1">%2$s</xliff:g> ແລ້ວ"</string>
     <string name="action_deep_shortcut" msgid="2864038805849372848">"ທາງລັດ"</string>
-    <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> ທາງລັດສຳລັບ <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
-    <string name="shortcuts_menu_with_notifications_description" msgid="8985659504915468840">"<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> ທາງລັດ ແລະ <xliff:g id="NUMBER_OF_NOTIFICATIONS">%2$d</xliff:g> ການແຈ້ງເຕືອນສຳລັບ <xliff:g id="APP_NAME">%3$s</xliff:g>"</string>
+    <!-- no translation found for shortcuts_menu_with_notifications_description (2676582286544232849) -->
+    <skip />
     <string name="action_dismiss_notification" msgid="5909461085055959187">"ປິດໄວ້"</string>
     <string name="notification_dismissed" msgid="6002233469409822874">"ປິດການແຈ້ງເຕືອນແລ້ວ"</string>
     <string name="all_apps_personal_tab" msgid="4190252696685155002">"ສ່ວນຕົວ"</string>
diff --git a/res/values-lt/strings.xml b/res/values-lt/strings.xml
index d635894..ac8684c 100644
--- a/res/values-lt/strings.xml
+++ b/res/values-lt/strings.xml
@@ -132,8 +132,8 @@
     <string name="action_decrease_height" msgid="282377193880900022">"Sumažinti aukštį"</string>
     <string name="widget_resized" msgid="9130327887929620">"Valdiklio dydis pakeistas: plotis – <xliff:g id="NUMBER_0">%1$s</xliff:g>, aukštis – <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
     <string name="action_deep_shortcut" msgid="2864038805849372848">"Spartieji klavišai"</string>
-    <string name="shortcuts_menu_description" msgid="406159963824238648">"Programos „<xliff:g id="APP_NAME">%2$s</xliff:g>“ spartieji klavišai (<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g>)"</string>
-    <string name="shortcuts_menu_with_notifications_description" msgid="8985659504915468840">"„<xliff:g id="APP_NAME">%3$s</xliff:g>“ spartieji klavišai (<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g>) ir pranešimai (<xliff:g id="NUMBER_OF_NOTIFICATIONS">%2$d</xliff:g>)"</string>
+    <!-- no translation found for shortcuts_menu_with_notifications_description (2676582286544232849) -->
+    <skip />
     <string name="action_dismiss_notification" msgid="5909461085055959187">"Atsisakyti"</string>
     <string name="notification_dismissed" msgid="6002233469409822874">"Pranešimo atsisakyta"</string>
     <string name="all_apps_personal_tab" msgid="4190252696685155002">"Asmeninės"</string>
diff --git a/res/values-lv/strings.xml b/res/values-lv/strings.xml
index 0584aff..0ed4093 100644
--- a/res/values-lv/strings.xml
+++ b/res/values-lv/strings.xml
@@ -131,8 +131,8 @@
     <string name="action_decrease_height" msgid="282377193880900022">"Samazināt augstumu"</string>
     <string name="widget_resized" msgid="9130327887929620">"Logrīka lielums mainīts — platums: <xliff:g id="NUMBER_0">%1$s</xliff:g>, augstums: <xliff:g id="NUMBER_1">%2$s</xliff:g>."</string>
     <string name="action_deep_shortcut" msgid="2864038805849372848">"Saīsnes"</string>
-    <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> saīsnes lietotnei <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
-    <string name="shortcuts_menu_with_notifications_description" msgid="8985659504915468840">"<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> saīsnes un <xliff:g id="NUMBER_OF_NOTIFICATIONS">%2$d</xliff:g> paziņojumi lietotnei <xliff:g id="APP_NAME">%3$s</xliff:g>"</string>
+    <!-- no translation found for shortcuts_menu_with_notifications_description (2676582286544232849) -->
+    <skip />
     <string name="action_dismiss_notification" msgid="5909461085055959187">"Nerādīt"</string>
     <string name="notification_dismissed" msgid="6002233469409822874">"Paziņojums netiek rādīts"</string>
     <string name="all_apps_personal_tab" msgid="4190252696685155002">"Personīgās lietotnes"</string>
diff --git a/res/values-mk/strings.xml b/res/values-mk/strings.xml
index 54d9c80..3a03315 100644
--- a/res/values-mk/strings.xml
+++ b/res/values-mk/strings.xml
@@ -130,8 +130,8 @@
     <string name="action_decrease_height" msgid="282377193880900022">"Намали висина"</string>
     <string name="widget_resized" msgid="9130327887929620">"Големината на виџетот е променета на ширина <xliff:g id="NUMBER_0">%1$s</xliff:g> висина <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
     <string name="action_deep_shortcut" msgid="2864038805849372848">"Кратенки"</string>
-    <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> кратенки за <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
-    <string name="shortcuts_menu_with_notifications_description" msgid="8985659504915468840">"<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> кратенки и <xliff:g id="NUMBER_OF_NOTIFICATIONS">%2$d</xliff:g> известувања за <xliff:g id="APP_NAME">%3$s</xliff:g>"</string>
+    <!-- no translation found for shortcuts_menu_with_notifications_description (2676582286544232849) -->
+    <skip />
     <string name="action_dismiss_notification" msgid="5909461085055959187">"Отфрли"</string>
     <string name="notification_dismissed" msgid="6002233469409822874">"Известувањето е отфрлено"</string>
     <string name="all_apps_personal_tab" msgid="4190252696685155002">"Лично"</string>
diff --git a/res/values-ml/strings.xml b/res/values-ml/strings.xml
index a060933..7ad2803 100644
--- a/res/values-ml/strings.xml
+++ b/res/values-ml/strings.xml
@@ -130,8 +130,8 @@
     <string name="action_decrease_height" msgid="282377193880900022">"ഉയരം കുറയ്‌ക്കുക"</string>
     <string name="widget_resized" msgid="9130327887929620">"വീതി <xliff:g id="NUMBER_0">%1$s</xliff:g> ഉയരം <xliff:g id="NUMBER_1">%2$s</xliff:g>-ലേക്ക് വിഡ്‌ജെറ്റിന്റെ വലുപ്പം മാറ്റി"</string>
     <string name="action_deep_shortcut" msgid="2864038805849372848">"കുറുക്കുവഴികൾ"</string>
-    <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="APP_NAME">%2$s</xliff:g> ആപ്പിനുള്ള <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> കുറുക്കുവഴികൾ"</string>
-    <string name="shortcuts_menu_with_notifications_description" msgid="8985659504915468840">"<xliff:g id="APP_NAME">%3$s</xliff:g> ആപ്പിനായുള്ള <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> കുറുക്കുവഴികളും <xliff:g id="NUMBER_OF_NOTIFICATIONS">%2$d</xliff:g> അറിയിപ്പുകളും"</string>
+    <!-- no translation found for shortcuts_menu_with_notifications_description (2676582286544232849) -->
+    <skip />
     <string name="action_dismiss_notification" msgid="5909461085055959187">"നിരസിക്കുക"</string>
     <string name="notification_dismissed" msgid="6002233469409822874">"അറിയിപ്പ് നിരസിച്ചു"</string>
     <string name="all_apps_personal_tab" msgid="4190252696685155002">"വ്യക്തിപരം"</string>
diff --git a/res/values-mn/strings.xml b/res/values-mn/strings.xml
index a3507c5..3dcc495 100644
--- a/res/values-mn/strings.xml
+++ b/res/values-mn/strings.xml
@@ -130,8 +130,8 @@
     <string name="action_decrease_height" msgid="282377193880900022">"Намсгах"</string>
     <string name="widget_resized" msgid="9130327887929620">"Виджэтийн өргөн <xliff:g id="NUMBER_0">%1$s</xliff:g>, өндөр <xliff:g id="NUMBER_1">%2$s</xliff:g> болсон"</string>
     <string name="action_deep_shortcut" msgid="2864038805849372848">"Товчлол"</string>
-    <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="APP_NAME">%2$s</xliff:g>-н <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> товчлол"</string>
-    <string name="shortcuts_menu_with_notifications_description" msgid="8985659504915468840">"<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> товчлол болон <xliff:g id="APP_NAME">%3$s</xliff:g>-н <xliff:g id="NUMBER_OF_NOTIFICATIONS">%2$d</xliff:g> мэдэгдэл"</string>
+    <!-- no translation found for shortcuts_menu_with_notifications_description (2676582286544232849) -->
+    <skip />
     <string name="action_dismiss_notification" msgid="5909461085055959187">"Хаах"</string>
     <string name="notification_dismissed" msgid="6002233469409822874">"Мэдэгдлийг хаасан"</string>
     <string name="all_apps_personal_tab" msgid="4190252696685155002">"Хувийн"</string>
diff --git a/res/values-mr/strings.xml b/res/values-mr/strings.xml
index bf1e188..7b9aebd 100644
--- a/res/values-mr/strings.xml
+++ b/res/values-mr/strings.xml
@@ -130,8 +130,8 @@
     <string name="action_decrease_height" msgid="282377193880900022">"उंची कमी करा"</string>
     <string name="widget_resized" msgid="9130327887929620">"विजेटचा आकार रुंदी <xliff:g id="NUMBER_0">%1$s</xliff:g> उंची <xliff:g id="NUMBER_1">%2$s</xliff:g> मध्ये बदलला"</string>
     <string name="action_deep_shortcut" msgid="2864038805849372848">"शॉर्टकट"</string>
-    <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="APP_NAME">%2$s</xliff:g> साठी <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> शॉर्टकट"</string>
-    <string name="shortcuts_menu_with_notifications_description" msgid="8985659504915468840">"<xliff:g id="APP_NAME">%3$s</xliff:g>साठी <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> शॉर्टकट आणि <xliff:g id="NUMBER_OF_NOTIFICATIONS">%2$d</xliff:g> सूचना"</string>
+    <!-- no translation found for shortcuts_menu_with_notifications_description (2676582286544232849) -->
+    <skip />
     <string name="action_dismiss_notification" msgid="5909461085055959187">"डिसमिस करा"</string>
     <string name="notification_dismissed" msgid="6002233469409822874">"सूचना डिसमिस केली"</string>
     <string name="all_apps_personal_tab" msgid="4190252696685155002">"वैयक्तिक"</string>
diff --git a/res/values-ms/strings.xml b/res/values-ms/strings.xml
index 3c223b6..ea178b8 100644
--- a/res/values-ms/strings.xml
+++ b/res/values-ms/strings.xml
@@ -130,8 +130,8 @@
     <string name="action_decrease_height" msgid="282377193880900022">"Kurangkan ketinggian"</string>
     <string name="widget_resized" msgid="9130327887929620">"Saiz widget diubah menjadi <xliff:g id="NUMBER_0">%1$s</xliff:g> lebar <xliff:g id="NUMBER_1">%2$s</xliff:g> tinggi"</string>
     <string name="action_deep_shortcut" msgid="2864038805849372848">"Pintasan"</string>
-    <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> pintasan untuk <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
-    <string name="shortcuts_menu_with_notifications_description" msgid="8985659504915468840">"<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> pintasan dan <xliff:g id="NUMBER_OF_NOTIFICATIONS">%2$d</xliff:g> pemberitahuan untuk <xliff:g id="APP_NAME">%3$s</xliff:g>"</string>
+    <!-- no translation found for shortcuts_menu_with_notifications_description (2676582286544232849) -->
+    <skip />
     <string name="action_dismiss_notification" msgid="5909461085055959187">"Ketepikan"</string>
     <string name="notification_dismissed" msgid="6002233469409822874">"Pemberitahuan diketepikan"</string>
     <string name="all_apps_personal_tab" msgid="4190252696685155002">"Peribadi"</string>
diff --git a/res/values-my/strings.xml b/res/values-my/strings.xml
index 59ac4ca..315ebf5 100644
--- a/res/values-my/strings.xml
+++ b/res/values-my/strings.xml
@@ -130,8 +130,8 @@
     <string name="action_decrease_height" msgid="282377193880900022">"အမြင့်အား လျှော့ပါ"</string>
     <string name="widget_resized" msgid="9130327887929620">"Widget အား အကျယ် <xliff:g id="NUMBER_0">%1$s</xliff:g> အမြင့် <xliff:g id="NUMBER_1">%2$s</xliff:g> အရွယ်အစားပြန်လည်ချိန်ညှိပြီး၏"</string>
     <string name="action_deep_shortcut" msgid="2864038805849372848">"ဖြတ်လမ်းများ"</string>
-    <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="APP_NAME">%2$s</xliff:g> အတွက် အမြန်နည်း <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> ခု"</string>
-    <string name="shortcuts_menu_with_notifications_description" msgid="8985659504915468840">"<xliff:g id="APP_NAME">%3$s</xliff:g> အတွက် ဖြတ်လမ်းလင့်ခ် <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> နှင့် အကြောင်းကြားချက် <xliff:g id="NUMBER_OF_NOTIFICATIONS">%2$d</xliff:g> ခု"</string>
+    <!-- no translation found for shortcuts_menu_with_notifications_description (2676582286544232849) -->
+    <skip />
     <string name="action_dismiss_notification" msgid="5909461085055959187">"ပယ်ရန်"</string>
     <string name="notification_dismissed" msgid="6002233469409822874">"အသိပေးချက်ကို ဖယ်ထုတ်ပြီးပါပြီ"</string>
     <string name="all_apps_personal_tab" msgid="4190252696685155002">"ကိုယ်ပိုင်"</string>
diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml
index 04d0b52..d5beead 100644
--- a/res/values-nb/strings.xml
+++ b/res/values-nb/strings.xml
@@ -130,8 +130,8 @@
     <string name="action_decrease_height" msgid="282377193880900022">"Reduser høyden"</string>
     <string name="widget_resized" msgid="9130327887929620">"Størrelsen på modulen er endret til bredde <xliff:g id="NUMBER_0">%1$s</xliff:g> og høyde <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
     <string name="action_deep_shortcut" msgid="2864038805849372848">"Snarveier"</string>
-    <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> snarveier for <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
-    <string name="shortcuts_menu_with_notifications_description" msgid="8985659504915468840">"<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> snarveier og <xliff:g id="NUMBER_OF_NOTIFICATIONS">%2$d</xliff:g> varsler for <xliff:g id="APP_NAME">%3$s</xliff:g>"</string>
+    <!-- no translation found for shortcuts_menu_with_notifications_description (2676582286544232849) -->
+    <skip />
     <string name="action_dismiss_notification" msgid="5909461085055959187">"Avvis"</string>
     <string name="notification_dismissed" msgid="6002233469409822874">"Varselet ble avvist"</string>
     <string name="all_apps_personal_tab" msgid="4190252696685155002">"Personlig"</string>
diff --git a/res/values-ne/strings.xml b/res/values-ne/strings.xml
index a8a64f1..f44c47b 100644
--- a/res/values-ne/strings.xml
+++ b/res/values-ne/strings.xml
@@ -130,8 +130,8 @@
     <string name="action_decrease_height" msgid="282377193880900022">"उँचाइ घटाउनुहोस्"</string>
     <string name="widget_resized" msgid="9130327887929620">"विजेट चौडाइ <xliff:g id="NUMBER_0">%1$s</xliff:g> उचाइ <xliff:g id="NUMBER_1">%2$s</xliff:g> मा पुनः आकार मिलाइयो"</string>
     <string name="action_deep_shortcut" msgid="2864038805849372848">"सर्टकटहरू"</string>
-    <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="APP_NAME">%2$s</xliff:g> का <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> सर्टकटहरू"</string>
-    <string name="shortcuts_menu_with_notifications_description" msgid="8985659504915468840">"<xliff:g id="APP_NAME">%3$s</xliff:g> का <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> सर्टकट र <xliff:g id="NUMBER_OF_NOTIFICATIONS">%2$d</xliff:g> सूचनाहरू"</string>
+    <!-- no translation found for shortcuts_menu_with_notifications_description (2676582286544232849) -->
+    <skip />
     <string name="action_dismiss_notification" msgid="5909461085055959187">"खारेज गर्नुहोस्"</string>
     <string name="notification_dismissed" msgid="6002233469409822874">"सूचना खारेज गरियो"</string>
     <string name="all_apps_personal_tab" msgid="4190252696685155002">"व्यक्तिगत"</string>
diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml
index 97e576c..e1c059a 100644
--- a/res/values-nl/strings.xml
+++ b/res/values-nl/strings.xml
@@ -130,8 +130,8 @@
     <string name="action_decrease_height" msgid="282377193880900022">"Hoogte verkleinen"</string>
     <string name="widget_resized" msgid="9130327887929620">"Formaat van widget gewijzigd in breedte <xliff:g id="NUMBER_0">%1$s</xliff:g> en hoogte <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
     <string name="action_deep_shortcut" msgid="2864038805849372848">"Snelkoppelingen"</string>
-    <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> snelkoppelingen voor <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
-    <string name="shortcuts_menu_with_notifications_description" msgid="8985659504915468840">"<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> snelkoppelingen en <xliff:g id="NUMBER_OF_NOTIFICATIONS">%2$d</xliff:g> meldingen voor <xliff:g id="APP_NAME">%3$s</xliff:g>"</string>
+    <!-- no translation found for shortcuts_menu_with_notifications_description (2676582286544232849) -->
+    <skip />
     <string name="action_dismiss_notification" msgid="5909461085055959187">"Sluiten"</string>
     <string name="notification_dismissed" msgid="6002233469409822874">"Melding gesloten"</string>
     <string name="all_apps_personal_tab" msgid="4190252696685155002">"Privé"</string>
diff --git a/res/values-or/strings.xml b/res/values-or/strings.xml
index 3cda291..9152b43 100644
--- a/res/values-or/strings.xml
+++ b/res/values-or/strings.xml
@@ -130,8 +130,8 @@
     <string name="action_decrease_height" msgid="282377193880900022">"ଉଚ୍ଚତା କମ୍‌ କରନ୍ତୁ"</string>
     <string name="widget_resized" msgid="9130327887929620">"ୱିଜେଟକୁ <xliff:g id="NUMBER_0">%1$s</xliff:g> ଓସାର ଓ <xliff:g id="NUMBER_1">%2$s</xliff:g> ଉଚ୍ଚରେ ପୁନଃଆକାର ଦିଆଗଲା"</string>
     <string name="action_deep_shortcut" msgid="2864038805849372848">"ଶର୍ଟକଟ୍‍"</string>
-    <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="APP_NAME">%2$s</xliff:g> ପାଇଁ <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g>ଟି ଶର୍ଟକଟ୍‌"</string>
-    <string name="shortcuts_menu_with_notifications_description" msgid="8985659504915468840">"<xliff:g id="APP_NAME">%3$s</xliff:g> ପାଇଁ <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g>ଟି ଶର୍ଟକଟ୍‌ ଏବଂ <xliff:g id="NUMBER_OF_NOTIFICATIONS">%2$d</xliff:g>ଟି ବିଜ୍ଞପ୍ତି"</string>
+    <!-- no translation found for shortcuts_menu_with_notifications_description (2676582286544232849) -->
+    <skip />
     <string name="action_dismiss_notification" msgid="5909461085055959187">"ଖାରଜ କରନ୍ତୁ"</string>
     <string name="notification_dismissed" msgid="6002233469409822874">"ବିଜ୍ଞପ୍ତି ଖାରଜ କରାଗଲା"</string>
     <string name="all_apps_personal_tab" msgid="4190252696685155002">"ବ୍ୟକ୍ତିଗତ"</string>
diff --git a/res/values-pa/strings.xml b/res/values-pa/strings.xml
index c077869..237e519 100644
--- a/res/values-pa/strings.xml
+++ b/res/values-pa/strings.xml
@@ -130,8 +130,8 @@
     <string name="action_decrease_height" msgid="282377193880900022">"ਉਂਚਾਈ ਘਟਾਓ"</string>
     <string name="widget_resized" msgid="9130327887929620">"ਵਿਜੈਟ ਨੂੰ ਚੌੜਾਈ <xliff:g id="NUMBER_0">%1$s</xliff:g> ਉਂਚਾਈ <xliff:g id="NUMBER_1">%2$s</xliff:g> ਨੂੰ ਮੁੜ ਆਕਾਰ ਦਿੱਤਾ"</string>
     <string name="action_deep_shortcut" msgid="2864038805849372848">"ਸ਼ਾਰਟਕੱਟ"</string>
-    <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="APP_NAME">%2$s</xliff:g> ਲਈ <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> ਸ਼ਾਰਟਕੱਟ"</string>
-    <string name="shortcuts_menu_with_notifications_description" msgid="8985659504915468840">"<xliff:g id="APP_NAME">%3$s</xliff:g> ਲਈ <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> ਸ਼ਾਰਟਕੱਟ ਅਤੇ <xliff:g id="NUMBER_OF_NOTIFICATIONS">%2$d</xliff:g> ਸੂਚਨਾਵਾਂ"</string>
+    <!-- no translation found for shortcuts_menu_with_notifications_description (2676582286544232849) -->
+    <skip />
     <string name="action_dismiss_notification" msgid="5909461085055959187">"ਖਾਰਜ ਕਰੋ"</string>
     <string name="notification_dismissed" msgid="6002233469409822874">"ਸੂਚਨਾ ਖਾਰਜ ਕੀਤੀ ਗਈ"</string>
     <string name="all_apps_personal_tab" msgid="4190252696685155002">"ਨਿੱਜੀ"</string>
diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml
index 6763082..65de777 100644
--- a/res/values-pl/strings.xml
+++ b/res/values-pl/strings.xml
@@ -132,8 +132,8 @@
     <string name="action_decrease_height" msgid="282377193880900022">"Zmniejsz wysokość"</string>
     <string name="widget_resized" msgid="9130327887929620">"Szerokość i wysokość widżetu zmieniła się na <xliff:g id="NUMBER_0">%1$s</xliff:g> x <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
     <string name="action_deep_shortcut" msgid="2864038805849372848">"Skróty"</string>
-    <string name="shortcuts_menu_description" msgid="406159963824238648">"Skróty aplikacji <xliff:g id="APP_NAME">%2$s</xliff:g>: <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g>"</string>
-    <string name="shortcuts_menu_with_notifications_description" msgid="8985659504915468840">"Skróty (<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g>) i powiadomienia (<xliff:g id="NUMBER_OF_NOTIFICATIONS">%2$d</xliff:g>) aplikacji <xliff:g id="APP_NAME">%3$s</xliff:g>"</string>
+    <!-- no translation found for shortcuts_menu_with_notifications_description (2676582286544232849) -->
+    <skip />
     <string name="action_dismiss_notification" msgid="5909461085055959187">"Odrzuć"</string>
     <string name="notification_dismissed" msgid="6002233469409822874">"Powiadomienie odrzucone"</string>
     <string name="all_apps_personal_tab" msgid="4190252696685155002">"Osobiste"</string>
diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml
index 8448ae0..48dcebb 100644
--- a/res/values-pt-rPT/strings.xml
+++ b/res/values-pt-rPT/strings.xml
@@ -130,8 +130,8 @@
     <string name="action_decrease_height" msgid="282377193880900022">"Diminuir altura"</string>
     <string name="widget_resized" msgid="9130327887929620">"Widget redimensionado para a largura <xliff:g id="NUMBER_0">%1$s</xliff:g>, altura <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
     <string name="action_deep_shortcut" msgid="2864038805849372848">"Atalhos"</string>
-    <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> atalhos para a aplicação <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
-    <string name="shortcuts_menu_with_notifications_description" msgid="8985659504915468840">"<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> atalhos e <xliff:g id="NUMBER_OF_NOTIFICATIONS">%2$d</xliff:g> notificações para a aplicação <xliff:g id="APP_NAME">%3$s</xliff:g>"</string>
+    <!-- no translation found for shortcuts_menu_with_notifications_description (2676582286544232849) -->
+    <skip />
     <string name="action_dismiss_notification" msgid="5909461085055959187">"Ignorar"</string>
     <string name="notification_dismissed" msgid="6002233469409822874">"Notificação ignorada"</string>
     <string name="all_apps_personal_tab" msgid="4190252696685155002">"Pessoal"</string>
diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml
index 754871e..25bde0a 100644
--- a/res/values-pt/strings.xml
+++ b/res/values-pt/strings.xml
@@ -130,8 +130,8 @@
     <string name="action_decrease_height" msgid="282377193880900022">"Diminuir altura"</string>
     <string name="widget_resized" msgid="9130327887929620">"Widget redimensionado para a largura <xliff:g id="NUMBER_0">%1$s</xliff:g>, altura <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
     <string name="action_deep_shortcut" msgid="2864038805849372848">"Atalhos"</string>
-    <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> atalhos para <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
-    <string name="shortcuts_menu_with_notifications_description" msgid="8985659504915468840">"<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> atalhos e <xliff:g id="NUMBER_OF_NOTIFICATIONS">%2$d</xliff:g> notificações para o app <xliff:g id="APP_NAME">%3$s</xliff:g>"</string>
+    <!-- no translation found for shortcuts_menu_with_notifications_description (2676582286544232849) -->
+    <skip />
     <string name="action_dismiss_notification" msgid="5909461085055959187">"Dispensar"</string>
     <string name="notification_dismissed" msgid="6002233469409822874">"Notificação dispensada"</string>
     <string name="all_apps_personal_tab" msgid="4190252696685155002">"Pessoais"</string>
diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml
index 5382a29..74809dd 100644
--- a/res/values-ru/strings.xml
+++ b/res/values-ru/strings.xml
@@ -132,8 +132,8 @@
     <string name="action_decrease_height" msgid="282377193880900022">"Уменьшить высоту"</string>
     <string name="widget_resized" msgid="9130327887929620">"Изменен размер виджета: до <xliff:g id="NUMBER_0">%1$s</xliff:g> в ширину и <xliff:g id="NUMBER_1">%2$s</xliff:g> в высоту"</string>
     <string name="action_deep_shortcut" msgid="2864038805849372848">"Ярлыки"</string>
-    <string name="shortcuts_menu_description" msgid="406159963824238648">"Количество ярлыков для приложения \"<xliff:g id="APP_NAME">%2$s</xliff:g>\": <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g>"</string>
-    <string name="shortcuts_menu_with_notifications_description" msgid="8985659504915468840">"Количество ярлыков для приложения \"<xliff:g id="APP_NAME">%3$s</xliff:g>\": <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g>. Количество уведомлений: <xliff:g id="NUMBER_OF_NOTIFICATIONS">%2$d</xliff:g>."</string>
+    <!-- no translation found for shortcuts_menu_with_notifications_description (2676582286544232849) -->
+    <skip />
     <string name="action_dismiss_notification" msgid="5909461085055959187">"Закрыть"</string>
     <string name="notification_dismissed" msgid="6002233469409822874">"Уведомление закрыто"</string>
     <string name="all_apps_personal_tab" msgid="4190252696685155002">"Личные"</string>
diff --git a/res/values-sk/strings.xml b/res/values-sk/strings.xml
index 3788197..cbffd1b 100644
--- a/res/values-sk/strings.xml
+++ b/res/values-sk/strings.xml
@@ -132,8 +132,8 @@
     <string name="action_decrease_height" msgid="282377193880900022">"Znížiť výšku"</string>
     <string name="widget_resized" msgid="9130327887929620">"Veľkosť miniaplikácie bola zmenená na <xliff:g id="NUMBER_0">%1$s</xliff:g> x <xliff:g id="NUMBER_1">%2$s</xliff:g> (šírka x výška)"</string>
     <string name="action_deep_shortcut" msgid="2864038805849372848">"Skratky"</string>
-    <string name="shortcuts_menu_description" msgid="406159963824238648">"Počet skratiek aplikácie <xliff:g id="APP_NAME">%2$s</xliff:g>: <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g>"</string>
-    <string name="shortcuts_menu_with_notifications_description" msgid="8985659504915468840">"Odkazy (<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g>) a upozornenia (<xliff:g id="NUMBER_OF_NOTIFICATIONS">%2$d</xliff:g>) pre aplikáciu <xliff:g id="APP_NAME">%3$s</xliff:g>"</string>
+    <!-- no translation found for shortcuts_menu_with_notifications_description (2676582286544232849) -->
+    <skip />
     <string name="action_dismiss_notification" msgid="5909461085055959187">"Zavrieť"</string>
     <string name="notification_dismissed" msgid="6002233469409822874">"Upozornenie bolo zavreté"</string>
     <string name="all_apps_personal_tab" msgid="4190252696685155002">"Osobné"</string>
diff --git a/res/values-sl/strings.xml b/res/values-sl/strings.xml
index 6b4e4a5..df934cd 100644
--- a/res/values-sl/strings.xml
+++ b/res/values-sl/strings.xml
@@ -132,8 +132,8 @@
     <string name="action_decrease_height" msgid="282377193880900022">"Zmanjšanje višine"</string>
     <string name="widget_resized" msgid="9130327887929620">"Velikost pripomočka je bila spremenjena na <xliff:g id="NUMBER_0">%1$s</xliff:g> širine in <xliff:g id="NUMBER_1">%2$s</xliff:g> višine"</string>
     <string name="action_deep_shortcut" msgid="2864038805849372848">"Bližnjice"</string>
-    <string name="shortcuts_menu_description" msgid="406159963824238648">"Št. bližnjic za aplikacijo <xliff:g id="APP_NAME">%2$s</xliff:g>: <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g>"</string>
-    <string name="shortcuts_menu_with_notifications_description" msgid="8985659504915468840">"Bližnjice (<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g>) in obvestila (<xliff:g id="NUMBER_OF_NOTIFICATIONS">%2$d</xliff:g>) aplikacije <xliff:g id="APP_NAME">%3$s</xliff:g>"</string>
+    <!-- no translation found for shortcuts_menu_with_notifications_description (2676582286544232849) -->
+    <skip />
     <string name="action_dismiss_notification" msgid="5909461085055959187">"Opusti"</string>
     <string name="notification_dismissed" msgid="6002233469409822874">"Obvestilo je bilo opuščeno"</string>
     <string name="all_apps_personal_tab" msgid="4190252696685155002">"Osebno"</string>
diff --git a/res/values-sq/strings.xml b/res/values-sq/strings.xml
index 82cc42a..ef7cde7 100644
--- a/res/values-sq/strings.xml
+++ b/res/values-sq/strings.xml
@@ -130,8 +130,8 @@
     <string name="action_decrease_height" msgid="282377193880900022">"Zvogëlo lartësinë"</string>
     <string name="widget_resized" msgid="9130327887929620">"Madhësia e miniaplikacionit u ndryshua me gjerësinë <xliff:g id="NUMBER_0">%1$s</xliff:g> dhe lartësinë <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
     <string name="action_deep_shortcut" msgid="2864038805849372848">"Shkurtoret"</string>
-    <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> shkurtesa për <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
-    <string name="shortcuts_menu_with_notifications_description" msgid="8985659504915468840">"<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> shkurtore dhe <xliff:g id="NUMBER_OF_NOTIFICATIONS">%2$d</xliff:g> njoftime për <xliff:g id="APP_NAME">%3$s</xliff:g>"</string>
+    <!-- no translation found for shortcuts_menu_with_notifications_description (2676582286544232849) -->
+    <skip />
     <string name="action_dismiss_notification" msgid="5909461085055959187">"Hiqe"</string>
     <string name="notification_dismissed" msgid="6002233469409822874">"Njoftimi u hoq"</string>
     <string name="all_apps_personal_tab" msgid="4190252696685155002">"Personale"</string>
diff --git a/res/values-sr/strings.xml b/res/values-sr/strings.xml
index 9a6081e..d4223a8 100644
--- a/res/values-sr/strings.xml
+++ b/res/values-sr/strings.xml
@@ -131,8 +131,8 @@
     <string name="action_decrease_height" msgid="282377193880900022">"Смањи висину"</string>
     <string name="widget_resized" msgid="9130327887929620">"Величина виџета је промењена на ширину <xliff:g id="NUMBER_0">%1$s</xliff:g> и висину <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
     <string name="action_deep_shortcut" msgid="2864038805849372848">"Пречице"</string>
-    <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> пречице(а) за <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
-    <string name="shortcuts_menu_with_notifications_description" msgid="8985659504915468840">"Пречице (<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g>) и обавештења (<xliff:g id="NUMBER_OF_NOTIFICATIONS">%2$d</xliff:g>) за <xliff:g id="APP_NAME">%3$s</xliff:g>"</string>
+    <!-- no translation found for shortcuts_menu_with_notifications_description (2676582286544232849) -->
+    <skip />
     <string name="action_dismiss_notification" msgid="5909461085055959187">"Одбаци"</string>
     <string name="notification_dismissed" msgid="6002233469409822874">"Обавештење је одбачено"</string>
     <string name="all_apps_personal_tab" msgid="4190252696685155002">"Личне"</string>
diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml
index 90f76db..2fda5e2 100644
--- a/res/values-sv/strings.xml
+++ b/res/values-sv/strings.xml
@@ -130,8 +130,8 @@
     <string name="action_decrease_height" msgid="282377193880900022">"Minska höjden"</string>
     <string name="widget_resized" msgid="9130327887929620">"Widgetens storlek har ändrats till: bredd <xliff:g id="NUMBER_0">%1$s</xliff:g>, höjd <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
     <string name="action_deep_shortcut" msgid="2864038805849372848">"Genvägar"</string>
-    <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> genvägar för <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
-    <string name="shortcuts_menu_with_notifications_description" msgid="8985659504915468840">"<xliff:g id="APP_NAME">%3$s</xliff:g> har <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> genvägar och <xliff:g id="NUMBER_OF_NOTIFICATIONS">%2$d</xliff:g> aviseringar"</string>
+    <!-- no translation found for shortcuts_menu_with_notifications_description (2676582286544232849) -->
+    <skip />
     <string name="action_dismiss_notification" msgid="5909461085055959187">"Ignorera"</string>
     <string name="notification_dismissed" msgid="6002233469409822874">"Aviseringen togs bort"</string>
     <string name="all_apps_personal_tab" msgid="4190252696685155002">"Privat"</string>
diff --git a/res/values-sw/strings.xml b/res/values-sw/strings.xml
index d23c891..5981b86 100644
--- a/res/values-sw/strings.xml
+++ b/res/values-sw/strings.xml
@@ -132,8 +132,8 @@
     <string name="action_decrease_height" msgid="282377193880900022">"Punguza urefu"</string>
     <string name="widget_resized" msgid="9130327887929620">"Wijeti imepunguzwa hadi upana <xliff:g id="NUMBER_0">%1$s</xliff:g> urefu <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
     <string name="action_deep_shortcut" msgid="2864038805849372848">"Njia za mkato"</string>
-    <string name="shortcuts_menu_description" msgid="406159963824238648">"Njia <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> za mkato za <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
-    <string name="shortcuts_menu_with_notifications_description" msgid="8985659504915468840">"Njia <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> za mkato na arifa <xliff:g id="NUMBER_OF_NOTIFICATIONS">%2$d</xliff:g> za <xliff:g id="APP_NAME">%3$s</xliff:g>"</string>
+    <!-- no translation found for shortcuts_menu_with_notifications_description (2676582286544232849) -->
+    <skip />
     <string name="action_dismiss_notification" msgid="5909461085055959187">"Ondoa"</string>
     <string name="notification_dismissed" msgid="6002233469409822874">"Arifa imeondolewa"</string>
     <string name="all_apps_personal_tab" msgid="4190252696685155002">"Binafsi"</string>
diff --git a/res/values-sw720dp/dimens.xml b/res/values-sw720dp/dimens.xml
index 1497b5a..b211207 100644
--- a/res/values-sw720dp/dimens.xml
+++ b/res/values-sw720dp/dimens.xml
@@ -15,9 +15,6 @@
 -->
 
 <resources>
-    <!-- Dynamic Grid -->
-    <dimen name="dynamic_grid_min_page_indicator_size">24dp</dimen>
-
     <!-- All Apps -->
     <dimen name="all_apps_button_scale_down">8dp</dimen>
     <dimen name="all_apps_empty_search_message_top_offset">64dp</dimen>
diff --git a/res/values-ta/strings.xml b/res/values-ta/strings.xml
index a51247c..5ff5ecc 100644
--- a/res/values-ta/strings.xml
+++ b/res/values-ta/strings.xml
@@ -130,8 +130,8 @@
     <string name="action_decrease_height" msgid="282377193880900022">"உயரத்தைக் குறை"</string>
     <string name="widget_resized" msgid="9130327887929620">"அகலம் <xliff:g id="NUMBER_0">%1$s</xliff:g> மற்றும் உயரம் <xliff:g id="NUMBER_1">%2$s</xliff:g>க்கு விட்ஜெட் அளவு மாற்றப்பட்டது"</string>
     <string name="action_deep_shortcut" msgid="2864038805849372848">"குறுக்குவழிகள்"</string>
-    <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="APP_NAME">%2$s</xliff:g>க்கான <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> குறுக்குவழிகள்"</string>
-    <string name="shortcuts_menu_with_notifications_description" msgid="8985659504915468840">"<xliff:g id="APP_NAME">%3$s</xliff:g> பயன்பாட்டிற்கான <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> குறுக்குவழிகளும் <xliff:g id="NUMBER_OF_NOTIFICATIONS">%2$d</xliff:g> அறிவிப்புகளும் உள்ளன"</string>
+    <!-- no translation found for shortcuts_menu_with_notifications_description (2676582286544232849) -->
+    <skip />
     <string name="action_dismiss_notification" msgid="5909461085055959187">"நிராகரி"</string>
     <string name="notification_dismissed" msgid="6002233469409822874">"அறிவிப்பு நிராகரிக்கப்பட்டது"</string>
     <string name="all_apps_personal_tab" msgid="4190252696685155002">"தனிப்பட்டவை"</string>
diff --git a/res/values-te/strings.xml b/res/values-te/strings.xml
index bffb1a8..0967119 100644
--- a/res/values-te/strings.xml
+++ b/res/values-te/strings.xml
@@ -130,8 +130,8 @@
     <string name="action_decrease_height" msgid="282377193880900022">"ఎత్తును తగ్గించు"</string>
     <string name="widget_resized" msgid="9130327887929620">"విడ్జెట్ పరిమాణం వెడల్పు <xliff:g id="NUMBER_0">%1$s</xliff:g>కి, ఎత్తు <xliff:g id="NUMBER_1">%2$s</xliff:g>కి మార్చబడింది"</string>
     <string name="action_deep_shortcut" msgid="2864038805849372848">"సత్వరమార్గాలు"</string>
-    <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="APP_NAME">%2$s</xliff:g> కోసం <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> సత్వరమార్గాలు"</string>
-    <string name="shortcuts_menu_with_notifications_description" msgid="8985659504915468840">"<xliff:g id="APP_NAME">%3$s</xliff:g> కోసం <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> సత్వరమార్గాలు మరియు <xliff:g id="NUMBER_OF_NOTIFICATIONS">%2$d</xliff:g> నోటిఫికేషన్‌లు"</string>
+    <!-- no translation found for shortcuts_menu_with_notifications_description (2676582286544232849) -->
+    <skip />
     <string name="action_dismiss_notification" msgid="5909461085055959187">"తీసివేయి"</string>
     <string name="notification_dismissed" msgid="6002233469409822874">"నోటిఫికేషన్ తీసివేయబడింది"</string>
     <string name="all_apps_personal_tab" msgid="4190252696685155002">"వ్యక్తిగతం"</string>
diff --git a/res/values-th/strings.xml b/res/values-th/strings.xml
index e4ac998..52ea752 100644
--- a/res/values-th/strings.xml
+++ b/res/values-th/strings.xml
@@ -130,8 +130,8 @@
     <string name="action_decrease_height" msgid="282377193880900022">"ลดความสูง"</string>
     <string name="widget_resized" msgid="9130327887929620">"ปรับขนาดของวิดเจ็ตเป็นกว้าง <xliff:g id="NUMBER_0">%1$s</xliff:g> สูง <xliff:g id="NUMBER_1">%2$s</xliff:g> แล้ว"</string>
     <string name="action_deep_shortcut" msgid="2864038805849372848">"ทางลัด"</string>
-    <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> ทางลัดสำหรับ <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
-    <string name="shortcuts_menu_with_notifications_description" msgid="8985659504915468840">"ทางลัด <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> รายการและการแจ้งเตือน <xliff:g id="NUMBER_OF_NOTIFICATIONS">%2$d</xliff:g> รายการสำหรับ <xliff:g id="APP_NAME">%3$s</xliff:g>"</string>
+    <!-- no translation found for shortcuts_menu_with_notifications_description (2676582286544232849) -->
+    <skip />
     <string name="action_dismiss_notification" msgid="5909461085055959187">"ปิด"</string>
     <string name="notification_dismissed" msgid="6002233469409822874">"ปิดการแจ้งเตือนแล้ว"</string>
     <string name="all_apps_personal_tab" msgid="4190252696685155002">"ส่วนตัว"</string>
diff --git a/res/values-tl/strings.xml b/res/values-tl/strings.xml
index 5f0ba6f..0047aae 100644
--- a/res/values-tl/strings.xml
+++ b/res/values-tl/strings.xml
@@ -130,8 +130,8 @@
     <string name="action_decrease_height" msgid="282377193880900022">"Bawasan ang taas"</string>
     <string name="widget_resized" msgid="9130327887929620">"Na-resize ang widget sa lapad <xliff:g id="NUMBER_0">%1$s</xliff:g> taas <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
     <string name="action_deep_shortcut" msgid="2864038805849372848">"Mga Shortcut"</string>
-    <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> (na) shortcut para sa <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
-    <string name="shortcuts_menu_with_notifications_description" msgid="8985659504915468840">"<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> (na) shortcut at <xliff:g id="NUMBER_OF_NOTIFICATIONS">%2$d</xliff:g> (na) notification para sa <xliff:g id="APP_NAME">%3$s</xliff:g>"</string>
+    <!-- no translation found for shortcuts_menu_with_notifications_description (2676582286544232849) -->
+    <skip />
     <string name="action_dismiss_notification" msgid="5909461085055959187">"I-dismiss"</string>
     <string name="notification_dismissed" msgid="6002233469409822874">"Na-dismiss ang notification"</string>
     <string name="all_apps_personal_tab" msgid="4190252696685155002">"Personal"</string>
diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml
index 3cae0d6..cfa9f9e 100644
--- a/res/values-tr/strings.xml
+++ b/res/values-tr/strings.xml
@@ -130,8 +130,8 @@
     <string name="action_decrease_height" msgid="282377193880900022">"Yüksekliği azalt"</string>
     <string name="widget_resized" msgid="9130327887929620">"Widget, <xliff:g id="NUMBER_0">%1$s</xliff:g> genişlik ve <xliff:g id="NUMBER_1">%2$s</xliff:g> yükseklik değerine yeniden boyutlandırıldı"</string>
     <string name="action_deep_shortcut" msgid="2864038805849372848">"Kısayollar"</string>
-    <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="APP_NAME">%2$s</xliff:g> için <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> kısayol"</string>
-    <string name="shortcuts_menu_with_notifications_description" msgid="8985659504915468840">"<xliff:g id="APP_NAME">%3$s</xliff:g> için <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> kısayol ve <xliff:g id="NUMBER_OF_NOTIFICATIONS">%2$d</xliff:g> bildirim"</string>
+    <!-- no translation found for shortcuts_menu_with_notifications_description (2676582286544232849) -->
+    <skip />
     <string name="action_dismiss_notification" msgid="5909461085055959187">"Kapat"</string>
     <string name="notification_dismissed" msgid="6002233469409822874">"Bildirim kapatıldı"</string>
     <string name="all_apps_personal_tab" msgid="4190252696685155002">"Kişisel"</string>
diff --git a/res/values-uk/strings.xml b/res/values-uk/strings.xml
index e510192..aa5c676 100644
--- a/res/values-uk/strings.xml
+++ b/res/values-uk/strings.xml
@@ -132,8 +132,8 @@
     <string name="action_decrease_height" msgid="282377193880900022">"Зменшити висоту"</string>
     <string name="widget_resized" msgid="9130327887929620">"Розміри віджета змінено на <xliff:g id="NUMBER_0">%1$s</xliff:g> завширшки та <xliff:g id="NUMBER_1">%2$s</xliff:g> заввишки"</string>
     <string name="action_deep_shortcut" msgid="2864038805849372848">"Ярлики"</string>
-    <string name="shortcuts_menu_description" msgid="406159963824238648">"Ярликів для додатка <xliff:g id="APP_NAME">%2$s</xliff:g>: <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g>"</string>
-    <string name="shortcuts_menu_with_notifications_description" msgid="8985659504915468840">"Ярлики (<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g>) і сповіщення (<xliff:g id="NUMBER_OF_NOTIFICATIONS">%2$d</xliff:g>) додатка <xliff:g id="APP_NAME">%3$s</xliff:g>"</string>
+    <!-- no translation found for shortcuts_menu_with_notifications_description (2676582286544232849) -->
+    <skip />
     <string name="action_dismiss_notification" msgid="5909461085055959187">"Закрити"</string>
     <string name="notification_dismissed" msgid="6002233469409822874">"Сповіщення закрито"</string>
     <string name="all_apps_personal_tab" msgid="4190252696685155002">"Особисті додатки"</string>
diff --git a/res/values-ur/strings.xml b/res/values-ur/strings.xml
index 77aa0a1..d8e339d 100644
--- a/res/values-ur/strings.xml
+++ b/res/values-ur/strings.xml
@@ -130,8 +130,8 @@
     <string name="action_decrease_height" msgid="282377193880900022">"اونچائی کم کریں"</string>
     <string name="widget_resized" msgid="9130327887929620">"ویجیٹ کے سائز کو چوڑائی <xliff:g id="NUMBER_0">%1$s</xliff:g> اونچائی <xliff:g id="NUMBER_1">%2$s</xliff:g> میں تبدیل کر دیا گیا"</string>
     <string name="action_deep_shortcut" msgid="2864038805849372848">"شارٹ کٹس"</string>
-    <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="APP_NAME">%2$s</xliff:g> کیلئے <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> شارٹ کٹس"</string>
-    <string name="shortcuts_menu_with_notifications_description" msgid="8985659504915468840">"<xliff:g id="APP_NAME">%3$s</xliff:g> کے <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> شارٹ کٹس اور <xliff:g id="NUMBER_OF_NOTIFICATIONS">%2$d</xliff:g> اطلاعات"</string>
+    <!-- no translation found for shortcuts_menu_with_notifications_description (2676582286544232849) -->
+    <skip />
     <string name="action_dismiss_notification" msgid="5909461085055959187">"برخاست کریں"</string>
     <string name="notification_dismissed" msgid="6002233469409822874">"اطلاع مسترد ہو گئی"</string>
     <string name="all_apps_personal_tab" msgid="4190252696685155002">"ذاتی"</string>
diff --git a/res/values-uz/strings.xml b/res/values-uz/strings.xml
index 0360a71..6b53e96 100644
--- a/res/values-uz/strings.xml
+++ b/res/values-uz/strings.xml
@@ -130,8 +130,8 @@
     <string name="action_decrease_height" msgid="282377193880900022">"Bo‘yini kichraytirish"</string>
     <string name="widget_resized" msgid="9130327887929620">"Vidjetning eni <xliff:g id="NUMBER_0">%1$s</xliff:g>, bo‘yi <xliff:g id="NUMBER_1">%2$s</xliff:g> qilib o‘zgartirildi"</string>
     <string name="action_deep_shortcut" msgid="2864038805849372848">"Tezkor tugmalar"</string>
-    <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="APP_NAME">%2$s</xliff:g> ilovasi uchun <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> ta tezkor tugma"</string>
-    <string name="shortcuts_menu_with_notifications_description" msgid="8985659504915468840">"<xliff:g id="APP_NAME">%3$s</xliff:g> ilovasi uchun <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> ta yorliq va <xliff:g id="NUMBER_OF_NOTIFICATIONS">%2$d</xliff:g> ta bildirishnoma"</string>
+    <!-- no translation found for shortcuts_menu_with_notifications_description (2676582286544232849) -->
+    <skip />
     <string name="action_dismiss_notification" msgid="5909461085055959187">"Yopish"</string>
     <string name="notification_dismissed" msgid="6002233469409822874">"Bildirishnoma yopildi"</string>
     <string name="all_apps_personal_tab" msgid="4190252696685155002">"Shaxsiy"</string>
diff --git a/res/values-vi/strings.xml b/res/values-vi/strings.xml
index 52d396e..ab88cfe 100644
--- a/res/values-vi/strings.xml
+++ b/res/values-vi/strings.xml
@@ -130,8 +130,8 @@
     <string name="action_decrease_height" msgid="282377193880900022">"Giảm chiều cao"</string>
     <string name="widget_resized" msgid="9130327887929620">"Đã đổi kích thước tiện ích thành chiều rộng <xliff:g id="NUMBER_0">%1$s</xliff:g> chiều cao <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
     <string name="action_deep_shortcut" msgid="2864038805849372848">"Lối tắt"</string>
-    <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> phím tắt cho <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
-    <string name="shortcuts_menu_with_notifications_description" msgid="8985659504915468840">"<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> phím tắt và <xliff:g id="NUMBER_OF_NOTIFICATIONS">%2$d</xliff:g> thông báo cho <xliff:g id="APP_NAME">%3$s</xliff:g>"</string>
+    <!-- no translation found for shortcuts_menu_with_notifications_description (2676582286544232849) -->
+    <skip />
     <string name="action_dismiss_notification" msgid="5909461085055959187">"Loại bỏ"</string>
     <string name="notification_dismissed" msgid="6002233469409822874">"Đã loại bỏ thông báo"</string>
     <string name="all_apps_personal_tab" msgid="4190252696685155002">"Cá nhân"</string>
diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml
index dc3bc1f..a92208c 100644
--- a/res/values-zh-rCN/strings.xml
+++ b/res/values-zh-rCN/strings.xml
@@ -130,8 +130,8 @@
     <string name="action_decrease_height" msgid="282377193880900022">"减小高度"</string>
     <string name="widget_resized" msgid="9130327887929620">"微件尺寸已调整为:宽度 <xliff:g id="NUMBER_0">%1$s</xliff:g>,高度 <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
     <string name="action_deep_shortcut" msgid="2864038805849372848">"快捷方式"</string>
-    <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="APP_NAME">%2$s</xliff:g>有 <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> 个快捷方式"</string>
-    <string name="shortcuts_menu_with_notifications_description" msgid="8985659504915468840">"<xliff:g id="APP_NAME">%3$s</xliff:g>的 <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> 个快捷方式和 <xliff:g id="NUMBER_OF_NOTIFICATIONS">%2$d</xliff:g> 条通知"</string>
+    <!-- no translation found for shortcuts_menu_with_notifications_description (2676582286544232849) -->
+    <skip />
     <string name="action_dismiss_notification" msgid="5909461085055959187">"关闭"</string>
     <string name="notification_dismissed" msgid="6002233469409822874">"已关闭通知"</string>
     <string name="all_apps_personal_tab" msgid="4190252696685155002">"个人"</string>
diff --git a/res/values-zh-rHK/strings.xml b/res/values-zh-rHK/strings.xml
index b1a8d9d..0f25300 100644
--- a/res/values-zh-rHK/strings.xml
+++ b/res/values-zh-rHK/strings.xml
@@ -130,8 +130,8 @@
     <string name="action_decrease_height" msgid="282377193880900022">"減少高度"</string>
     <string name="widget_resized" msgid="9130327887929620">"已調整小工具的大小至闊 <xliff:g id="NUMBER_0">%1$s</xliff:g> 高 <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
     <string name="action_deep_shortcut" msgid="2864038805849372848">"捷徑"</string>
-    <string name="shortcuts_menu_description" msgid="406159963824238648">"「<xliff:g id="APP_NAME">%2$s</xliff:g>」嘅 <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> 個捷徑"</string>
-    <string name="shortcuts_menu_with_notifications_description" msgid="8985659504915468840">"「<xliff:g id="APP_NAME">%3$s</xliff:g>」嘅 <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> 個捷徑同 <xliff:g id="NUMBER_OF_NOTIFICATIONS">%2$d</xliff:g> 個通知"</string>
+    <!-- no translation found for shortcuts_menu_with_notifications_description (2676582286544232849) -->
+    <skip />
     <string name="action_dismiss_notification" msgid="5909461085055959187">"關閉"</string>
     <string name="notification_dismissed" msgid="6002233469409822874">"關閉咗通知"</string>
     <string name="all_apps_personal_tab" msgid="4190252696685155002">"個人"</string>
diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml
index d8473b6..c187b96 100644
--- a/res/values-zh-rTW/strings.xml
+++ b/res/values-zh-rTW/strings.xml
@@ -130,8 +130,8 @@
     <string name="action_decrease_height" msgid="282377193880900022">"減少高度"</string>
     <string name="widget_resized" msgid="9130327887929620">"已將小工具的寬度和高度分別調整為 <xliff:g id="NUMBER_0">%1$s</xliff:g> 和 <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
     <string name="action_deep_shortcut" msgid="2864038805849372848">"捷徑"</string>
-    <string name="shortcuts_menu_description" msgid="406159963824238648">"「<xliff:g id="APP_NAME">%2$s</xliff:g>」有 <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> 個捷徑"</string>
-    <string name="shortcuts_menu_with_notifications_description" msgid="8985659504915468840">"<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> 個捷徑和 <xliff:g id="NUMBER_OF_NOTIFICATIONS">%2$d</xliff:g> 則「<xliff:g id="APP_NAME">%3$s</xliff:g>」通知"</string>
+    <!-- no translation found for shortcuts_menu_with_notifications_description (2676582286544232849) -->
+    <skip />
     <string name="action_dismiss_notification" msgid="5909461085055959187">"關閉"</string>
     <string name="notification_dismissed" msgid="6002233469409822874">"已關閉通知"</string>
     <string name="all_apps_personal_tab" msgid="4190252696685155002">"個人"</string>
diff --git a/res/values-zu/strings.xml b/res/values-zu/strings.xml
index 852441f..6f92847 100644
--- a/res/values-zu/strings.xml
+++ b/res/values-zu/strings.xml
@@ -130,8 +130,8 @@
     <string name="action_decrease_height" msgid="282377193880900022">"Nciphisa ubude"</string>
     <string name="widget_resized" msgid="9130327887929620">"Iwijethi inikezwe usayizi omusha ngobubanzi obungu-<xliff:g id="NUMBER_0">%1$s</xliff:g> ubude obungu-<xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
     <string name="action_deep_shortcut" msgid="2864038805849372848">"Izinqamuleli"</string>
-    <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> izinqamuleli ze-<xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
-    <string name="shortcuts_menu_with_notifications_description" msgid="8985659504915468840">"<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> izinqamuleli nezaziso ezingu-<xliff:g id="NUMBER_OF_NOTIFICATIONS">%2$d</xliff:g> ze-<xliff:g id="APP_NAME">%3$s</xliff:g>"</string>
+    <!-- no translation found for shortcuts_menu_with_notifications_description (2676582286544232849) -->
+    <skip />
     <string name="action_dismiss_notification" msgid="5909461085055959187">"Cashisa"</string>
     <string name="notification_dismissed" msgid="6002233469409822874">"Isaziso sicashisiwe"</string>
     <string name="all_apps_personal_tab" msgid="4190252696685155002">"Okomuntu siqu"</string>
diff --git a/res/values/config.xml b/res/values/config.xml
index 6158f29..d5bb131 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -41,9 +41,6 @@
     <item type="id" name="drag_event_parity" />
 
 <!-- AllApps & Launcher transitions -->
-    <!-- The alpha of the AppsCustomize bg in spring loaded mode -->
-    <integer name="config_workspaceScrimAlpha">76</integer>
-
     <!-- Out of 100, the percent to shrink the workspace during spring loaded mode. -->
     <integer name="config_workspaceSpringLoadShrinkPercentage">90</integer>
 
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index b1ad11e..07e0b04 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -20,7 +20,6 @@
 
     <!-- Dynamic Grid -->
     <dimen name="dynamic_grid_edge_margin">8dp</dimen>
-    <dimen name="dynamic_grid_min_page_indicator_size">24dp</dimen>
     <dimen name="dynamic_grid_page_indicator_line_height">1dp</dimen>
     <dimen name="dynamic_grid_icon_drawable_padding">8dp</dimen>
     <dimen name="dynamic_grid_workspace_top_padding">8dp</dimen>
@@ -42,6 +41,7 @@
     <dimen name="all_apps_scrim_radius">8dp</dimen>
     <dimen name="all_apps_scrim_margin">8dp</dimen>
     <dimen name="all_apps_scrim_blur">4dp</dimen>
+    <dimen name="vertical_drag_handle_size">24dp</dimen>
 
 <!-- Drop target bar -->
     <dimen name="dynamic_grid_drop_target_size">48dp</dimen>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 5dc7844..7bc11c3 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -244,6 +244,11 @@
     <!-- Title for a bottom sheet that shows widgets for a particular app -->
     <string name="widgets_bottom_sheet_title"><xliff:g id="name" example="Messenger">%1$s</xliff:g> widgets</string>
 
+    <!-- Accessibility title for the popup containing a list of widgets. [CHAR_LIMIT=50] -->
+    <string name="widgets_list">Widgets list</string>
+    <!-- Text announced by accessibility when the popup containing the list of widgets is closed. [CHAR_LIMIT=100] -->
+    <string name="widgets_list_closed">Widgets list closed</string>
+
 <!-- Strings for accessibility actions -->
     <!-- Accessibility action to add an app to workspace. [CHAR_LIMIT=30] -->
     <string name="action_add_to_workspace">Add to Home screen</string>
@@ -310,7 +315,7 @@
 
     <!-- Accessibility action to show quick actions menu for an icon. [CHAR_LIMIT=30] -->
     <string name="action_deep_shortcut">Shortcuts</string>
-    <!-- Accessibility description when the shortcuts menu has notifications as well as shortcuts. [CHAR_LIMIT=50] -->
+    <!-- Accessibility description when the context menu of a launcher icon that has notifications as well as shortcuts (providing quick access to app's actions). The "shortcuts" translation should be consistent with the one for action_deep_shortcut. [CHAR_LIMIT=50] -->
     <string name="shortcuts_menu_with_notifications_description">Shortcuts and notifications
     </string>
 
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 8526d7c..631626f 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -60,7 +60,7 @@
         <item name="android:textColorTertiary">#CCFFFFFF</item>
         <item name="android:textColorHint">#A0FFFFFF</item>
         <item name="android:colorControlHighlight">#A0FFFFFF</item>
-        <item name="android:colorPrimary">#FF333333</item>
+        <item name="android:colorPrimary">#FF212121</item>
         <item name="allAppsScrimColor">#EA212121</item>
         <item name="allAppsNavBarScrimColor">#80000000</item>
         <item name="popupColorPrimary">?android:attr/colorPrimary</item>
diff --git a/src/com/android/launcher3/AbstractFloatingView.java b/src/com/android/launcher3/AbstractFloatingView.java
index 097c341..5a1c158 100644
--- a/src/com/android/launcher3/AbstractFloatingView.java
+++ b/src/com/android/launcher3/AbstractFloatingView.java
@@ -16,10 +16,18 @@
 
 package com.android.launcher3;
 
+import static android.view.accessibility.AccessibilityEvent.TYPE_VIEW_FOCUSED;
+import static android.view.accessibility.AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED;
+import static android.view.accessibility.AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED;
+
+import static com.android.launcher3.compat.AccessibilityManagerCompat.isAccessibilityEnabled;
+import static com.android.launcher3.compat.AccessibilityManagerCompat.sendCustomAccessibilityEvent;
+
 import android.annotation.SuppressLint;
 import android.content.Context;
 import android.support.annotation.IntDef;
 import android.util.AttributeSet;
+import android.util.Pair;
 import android.view.MotionEvent;
 import android.view.View;
 import android.widget.LinearLayout;
@@ -123,6 +131,25 @@
         return false;
     }
 
+    protected void announceAccessibilityChanges() {
+        Pair<View, String> targetInfo = getAccessibilityTarget();
+        if (targetInfo == null || !isAccessibilityEnabled(getContext())) {
+            return;
+        }
+        sendCustomAccessibilityEvent(
+                targetInfo.first, TYPE_WINDOW_STATE_CHANGED, targetInfo.second);
+
+        if (mIsOpen) {
+            sendAccessibilityEvent(TYPE_VIEW_FOCUSED);
+        }
+        BaseDraggingActivity.fromContext(getContext()).getDragLayer()
+                .sendAccessibilityEvent(TYPE_WINDOW_CONTENT_CHANGED);
+    }
+
+    protected Pair<View, String> getAccessibilityTarget() {
+        return null;
+    }
+
     protected static <T extends AbstractFloatingView> T getOpenView(
             BaseDraggingActivity activity, @FloatingViewType int type) {
         BaseDragLayer dragLayer = activity.getDragLayer();
diff --git a/src/com/android/launcher3/BaseActivity.java b/src/com/android/launcher3/BaseActivity.java
index a41edc0..4219667 100644
--- a/src/com/android/launcher3/BaseActivity.java
+++ b/src/com/android/launcher3/BaseActivity.java
@@ -16,6 +16,8 @@
 
 package com.android.launcher3;
 
+import static com.android.launcher3.util.SystemUiController.UI_STATE_OVERVIEW;
+
 import static java.lang.annotation.RetentionPolicy.SOURCE;
 
 import android.app.Activity;
@@ -23,15 +25,16 @@
 import android.content.ContextWrapper;
 import android.content.Intent;
 import android.content.res.Configuration;
-import android.graphics.Point;
 import android.support.annotation.IntDef;
-import android.view.Display;
 import android.view.View.AccessibilityDelegate;
 
 import com.android.launcher3.DeviceProfile.OnDeviceProfileChangeListener;
 import com.android.launcher3.logging.UserEventDispatcher;
+import com.android.launcher3.uioverrides.UiFactory;
 import com.android.launcher3.util.SystemUiController;
 
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
 import java.lang.annotation.Retention;
 import java.util.ArrayList;
 
@@ -153,6 +156,12 @@
     protected void onPause() {
         mActivityFlags &= ~ACTIVITY_STATE_RESUMED;
         super.onPause();
+
+        // Reset the overridden sysui flags used for the task-swipe launch animation, we do this
+        // here instead of at the end of the animation because the start of the new activity does
+        // not happen immediately, which would cause us to reset to launcher's sysui flags and then
+        // back to the new app (causing a flash)
+        getSystemUiController().updateUiState(UI_STATE_OVERVIEW, 0);
     }
 
     public boolean isStarted() {
@@ -213,20 +222,22 @@
         return mForceInvisible != 0;
     }
 
-    /**
-     * Sets the device profile, adjusting it accordingly in case of multi-window
-     */
-    protected void setDeviceProfile(DeviceProfile dp) {
-        mDeviceProfile = dp;
-        if (isInMultiWindowModeCompat()) {
-            Display display = getWindowManager().getDefaultDisplay();
-            Point mwSize = new Point();
-            display.getSize(mwSize);
-            mDeviceProfile = mDeviceProfile.getMultiWindowProfile(this, mwSize);
+    public interface MultiWindowModeChangedListener {
+        void onMultiWindowModeChanged(boolean isInMultiWindowMode);
+    }
+
+    @Override
+    public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {
+        if (!UiFactory.dumpActivity(this, writer)) {
+            super.dump(prefix, fd, writer, args);
         }
     }
 
-    public interface MultiWindowModeChangedListener {
-        void onMultiWindowModeChanged(boolean isInMultiWindowMode);
+    protected void dumpMisc(PrintWriter writer) {
+        writer.println(" deviceProfile isTransposed=" + getDeviceProfile().isVerticalBarLayout());
+        writer.println(" orientation=" + getResources().getConfiguration().orientation);
+        writer.println(" mSystemUiController: " + mSystemUiController);
+        writer.println(" mActivityFlags: " + mActivityFlags);
+        writer.println(" mForceInvisible: " + mForceInvisible);
     }
 }
diff --git a/src/com/android/launcher3/BaseDraggingActivity.java b/src/com/android/launcher3/BaseDraggingActivity.java
index 1400432..e47dbe5 100644
--- a/src/com/android/launcher3/BaseDraggingActivity.java
+++ b/src/com/android/launcher3/BaseDraggingActivity.java
@@ -28,12 +28,14 @@
 import android.os.UserHandle;
 import android.util.Log;
 import android.view.ActionMode;
+import android.view.Surface;
 import android.view.View;
 import android.widget.Toast;
 
 import com.android.launcher3.LauncherSettings.Favorites;
 import com.android.launcher3.badge.BadgeInfo;
 import com.android.launcher3.compat.LauncherAppsCompat;
+import com.android.launcher3.uioverrides.DisplayRotationListener;
 import com.android.launcher3.uioverrides.WallpaperColorInfo;
 import com.android.launcher3.shortcuts.DeepShortcutManager;
 import com.android.launcher3.views.BaseDragLayer;
@@ -61,10 +63,13 @@
 
     private int mThemeRes = R.style.LauncherTheme;
 
+    private DisplayRotationListener mRotationListener;
+
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         mIsSafeModeEnabled = getPackageManager().isSafeMode();
+        mRotationListener = new DisplayRotationListener(this, this::onDeviceRotationChanged);
 
         // Update theme
         WallpaperColorInfo wallpaperColorInfo = WallpaperColorInfo.getInstance(this);
@@ -237,12 +242,30 @@
     protected void onDestroy() {
         super.onDestroy();
         WallpaperColorInfo.getInstance(this).removeOnChangeListener(this);
+        mRotationListener.disable();
     }
 
     public <T extends BaseDraggingActivity> void setOnStartCallback(OnStartCallback<T> callback) {
         mOnStartCallback = callback;
     }
 
+    protected void onDeviceProfileInitiated() {
+        if (mDeviceProfile.isVerticalBarLayout()) {
+            mRotationListener.enable();
+            mDeviceProfile.updateIsSeascape(getWindowManager());
+        } else {
+            mRotationListener.disable();
+        }
+    }
+
+    private void onDeviceRotationChanged() {
+        if (mDeviceProfile.updateIsSeascape(getWindowManager())) {
+            reapplyUi();
+        }
+    }
+
+    protected abstract void reapplyUi();
+
     /**
      * Callback for listening for onStart
      */
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index 4deed73..2f47728 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -25,6 +25,8 @@
 import android.graphics.PointF;
 import android.graphics.Rect;
 import android.util.DisplayMetrics;
+import android.view.Surface;
+import android.view.WindowManager;
 
 import com.android.launcher3.CellLayout.ContainerType;
 import com.android.launcher3.badge.BadgeRenderer;
@@ -68,8 +70,8 @@
     public float workspaceSpringLoadShrinkFactor;
     public final int workspaceSpringLoadedBottomSpace;
 
-    // Page indicator
-    public final int pageIndicatorSizePx;
+    // Drag handle
+    public final int verticalDragHandleSizePx;
 
     // Workspace icons
     public int iconSizePx;
@@ -118,6 +120,7 @@
     private final Rect mInsets = new Rect();
     public final Rect workspacePadding = new Rect();
     private final Rect mHotseatPadding = new Rect();
+    private boolean mIsSeascape;
 
     // Icon badges
     public BadgeRenderer mBadgeRenderer;
@@ -157,8 +160,8 @@
                 res.getDimensionPixelSize(R.dimen.dynamic_grid_cell_layout_padding);
         cellLayoutBottomPaddingPx =
                 res.getDimensionPixelSize(R.dimen.dynamic_grid_cell_layout_bottom_padding);
-        pageIndicatorSizePx = res.getDimensionPixelSize(
-                R.dimen.dynamic_grid_min_page_indicator_size);
+        verticalDragHandleSizePx = res.getDimensionPixelSize(
+                R.dimen.vertical_drag_handle_size);
         defaultPageSpacingPx =
                 res.getDimensionPixelSize(R.dimen.dynamic_grid_workspace_page_spacing);
         topWorkspacePadding =
@@ -205,7 +208,7 @@
             // in portrait mode closer together by adding more height to the hotseat.
             // Note: This calculation was created after noticing a pattern in the design spec.
             int extraSpace = getCellSize().y - iconSizePx - iconDrawablePaddingPx;
-            hotseatBarSizePx += extraSpace - pageIndicatorSizePx;
+            hotseatBarSizePx += extraSpace - verticalDragHandleSizePx;
 
             // Recalculate the available dimensions using the new hotseat size.
             updateAvailableDimensions(dm, res);
@@ -329,7 +332,7 @@
 
         if (!isVerticalLayout) {
             int expectedWorkspaceHeight = availableHeightPx - hotseatBarSizePx
-                    - pageIndicatorSizePx - topWorkspacePadding;
+                    - verticalDragHandleSizePx - topWorkspacePadding;
             float minRequiredHeight = dropTargetBarSizePx + workspaceSpringLoadedBottomSpace;
             workspaceSpringLoadShrinkFactor = Math.min(
                     res.getInteger(R.integer.config_workspaceSpringLoadShrinkPercentage) / 100.0f,
@@ -426,13 +429,13 @@
             padding.right = hotseatBarSidePaddingPx;
             if (isSeascape()) {
                 padding.left += hotseatBarSizePx;
-                padding.right += pageIndicatorSizePx;
+                padding.right += verticalDragHandleSizePx;
             } else {
-                padding.left += pageIndicatorSizePx;
+                padding.left += verticalDragHandleSizePx;
                 padding.right += hotseatBarSizePx;
             }
         } else {
-            int paddingBottom = hotseatBarSizePx + pageIndicatorSizePx;
+            int paddingBottom = hotseatBarSizePx + verticalDragHandleSizePx;
             if (isTablet) {
                 // Pad the left and right of the workspace to ensure consistent spacing
                 // between all icons
@@ -499,7 +502,7 @@
                     mInsets.top + dropTargetBarSizePx + edgeMarginPx,
                     mInsets.left + availableWidthPx - edgeMarginPx,
                     mInsets.top + availableHeightPx - hotseatBarSizePx
-                            - pageIndicatorSizePx - edgeMarginPx);
+                            - verticalDragHandleSizePx - edgeMarginPx);
         }
     }
 
@@ -519,9 +522,22 @@
         return isLandscape && transposeLayoutWithOrientation;
     }
 
+    /**
+     * Updates orientation information and returns true if it has changed from the previous value.
+     */
+    public boolean updateIsSeascape(WindowManager wm) {
+        if (isVerticalBarLayout()) {
+            boolean isSeascape = wm.getDefaultDisplay().getRotation() == Surface.ROTATION_270;
+            if (mIsSeascape != isSeascape) {
+                mIsSeascape = isSeascape;
+                return true;
+            }
+        }
+        return false;
+    }
+
     public boolean isSeascape() {
-        // TODO: This might not hold true for multi window mode, use configuration insead.
-        return isVerticalBarLayout() && mInsets.left > mInsets.right;
+        return isVerticalBarLayout() && mIsSeascape;
     }
 
     public boolean shouldFadeAdjacentWorkspaceScreens() {
diff --git a/src/com/android/launcher3/IconCache.java b/src/com/android/launcher3/IconCache.java
index 168bd08..8d79737 100644
--- a/src/com/android/launcher3/IconCache.java
+++ b/src/com/android/launcher3/IconCache.java
@@ -107,6 +107,8 @@
     private final BitmapFactory.Options mLowResOptions;
     private final BitmapFactory.Options mHighResOptions;
 
+    private int mPendingIconRequestCount = 0;
+
     public IconCache(Context context, InvariantDeviceProfile inv) {
         mContext = context;
         mPackageManager = context.getPackageManager();
@@ -411,8 +413,13 @@
      */
     public IconLoadRequest updateIconInBackground(final ItemInfoUpdateReceiver caller,
             final ItemInfoWithIcon info) {
-        Runnable request = new Runnable() {
+        Preconditions.assertUIThread();
+        if (mPendingIconRequestCount <= 0) {
+            LauncherModel.setWorkerPriority(Process.THREAD_PRIORITY_FOREGROUND);
+        }
+        mPendingIconRequestCount ++;
 
+        IconLoadRequest request = new IconLoadRequest(mWorkerHandler, this::onIconRequestEnd) {
             @Override
             public void run() {
                 if (info instanceof AppInfo || info instanceof ShortcutInfo) {
@@ -420,17 +427,21 @@
                 } else if (info instanceof PackageItemInfo) {
                     getTitleAndIconForApp((PackageItemInfo) info, false);
                 }
-                mMainThreadExecutor.execute(new Runnable() {
-
-                    @Override
-                    public void run() {
-                        caller.reapplyItemInfo(info);
-                    }
+                mMainThreadExecutor.execute(() -> {
+                    caller.reapplyItemInfo(info);
+                    onEnd();
                 });
             }
         };
-        mWorkerHandler.post(request);
-        return new IconLoadRequest(request, mWorkerHandler);
+        Utilities.postAsyncCallback(mWorkerHandler, request);
+        return request;
+    }
+
+    private void onIconRequestEnd() {
+        mPendingIconRequestCount --;
+        if (mPendingIconRequestCount <= 0) {
+            LauncherModel.setWorkerPriority(Process.THREAD_PRIORITY_BACKGROUND);
+        }
     }
 
     /**
@@ -707,17 +718,27 @@
         return false;
     }
 
-    public static class IconLoadRequest {
-        private final Runnable mRunnable;
+    public static abstract class IconLoadRequest implements Runnable {
         private final Handler mHandler;
+        private final Runnable mEndRunnable;
 
-        IconLoadRequest(Runnable runnable, Handler handler) {
-            mRunnable = runnable;
+        private boolean mEnded = false;
+
+        IconLoadRequest(Handler handler, Runnable endRunnable) {
             mHandler = handler;
+            mEndRunnable = endRunnable;
         }
 
         public void cancel() {
-            mHandler.removeCallbacks(mRunnable);
+            mHandler.removeCallbacks(this);
+            onEnd();
+        }
+
+        public void onEnd() {
+            if (!mEnded) {
+                mEnded = true;
+                mEndRunnable.run();
+            }
         }
     }
 
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index d8bb90a..e851499 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -22,6 +22,7 @@
 import static com.android.launcher3.LauncherAnimUtils.SPRING_LOADED_EXIT_DELAY;
 import static com.android.launcher3.LauncherState.ALL_APPS;
 import static com.android.launcher3.LauncherState.NORMAL;
+import static com.android.launcher3.dragndrop.DragLayer.ALPHA_INDEX_LAUNCHER_LOAD;
 import static com.android.launcher3.logging.LoggerUtils.newContainerTarget;
 
 import android.animation.Animator;
@@ -45,6 +46,7 @@
 import android.content.pm.PackageManager;
 import android.content.res.Configuration;
 import android.database.sqlite.SQLiteDatabase;
+import android.graphics.Point;
 import android.os.AsyncTask;
 import android.os.Build;
 import android.os.Bundle;
@@ -57,6 +59,7 @@
 import android.text.method.TextKeyListener;
 import android.util.Log;
 import android.util.SparseArray;
+import android.view.Display;
 import android.view.KeyEvent;
 import android.view.KeyboardShortcutGroup;
 import android.view.KeyboardShortcutInfo;
@@ -103,6 +106,8 @@
 import com.android.launcher3.util.ComponentKey;
 import com.android.launcher3.util.ItemInfoMatcher;
 import com.android.launcher3.util.MultiHashMap;
+import com.android.launcher3.util.MultiValueAlpha;
+import com.android.launcher3.util.MultiValueAlpha.AlphaProperty;
 import com.android.launcher3.util.PackageManagerHelper;
 import com.android.launcher3.util.PackageUserKey;
 import com.android.launcher3.util.PendingRequestArgs;
@@ -194,7 +199,6 @@
     private final int[] mTmpAddItemCellCoordinates = new int[2];
 
     @Thunk Hotseat mHotseat;
-    private View mDragHandleIndicator;
     @Nullable private View mHotseatSearchBox;
 
     private DropTargetBar mDropTargetBar;
@@ -219,9 +223,6 @@
     private IconCache mIconCache;
     private LauncherAccessibilityDelegate mAccessibilityDelegate;
 
-    private ObjectAnimator mScrimAnimator;
-    private boolean mShouldFadeInScrim;
-
     private PopupDataProvider mPopupDataProvider;
 
     private int mSynchronouslyBoundPage = PagedView.INVALID_PAGE;
@@ -239,16 +240,9 @@
     private PendingRequestArgs mPendingRequestArgs;
 
     public ViewGroupFocusHelper mFocusHandler;
-    private boolean mAppLaunchSuccess;
 
     private RotationHelper mRotationHelper;
 
-    // Used to keep track of the swipe up state
-    private SharedPreferences.OnSharedPreferenceChangeListener mSharedPrefsListener =
-            (sharedPreferences, s) -> {
-                mDragLayer.setup(mDragController);
-            };
-
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         if (DEBUG_STRICT_MODE) {
@@ -276,7 +270,6 @@
         initDeviceProfile(app.getInvariantDeviceProfile());
 
         mSharedPrefs = Utilities.getPrefs(this);
-        mSharedPrefs.registerOnSharedPreferenceChangeListener(mSharedPrefsListener);
         mIconCache = app.getIconCache();
         mAccessibilityDelegate = new LauncherAccessibilityDelegate(this);
 
@@ -319,7 +312,7 @@
             if (!internalStateHandled) {
                 // If we are not binding synchronously, show a fade in animation when
                 // the first page bind completes.
-                mLauncherView.setAlpha(0);
+                mDragLayer.getAlphaProperty(ALPHA_INDEX_LAUNCHER_LOAD).setValue(0);
             }
         } else {
             // Pages bound synchronously.
@@ -335,11 +328,7 @@
         getRootView().dispatchInsets();
 
         // Listen for broadcasts
-        IntentFilter filter = new IntentFilter();
-        filter.addAction(Intent.ACTION_SCREEN_OFF);
-        filter.addAction(Intent.ACTION_USER_PRESENT); // When the device wakes up + keyguard is gone
-        registerReceiver(mReceiver, filter);
-        mShouldFadeInScrim = true;
+        registerReceiver(mScreenOffReceiver, new IntentFilter(Intent.ACTION_SCREEN_OFF));
 
         getSystemUiController().updateUiState(SystemUiController.UI_STATE_BASE_WINDOW,
                 Themes.getAttrBoolean(this, R.attr.isWorkspaceDarkText));
@@ -359,12 +348,8 @@
             mUserEventDispatcher = null;
             initDeviceProfile(mDeviceProfile.inv);
             dispatchDeviceProfileChanged();
-
-            getRootView().dispatchInsets();
-            getStateManager().reapplyState(true /* cancelCurrentAnimation */);
-
-            // Recreate touch controllers
-            mDragLayer.setup(mDragController);
+            reapplyUi();
+            mDragLayer.recreateControllers();
 
             // TODO: We can probably avoid rebind when only screen size changed.
             rebindModel();
@@ -376,6 +361,12 @@
     }
 
     @Override
+    protected void reapplyUi() {
+        getRootView().dispatchInsets();
+        getStateManager().reapplyState(true /* cancelCurrentAnimation */);
+    }
+
+    @Override
     public void rebindModel() {
         int currentPage = mWorkspace.getNextPage();
         if (mModel.startLoader(currentPage)) {
@@ -386,7 +377,14 @@
 
     private void initDeviceProfile(InvariantDeviceProfile idp) {
         // Load configuration-specific DeviceProfile
-        setDeviceProfile(idp.getDeviceProfile(this));
+        mDeviceProfile = idp.getDeviceProfile(this);
+        if (isInMultiWindowModeCompat()) {
+            Display display = getWindowManager().getDefaultDisplay();
+            Point mwSize = new Point();
+            display.getSize(mwSize);
+            mDeviceProfile = mDeviceProfile.getMultiWindowProfile(this, mwSize);
+        }
+        onDeviceProfileInitiated();
         mModelWriter = mModel.getWriter(mDeviceProfile.isVerticalBarLayout(), true);
     }
 
@@ -731,10 +729,8 @@
         }
         mAppWidgetHost.setListenIfResumed(false);
 
-        if (!mAppLaunchSuccess) {
-            getUserEventDispatcher().logActionCommand(Action.Command.STOP,
-                    mStateManager.getState().containerType, -1);
-        }
+        getUserEventDispatcher().logActionCommand(Action.Command.STOP,
+                mStateManager.getState().containerType, -1);
         NotificationListener.removeNotificationsChangedListener();
         getStateManager().moveToRestState();
 
@@ -752,25 +748,6 @@
         }
         mAppWidgetHost.setListenIfResumed(true);
         NotificationListener.setNotificationsChangedListener(mPopupDataProvider);
-
-        if (mShouldFadeInScrim && mLauncherView.getBackground() != null) {
-            if (mScrimAnimator != null) {
-                mScrimAnimator.cancel();
-            }
-            mLauncherView.getBackground().setAlpha(0);
-            mScrimAnimator = ObjectAnimator.ofInt(mLauncherView.getBackground(),
-                    LauncherAnimUtils.DRAWABLE_ALPHA, 0, 255);
-            mScrimAnimator.addListener(new AnimatorListenerAdapter() {
-                @Override
-                public void onAnimationEnd(Animator animation) {
-                    mScrimAnimator = null;
-                }
-            });
-            mScrimAnimator.setDuration(600);
-            mScrimAnimator.setStartDelay(getWindow().getTransitionBackgroundFadeDuration());
-            mScrimAnimator.start();
-        }
-        mShouldFadeInScrim = false;
         UiFactory.onStart(this);
     }
 
@@ -780,7 +757,6 @@
         super.onResume();
         TraceHelper.partitionSection("ON_RESUME", "superCall");
 
-        mAppLaunchSuccess = false;
         getUserEventDispatcher().resetElapsedSessionMillis();
         setOnResumeCallback(null);
         // Process any items that were added while Launcher was away.
@@ -920,7 +896,6 @@
         mOverviewPanel = findViewById(R.id.overview_panel);
         mOverviewPanelContainer = findViewById(R.id.overview_panel_container);
         mHotseat = findViewById(R.id.hotseat);
-        mDragHandleIndicator = findViewById(R.id.drag_indicator);
         mHotseatSearchBox = findViewById(R.id.search_container_hotseat);
 
         mLauncherView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
@@ -928,9 +903,8 @@
                 | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
 
         // Setup the drag layer
-        Runnable setupDragLayer = () -> mDragLayer.setup(mDragController);
-        UiFactory.setOnTouchControllersChangedListener(this, setupDragLayer);
-        setupDragLayer.run();
+        mDragLayer.setup(mDragController, mWorkspace);
+        UiFactory.setOnTouchControllersChangedListener(this, mDragLayer::recreateControllers);
 
         mWorkspace.setup(mDragController);
         // Until the workspace is bound, ensure that we keep the wallpaper offset locked to the
@@ -1107,21 +1081,13 @@
         hostView.setOnFocusChangeListener(mFocusHandler);
     }
 
-    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+    private final BroadcastReceiver mScreenOffReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
-            final String action = intent.getAction();
-            if (Intent.ACTION_SCREEN_OFF.equals(action)) {
-                // Reset AllApps to its initial state only if we are not in the middle of
-                // processing a multi-step drop
-                if (mAppsView != null && mPendingRequestArgs == null) {
-                    mStateManager.goToState(NORMAL);
-                }
-                mShouldFadeInScrim = true;
-            } else if (Intent.ACTION_USER_PRESENT.equals(action)) {
-                // ACTION_USER_PRESENT is sent after onStart/onResume. This covers the case where
-                // the user unlocked and the Launcher is not in the foreground.
-                mShouldFadeInScrim = false;
+            // Reset AllApps to its initial state only if we are not in the middle of
+            // processing a multi-step drop
+            if (mPendingRequestArgs == null) {
+                mStateManager.goToState(NORMAL);
             }
         }
     };
@@ -1181,10 +1147,6 @@
         return mHotseat;
     }
 
-    public View getDragHandleIndicator() {
-        return mDragHandleIndicator;
-    }
-
     public View getHotseatSearchBox() {
         return mHotseatSearchBox;
     }
@@ -1260,7 +1222,7 @@
                 }
 
                 // Reset the apps view
-                if (!alreadyOnHome && mAppsView != null) {
+                if (!alreadyOnHome) {
                     mAppsView.reset(isStarted() /* animate */);
                 }
 
@@ -1329,7 +1291,7 @@
     public void onDestroy() {
         super.onDestroy();
 
-        unregisterReceiver(mReceiver);
+        unregisterReceiver(mScreenOffReceiver);
         mWorkspace.removeFolderListeners();
 
         UiFactory.setOnTouchControllersChangedListener(this, null);
@@ -1342,7 +1304,6 @@
             LauncherAppState.getInstance(this).setLauncher(null);
         }
         mRotationHelper.destroy();
-        mSharedPrefs.unregisterOnSharedPreferenceChangeListener(mSharedPrefsListener);
 
         try {
             mAppWidgetHost.stopListening();
@@ -1669,8 +1630,8 @@
     }
 
     public boolean startActivitySafely(View v, Intent intent, ItemInfo item) {
-        mAppLaunchSuccess = super.startActivitySafely(v, intent, item);
-        if (mAppLaunchSuccess && v instanceof BubbleTextView) {
+        boolean success = super.startActivitySafely(v, intent, item);
+        if (success && v instanceof BubbleTextView) {
             // This is set to the view that launched the activity that navigated the user away
             // from launcher. Since there is no callback for when the activity has finished
             // launching, enable the press state and keep this reference to reset the press
@@ -1679,7 +1640,7 @@
             btv.setStayPressed(true);
             setOnResumeCallback(btv);
         }
-        return mAppLaunchSuccess;
+        return success;
     }
 
     boolean isHotseatLayout(View layout) {
@@ -2126,9 +2087,18 @@
 
     @Override
     public void finishFirstPageBind(final ViewOnDrawExecutor executor) {
-        if (mLauncherView.getAlpha() < 1) {
-            mLauncherView.animate().alpha(1).withEndAction(
-                    executor == null ? null : executor::onLoadAnimationCompleted).start();
+        AlphaProperty property = mDragLayer.getAlphaProperty(ALPHA_INDEX_LAUNCHER_LOAD);
+        if (property.getValue() < 1) {
+            ObjectAnimator anim = ObjectAnimator.ofFloat(property, MultiValueAlpha.VALUE, 1);
+            if (executor != null) {
+                anim.addListener(new AnimatorListenerAdapter() {
+                    @Override
+                    public void onAnimationEnd(Animator animation) {
+                        executor.onLoadAnimationCompleted();
+                    }
+                });
+            }
+            anim.start();
         } else if (executor != null) {
             executor.onLoadAnimationCompleted();
         }
@@ -2305,8 +2275,8 @@
         writer.print(prefix + "\tmWorkspaceLoading=" + mWorkspaceLoading);
         writer.print(" mPendingRequestArgs=" + mPendingRequestArgs);
         writer.println(" mPendingActivityResult=" + mPendingActivityResult);
-        writer.println(" deviceProfile isTransposed=" + getDeviceProfile().isVerticalBarLayout());
-        writer.println(" orientation=" + getResources().getConfiguration().orientation);
+        writer.println(" mRotationHelper: " + mRotationHelper);
+        dumpMisc(writer);
 
         try {
             FileLog.flushAll(writer);
@@ -2331,16 +2301,18 @@
             shortcutInfos.add(new KeyboardShortcutInfo(getString(R.string.all_apps_button_label),
                     KeyEvent.KEYCODE_A, KeyEvent.META_CTRL_ON));
         }
-        View currentFocus = getCurrentFocus();
-        if (new CustomActionsPopup(this, currentFocus).canShow()) {
-            shortcutInfos.add(new KeyboardShortcutInfo(getString(R.string.custom_actions),
-                    KeyEvent.KEYCODE_O, KeyEvent.META_CTRL_ON));
-        }
-        if (currentFocus.getTag() instanceof ItemInfo
-                && DeepShortcutManager.supportsShortcuts((ItemInfo) currentFocus.getTag())) {
-            shortcutInfos.add(new KeyboardShortcutInfo(
-                    getString(R.string.shortcuts_menu_with_notifications_description),
-                    KeyEvent.KEYCODE_S, KeyEvent.META_CTRL_ON));
+        final View currentFocus = getCurrentFocus();
+        if (currentFocus != null) {
+            if (new CustomActionsPopup(this, currentFocus).canShow()) {
+                shortcutInfos.add(new KeyboardShortcutInfo(getString(R.string.custom_actions),
+                        KeyEvent.KEYCODE_O, KeyEvent.META_CTRL_ON));
+            }
+            if (currentFocus.getTag() instanceof ItemInfo
+                    && DeepShortcutManager.supportsShortcuts((ItemInfo) currentFocus.getTag())) {
+                shortcutInfos.add(new KeyboardShortcutInfo(
+                        getString(R.string.shortcuts_menu_with_notifications_description),
+                        KeyEvent.KEYCODE_S, KeyEvent.META_CTRL_ON));
+            }
         }
         if (!shortcutInfos.isEmpty()) {
             data.add(new KeyboardShortcutGroup(getString(R.string.home_screen), shortcutInfos));
diff --git a/src/com/android/launcher3/LauncherAnimUtils.java b/src/com/android/launcher3/LauncherAnimUtils.java
index 9869fdf..03ffded 100644
--- a/src/com/android/launcher3/LauncherAnimUtils.java
+++ b/src/com/android/launcher3/LauncherAnimUtils.java
@@ -39,6 +39,9 @@
     public static final int SPRING_LOADED_TRANSITION_MS = 150;
     public static final int SPRING_LOADED_EXIT_DELAY = 500;
 
+    // The progress of an animation to all apps must be at least this far along to snap to all apps.
+    public static final float MIN_PROGRESS_TO_ALL_APPS = 0.5f;
+
     static WeakHashMap<Animator, Object> sAnimators = new WeakHashMap<Animator, Object>();
     static Animator.AnimatorListener sEndAnimListener = new Animator.AnimatorListener() {
         public void onAnimationStart(Animator animation) {
@@ -165,16 +168,8 @@
                 }
             };
 
-    public static final Property<View, Float> ELEVATION =
-            new Property<View, Float>(Float.class, "elevation") {
-                @Override
-                public Float get(View view) {
-                    return view.getElevation();
-                }
-
-                @Override
-                public void set(View view, Float elevation) {
-                    view.setElevation(elevation);
-                }
-            };
+    /** Increase the duration if we prevented the fling, as we are going against a high velocity. */
+    public static int blockedFlingDurationFactor(float velocity) {
+        return (int) Utilities.boundToRange(Math.abs(velocity) / 2, 2f, 6f);
+    }
 }
diff --git a/src/com/android/launcher3/LauncherRootView.java b/src/com/android/launcher3/LauncherRootView.java
index ad1456a2..3cf6d62 100644
--- a/src/com/android/launcher3/LauncherRootView.java
+++ b/src/com/android/launcher3/LauncherRootView.java
@@ -14,19 +14,14 @@
 import android.view.View;
 import android.view.ViewDebug;
 
-import com.android.launcher3.util.Themes;
-
 public class LauncherRootView extends InsettableFrameLayout {
 
     private final Launcher mLauncher;
 
     private final Paint mOpaquePaint;
+
     @ViewDebug.ExportedProperty(category = "launcher")
-    private boolean mDrawSideInsetBar;
-    @ViewDebug.ExportedProperty(category = "launcher")
-    private int mLeftInsetBarWidth;
-    @ViewDebug.ExportedProperty(category = "launcher")
-    private int mRightInsetBarWidth;
+    private final Rect mConsumedInsets = new Rect();
 
     private View mAlignedView;
     private WindowStateListener mWindowStateListener;
@@ -54,18 +49,26 @@
     @TargetApi(23)
     @Override
     protected boolean fitSystemWindows(Rect insets) {
-        mDrawSideInsetBar = (insets.right > 0 || insets.left > 0) &&
+        mConsumedInsets.setEmpty();
+        boolean drawInsetBar = false;
+        if (mLauncher.isInMultiWindowModeCompat()
+                && (insets.left > 0 || insets.right > 0 || insets.bottom > 0)) {
+            mConsumedInsets.left = insets.left;
+            mConsumedInsets.right = insets.right;
+            mConsumedInsets.bottom = insets.bottom;
+            insets = new Rect(0, insets.top, 0, 0);
+            drawInsetBar = true;
+        } else  if ((insets.right > 0 || insets.left > 0) &&
                 (!Utilities.ATLEAST_MARSHMALLOW ||
-                        getContext().getSystemService(ActivityManager.class).isLowRamDevice());
-        if (mDrawSideInsetBar) {
-            mLeftInsetBarWidth = insets.left;
-            mRightInsetBarWidth = insets.right;
+                        getContext().getSystemService(ActivityManager.class).isLowRamDevice())) {
+            mConsumedInsets.left = insets.left;
+            mConsumedInsets.right = insets.right;
             insets = new Rect(0, insets.top, 0, insets.bottom);
-        } else {
-            mLeftInsetBarWidth = mRightInsetBarWidth = 0;
+            drawInsetBar = true;
         }
+
         mLauncher.getSystemUiController().updateUiState(
-                UI_STATE_ROOT_VIEW, mDrawSideInsetBar ? FLAG_DARK_NAV : 0);
+                UI_STATE_ROOT_VIEW, drawInsetBar ? FLAG_DARK_NAV : 0);
 
         // Update device profile before notifying th children.
         mLauncher.getDeviceProfile().updateInsets(insets);
@@ -73,11 +76,14 @@
         setInsets(insets);
 
         if (mAlignedView != null) {
-            // Apply margins on aligned view to handle left/right insets.
+            // Apply margins on aligned view to handle consumed insets.
             MarginLayoutParams lp = (MarginLayoutParams) mAlignedView.getLayoutParams();
-            if (lp.leftMargin != mLeftInsetBarWidth || lp.rightMargin != mRightInsetBarWidth) {
-                lp.leftMargin = mLeftInsetBarWidth;
-                lp.rightMargin = mRightInsetBarWidth;
+            if (lp.leftMargin != mConsumedInsets.left || lp.rightMargin != mConsumedInsets.right ||
+                    lp.bottomMargin != mConsumedInsets.bottom) {
+                lp.leftMargin = mConsumedInsets.left;
+                lp.rightMargin = mConsumedInsets.right;
+                lp.topMargin = mConsumedInsets.top;
+                lp.bottomMargin = mConsumedInsets.bottom;
                 mAlignedView.setLayoutParams(lp);
             }
         }
@@ -95,8 +101,6 @@
         if (!insets.equals(mInsets)) {
             super.setInsets(insets);
         }
-        setBackground(insets.top == 0 ? null
-                : Themes.getAttrDrawable(getContext(), R.attr.workspaceStatusBarScrim));
     }
 
     public void dispatchInsets() {
@@ -109,14 +113,16 @@
         super.dispatchDraw(canvas);
 
         // If the right inset is opaque, draw a black rectangle to ensure that is stays opaque.
-        if (mDrawSideInsetBar) {
-            if (mRightInsetBarWidth > 0) {
-                int width = getWidth();
-                canvas.drawRect(width - mRightInsetBarWidth, 0, width, getHeight(), mOpaquePaint);
-            }
-            if (mLeftInsetBarWidth > 0) {
-                canvas.drawRect(0, 0, mLeftInsetBarWidth, getHeight(), mOpaquePaint);
-            }
+        if (mConsumedInsets.right > 0) {
+            int width = getWidth();
+            canvas.drawRect(width - mConsumedInsets.right, 0, width, getHeight(), mOpaquePaint);
+        }
+        if (mConsumedInsets.left > 0) {
+            canvas.drawRect(0, 0, mConsumedInsets.left, getHeight(), mOpaquePaint);
+        }
+        if (mConsumedInsets.bottom > 0) {
+            int height = getHeight();
+            canvas.drawRect(0, height - mConsumedInsets.bottom, getWidth(), height, mOpaquePaint);
         }
     }
 
diff --git a/src/com/android/launcher3/LauncherState.java b/src/com/android/launcher3/LauncherState.java
index 4697b82..fbe27b0 100644
--- a/src/com/android/launcher3/LauncherState.java
+++ b/src/com/android/launcher3/LauncherState.java
@@ -21,6 +21,7 @@
 import static com.android.launcher3.anim.Interpolators.ACCEL_2;
 import static com.android.launcher3.states.RotationHelper.REQUEST_NONE;
 
+import android.graphics.Rect;
 import android.view.View;
 import android.view.animation.Interpolator;
 
@@ -50,19 +51,17 @@
     public static final int ALL_APPS_HEADER = 1 << 2;
     public static final int ALL_APPS_HEADER_EXTRA = 1 << 3; // e.g. app predictions
     public static final int ALL_APPS_CONTENT = 1 << 4;
-    public static final int DRAG_HANDLE_INDICATOR = 1 << 5;
 
-    protected static final int FLAG_SHOW_SCRIM = 1 << 0;
-    protected static final int FLAG_MULTI_PAGE = 1 << 1;
-    protected static final int FLAG_DISABLE_ACCESSIBILITY = 1 << 2;
-    protected static final int FLAG_DISABLE_RESTORE = 1 << 3;
-    protected static final int FLAG_WORKSPACE_ICONS_CAN_BE_DRAGGED = 1 << 4;
-    protected static final int FLAG_DISABLE_PAGE_CLIPPING = 1 << 5;
-    protected static final int FLAG_PAGE_BACKGROUNDS = 1 << 6;
-    protected static final int FLAG_ALL_APPS_SCRIM = 1 << 7;
-    protected static final int FLAG_DISABLE_INTERACTION = 1 << 8;
-    protected static final int FLAG_OVERVIEW_UI = 1 << 9;
-    protected static final int FLAG_HIDE_BACK_BUTTON = 1 << 10;
+    protected static final int FLAG_MULTI_PAGE = 1 << 0;
+    protected static final int FLAG_DISABLE_ACCESSIBILITY = 1 << 1;
+    protected static final int FLAG_DISABLE_RESTORE = 1 << 2;
+    protected static final int FLAG_WORKSPACE_ICONS_CAN_BE_DRAGGED = 1 << 3;
+    protected static final int FLAG_DISABLE_PAGE_CLIPPING = 1 << 4;
+    protected static final int FLAG_PAGE_BACKGROUNDS = 1 << 5;
+    protected static final int FLAG_DISABLE_INTERACTION = 1 << 6;
+    protected static final int FLAG_OVERVIEW_UI = 1 << 7;
+    protected static final int FLAG_HIDE_BACK_BUTTON = 1 << 8;
+    protected static final int FLAG_HAS_SYS_UI_SCRIM = 1 << 9;
 
     protected static final PageAlphaProvider DEFAULT_ALPHA_PROVIDER =
             new PageAlphaProvider(ACCEL_2) {
@@ -77,8 +76,9 @@
     /**
      * TODO: Create a separate class for NORMAL state.
      */
-    public static final LauncherState NORMAL = new LauncherState(0, ContainerType.WORKSPACE,
-            0, FLAG_DISABLE_RESTORE | FLAG_WORKSPACE_ICONS_CAN_BE_DRAGGED | FLAG_HIDE_BACK_BUTTON);
+    public static final LauncherState NORMAL = new LauncherState(0, ContainerType.WORKSPACE, 0,
+            FLAG_DISABLE_RESTORE | FLAG_WORKSPACE_ICONS_CAN_BE_DRAGGED | FLAG_HIDE_BACK_BUTTON |
+            FLAG_HAS_SYS_UI_SCRIM);
 
     /**
      * Various Launcher states arranged in the increasing order of UI layers
@@ -88,6 +88,8 @@
     public static final LauncherState FAST_OVERVIEW = new FastOverviewState(3);
     public static final LauncherState ALL_APPS = new AllAppsState(4);
 
+    protected static final Rect sTempRect = new Rect();
+
     public final int ordinal;
 
     /**
@@ -116,9 +118,7 @@
      *
      * @see WorkspaceStateTransitionAnimation
      */
-    public final boolean hasScrim;
     public final boolean hasWorkspacePageBackground;
-    public final boolean hasAllAppsScrim;
 
     public final int transitionDuration;
 
@@ -149,14 +149,13 @@
      */
     public final boolean hideBackButton;
 
+    public final boolean hasSysUiScrim;
+
     public LauncherState(int id, int containerType, int transitionDuration, int flags) {
         this.containerType = containerType;
         this.transitionDuration = transitionDuration;
 
-        this.hasScrim = (flags & FLAG_SHOW_SCRIM) != 0;
         this.hasWorkspacePageBackground = (flags & FLAG_PAGE_BACKGROUNDS) != 0;
-        this.hasAllAppsScrim = (flags & FLAG_ALL_APPS_SCRIM) != 0;
-
         this.hasMultipleVisiblePages = (flags & FLAG_MULTI_PAGE) != 0;
         this.workspaceAccessibilityFlag = (flags & FLAG_DISABLE_ACCESSIBILITY) != 0
                 ? IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS
@@ -167,6 +166,7 @@
         this.disableInteraction = (flags & FLAG_DISABLE_INTERACTION) != 0;
         this.overviewUi = (flags & FLAG_OVERVIEW_UI) != 0;
         this.hideBackButton = (flags & FLAG_HIDE_BACK_BUTTON) != 0;
+        this.hasSysUiScrim = (flags & FLAG_HAS_SYS_UI_SCRIM) != 0;
 
         this.ordinal = id;
         sAllStates[id] = this;
@@ -186,7 +186,7 @@
      *   translationY factor where 0 is top aligned and 0.5 is centered vertically
      */
     public float[] getOverviewScaleAndTranslationYFactor(Launcher launcher) {
-        return new float[] {1.2f, 0.2f};
+        return new float[] {1.1f, 0f};
     }
 
     public void onStateEnabled(Launcher launcher) {
@@ -201,9 +201,9 @@
 
     public int getVisibleElements(Launcher launcher) {
         if (launcher.getDeviceProfile().isVerticalBarLayout()) {
-            return HOTSEAT_ICONS | DRAG_HANDLE_INDICATOR;
+            return HOTSEAT_ICONS;
         }
-        return HOTSEAT_ICONS | DRAG_HANDLE_INDICATOR | HOTSEAT_SEARCH_BOX;
+        return HOTSEAT_ICONS | HOTSEAT_SEARCH_BOX;
     }
 
     /**
@@ -215,6 +215,10 @@
         return 1f;
     }
 
+    public float getWorkspaceScrimAlpha(Launcher launcher) {
+        return 0;
+    }
+
     public String getDescription(Launcher launcher) {
         return launcher.getWorkspace().getCurrentPageDescription();
     }
diff --git a/src/com/android/launcher3/LauncherStateManager.java b/src/com/android/launcher3/LauncherStateManager.java
index 7f25301..e6fc4c6 100644
--- a/src/com/android/launcher3/LauncherStateManager.java
+++ b/src/com/android/launcher3/LauncherStateManager.java
@@ -16,7 +16,17 @@
 
 package com.android.launcher3;
 
+import static android.view.View.VISIBLE;
 import static com.android.launcher3.LauncherState.NORMAL;
+import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_OVERVIEW_FADE;
+import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_OVERVIEW_SCALE;
+import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_WORKSPACE_FADE;
+import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_WORKSPACE_SCALE;
+import static com.android.launcher3.anim.Interpolators.ACCEL;
+import static com.android.launcher3.anim.Interpolators.DEACCEL;
+import static com.android.launcher3.anim.Interpolators.DEACCEL_1_7;
+import static com.android.launcher3.anim.Interpolators.OVERSHOOT_1_2;
+import static com.android.launcher3.anim.Interpolators.clampToProgress;
 import static com.android.launcher3.anim.PropertySetter.NO_ANIM_PROPERTY_SETTER;
 
 import android.animation.Animator;
@@ -24,6 +34,7 @@
 import android.animation.AnimatorSet;
 import android.os.Handler;
 import android.os.Looper;
+import android.support.annotation.IntDef;
 import android.view.View;
 
 import com.android.launcher3.anim.AnimationSuccessListener;
@@ -33,6 +44,8 @@
 import com.android.launcher3.anim.PropertySetter.AnimatedPropertySetter;
 import com.android.launcher3.uioverrides.UiFactory;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
 
 /**
@@ -80,6 +93,21 @@
 
     public static final String TAG = "StateManager";
 
+    // We separate the state animations into "atomic" and "non-atomic" components. The atomic
+    // components may be run atomically - that is, all at once, instead of user-controlled. However,
+    // atomic components are not restricted to this purpose; they can be user-controlled alongside
+    // non atomic components as well.
+    @IntDef(flag = true, value = {
+            NON_ATOMIC_COMPONENT,
+            ATOMIC_COMPONENT
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface AnimationComponents {}
+    public static final int NON_ATOMIC_COMPONENT = 1 << 0;
+    public static final int ATOMIC_COMPONENT = 1 << 1;
+
+    public static final int ANIM_ALL = NON_ATOMIC_COMPONENT | ATOMIC_COMPONENT;
+
     private final AnimationConfig mConfig = new AnimationConfig();
     private final Handler mUiHandler;
     private final Launcher mLauncher;
@@ -219,8 +247,10 @@
         // transition plays in reverse and use the same duration as previous state.
         mConfig.duration = state == NORMAL ? mState.transitionDuration : state.transitionDuration;
 
+        AnimatorSetBuilder builder = new AnimatorSetBuilder();
+        prepareForAtomicAnimation(mState, state, builder);
         AnimatorSet animation = createAnimationToNewWorkspaceInternal(
-                state, new AnimatorSetBuilder(), onCompleteRunnable);
+                state, builder, onCompleteRunnable);
         Runnable runnable = new StartAnimRunnable(animation, state.getFinalFocus(mLauncher));
         if (delay > 0) {
             mUiHandler.postDelayed(runnable, delay);
@@ -230,6 +260,43 @@
     }
 
     /**
+     * Prepares for a non-user controlled animation from fromState to toState. Preparations include:
+     * - Setting interpolators for various animations included in the state transition.
+     * - Setting some start values (e.g. scale) for views that are hidden but about to be shown.
+     */
+    public void prepareForAtomicAnimation(LauncherState fromState, LauncherState toState,
+            AnimatorSetBuilder builder) {
+        if (fromState == NORMAL && toState.overviewUi) {
+            builder.setInterpolator(ANIM_WORKSPACE_SCALE, OVERSHOOT_1_2);
+            builder.setInterpolator(ANIM_WORKSPACE_FADE, OVERSHOOT_1_2);
+            builder.setInterpolator(ANIM_OVERVIEW_SCALE, OVERSHOOT_1_2);
+            builder.setInterpolator(ANIM_OVERVIEW_FADE, OVERSHOOT_1_2);
+
+            // Start from a higher overview scale, but only if we're invisible so we don't jump.
+            UiFactory.prepareToShowOverview(mLauncher);
+        } else if (fromState.overviewUi && toState == NORMAL) {
+            builder.setInterpolator(ANIM_WORKSPACE_SCALE, DEACCEL);
+            builder.setInterpolator(ANIM_WORKSPACE_FADE, ACCEL);
+            builder.setInterpolator(ANIM_OVERVIEW_SCALE, clampToProgress(ACCEL, 0, 0.9f));
+            builder.setInterpolator(ANIM_OVERVIEW_FADE, DEACCEL_1_7);
+            Workspace workspace = mLauncher.getWorkspace();
+
+            // Start from a higher workspace scale, but only if we're invisible so we don't jump.
+            boolean isWorkspaceVisible = workspace.getVisibility() == VISIBLE;
+            if (isWorkspaceVisible) {
+                CellLayout currentChild = (CellLayout) workspace.getChildAt(
+                        workspace.getCurrentPage());
+                isWorkspaceVisible = currentChild.getVisibility() == VISIBLE
+                        && currentChild.getShortcutsAndWidgets().getAlpha() > 0;
+            }
+            if (!isWorkspaceVisible) {
+                workspace.setScaleX(0.92f);
+                workspace.setScaleY(0.92f);
+            }
+        }
+    }
+
+    /**
      * Creates a {@link AnimatorPlaybackController} that can be used for a controlled
      * state transition.
      * @param state the final state for the transition.
@@ -238,13 +305,21 @@
      */
     public AnimatorPlaybackController createAnimationToNewWorkspace(
             LauncherState state, long duration) {
-        return createAnimationToNewWorkspace(state, new AnimatorSetBuilder(), duration, null);
+        return createAnimationToNewWorkspace(state, duration, LauncherStateManager.ANIM_ALL);
+    }
+
+    public AnimatorPlaybackController createAnimationToNewWorkspace(
+            LauncherState state, long duration, @AnimationComponents int animComponents) {
+        return createAnimationToNewWorkspace(state, new AnimatorSetBuilder(), duration, null,
+                animComponents);
     }
 
     public AnimatorPlaybackController createAnimationToNewWorkspace(LauncherState state,
-            AnimatorSetBuilder builder, long duration, Runnable onCancelRunnable) {
+            AnimatorSetBuilder builder, long duration, Runnable onCancelRunnable,
+            @AnimationComponents int animComponents) {
         mConfig.reset();
         mConfig.userControlled = true;
+        mConfig.animComponents = animComponents;
         mConfig.duration = duration;
         mConfig.playbackController = AnimatorPlaybackController.wrap(
                 createAnimationToNewWorkspaceInternal(state, builder, null), duration,
@@ -361,6 +436,7 @@
     }
 
     public void setCurrentUserControlledAnimation(AnimatorPlaybackController controller) {
+        clearCurrentAnimation();
         setCurrentAnimation(controller.getTarget());
         mConfig.userControlled = true;
         mConfig.playbackController = controller;
@@ -374,9 +450,15 @@
      */
     public void setCurrentAnimation(AnimatorSet anim, Animator... childAnimations) {
         for (Animator childAnim : childAnimations) {
-            if (childAnim != null && mConfig.mCurrentAnimation == childAnim) {
-                mConfig.mCurrentAnimation.removeListener(mConfig);
-                mConfig.mCurrentAnimation = null;
+            if (childAnim == null) {
+                continue;
+            }
+            if (mConfig.playbackController != null
+                    && mConfig.playbackController.getTarget() == childAnim) {
+                clearCurrentAnimation();
+                break;
+            } else if (mConfig.mCurrentAnimation == childAnim) {
+                clearCurrentAnimation();
                 break;
             }
         }
@@ -388,6 +470,14 @@
         mConfig.setAnimation(anim, null);
     }
 
+    private void clearCurrentAnimation() {
+        if (mConfig.mCurrentAnimation != null) {
+            mConfig.mCurrentAnimation.removeListener(mConfig);
+            mConfig.mCurrentAnimation = null;
+        }
+        mConfig.playbackController = null;
+    }
+
     private class StartAnimRunnable implements Runnable {
 
         private final AnimatorSet mAnim;
@@ -414,6 +504,7 @@
         public long duration;
         public boolean userControlled;
         public AnimatorPlaybackController playbackController;
+        public @AnimationComponents int animComponents = ANIM_ALL;
         private PropertySetter mPropertySetter;
 
         private AnimatorSet mCurrentAnimation;
@@ -425,6 +516,7 @@
         public void reset() {
             duration = 0;
             userControlled = false;
+            animComponents = ANIM_ALL;
             mPropertySetter = null;
             mTargetState = null;
 
@@ -460,6 +552,14 @@
             mTargetState = targetState;
             mCurrentAnimation.addListener(this);
         }
+
+        public boolean playAtomicComponent() {
+            return (animComponents & ATOMIC_COMPONENT) != 0;
+        }
+
+        public boolean playNonAtomicComponent() {
+            return (animComponents & NON_ATOMIC_COMPONENT) != 0;
+        }
     }
 
     public interface StateHandler {
diff --git a/src/com/android/launcher3/PagedView.java b/src/com/android/launcher3/PagedView.java
index 57f1386..a71fbf1 100644
--- a/src/com/android/launcher3/PagedView.java
+++ b/src/com/android/launcher3/PagedView.java
@@ -27,6 +27,7 @@
 import android.graphics.Matrix;
 import android.graphics.Rect;
 import android.os.Bundle;
+import android.provider.Settings;
 import android.util.AttributeSet;
 import android.util.Log;
 import android.view.InputDevice;
@@ -44,6 +45,7 @@
 import android.widget.ScrollView;
 
 import com.android.launcher3.anim.Interpolators;
+import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.pageindicators.PageIndicator;
 import com.android.launcher3.touch.OverScroll;
 import com.android.launcher3.util.Thunk;
@@ -92,7 +94,6 @@
 
     @ViewDebug.ExportedProperty(category = "launcher")
     protected int mCurrentPage;
-    private int mChildCountOnLastLayout;
 
     @ViewDebug.ExportedProperty(category = "launcher")
     protected int mNextPage = INVALID_PAGE;
@@ -108,7 +109,7 @@
     private float mLastMotionXRemainder;
     private float mTotalMotionX;
 
-    private int[] mPageScrolls;
+    protected int[] mPageScrolls;
 
     protected final static int TOUCH_STATE_REST = 0;
     protected final static int TOUCH_STATE_SCROLLING = 1;
@@ -239,6 +240,12 @@
         return index;
     }
 
+    protected void scrollAndForceFinish(int scrollX) {
+        scrollTo(scrollX, 0);
+        mScroller.setFinalX(scrollX);
+        forceFinishScroller(true);
+    }
+
     /**
      * Updates the scroll of the current page immediately to its final scroll position.  We use this
      * in CustomizePagedView to allow tabs to share the same PagedView while resetting the scroll of
@@ -250,9 +257,7 @@
         if (0 <= mCurrentPage && mCurrentPage < getPageCount()) {
             newX = getScrollForPage(mCurrentPage);
         }
-        scrollTo(newX, 0);
-        mScroller.setFinalX(newX);
-        forceFinishScroller(true);
+        scrollAndForceFinish(newX);
     }
 
     private void abortScrollerAnimation(boolean resetNextPage) {
@@ -539,22 +544,27 @@
         setMeasuredDimension(widthSize, heightSize);
     }
 
+    protected void restoreScrollOnLayout() {
+        setCurrentPage(getNextPage());
+    }
+
     @SuppressLint("DrawAllocation")
     @Override
     protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
         mIsLayoutValid = true;
-        if (getChildCount() == 0) {
+        final int childCount = getChildCount();
+        boolean pageScrollChanged = false;
+        if (mPageScrolls == null || childCount != mPageScrolls.length) {
+            mPageScrolls = new int[childCount];
+            pageScrollChanged = true;
+        }
+
+        if (childCount == 0) {
             return;
         }
 
         if (DEBUG) Log.d(TAG, "PagedView.onLayout()");
-        final int childCount = getChildCount();
 
-        boolean pageScrollChanged = false;
-        if (mPageScrolls == null || childCount != mChildCountOnLastLayout) {
-            mPageScrolls = new int[childCount];
-            pageScrollChanged = true;
-        }
         if (getPageScrolls(mPageScrolls, true, SIMPLE_SCROLL_LOGIC)) {
             pageScrollChanged = true;
         }
@@ -589,9 +599,8 @@
         }
 
         if (mScroller.isFinished() && pageScrollChanged) {
-            setCurrentPage(getNextPage());
+            restoreScrollOnLayout();
         }
-        mChildCountOnLastLayout = childCount;
     }
 
     /**
@@ -1422,7 +1431,7 @@
         return snapToPage(whichPage, duration, false, null);
     }
 
-    protected boolean snapToPage(int whichPage, int duration, TimeInterpolator interpolator) {
+    public boolean snapToPage(int whichPage, int duration, TimeInterpolator interpolator) {
         return snapToPage(whichPage, duration, false, interpolator);
     }
 
@@ -1441,6 +1450,12 @@
 
     protected boolean snapToPage(int whichPage, int delta, int duration, boolean immediate,
             TimeInterpolator interpolator) {
+
+        if (FeatureFlags.IS_DOGFOOD_BUILD) {
+            duration *= Settings.System.getFloat(getContext().getContentResolver(),
+                    Settings.System.WINDOW_ANIMATION_SCALE, 1);
+        }
+
         whichPage = validateNewPage(whichPage);
 
         mNextPage = whichPage;
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index bd7e6eb..2df34d5 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -22,6 +22,7 @@
 import static com.android.launcher3.LauncherState.ALL_APPS;
 import static com.android.launcher3.LauncherState.NORMAL;
 import static com.android.launcher3.LauncherState.SPRING_LOADED;
+import static com.android.launcher3.dragndrop.DragLayer.ALPHA_INDEX_OVERLAY;
 
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
@@ -75,14 +76,11 @@
 import com.android.launcher3.folder.PreviewBackground;
 import com.android.launcher3.graphics.DragPreviewProvider;
 import com.android.launcher3.graphics.PreloadIconDrawable;
-import com.android.launcher3.graphics.ViewScrim;
-import com.android.launcher3.graphics.WorkspaceAndHotseatScrim;
 import com.android.launcher3.pageindicators.WorkspacePageIndicator;
 import com.android.launcher3.popup.PopupContainerWithArrow;
 import com.android.launcher3.shortcuts.ShortcutDragPreviewProvider;
 import com.android.launcher3.touch.ItemLongClickListener;
 import com.android.launcher3.touch.WorkspaceTouchListener;
-import com.android.launcher3.uioverrides.UiFactory;
 import com.android.launcher3.userevent.nano.LauncherLogProto.Action;
 import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
 import com.android.launcher3.userevent.nano.LauncherLogProto.Target;
@@ -195,7 +193,7 @@
 
     // Variables relating to the creation of user folders by hovering shortcuts over shortcuts
     private static final int FOLDER_CREATION_TIMEOUT = 0;
-    public static final int REORDER_TIMEOUT = 350;
+    public static final int REORDER_TIMEOUT = 650;
     private final Alarm mFolderCreationAlarm = new Alarm();
     private final Alarm mReorderAlarm = new Alarm();
     private PreviewBackground mFolderCreateBg;
@@ -280,9 +278,6 @@
 
         // Disable multitouch across the workspace/all apps/customize tray
         setMotionEventSplittingEnabled(true);
-
-        // Attach a scrim
-        new WorkspaceAndHotseatScrim(this).attach();
         setOnTouchListener(new WorkspaceTouchListener(mLauncher, this));
     }
 
@@ -1180,7 +1175,7 @@
         // different effects based on device performance. On at least one relatively high-end
         // device I've tried, translating the launcher causes things to get quite laggy.
         mLauncher.getDragLayer().setTranslationX(transX);
-        mLauncher.getDragLayer().setAlpha(alpha);
+        mLauncher.getDragLayer().getAlphaProperty(ALPHA_INDEX_OVERLAY).setValue(alpha);
     }
 
     /**
@@ -1302,7 +1297,9 @@
     }
 
     private void updatePageAlphaValues() {
-        if (!workspaceInModalState() && !mIsSwitchingState) {
+        // We need to check the isDragging case because updatePageAlphaValues is called between
+        // goToState(SPRING_LOADED) and onStartStateTransition.
+        if (!workspaceInModalState() && !mIsSwitchingState && !mDragController.isDragging()) {
             int screenCenter = getScrollX() + getMeasuredWidth() / 2;
             for (int i = 0; i < getChildCount(); i++) {
                 CellLayout child = (CellLayout) getChildAt(i);
@@ -2153,7 +2150,7 @@
         }
         // Invalidating the scrim will also force this CellLayout
         // to be invalidated so that it is highlighted if necessary.
-        ViewScrim.get(this).invalidate();
+        mLauncher.getDragLayer().getScrim().invalidate();
     }
 
     public CellLayout getCurrentDragOverlappingLayout() {
diff --git a/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java b/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java
index 77a45bf..e734e70 100644
--- a/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java
+++ b/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java
@@ -18,19 +18,24 @@
 
 import static com.android.launcher3.LauncherAnimUtils.DRAWABLE_ALPHA;
 import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY;
-import static com.android.launcher3.LauncherState.DRAG_HANDLE_INDICATOR;
 import static com.android.launcher3.LauncherState.HOTSEAT_ICONS;
 import static com.android.launcher3.LauncherState.HOTSEAT_SEARCH_BOX;
+import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_WORKSPACE_FADE;
+import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_WORKSPACE_SCALE;
+import static com.android.launcher3.anim.Interpolators.LINEAR;
+import static com.android.launcher3.anim.Interpolators.ZOOM_OUT;
 import static com.android.launcher3.anim.PropertySetter.NO_ANIM_PROPERTY_SETTER;
+import static com.android.launcher3.graphics.WorkspaceAndHotseatScrim.SCRIM_PROGRESS;
+import static com.android.launcher3.graphics.WorkspaceAndHotseatScrim.SYSUI_PROGRESS;
 
 import android.view.View;
+import android.view.animation.Interpolator;
 
 import com.android.launcher3.LauncherState.PageAlphaProvider;
 import com.android.launcher3.LauncherStateManager.AnimationConfig;
 import com.android.launcher3.anim.AnimatorSetBuilder;
-import com.android.launcher3.anim.Interpolators;
 import com.android.launcher3.anim.PropertySetter;
-import com.android.launcher3.graphics.ViewScrim;
+import com.android.launcher3.graphics.WorkspaceAndHotseatScrim;
 
 /**
  * Manages the animations between each of the workspace states.
@@ -48,12 +53,13 @@
     }
 
     public void setState(LauncherState toState) {
-        setWorkspaceProperty(toState, NO_ANIM_PROPERTY_SETTER);
+        setWorkspaceProperty(toState, NO_ANIM_PROPERTY_SETTER, new AnimatorSetBuilder(),
+                new AnimationConfig());
     }
 
     public void setStateWithAnimation(LauncherState toState, AnimatorSetBuilder builder,
             AnimationConfig config) {
-        setWorkspaceProperty(toState, config.getPropertySetter(builder));
+        setWorkspaceProperty(toState, config.getPropertySetter(builder), builder, config);
     }
 
     public float getFinalScale() {
@@ -63,57 +69,72 @@
     /**
      * Starts a transition animation for the workspace.
      */
-    private void setWorkspaceProperty(LauncherState state, PropertySetter propertySetter) {
+    private void setWorkspaceProperty(LauncherState state, PropertySetter propertySetter,
+            AnimatorSetBuilder builder, AnimationConfig config) {
         float[] scaleAndTranslation = state.getWorkspaceScaleAndTranslation(mLauncher);
         mNewScale = scaleAndTranslation[0];
         PageAlphaProvider pageAlphaProvider = state.getWorkspacePageAlphaProvider(mLauncher);
         final int childCount = mWorkspace.getChildCount();
         for (int i = 0; i < childCount; i++) {
             applyChildState(state, (CellLayout) mWorkspace.getChildAt(i), i, pageAlphaProvider,
-                    propertySetter);
+                    propertySetter, builder, config);
         }
 
-        propertySetter.setFloat(mWorkspace, SCALE_PROPERTY, mNewScale, Interpolators.ZOOM_OUT);
-        propertySetter.setFloat(mWorkspace, View.TRANSLATION_X,
-                scaleAndTranslation[1], Interpolators.ZOOM_OUT);
-        propertySetter.setFloat(mWorkspace, View.TRANSLATION_Y,
-                scaleAndTranslation[2], Interpolators.ZOOM_OUT);
-
         int elements = state.getVisibleElements(mLauncher);
-        float hotseatIconsAlpha = (elements & HOTSEAT_ICONS) != 0 ? 1 : 0;
-        propertySetter.setViewAlpha(mLauncher.getHotseat().getLayout(), hotseatIconsAlpha,
+        Interpolator fadeInterpolator = builder.getInterpolator(ANIM_WORKSPACE_FADE,
                 pageAlphaProvider.interpolator);
-        propertySetter.setViewAlpha(mLauncher.getWorkspace().getPageIndicator(),
-                hotseatIconsAlpha, pageAlphaProvider.interpolator);
+        boolean playAtomicComponent = config.playAtomicComponent();
+        if (playAtomicComponent) {
+            Interpolator scaleInterpolator = builder.getInterpolator(ANIM_WORKSPACE_SCALE, ZOOM_OUT);
+            propertySetter.setFloat(mWorkspace, SCALE_PROPERTY, mNewScale, scaleInterpolator);
+            float hotseatIconsAlpha = (elements & HOTSEAT_ICONS) != 0 ? 1 : 0;
+            propertySetter.setViewAlpha(mLauncher.getHotseat().getLayout(), hotseatIconsAlpha,
+                    fadeInterpolator);
+            propertySetter.setViewAlpha(mLauncher.getWorkspace().getPageIndicator(),
+                    hotseatIconsAlpha, fadeInterpolator);
+        }
+
+        if (!config.playNonAtomicComponent()) {
+            // Only the alpha and scale, handled above, are included in the atomic animation.
+            return;
+        }
+
+        Interpolator translationInterpolator = !playAtomicComponent ? LINEAR : ZOOM_OUT;
+        propertySetter.setFloat(mWorkspace, View.TRANSLATION_X,
+                scaleAndTranslation[1], translationInterpolator);
+        propertySetter.setFloat(mWorkspace, View.TRANSLATION_Y,
+                scaleAndTranslation[2], translationInterpolator);
 
         propertySetter.setViewAlpha(mLauncher.getHotseatSearchBox(),
-                (elements & HOTSEAT_SEARCH_BOX) != 0 ? 1 : 0,
-                pageAlphaProvider.interpolator);
-
-        propertySetter.setViewAlpha(mLauncher.getDragHandleIndicator(),
-                (elements & DRAG_HANDLE_INDICATOR) != 0 ? 1 : 0,
-                pageAlphaProvider.interpolator);
+                (elements & HOTSEAT_SEARCH_BOX) != 0 ? 1 : 0, fadeInterpolator);
 
         // Set scrim
-        propertySetter.setFloat(ViewScrim.get(mWorkspace), ViewScrim.PROGRESS,
-                state.hasScrim ? 1 : 0, Interpolators.LINEAR);
-        propertySetter.setFloat(ViewScrim.get(mLauncher.getAppsView()), ViewScrim.PROGRESS,
-                state.hasAllAppsScrim ? 1 : 0, Interpolators.LINEAR);
+        WorkspaceAndHotseatScrim scrim = mLauncher.getDragLayer().getScrim();
+        propertySetter.setFloat(scrim, SCRIM_PROGRESS, state.getWorkspaceScrimAlpha(mLauncher),
+                LINEAR);
+        propertySetter.setFloat(scrim, SYSUI_PROGRESS, state.hasSysUiScrim ? 1 : 0, LINEAR);
     }
 
     public void applyChildState(LauncherState state, CellLayout cl, int childIndex) {
         applyChildState(state, cl, childIndex, state.getWorkspacePageAlphaProvider(mLauncher),
-                NO_ANIM_PROPERTY_SETTER);
+                NO_ANIM_PROPERTY_SETTER, new AnimatorSetBuilder(), new AnimationConfig());
     }
 
     private void applyChildState(LauncherState state, CellLayout cl, int childIndex,
-            PageAlphaProvider pageAlphaProvider, PropertySetter propertySetter) {
+            PageAlphaProvider pageAlphaProvider, PropertySetter propertySetter,
+            AnimatorSetBuilder builder, AnimationConfig config) {
         float pageAlpha = pageAlphaProvider.getPageAlpha(childIndex);
         int drawableAlpha = Math.round(pageAlpha * (state.hasWorkspacePageBackground ? 255 : 0));
 
-        propertySetter.setInt(cl.getScrimBackground(),
-                DRAWABLE_ALPHA, drawableAlpha, Interpolators.ZOOM_OUT);
-        propertySetter.setFloat(cl.getShortcutsAndWidgets(), View.ALPHA,
-                pageAlpha, pageAlphaProvider.interpolator);
+        if (config.playNonAtomicComponent()) {
+            propertySetter.setInt(cl.getScrimBackground(),
+                    DRAWABLE_ALPHA, drawableAlpha, ZOOM_OUT);
+        }
+        if (config.playAtomicComponent()) {
+            Interpolator fadeInterpolator = builder.getInterpolator(ANIM_WORKSPACE_FADE,
+                    pageAlphaProvider.interpolator);
+            propertySetter.setFloat(cl.getShortcutsAndWidgets(), View.ALPHA,
+                    pageAlpha, fadeInterpolator);
+        }
     }
 }
\ No newline at end of file
diff --git a/src/com/android/launcher3/allapps/AllAppsContainerView.java b/src/com/android/launcher3/allapps/AllAppsContainerView.java
index 211d98f..f8648bb 100644
--- a/src/com/android/launcher3/allapps/AllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsContainerView.java
@@ -47,7 +47,6 @@
 import com.android.launcher3.R;
 import com.android.launcher3.Utilities;
 import com.android.launcher3.config.FeatureFlags;
-import com.android.launcher3.uioverrides.AllAppsScrim;
 import com.android.launcher3.keyboard.FocusedItemDecorator;
 import com.android.launcher3.userevent.nano.LauncherLogProto.Target;
 import com.android.launcher3.util.ItemInfoMatcher;
@@ -110,9 +109,6 @@
 
         mAllAppsStore.addUpdateListener(this::onAppsUpdated);
 
-        // Attach a scrim to be drawn behind all-apps and hotseat
-        new AllAppsScrim(this).attach();
-
         addSpringView(R.id.all_apps_header);
         addSpringView(R.id.apps_list_view);
         addSpringView(R.id.all_apps_tabs_view_pager);
diff --git a/src/com/android/launcher3/allapps/AllAppsTransitionController.java b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
index 53d3da6..b5c821a 100644
--- a/src/com/android/launcher3/allapps/AllAppsTransitionController.java
+++ b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
@@ -3,6 +3,8 @@
 import static com.android.launcher3.LauncherState.ALL_APPS_CONTENT;
 import static com.android.launcher3.LauncherState.ALL_APPS_HEADER;
 import static com.android.launcher3.LauncherState.ALL_APPS_HEADER_EXTRA;
+import static com.android.launcher3.LauncherState.OVERVIEW;
+import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_OVERVIEW_SCALE;
 import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_VERTICAL_PROGRESS;
 import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN;
 import static com.android.launcher3.anim.Interpolators.LINEAR;
@@ -23,12 +25,13 @@
 import com.android.launcher3.LauncherStateManager.AnimationConfig;
 import com.android.launcher3.LauncherStateManager.StateHandler;
 import com.android.launcher3.R;
+import com.android.launcher3.Utilities;
 import com.android.launcher3.anim.AnimationSuccessListener;
 import com.android.launcher3.anim.AnimatorSetBuilder;
 import com.android.launcher3.anim.PropertySetter;
-import com.android.launcher3.uioverrides.AllAppsScrim;
-import com.android.launcher3.graphics.ViewScrim;
+import com.android.launcher3.uioverrides.UiFactory;
 import com.android.launcher3.util.Themes;
+import com.android.launcher3.views.ScrimView;
 
 /**
  * Handles AllApps view transition.
@@ -57,7 +60,7 @@
     };
 
     private AllAppsContainerView mAppsView;
-    private AllAppsScrim mAllAppsScrim;
+    private ScrimView mScrimView;
 
     private final Launcher mLauncher;
     private final boolean mIsDarkTheme;
@@ -102,7 +105,6 @@
             mAppsView.setAlpha(1);
             mLauncher.getHotseat().setTranslationY(0);
             mLauncher.getWorkspace().getPageIndicator().setTranslationY(0);
-            mLauncher.getDragHandleIndicator().setTranslationY(0);
         }
     }
 
@@ -117,7 +119,7 @@
      */
     public void setProgress(float progress) {
         mProgress = progress;
-        mAllAppsScrim.onVerticalProgress(progress);
+        mScrimView.setProgress(progress);
         float shiftCurrent = progress * mShiftRange;
 
         mAppsView.setTranslationY(shiftCurrent);
@@ -126,12 +128,12 @@
         if (!mIsVerticalLayout) {
             mLauncher.getHotseat().setTranslationY(hotseatTranslation);
             mLauncher.getWorkspace().getPageIndicator().setTranslationY(hotseatTranslation);
-            mLauncher.getDragHandleIndicator().setTranslationY(hotseatTranslation);
         }
 
         // Use a light system UI (dark icons) if all apps is behind at least half of the
         // status bar.
-        boolean forceChange = shiftCurrent <= mShiftRange / 4;
+        boolean forceChange = shiftCurrent - mScrimView.getDragHandleSize()
+                <= mLauncher.getDeviceProfile().getInsets().top / 2;
         if (forceChange) {
             mLauncher.getSystemUiController().updateUiState(UI_STATE_ALL_APPS, !mIsDarkTheme);
         } else {
@@ -169,12 +171,26 @@
             return;
         }
 
-        Interpolator interpolator = config.userControlled ? LINEAR : FAST_OUT_SLOW_IN;
+        if (!config.playNonAtomicComponent()) {
+            // There is no atomic component for the all apps transition, so just return early.
+            return;
+        }
+
+        Interpolator interpolator = config.userControlled ? LINEAR : toState == OVERVIEW
+                ? builder.getInterpolator(ANIM_OVERVIEW_SCALE, FAST_OUT_SLOW_IN)
+                : FAST_OUT_SLOW_IN;
         ObjectAnimator anim =
                 ObjectAnimator.ofFloat(this, ALL_APPS_PROGRESS, mProgress, targetProgress);
         anim.setDuration(config.duration);
         anim.setInterpolator(builder.getInterpolator(ANIM_VERTICAL_PROGRESS, interpolator));
         anim.addListener(getProgressAnimatorListener());
+        if (toState.hideBackButton) {
+            anim.addUpdateListener(animation -> {
+                final float alpha = (float) animation.getAnimatedValue();
+                UiFactory.setBackButtonAlpha(mLauncher, 1 - Utilities.boundToRange(alpha, 0, 1),
+                        false /* animate */);
+            });
+        }
 
         builder.play(anim);
 
@@ -209,8 +225,7 @@
 
     public void setupViews(AllAppsContainerView appsView) {
         mAppsView = appsView;
-        mAllAppsScrim = (AllAppsScrim) ViewScrim.get(mAppsView);
-        mAllAppsScrim.reInitUi();
+        mScrimView = mLauncher.findViewById(R.id.scrim_view);
     }
 
     /**
@@ -220,8 +235,8 @@
         mScrollRangeDelta = delta;
         mShiftRange = mLauncher.getDeviceProfile().heightPx - mScrollRangeDelta;
 
-        if (mAllAppsScrim != null) {
-            mAllAppsScrim.reInitUi();
+        if (mScrimView != null) {
+            mScrimView.reInitUi();
         }
     }
 
diff --git a/src/com/android/launcher3/allapps/DiscoveryBounce.java b/src/com/android/launcher3/allapps/DiscoveryBounce.java
index 8f1c8df..deaf8d3 100644
--- a/src/com/android/launcher3/allapps/DiscoveryBounce.java
+++ b/src/com/android/launcher3/allapps/DiscoveryBounce.java
@@ -18,6 +18,8 @@
 
 import static com.android.launcher3.LauncherState.NORMAL;
 import static com.android.launcher3.LauncherState.OVERVIEW;
+import static com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType.HOTSEAT;
+import static com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType.PREDICTION;
 
 import android.animation.Animator;
 import android.animation.AnimatorInflater;
@@ -127,6 +129,7 @@
                 AnimatorInflater.loadAnimator(launcher, R.animator.discovery_bounce));
         view.mIsOpen = true;
         launcher.getDragLayer().addView(view);
+        launcher.getUserEventDispatcher().logActionBounceTip(HOTSEAT);
     }
 
     public static void showForOverviewIfNeeded(Launcher launcher) {
@@ -156,14 +159,14 @@
         float verticalProgress = OVERVIEW.getVerticalProgress(launcher);
 
         TimeInterpolator pathInterpolator = new PathInterpolator(0.35f, 0, 0.5f, 1);
-        Keyframe keyframe3 = Keyframe.ofFloat(0.423f, verticalProgress - (1 - 0.9438f));
+        Keyframe keyframe3 = Keyframe.ofFloat(0.423f, verticalProgress - (1 - 0.9738f));
         keyframe3.setInterpolator(pathInterpolator);
-        Keyframe keyframe4 = Keyframe.ofFloat(0.654f, verticalProgress);
+        Keyframe keyframe4 = Keyframe.ofFloat(0.754f, verticalProgress);
         keyframe4.setInterpolator(pathInterpolator);
 
         PropertyValuesHolder propertyValuesHolder = PropertyValuesHolder.ofKeyframe("progress",
                 Keyframe.ofFloat(0, verticalProgress),
-                Keyframe.ofFloat(0.346f, verticalProgress), keyframe3, keyframe4,
+                Keyframe.ofFloat(0.246f, verticalProgress), keyframe3, keyframe4,
                 Keyframe.ofFloat(1f, verticalProgress));
         ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(null,
                 new PropertyValuesHolder[]{propertyValuesHolder});
@@ -173,5 +176,6 @@
         DiscoveryBounce view = new DiscoveryBounce(launcher, animator);
         view.mIsOpen = true;
         launcher.getDragLayer().addView(view);
+        launcher.getUserEventDispatcher().logActionBounceTip(PREDICTION);
     }
 }
diff --git a/src/com/android/launcher3/allapps/FloatingHeaderView.java b/src/com/android/launcher3/allapps/FloatingHeaderView.java
index 5a66ccd..462e7f3 100644
--- a/src/com/android/launcher3/allapps/FloatingHeaderView.java
+++ b/src/com/android/launcher3/allapps/FloatingHeaderView.java
@@ -96,7 +96,7 @@
         mMainRV = setupRV(mMainRV, mAH[AllAppsContainerView.AdapterHolder.MAIN].recyclerView);
         mWorkRV = setupRV(mWorkRV, mAH[AllAppsContainerView.AdapterHolder.WORK].recyclerView);
         mParent = (ViewGroup) mMainRV.getParent();
-        setMainActive(mMainRVActive);
+        setMainActive(mMainRVActive || mWorkRV == null);
         reset(false);
     }
 
diff --git a/src/com/android/launcher3/anim/AnimatorPlaybackController.java b/src/com/android/launcher3/anim/AnimatorPlaybackController.java
index 8e729e8..84085cb 100644
--- a/src/com/android/launcher3/anim/AnimatorPlaybackController.java
+++ b/src/com/android/launcher3/anim/AnimatorPlaybackController.java
@@ -206,6 +206,10 @@
         mOnCancelRunnable = runnable;
     }
 
+    public Runnable getOnCancelRunnable() {
+        return mOnCancelRunnable;
+    }
+
     public static class AnimatorPlaybackControllerVL extends AnimatorPlaybackController {
 
         private final ValueAnimator[] mChildAnimations;
diff --git a/src/com/android/launcher3/anim/AnimatorSetBuilder.java b/src/com/android/launcher3/anim/AnimatorSetBuilder.java
index b209a2d..f10bce8 100644
--- a/src/com/android/launcher3/anim/AnimatorSetBuilder.java
+++ b/src/com/android/launcher3/anim/AnimatorSetBuilder.java
@@ -16,7 +16,6 @@
 package com.android.launcher3.anim;
 
 import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
 import android.animation.AnimatorSet;
 import android.util.SparseArray;
 import android.view.animation.Interpolator;
@@ -32,7 +31,10 @@
 public class AnimatorSetBuilder {
 
     public static final int ANIM_VERTICAL_PROGRESS = 0;
-    public static final int ANIM_OVERVIEW_TRANSLATION = 1;
+    public static final int ANIM_WORKSPACE_SCALE = 1;
+    public static final int ANIM_WORKSPACE_FADE = 2;
+    public static final int ANIM_OVERVIEW_SCALE = 3;
+    public static final int ANIM_OVERVIEW_FADE = 4;
 
     protected final ArrayList<Animator> mAnims = new ArrayList<>();
 
@@ -56,9 +58,9 @@
         AnimatorSet anim = LauncherAnimUtils.createAnimatorSet();
         anim.playTogether(mAnims);
         if (!mOnFinishRunnables.isEmpty()) {
-            anim.addListener(new AnimatorListenerAdapter() {
+            anim.addListener(new AnimationSuccessListener() {
                 @Override
-                public void onAnimationEnd(Animator animation) {
+                public void onAnimationSuccess(Animator animation) {
                     for (Runnable onFinishRunnable : mOnFinishRunnables) {
                         onFinishRunnable.run();
                     }
diff --git a/src/com/android/launcher3/anim/Interpolators.java b/src/com/android/launcher3/anim/Interpolators.java
index 06ddf22..bace7df 100644
--- a/src/com/android/launcher3/anim/Interpolators.java
+++ b/src/com/android/launcher3/anim/Interpolators.java
@@ -38,6 +38,7 @@
 
     public static final Interpolator DEACCEL = new DecelerateInterpolator();
     public static final Interpolator DEACCEL_1_5 = new DecelerateInterpolator(1.5f);
+    public static final Interpolator DEACCEL_1_7 = new DecelerateInterpolator(1.7f);
     public static final Interpolator DEACCEL_2 = new DecelerateInterpolator(2);
     public static final Interpolator DEACCEL_2_5 = new DecelerateInterpolator(2.5f);
     public static final Interpolator DEACCEL_3 = new DecelerateInterpolator(3f);
@@ -57,9 +58,7 @@
         EXAGGERATED_EASE = new PathInterpolator(exaggeratedEase);
     }
 
-    public static final Interpolator APP_CLOSE_ALPHA = new PathInterpolator(0.4f, 0, 1f, 1f);
-
-    public static final Interpolator OVERSHOOT_0 = new OvershootInterpolator(0);
+    public static final Interpolator OVERSHOOT_1_2 = new OvershootInterpolator(1.2f);
 
     public static final Interpolator TOUCH_RESPONSE_INTERPOLATOR =
             new PathInterpolator(0.3f, 0f, 0.1f, 1f);
@@ -116,4 +115,24 @@
     public static Interpolator scrollInterpolatorForVelocity(float velocity) {
         return Math.abs(velocity) > FAST_FLING_PX_MS ? SCROLL : SCROLL_CUBIC;
     }
+
+    /**
+     * Runs the given interpolator such that the entire progress is set between the given bounds.
+     * That is, we set the interpolation to 0 until lowerBound and reach 1 by upperBound.
+     */
+    public static Interpolator clampToProgress(Interpolator interpolator, float lowerBound,
+            float upperBound) {
+        if (upperBound <= lowerBound) {
+            throw new IllegalArgumentException("lowerBound must be less than upperBound");
+        }
+        return t -> {
+            if (t < lowerBound) {
+                return 0;
+            }
+            if (t > upperBound) {
+                return 1;
+            }
+            return interpolator.getInterpolation((t - lowerBound) / (upperBound - lowerBound));
+        };
+    }
 }
\ No newline at end of file
diff --git a/src/com/android/launcher3/dragndrop/DragLayer.java b/src/com/android/launcher3/dragndrop/DragLayer.java
index 8519365..53e9e2d 100644
--- a/src/com/android/launcher3/dragndrop/DragLayer.java
+++ b/src/com/android/launcher3/dragndrop/DragLayer.java
@@ -1,3 +1,4 @@
+
 /*
  * Copyright (C) 2008 The Android Open Source Project
  *
@@ -42,10 +43,12 @@
 import com.android.launcher3.Launcher;
 import com.android.launcher3.R;
 import com.android.launcher3.ShortcutAndWidgetContainer;
+import com.android.launcher3.Workspace;
 import com.android.launcher3.anim.Interpolators;
 import com.android.launcher3.folder.Folder;
 import com.android.launcher3.folder.FolderIcon;
 import com.android.launcher3.graphics.ViewScrim;
+import com.android.launcher3.graphics.WorkspaceAndHotseatScrim;
 import com.android.launcher3.keyboard.ViewGroupFocusHelper;
 import com.android.launcher3.uioverrides.UiFactory;
 import com.android.launcher3.util.Thunk;
@@ -58,6 +61,12 @@
  */
 public class DragLayer extends BaseDragLayer<Launcher> {
 
+    public static final int ALPHA_INDEX_OVERLAY = 0;
+    public static final int ALPHA_INDEX_LAUNCHER_LOAD = 1;
+    public static final int ALPHA_INDEX_TRANSITIONS = 2;
+    public static final int ALPHA_INDEX_SWIPE_UP = 3;
+    private static final int ALPHA_CHANNEL_COUNT = 4;
+
     public static final int ANIMATION_END_DISAPPEAR = 0;
     public static final int ANIMATION_END_REMAIN_VISIBLE = 2;
 
@@ -77,6 +86,7 @@
 
     // Related to adjacent page hints
     private final ViewGroupFocusHelper mFocusIndicatorHelper;
+    private final WorkspaceAndHotseatScrim mScrim;
 
     /**
      * Used to create a new DragLayer from XML.
@@ -85,17 +95,23 @@
      * @param attrs The attributes set containing the Workspace's customization values.
      */
     public DragLayer(Context context, AttributeSet attrs) {
-        super(context, attrs);
+        super(context, attrs, ALPHA_CHANNEL_COUNT);
 
         // Disable multitouch across the workspace/all apps/customize tray
         setMotionEventSplittingEnabled(false);
         setChildrenDrawingOrderEnabled(true);
 
         mFocusIndicatorHelper = new ViewGroupFocusHelper(this);
+        mScrim = new WorkspaceAndHotseatScrim(this);
     }
 
-    public void setup(DragController dragController) {
+    public void setup(DragController dragController, Workspace workspace) {
         mDragController = dragController;
+        mScrim.setWorkspace(workspace);
+        recreateControllers();
+    }
+
+    public void recreateControllers() {
         mControllers = UiFactory.createTouchControllers(mActivity);
     }
 
@@ -108,18 +124,6 @@
         return mDragController.dispatchKeyEvent(event) || super.dispatchKeyEvent(event);
     }
 
-    public boolean isEventOverHotseat(MotionEvent ev) {
-        return isEventOverView(mActivity.getHotseat(), ev);
-    }
-
-    private boolean isEventOverFolder(Folder folder, MotionEvent ev) {
-        return isEventOverView(folder, ev);
-    }
-
-    private boolean isEventOverDropTargetBar(MotionEvent ev) {
-        return isEventOverView(mActivity.getDropTargetBar(), ev);
-    }
-
     @Override
     protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
         ViewScrim scrim = ViewScrim.get(child);
@@ -139,24 +143,29 @@
         return super.findActiveController(ev);
     }
 
+    private boolean isEventOverAccessibleDropTargetBar(MotionEvent ev) {
+        return isInAccessibleDrag() && isEventOverView(mActivity.getDropTargetBar(), ev);
+    }
+
     @Override
     public boolean onInterceptHoverEvent(MotionEvent ev) {
         if (mActivity == null || mActivity.getWorkspace() == null) {
             return false;
         }
-        Folder currentFolder = Folder.getOpen(mActivity);
-        if (currentFolder == null) {
+        AbstractFloatingView topView = AbstractFloatingView.getTopOpenView(mActivity);
+        if (!(topView instanceof Folder)) {
             return false;
         } else {
             AccessibilityManager accessibilityManager = (AccessibilityManager)
                     getContext().getSystemService(Context.ACCESSIBILITY_SERVICE);
             if (accessibilityManager.isTouchExplorationEnabled()) {
+                Folder currentFolder = (Folder) topView;
                 final int action = ev.getAction();
                 boolean isOverFolderOrSearchBar;
                 switch (action) {
                     case MotionEvent.ACTION_HOVER_ENTER:
-                        isOverFolderOrSearchBar = isEventOverFolder(currentFolder, ev) ||
-                                (isInAccessibleDrag() && isEventOverDropTargetBar(ev));
+                        isOverFolderOrSearchBar = isEventOverView(topView, ev) ||
+                                isEventOverAccessibleDropTargetBar(ev);
                         if (!isOverFolderOrSearchBar) {
                             sendTapOutsideFolderAccessibilityEvent(currentFolder.isEditingName());
                             mHoverPointClosesFolder = true;
@@ -165,8 +174,8 @@
                         mHoverPointClosesFolder = false;
                         break;
                     case MotionEvent.ACTION_HOVER_MOVE:
-                        isOverFolderOrSearchBar = isEventOverFolder(currentFolder, ev) ||
-                                (isInAccessibleDrag() && isEventOverDropTargetBar(ev));
+                        isOverFolderOrSearchBar = isEventOverView(topView, ev) ||
+                                isEventOverAccessibleDropTargetBar(ev);
                         if (!isOverFolderOrSearchBar && !mHoverPointClosesFolder) {
                             sendTapOutsideFolderAccessibilityEvent(currentFolder.isEditingName());
                             mHoverPointClosesFolder = true;
@@ -201,18 +210,8 @@
 
     @Override
     public boolean onRequestSendAccessibilityEvent(View child, AccessibilityEvent event) {
-        // Shortcuts can appear above folder
-        View topView = AbstractFloatingView.getTopOpenView(mActivity);
-        if (topView != null) {
-            if (child == topView) {
-                return super.onRequestSendAccessibilityEvent(child, event);
-            }
-            if (isInAccessibleDrag() && child instanceof DropTargetBar) {
-                return super.onRequestSendAccessibilityEvent(child, event);
-            }
-            // Skip propagating onRequestSendAccessibilityEvent for all other children
-            // which are not topView
-            return false;
+        if (isInAccessibleDrag() && child instanceof DropTargetBar) {
+            return true;
         }
         return super.onRequestSendAccessibilityEvent(child, event);
     }
@@ -221,11 +220,9 @@
     public void addChildrenForAccessibility(ArrayList<View> childrenForAccessibility) {
         View topView = AbstractFloatingView.getTopOpenView(mActivity);
         if (topView != null) {
-            // Only add the top view as a child for accessibility when it is open
-            childrenForAccessibility.add(topView);
-
+            addAccessibleChildToList(topView, childrenForAccessibility);
             if (isInAccessibleDrag()) {
-                childrenForAccessibility.add(mActivity.getDropTargetBar());
+                addAccessibleChildToList(mActivity.getDropTargetBar(), childrenForAccessibility);
             }
         } else {
             super.addChildrenForAccessibility(childrenForAccessibility);
@@ -462,6 +459,7 @@
                 case ANIMATION_END_REMAIN_VISIBLE:
                     break;
                 }
+                mDropAnim = null;
             }
         });
         mDropAnim.start();
@@ -471,6 +469,7 @@
         if (mDropAnim != null) {
             mDropAnim.cancel();
         }
+        mDropAnim = null;
         if (mDropView != null) {
             mDragController.onDeferredEndDrag(mDropView);
         }
@@ -542,7 +541,24 @@
     @Override
     protected void dispatchDraw(Canvas canvas) {
         // Draw the background below children.
+        mScrim.draw(canvas);
         mFocusIndicatorHelper.draw(canvas);
         super.dispatchDraw(canvas);
     }
+
+    @Override
+    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+        super.onSizeChanged(w, h, oldw, oldh);
+        mScrim.setSize(w, h);
+    }
+
+    @Override
+    public void setInsets(Rect insets) {
+        super.setInsets(insets);
+        mScrim.onInsetsChanged(insets);
+    }
+
+    public WorkspaceAndHotseatScrim getScrim() {
+        return mScrim;
+    }
 }
diff --git a/src/com/android/launcher3/dragndrop/DragView.java b/src/com/android/launcher3/dragndrop/DragView.java
index e1e1f83..1e5f854 100644
--- a/src/com/android/launcher3/dragndrop/DragView.java
+++ b/src/com/android/launcher3/dragndrop/DragView.java
@@ -288,7 +288,7 @@
 
             if (mScaledMaskPath != null) {
                 mBgSpringDrawable.setColorFilter(mBaseFilter);
-                mBgSpringDrawable.setColorFilter(mBaseFilter);
+                mFgSpringDrawable.setColorFilter(mBaseFilter);
                 mBadge.setColorFilter(mBaseFilter);
             }
         } else {
diff --git a/src/com/android/launcher3/folder/Folder.java b/src/com/android/launcher3/folder/Folder.java
index 99c800d..b49952f 100644
--- a/src/com/android/launcher3/folder/Folder.java
+++ b/src/com/android/launcher3/folder/Folder.java
@@ -31,6 +31,7 @@
 import android.text.Selection;
 import android.util.AttributeSet;
 import android.util.Log;
+import android.util.Pair;
 import android.view.ActionMode;
 import android.view.FocusFinder;
 import android.view.KeyEvent;
@@ -516,15 +517,11 @@
             public void onAnimationStart(Animator animation) {
                 mFolderIcon.setBackgroundVisible(false);
                 mFolderIcon.drawLeaveBehindIfExists();
-
-                sendCustomAccessibilityEvent(
-                        Folder.this,
-                        AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED,
-                        mContent.getAccessibilityDescription());
             }
             @Override
             public void onAnimationEnd(Animator animation) {
                 mState = STATE_OPEN;
+                announceAccessibilityChanges();
 
                 mLauncher.getUserEventDispatcher().resetElapsedContainerMillis("folder opened");
                 mContent.setFocusOnFirstChild();
@@ -574,11 +571,6 @@
         }
 
         mContent.verifyVisibleHighResIcons(mContent.getNextPage());
-
-        // Notify the accessibility manager that this folder "window" has appeared and occluded
-        // the workspace items
-        sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
-        dragLayer.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED);
     }
 
     public void beginExternalDrag() {
@@ -612,6 +604,7 @@
             animateClosed();
         } else {
             closeComplete(false);
+            post(this::announceAccessibilityChanges);
         }
 
         // Notify the accessibility manager that this folder "window" has disappeared and no
@@ -626,18 +619,18 @@
             @Override
             public void onAnimationEnd(Animator animation) {
                 closeComplete(true);
-            }
-            @Override
-            public void onAnimationStart(Animator animation) {
-                sendCustomAccessibilityEvent(
-                        Folder.this,
-                        AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED,
-                        getContext().getString(R.string.folder_closed));
+                announceAccessibilityChanges();
             }
         });
         startAnimation(a);
     }
 
+    @Override
+    protected Pair<View, String> getAccessibilityTarget() {
+        return Pair.create(mContent, mIsOpen ? mContent.getAccessibilityDescription()
+                : getContext().getString(R.string.folder_closed));
+    }
+
     private void closeComplete(boolean wasAnimated) {
         // TODO: Clear all active animations.
         DragLayer parent = (DragLayer) getParent();
diff --git a/src/com/android/launcher3/graphics/WorkspaceAndHotseatScrim.java b/src/com/android/launcher3/graphics/WorkspaceAndHotseatScrim.java
index 5c991e9..bc4a06d 100644
--- a/src/com/android/launcher3/graphics/WorkspaceAndHotseatScrim.java
+++ b/src/com/android/launcher3/graphics/WorkspaceAndHotseatScrim.java
@@ -16,6 +16,14 @@
 
 package com.android.launcher3.graphics;
 
+import static android.content.Intent.ACTION_SCREEN_OFF;
+import static android.content.Intent.ACTION_USER_PRESENT;
+
+import android.animation.ObjectAnimator;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
 import android.graphics.Color;
@@ -25,8 +33,10 @@
 import android.graphics.RectF;
 import android.graphics.Region;
 import android.graphics.Shader;
+import android.graphics.drawable.Drawable;
 import android.support.v4.graphics.ColorUtils;
 import android.util.DisplayMetrics;
+import android.util.Property;
 import android.view.View;
 
 import com.android.launcher3.CellLayout;
@@ -35,13 +45,68 @@
 import com.android.launcher3.Utilities;
 import com.android.launcher3.Workspace;
 import com.android.launcher3.uioverrides.WallpaperColorInfo;
+import com.android.launcher3.util.Themes;
 
 /**
  * View scrim which draws behind hotseat and workspace
  */
-public class WorkspaceAndHotseatScrim extends ViewScrim<Workspace> implements
+public class WorkspaceAndHotseatScrim implements
         View.OnAttachStateChangeListener, WallpaperColorInfo.OnChangeListener {
 
+    public static Property<WorkspaceAndHotseatScrim, Float> SCRIM_PROGRESS =
+            new Property<WorkspaceAndHotseatScrim, Float>(Float.TYPE, "scrimProgress") {
+                @Override
+                public Float get(WorkspaceAndHotseatScrim scrim) {
+                    return scrim.mScrimProgress;
+                }
+
+                @Override
+                public void set(WorkspaceAndHotseatScrim scrim, Float value) {
+                    scrim.setScrimProgress(value);
+                }
+            };
+
+    public static Property<WorkspaceAndHotseatScrim, Float> SYSUI_PROGRESS =
+            new Property<WorkspaceAndHotseatScrim, Float>(Float.TYPE, "sysUiProgress") {
+                @Override
+                public Float get(WorkspaceAndHotseatScrim scrim) {
+                    return scrim.mSysUiProgress;
+                }
+
+                @Override
+                public void set(WorkspaceAndHotseatScrim scrim, Float value) {
+                    scrim.setSysUiProgress(value);
+                }
+            };
+
+    private static Property<WorkspaceAndHotseatScrim, Float> SYSUI_ANIM_MULTIPLIER =
+            new Property<WorkspaceAndHotseatScrim, Float>(Float.TYPE, "sysUiAnimMultiplier") {
+                @Override
+                public Float get(WorkspaceAndHotseatScrim scrim) {
+                    return scrim.mSysUiAnimMultiplier;
+                }
+
+                @Override
+                public void set(WorkspaceAndHotseatScrim scrim, Float value) {
+                    scrim.mSysUiAnimMultiplier = value;
+                    scrim.reapplySysUiAlpha();
+                }
+            };
+
+    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            final String action = intent.getAction();
+            if (ACTION_SCREEN_OFF.equals(action)) {
+                mAnimateScrimOnNextDraw = true;
+            } else if (ACTION_USER_PRESENT.equals(action)) {
+                // ACTION_USER_PRESENT is sent after onStart/onResume. This covers the case where
+                // the user unlocked and the Launcher is not in the foreground.
+                mAnimateScrimOnNextDraw = false;
+            }
+        }
+    };
+
     private static final int DARK_SCRIM_COLOR = 0x55000000;
     private static final int MAX_HOTSEAT_SCRIM_ALPHA = 100;
     private static final int ALPHA_MASK_HEIGHT_DP = 500;
@@ -51,42 +116,62 @@
     private final Rect mHighlightRect = new Rect();
     private final Launcher mLauncher;
     private final WallpaperColorInfo mWallpaperColorInfo;
+    private final View mRoot;
 
-    private final boolean mHasHotseatScrim;
+    private Workspace mWorkspace;
+
+    private final boolean mHasSysUiScrim;
+    private boolean mDrawTopScrim, mDrawBottomScrim;
+
     private final RectF mFinalMaskRect = new RectF();
     private final Paint mBottomMaskPaint = new Paint(Paint.FILTER_BITMAP_FLAG);
-
     private final Bitmap mBottomMask;
     private final int mMaskHeight;
 
+    private final Drawable mTopScrim;
+
     private int mFullScrimColor;
 
-    private final int mMaxAlpha;
-    private int mAlpha = 0;
+    private float mScrimProgress;
+    private int mScrimAlpha = 0;
 
-    public WorkspaceAndHotseatScrim(Workspace view) {
-        super(view);
+    private float mSysUiProgress = 1;
+    private boolean mHideSysUiScrim;
+
+    private boolean mAnimateScrimOnNextDraw = false;
+    private float mSysUiAnimMultiplier = 1;
+
+    public WorkspaceAndHotseatScrim(View view) {
+        mRoot = view;
         mLauncher = Launcher.getLauncher(view.getContext());
         mWallpaperColorInfo = WallpaperColorInfo.getInstance(mLauncher);
 
-        mMaxAlpha = mLauncher.getResources().getInteger(R.integer.config_workspaceScrimAlpha);
         mMaskHeight = Utilities.pxFromDp(ALPHA_MASK_BITMAP_DP,
                 view.getResources().getDisplayMetrics());
 
-        mHasHotseatScrim = !mWallpaperColorInfo.supportsDarkText();
-        mBottomMask = mHasHotseatScrim ? createDitheredAlphaMask() : null;
+        mHasSysUiScrim = !mWallpaperColorInfo.supportsDarkText();
+        if (mHasSysUiScrim) {
+            mTopScrim = Themes.getAttrDrawable(view.getContext(), R.attr.workspaceStatusBarScrim);
+            mBottomMask = createDitheredAlphaMask();
+        } else {
+            mTopScrim = null;
+            mBottomMask = null;
+        }
 
         view.addOnAttachStateChangeListener(this);
         onExtractedColorsChanged(mWallpaperColorInfo);
     }
 
-    @Override
-    public void draw(Canvas canvas, int width, int height) {
+    public void setWorkspace(Workspace workspace)  {
+        mWorkspace = workspace;
+    }
+
+    public void draw(Canvas canvas) {
         // Draw the background below children.
-        if (mAlpha > 0) {
+        if (mScrimAlpha > 0) {
             // Update the scroll position first to ensure scrim cutout is in the right place.
-            mView.computeScrollWithoutInvalidation();
-            CellLayout currCellLayout = mView.getCurrentDragOverlappingLayout();
+            mWorkspace.computeScrollWithoutInvalidation();
+            CellLayout currCellLayout = mWorkspace.getCurrentDragOverlappingLayout();
             canvas.save();
             if (currCellLayout != null && currCellLayout != mLauncher.getHotseat().getLayout()) {
                 // Cut a hole in the darkening scrim on the page that should be highlighted, if any.
@@ -95,40 +180,122 @@
                 canvas.clipRect(mHighlightRect, Region.Op.DIFFERENCE);
             }
 
-            canvas.drawColor(ColorUtils.setAlphaComponent(mFullScrimColor, mAlpha));
+            canvas.drawColor(ColorUtils.setAlphaComponent(mFullScrimColor, mScrimAlpha));
             canvas.restore();
         }
 
-        if (mHasHotseatScrim && !mLauncher.getDeviceProfile().isVerticalBarLayout()) {
-            mFinalMaskRect.set(0, height - mMaskHeight, width, height);
-            mBottomMaskPaint.setAlpha(Math.round(MAX_HOTSEAT_SCRIM_ALPHA * (1 - mProgress)));
-            canvas.drawBitmap(mBottomMask, null, mFinalMaskRect, mBottomMaskPaint);
+        if (!mHideSysUiScrim && mHasSysUiScrim) {
+            if (mSysUiProgress <= 0) {
+                mAnimateScrimOnNextDraw = false;
+                return;
+            }
+
+            if (mAnimateScrimOnNextDraw) {
+                mSysUiAnimMultiplier = 0;
+                reapplySysUiAlphaNoInvalidate();
+
+                ObjectAnimator anim = ObjectAnimator.ofFloat(this, SYSUI_ANIM_MULTIPLIER, 1);
+                anim.setAutoCancel(true);
+                anim.setDuration(600);
+                anim.setStartDelay(mLauncher.getWindow().getTransitionBackgroundFadeDuration());
+                anim.start();
+                mAnimateScrimOnNextDraw = false;
+            }
+
+            if (mDrawTopScrim) {
+                mTopScrim.draw(canvas);
+            }
+            if (mDrawBottomScrim) {
+                canvas.drawBitmap(mBottomMask, null, mFinalMaskRect, mBottomMaskPaint);
+            }
         }
     }
 
-    @Override
-    protected void onProgressChanged() {
-        mAlpha = Math.round(mMaxAlpha * mProgress);
+    public void onInsetsChanged(Rect insets) {
+        mDrawTopScrim = insets.top > 0;
+        mDrawBottomScrim = !mLauncher.getDeviceProfile().isVerticalBarLayout();
+    }
+
+    private void setScrimProgress(float progress) {
+        if (mScrimProgress != progress) {
+            mScrimProgress = progress;
+            mScrimAlpha = Math.round(255 * mScrimProgress);
+            invalidate();
+        }
     }
 
     @Override
     public void onViewAttachedToWindow(View view) {
         mWallpaperColorInfo.addOnChangeListener(this);
         onExtractedColorsChanged(mWallpaperColorInfo);
+
+        if (mHasSysUiScrim) {
+            IntentFilter filter = new IntentFilter(ACTION_SCREEN_OFF);
+            filter.addAction(ACTION_USER_PRESENT); // When the device wakes up + keyguard is gone
+            mRoot.getContext().registerReceiver(mReceiver, filter);
+        }
     }
 
     @Override
     public void onViewDetachedFromWindow(View view) {
         mWallpaperColorInfo.removeOnChangeListener(this);
+        if (mHasSysUiScrim) {
+            mRoot.getContext().unregisterReceiver(mReceiver);
+        }
     }
 
     @Override
     public void onExtractedColorsChanged(WallpaperColorInfo wallpaperColorInfo) {
         // for super light wallpaper it needs to be darken for contrast to workspace
         // for dark wallpapers the text is white so darkening works as well
-        mFullScrimColor = ColorUtils.compositeColors(DARK_SCRIM_COLOR,
-                wallpaperColorInfo.getMainColor());
-        mBottomMaskPaint.setColor(mFullScrimColor);
+        mBottomMaskPaint.setColor(ColorUtils.compositeColors(DARK_SCRIM_COLOR,
+                wallpaperColorInfo.getMainColor()));
+        reapplySysUiAlpha();
+        mFullScrimColor = wallpaperColorInfo.getMainColor();
+        if (mScrimAlpha > 0) {
+            invalidate();
+        }
+    }
+
+    public void setSize(int w, int h) {
+        if (mHasSysUiScrim) {
+            mTopScrim.setBounds(0, 0, w, h);
+            mFinalMaskRect.set(0, h - mMaskHeight, w, h);
+        }
+    }
+
+    public void hideSysUiScrim(boolean hideSysUiScrim) {
+        mHideSysUiScrim = hideSysUiScrim;
+        if (!hideSysUiScrim) {
+            mAnimateScrimOnNextDraw = true;
+        }
+        invalidate();
+    }
+
+    private void setSysUiProgress(float progress) {
+        if (progress != mSysUiProgress) {
+            mSysUiProgress = progress;
+            reapplySysUiAlpha();
+        }
+    }
+
+    private void reapplySysUiAlpha() {
+        if (mHasSysUiScrim) {
+            reapplySysUiAlphaNoInvalidate();
+            if (!mHideSysUiScrim) {
+                invalidate();
+            }
+        }
+    }
+
+    private void reapplySysUiAlphaNoInvalidate() {
+        float factor = mSysUiProgress * mSysUiAnimMultiplier;
+        mBottomMaskPaint.setAlpha(Math.round(MAX_HOTSEAT_SCRIM_ALPHA * factor));
+        mTopScrim.setAlpha(Math.round(255 * factor));
+    }
+
+    public void invalidate() {
+        mRoot.invalidate();
     }
 
     public Bitmap createDitheredAlphaMask() {
diff --git a/src/com/android/launcher3/logging/LoggerUtils.java b/src/com/android/launcher3/logging/LoggerUtils.java
index 9d97cb9..83593aa 100644
--- a/src/com/android/launcher3/logging/LoggerUtils.java
+++ b/src/com/android/launcher3/logging/LoggerUtils.java
@@ -31,6 +31,7 @@
 import com.android.launcher3.userevent.nano.LauncherLogProto.ItemType;
 import com.android.launcher3.userevent.nano.LauncherLogProto.LauncherEvent;
 import com.android.launcher3.userevent.nano.LauncherLogProto.Target;
+import com.android.launcher3.userevent.nano.LauncherLogProto.TipType;
 import com.android.launcher3.util.InstantAppResolver;
 
 import java.lang.reflect.Field;
@@ -76,7 +77,7 @@
                 }
                 return str;
             case Action.Type.COMMAND: return getFieldName(action.command, Action.Command.class);
-            default: return UNKNOWN;
+            default: return getFieldName(action.type, Action.Type.class);
         }
     }
 
@@ -84,23 +85,32 @@
         if (t == null){
             return "";
         }
+        String str = "";
         switch (t.type) {
             case Target.Type.ITEM:
-                return getItemStr(t);
+                str = getItemStr(t);
+                break;
             case Target.Type.CONTROL:
-                return getFieldName(t.controlType, ControlType.class);
+                str = getFieldName(t.controlType, ControlType.class);
+                break;
             case Target.Type.CONTAINER:
-                String str = getFieldName(t.containerType, ContainerType.class);
+                str = getFieldName(t.containerType, ContainerType.class);
                 if (t.containerType == ContainerType.WORKSPACE ||
                         t.containerType == ContainerType.HOTSEAT) {
                     str += " id=" + t.pageIndex;
                 } else if (t.containerType == ContainerType.FOLDER) {
                     str += " grid(" + t.gridX + "," + t.gridY+ ")";
                 }
-                return str;
+                break;
             default:
-                return "UNKNOWN TARGET TYPE";
+                str += "UNKNOWN TARGET TYPE";
         }
+
+        if (t.tipType != TipType.DEFAULT_NONE) {
+            str += " " + getFieldName(t.tipType, TipType.class);
+        }
+
+        return str;
     }
 
     private static String getItemStr(Target t) {
@@ -121,6 +131,9 @@
                     + "), pageIdx=" + t.pageIndex;
 
         }
+        if (t.itemType == ItemType.TASK) {
+            typeStr += ", pageIdx=" + t.pageIndex;
+        }
         return typeStr;
     }
 
@@ -186,6 +199,12 @@
         return t;
     }
 
+    public static Target newControlTarget(int controlType) {
+        Target t = newTarget(Target.Type.CONTROL);
+        t.controlType = controlType;
+        return t;
+    }
+
     public static Target newContainerTarget(int containerType) {
         Target t = newTarget(Target.Type.CONTAINER);
         t.containerType = containerType;
diff --git a/src/com/android/launcher3/logging/UserEventDispatcher.java b/src/com/android/launcher3/logging/UserEventDispatcher.java
index 2c1eb32..850c948 100644
--- a/src/com/android/launcher3/logging/UserEventDispatcher.java
+++ b/src/com/android/launcher3/logging/UserEventDispatcher.java
@@ -16,8 +16,10 @@
 
 package com.android.launcher3.logging;
 
+import static com.android.launcher3.logging.LoggerUtils.newAction;
 import static com.android.launcher3.logging.LoggerUtils.newCommandAction;
 import static com.android.launcher3.logging.LoggerUtils.newContainerTarget;
+import static com.android.launcher3.logging.LoggerUtils.newControlTarget;
 import static com.android.launcher3.logging.LoggerUtils.newDropTarget;
 import static com.android.launcher3.logging.LoggerUtils.newItemTarget;
 import static com.android.launcher3.logging.LoggerUtils.newLauncherEvent;
@@ -130,6 +132,7 @@
     private boolean mIsInLandscapeMode;
     private String mUuidStr;
     protected InstantAppResolver mInstantAppResolver;
+    private boolean mAppOrTaskLaunch;
 
     //                      APP_ICON    SHORTCUT    WIDGET
     // --------------------------------------------------------------
@@ -161,9 +164,13 @@
             fillIntentInfo(event.srcTarget[0], intent);
         }
         dispatchUserEvent(event, intent);
+        mAppOrTaskLaunch = true;
     }
 
-    public void logTaskLaunchOrDismiss(int action, int direction, ComponentKey componentKey) {
+    public void logActionTip(int actionType, int viewType) { }
+
+    public void logTaskLaunchOrDismiss(int action, int direction, int taskIndex,
+            ComponentKey componentKey) {
         LauncherEvent event = newLauncherEvent(newTouchAction(action), // TAP or SWIPE or FLING
                 newTarget(Target.Type.ITEM));
         if (action == Action.Touch.SWIPE || action == Action.Touch.FLING) {
@@ -171,8 +178,10 @@
             event.action.dir = direction;
         }
         event.srcTarget[0].itemType = LauncherLogProto.ItemType.TASK;
+        event.srcTarget[0].pageIndex = taskIndex;
         fillComponentInfo(event.srcTarget[0], componentKey.componentName);
         dispatchUserEvent(event, null);
+        mAppOrTaskLaunch = true;
     }
 
     protected void fillIntentInfo(Target target, Intent intent) {
@@ -207,6 +216,11 @@
 
     public void logActionCommand(int command, Target srcTarget, Target dstTarget) {
         LauncherEvent event = newLauncherEvent(newCommandAction(command), srcTarget);
+        if (command == Action.Command.STOP && mAppOrTaskLaunch) {
+            // Prevent double logging by skipping STOP when app or task has been launched.
+            return;
+        }
+
         if (dstTarget != null) {
             event.destTarget = new Target[1];
             event.destTarget[0] = dstTarget;
@@ -243,6 +257,15 @@
         logActionOnControl(action, controlType, controlInContainer, -1);
     }
 
+    public void logActionOnControl(int action, int controlType, int parentContainer,
+                                   int grandParentContainer){
+        LauncherEvent event = newLauncherEvent(newTouchAction(action),
+                newControlTarget(controlType),
+                newContainerTarget(parentContainer),
+                newContainerTarget(grandParentContainer));
+        dispatchUserEvent(event, null);
+    }
+
     public void logActionOnControl(int action, int controlType, @Nullable View controlInContainer,
                                    int parentContainerType) {
         final LauncherEvent event = (controlInContainer == null && parentContainerType < 0)
@@ -269,6 +292,13 @@
         dispatchUserEvent(event, null);
     }
 
+    public void logActionBounceTip(int containerType) {
+        LauncherEvent event = newLauncherEvent(newAction(Action.Type.TIP),
+                newContainerTarget(containerType));
+        event.srcTarget[0].tipType = LauncherLogProto.TipType.BOUNCE;
+        dispatchUserEvent(event, null);
+    }
+
     public void logActionOnContainer(int action, int dir, int containerType) {
         logActionOnContainer(action, dir, containerType, 0);
     }
@@ -385,6 +415,7 @@
     }
 
     public void dispatchUserEvent(LauncherEvent ev, Intent intent) {
+        mAppOrTaskLaunch = false;
         ev.isInLandscapeMode = mIsInLandscapeMode;
         ev.isInMultiWindowMode = mIsInMultiWindowMode;
         ev.elapsedContainerMillis = SystemClock.uptimeMillis() - mElapsedContainerMillis;
@@ -393,7 +424,8 @@
         if (!IS_VERBOSE) {
             return;
         }
-        String log = "action:" + LoggerUtils.getActionStr(ev.action);
+        String log = "\n-----------------------------------------------------"
+                + "\naction:" + LoggerUtils.getActionStr(ev.action);
         if (ev.srcTarget != null && ev.srcTarget.length > 0) {
             log += "\n Source " + getTargetsStr(ev.srcTarget);
         }
diff --git a/src/com/android/launcher3/popup/ArrowPopup.java b/src/com/android/launcher3/popup/ArrowPopup.java
index 5589f17..9098777 100644
--- a/src/com/android/launcher3/popup/ArrowPopup.java
+++ b/src/com/android/launcher3/popup/ArrowPopup.java
@@ -367,6 +367,7 @@
         openAnim.addListener(new AnimatorListenerAdapter() {
             @Override
             public void onAnimationEnd(Animator animation) {
+                announceAccessibilityChanges();
                 mOpenCloseAnimator = null;
             }
         });
diff --git a/src/com/android/launcher3/popup/PopupContainerWithArrow.java b/src/com/android/launcher3/popup/PopupContainerWithArrow.java
index 763eb6f..f276fbf 100644
--- a/src/com/android/launcher3/popup/PopupContainerWithArrow.java
+++ b/src/com/android/launcher3/popup/PopupContainerWithArrow.java
@@ -34,6 +34,7 @@
 import android.os.Handler;
 import android.os.Looper;
 import android.util.AttributeSet;
+import android.util.Pair;
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewConfiguration;
@@ -263,9 +264,7 @@
 
         ItemInfo originalItemInfo = (ItemInfo) originalIcon.getTag();
         if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
-            setAccessibilityPaneTitle(getContext().getString(mNumNotifications == 0 ?
-                    R.string.action_deep_shortcut :
-                    R.string.shortcuts_menu_with_notifications_description));
+            setAccessibilityPaneTitle(getTitleForAccessibility());
         }
 
         mLauncher.getDragController().addDragListener(this);
@@ -281,6 +280,17 @@
                 this, shortcutIds, mShortcuts, notificationKeys));
     }
 
+    private String getTitleForAccessibility() {
+        return getContext().getString(mNumNotifications == 0 ?
+                R.string.action_deep_shortcut :
+                R.string.shortcuts_menu_with_notifications_description);
+    }
+
+    @Override
+    protected Pair<View, String> getAccessibilityTarget() {
+        return Pair.create(this, "");
+    }
+
     @Override
     protected void getTargetObjectLocation(Rect outPos) {
         mLauncher.getDragLayer().getDescendantRectRelativeToSelf(mOriginalIcon, outPos);
diff --git a/src/com/android/launcher3/qsb/QsbWidgetHostView.java b/src/com/android/launcher3/qsb/QsbWidgetHostView.java
index a8a41f6..7d8a4db 100644
--- a/src/com/android/launcher3/qsb/QsbWidgetHostView.java
+++ b/src/com/android/launcher3/qsb/QsbWidgetHostView.java
@@ -73,6 +73,18 @@
         return getDefaultView(this);
     }
 
+    @Override
+    protected View getDefaultView() {
+        View v = super.getDefaultView();
+        v.setOnClickListener(new OnClickListener() {
+            @Override
+            public void onClick(View view) {
+                Launcher.getLauncher(getContext()).startSearch("", false, null, true);
+            }
+        });
+        return v;
+    }
+
     public static View getDefaultView(ViewGroup parent) {
         View v = LayoutInflater.from(parent.getContext())
                 .inflate(R.layout.qsb_default_view, parent, false);
diff --git a/src/com/android/launcher3/states/RotationHelper.java b/src/com/android/launcher3/states/RotationHelper.java
index 0036bb9..e866445 100644
--- a/src/com/android/launcher3/states/RotationHelper.java
+++ b/src/com/android/launcher3/states/RotationHelper.java
@@ -150,4 +150,12 @@
             mActivity.setRequestedOrientation(activityFlags);
         }
     }
+
+    @Override
+    public String toString() {
+        return String.format("[mStateHandlerRequest=%d, mCurrentStateRequest=%d,"
+                + " mLastActivityFlags=%d, mIgnoreAutoRotateSettings=%b, mAutoRotateEnabled=%b]",
+                mStateHandlerRequest, mCurrentStateRequest, mLastActivityFlags,
+                mIgnoreAutoRotateSettings, mAutoRotateEnabled);
+    }
 }
diff --git a/src/com/android/launcher3/states/SpringLoadedState.java b/src/com/android/launcher3/states/SpringLoadedState.java
index 90d3821..aa7d0d5 100644
--- a/src/com/android/launcher3/states/SpringLoadedState.java
+++ b/src/com/android/launcher3/states/SpringLoadedState.java
@@ -33,7 +33,7 @@
  */
 public class SpringLoadedState extends LauncherState {
 
-    private static final int STATE_FLAGS = FLAG_SHOW_SCRIM | FLAG_MULTI_PAGE |
+    private static final int STATE_FLAGS = FLAG_MULTI_PAGE |
             FLAG_DISABLE_ACCESSIBILITY | FLAG_DISABLE_RESTORE | FLAG_WORKSPACE_ICONS_CAN_BE_DRAGGED |
             FLAG_DISABLE_PAGE_CLIPPING | FLAG_PAGE_BACKGROUNDS | FLAG_HIDE_BACK_BUTTON;
 
@@ -86,6 +86,11 @@
     }
 
     @Override
+    public float getWorkspaceScrimAlpha(Launcher launcher) {
+        return 0.3f;
+    }
+
+    @Override
     public void onStateDisabled(final Launcher launcher) {
         launcher.getWorkspace().getPageIndicator().setShouldAutoHide(true);
 
diff --git a/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java b/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java
index 658af95..0e68538 100644
--- a/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java
+++ b/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java
@@ -15,22 +15,38 @@
  */
 package com.android.launcher3.touch;
 
+import static com.android.launcher3.LauncherAnimUtils.MIN_PROGRESS_TO_ALL_APPS;
 import static com.android.launcher3.LauncherState.ALL_APPS;
 import static com.android.launcher3.LauncherState.NORMAL;
 import static com.android.launcher3.LauncherState.OVERVIEW;
+import static com.android.launcher3.LauncherStateManager.ANIM_ALL;
+import static com.android.launcher3.LauncherStateManager.ATOMIC_COMPONENT;
+import static com.android.launcher3.LauncherStateManager.NON_ATOMIC_COMPONENT;
 import static com.android.launcher3.Utilities.SINGLE_FRAME_MS;
 import static com.android.launcher3.anim.Interpolators.scrollInterpolatorForVelocity;
 
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.AnimatorSet;
 import android.animation.ValueAnimator;
+import android.view.HapticFeedbackConstants;
 import android.view.MotionEvent;
 
 import com.android.launcher3.Launcher;
+import com.android.launcher3.LauncherAnimUtils;
 import com.android.launcher3.LauncherState;
+import com.android.launcher3.LauncherStateManager.AnimationComponents;
+import com.android.launcher3.LauncherStateManager.AnimationConfig;
+import com.android.launcher3.LauncherStateManager.StateHandler;
 import com.android.launcher3.Utilities;
+import com.android.launcher3.anim.AnimationSuccessListener;
 import com.android.launcher3.anim.AnimatorPlaybackController;
+import com.android.launcher3.anim.AnimatorSetBuilder;
+import com.android.launcher3.uioverrides.UiFactory;
 import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction;
 import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch;
 import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
+import com.android.launcher3.util.FlingBlockCheck;
 import com.android.launcher3.util.PendingAnimation;
 import com.android.launcher3.util.TouchController;
 
@@ -41,11 +57,16 @@
         implements TouchController, SwipeDetector.Listener {
 
     private static final String TAG = "ASCTouchController";
-    public static final float RECATCH_REJECTION_FRACTION = .0875f;
 
     // Progress after which the transition is assumed to be a success in case user does not fling
     public static final float SUCCESS_TRANSITION_PROGRESS = 0.5f;
 
+    /**
+     * Play an atomic recents animation when the progress from NORMAL to OVERVIEW reaches this.
+     */
+    public static final float ATOMIC_OVERVIEW_ANIM_THRESHOLD = 0.5f;
+    protected static final long ATOMIC_DURATION = 200;
+
     protected final Launcher mLauncher;
     protected final SwipeDetector mDetector;
 
@@ -61,6 +82,18 @@
     // Ratio of transition process [0, 1] to drag displacement (px)
     private float mProgressMultiplier;
     private float mDisplacementShift;
+    private boolean mCanBlockFling;
+    private FlingBlockCheck mFlingBlockCheck = new FlingBlockCheck();
+
+    private AnimatorSet mAtomicAnim;
+    private boolean mPassedOverviewAtomicThreshold;
+    // mAtomicAnim plays the atomic components of the state animations when we pass the threshold.
+    // However, if we reinit to transition to a new state (e.g. OVERVIEW -> ALL_APPS) before the
+    // atomic animation finishes, we only control the non-atomic components so that we don't
+    // interfere with the atomic animation. When the atomic animation ends, we start controlling
+    // the atomic components as well, using this controller.
+    private AnimatorPlaybackController mAtomicComponentsController;
+    private float mAtomicComponentsStartProgress;
 
     public AbstractStateChangeTouchController(Launcher l, SwipeDetector.Direction dir) {
         mLauncher = l;
@@ -83,14 +116,8 @@
             boolean ignoreSlopWhenSettling = false;
 
             if (mCurrentAnimation != null) {
-                if (mCurrentAnimation.getProgressFraction() > 1 - RECATCH_REJECTION_FRACTION) {
-                    directionsToDetectScroll = SwipeDetector.DIRECTION_POSITIVE;
-                } else if (mCurrentAnimation.getProgressFraction() < RECATCH_REJECTION_FRACTION ) {
-                    directionsToDetectScroll = SwipeDetector.DIRECTION_NEGATIVE;
-                } else {
-                    directionsToDetectScroll = SwipeDetector.DIRECTION_BOTH;
-                    ignoreSlopWhenSettling = true;
-                }
+                directionsToDetectScroll = SwipeDetector.DIRECTION_BOTH;
+                ignoreSlopWhenSettling = true;
             } else {
                 directionsToDetectScroll = getSwipeDirection();
                 if (directionsToDetectScroll == 0) {
@@ -138,7 +165,7 @@
     protected abstract LauncherState getTargetState(LauncherState fromState,
             boolean isDragTowardPositive);
 
-    protected abstract float initCurrentAnimation();
+    protected abstract float initCurrentAnimation(@AnimationComponents int animComponents);
 
     /**
      * Returns the container that the touch started from when leaving NORMAL state.
@@ -169,24 +196,59 @@
         mToState = newToState;
 
         mStartProgress = 0;
+        mPassedOverviewAtomicThreshold = false;
         if (mCurrentAnimation != null) {
             mCurrentAnimation.setOnCancelRunnable(null);
         }
-        mProgressMultiplier = initCurrentAnimation();
+        int animComponents = goingBetweenNormalAndOverview(mFromState, mToState)
+                ? NON_ATOMIC_COMPONENT : ANIM_ALL;
+        if (mAtomicAnim != null) {
+            // Control the non-atomic components until the atomic animation finishes, then control
+            // the atomic components as well.
+            animComponents = NON_ATOMIC_COMPONENT;
+            mAtomicAnim.addListener(new AnimationSuccessListener() {
+                @Override
+                public void onAnimationSuccess(Animator animation) {
+                    cancelAtomicComponentsController();
+                    if (mCurrentAnimation != null) {
+                        mAtomicComponentsStartProgress = mCurrentAnimation.getProgressFraction();
+                        long duration = (long) (getShiftRange() * 2);
+                        mAtomicComponentsController = AnimatorPlaybackController.wrap(
+                                createAtomicAnimForState(mFromState, mToState, duration), duration);
+                        mAtomicComponentsController.dispatchOnStart();
+                    }
+                }
+            });
+        }
+        if (goingBetweenNormalAndOverview(mFromState, mToState)) {
+            cancelAtomicComponentsController();
+        }
+        mProgressMultiplier = initCurrentAnimation(animComponents);
+        mCurrentAnimation.getAnimationPlayer().addUpdateListener(animation ->
+                setBackButtonAlphaWithProgress((float) animation.getAnimatedValue()));
         mCurrentAnimation.dispatchOnStart();
         return true;
     }
 
+    private boolean goingBetweenNormalAndOverview(LauncherState fromState, LauncherState toState) {
+        return (fromState == NORMAL || fromState == OVERVIEW)
+                && (toState == NORMAL || toState == OVERVIEW)
+                && mPendingAnimation == null;
+    }
+
     @Override
     public void onDragStart(boolean start) {
         if (mCurrentAnimation == null) {
             mFromState = mToState = null;
+            mAtomicComponentsController = null;
             reinitCurrentAnimation(false, mDetector.wasInitialTouchPositive());
             mDisplacementShift = 0;
         } else {
             mCurrentAnimation.pause();
             mStartProgress = mCurrentAnimation.getProgressFraction();
         }
+        mCanBlockFling = mFromState == NORMAL;
+        mFlingBlockCheck.unblockFling();
     }
 
     @Override
@@ -198,17 +260,75 @@
         if (progress <= 0) {
             if (reinitCurrentAnimation(false, isDragTowardPositive)) {
                 mDisplacementShift = displacement;
+                if (mCanBlockFling) {
+                    mFlingBlockCheck.blockFling();
+                }
             }
         } else if (progress >= 1) {
             if (reinitCurrentAnimation(true, isDragTowardPositive)) {
                 mDisplacementShift = displacement;
+                if (mCanBlockFling) {
+                    mFlingBlockCheck.blockFling();
+                }
             }
+        } else {
+            mFlingBlockCheck.onEvent();
         }
+
         return true;
     }
 
     protected void updateProgress(float fraction) {
         mCurrentAnimation.setPlayFraction(fraction);
+        if (mAtomicComponentsController != null) {
+            mAtomicComponentsController.setPlayFraction(fraction - mAtomicComponentsStartProgress);
+        }
+        maybeUpdateAtomicAnim(mFromState, mToState, fraction);
+        setBackButtonAlphaWithProgress(fraction);
+    }
+
+    /**
+     * When going between normal and overview states, see if we passed the overview threshold and
+     * play the appropriate atomic animation if so.
+     */
+    private void maybeUpdateAtomicAnim(LauncherState fromState, LauncherState toState,
+            float progress) {
+        if (!goingBetweenNormalAndOverview(fromState, toState)) {
+            return;
+        }
+        float threshold = toState == OVERVIEW ? ATOMIC_OVERVIEW_ANIM_THRESHOLD
+                : 1f - ATOMIC_OVERVIEW_ANIM_THRESHOLD;
+        boolean passedThreshold = progress >= threshold;
+        if (passedThreshold != mPassedOverviewAtomicThreshold) {
+            LauncherState atomicFromState = passedThreshold ? fromState: toState;
+            LauncherState atomicToState = passedThreshold ? toState : fromState;
+            mPassedOverviewAtomicThreshold = passedThreshold;
+            if (mAtomicAnim != null) {
+                mAtomicAnim.cancel();
+            }
+            mAtomicAnim = createAtomicAnimForState(atomicFromState, atomicToState, ATOMIC_DURATION);
+            mAtomicAnim.addListener(new AnimatorListenerAdapter() {
+                @Override
+                public void onAnimationEnd(Animator animation) {
+                    mAtomicAnim = null;
+                }
+            });
+            mAtomicAnim.start();
+            mLauncher.getDragLayer().performHapticFeedback(HapticFeedbackConstants.CONTEXT_CLICK);
+        }
+    }
+
+    private AnimatorSet createAtomicAnimForState(LauncherState fromState, LauncherState targetState,
+            long duration) {
+        AnimatorSetBuilder builder = new AnimatorSetBuilder();
+        mLauncher.getStateManager().prepareForAtomicAnimation(fromState, targetState, builder);
+        AnimationConfig config = new AnimationConfig();
+        config.animComponents = ATOMIC_COMPONENT;
+        config.duration = duration;
+        for (StateHandler handler : mLauncher.getStateManager().getStateHandlers()) {
+            handler.setStateWithAnimation(targetState, builder, config);
+        }
+        return builder.build();
     }
 
     @Override
@@ -217,6 +337,11 @@
         final LauncherState targetState;
         final float progress = mCurrentAnimation.getProgressFraction();
 
+        boolean blockedFling = fling && mFlingBlockCheck.isBlocked();
+        if (blockedFling) {
+            fling = false;
+        }
+
         if (fling) {
             logAction = Touch.FLING;
             targetState =
@@ -225,12 +350,17 @@
             // snap to top or bottom using the release velocity
         } else {
             logAction = Touch.SWIPE;
-            targetState = (progress > SUCCESS_TRANSITION_PROGRESS) ? mToState : mFromState;
+            float successProgress = mToState == ALL_APPS
+                    ? MIN_PROGRESS_TO_ALL_APPS : SUCCESS_TRANSITION_PROGRESS;
+            targetState = (progress > successProgress) ? mToState : mFromState;
         }
 
         final float endProgress;
         final float startProgress;
         final long duration;
+        // Increase the duration if we prevented the fling, as we are going against a high velocity.
+        final int durationMultiplier = blockedFling && targetState == mFromState
+                ? LauncherAnimUtils.blockedFlingDurationFactor(velocity) : 1;
 
         if (targetState == mToState) {
             endProgress = 1;
@@ -241,11 +371,16 @@
                 startProgress = Utilities.boundToRange(
                         progress + velocity * SINGLE_FRAME_MS * mProgressMultiplier, 0f, 1f);
                 duration = SwipeDetector.calculateDuration(velocity,
-                        endProgress - Math.max(progress, 0));
+                        endProgress - Math.max(progress, 0)) * durationMultiplier;
             }
         } else {
+            // Let the state manager know that the animation didn't go to the target state,
+            // but don't cancel ourselves (we already clean up when the animation completes).
+            Runnable onCancel = mCurrentAnimation.getOnCancelRunnable();
             mCurrentAnimation.setOnCancelRunnable(null);
             mCurrentAnimation.dispatchOnCancel();
+            mCurrentAnimation.setOnCancelRunnable(onCancel);
+
             endProgress = 0;
             if (progress <= 0) {
                 duration = 0;
@@ -254,16 +389,65 @@
                 startProgress = Utilities.boundToRange(
                         progress + velocity * SINGLE_FRAME_MS * mProgressMultiplier, 0f, 1f);
                 duration = SwipeDetector.calculateDuration(velocity,
-                        Math.min(progress, 1) - endProgress);
+                        Math.min(progress, 1) - endProgress) * durationMultiplier;
             }
         }
 
         mCurrentAnimation.setEndAction(() -> onSwipeInteractionCompleted(targetState, logAction));
         ValueAnimator anim = mCurrentAnimation.getAnimationPlayer();
         anim.setFloatValues(startProgress, endProgress);
-        updateSwipeCompleteAnimation(anim, duration, targetState, velocity, fling);
+        maybeUpdateAtomicAnim(mFromState, targetState, targetState == mToState ? 1f : 0f);
+        updateSwipeCompleteAnimation(anim, Math.max(duration, getRemainingAtomicDuration()),
+                targetState, velocity, fling);
         mCurrentAnimation.dispatchOnStart();
         anim.start();
+        if (mAtomicAnim == null) {
+            startAtomicComponentsAnim(endProgress, anim.getDuration());
+        } else {
+            mAtomicAnim.addListener(new AnimationSuccessListener() {
+                @Override
+                public void onAnimationSuccess(Animator animator) {
+                    startAtomicComponentsAnim(endProgress, anim.getDuration());
+                }
+            });
+        }
+    }
+
+    /**
+     * Animates the atomic components from the current progress to the final progress.
+     *
+     * Note that this only applies when we are controlling the atomic components separately from
+     * the non-atomic components, which only happens if we reinit before the atomic animation
+     * finishes.
+     */
+    private void startAtomicComponentsAnim(float toProgress, long duration) {
+        if (mAtomicComponentsController != null) {
+            ValueAnimator atomicAnim = mAtomicComponentsController.getAnimationPlayer();
+            atomicAnim.setFloatValues(mAtomicComponentsController.getProgressFraction(), toProgress);
+            atomicAnim.setDuration(duration);
+            atomicAnim.start();
+            atomicAnim.addListener(new AnimatorListenerAdapter() {
+                @Override
+                public void onAnimationEnd(Animator animation) {
+                    mAtomicComponentsController = null;
+                }
+            });
+        }
+    }
+
+    private long getRemainingAtomicDuration() {
+        if (mAtomicAnim == null) {
+            return 0;
+        }
+        if (Utilities.ATLEAST_OREO) {
+            return mAtomicAnim.getTotalDuration() - mAtomicAnim.getCurrentPlayTime();
+        } else {
+            long remainingDuration = 0;
+            for (Animator anim : mAtomicAnim.getChildAnimations()) {
+                remainingDuration = Math.max(remainingDuration, anim.getDuration());
+            }
+            return remainingDuration;
+        }
     }
 
     protected void updateSwipeCompleteAnimation(ValueAnimator animator, long expectedDuration,
@@ -293,6 +477,14 @@
         }
     }
 
+    private void setBackButtonAlphaWithProgress(float progress) {
+        if (mFromState.hideBackButton ^ mToState.hideBackButton) {
+            progress = Utilities.boundToRange(progress, 0, 1);
+            final float alpha = mToState.hideBackButton ? 1 - progress : progress;
+            UiFactory.setBackButtonAlpha(mLauncher, alpha, false /* animate */);
+        }
+    }
+
     private void logReachedState(int logAction) {
         // Transition complete. log the action
         mLauncher.getUserEventDispatcher().logStateChangeAction(logAction,
@@ -305,7 +497,15 @@
 
     protected void clearState() {
         mCurrentAnimation = null;
+        cancelAtomicComponentsController();
         mDetector.finishedScrolling();
         mDetector.setDetectableScrollConditions(0, false);
     }
+
+    private void cancelAtomicComponentsController() {
+        if (mAtomicComponentsController != null) {
+            mAtomicComponentsController.getAnimationPlayer().cancel();
+            mAtomicComponentsController = null;
+        }
+    }
 }
diff --git a/src/com/android/launcher3/util/FlingBlockCheck.java b/src/com/android/launcher3/util/FlingBlockCheck.java
new file mode 100644
index 0000000..f9575b9
--- /dev/null
+++ b/src/com/android/launcher3/util/FlingBlockCheck.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.launcher3.util;
+
+import android.os.SystemClock;
+
+/**
+ * Determines whether a fling should be blocked. Currently we block flings when crossing thresholds
+ * to new states, and unblock after a short duration.
+ */
+public class FlingBlockCheck {
+    // Allow flinging to a new state after waiting this many milliseconds.
+    private static final long UNBLOCK_FLING_PAUSE_DURATION = 200;
+
+    private boolean mBlockFling;
+    private long mBlockFlingTime;
+
+    public void blockFling() {
+        mBlockFling = true;
+        mBlockFlingTime = SystemClock.uptimeMillis();
+    }
+
+    public void unblockFling() {
+        mBlockFling = false;
+        mBlockFlingTime = 0;
+    }
+
+    public void onEvent() {
+        // We prevent flinging after passing a state, but allow it if the user pauses briefly.
+        if (SystemClock.uptimeMillis() - mBlockFlingTime >= UNBLOCK_FLING_PAUSE_DURATION) {
+            mBlockFling = false;
+        }
+    }
+
+    public boolean isBlocked() {
+        return mBlockFling;
+    }
+}
diff --git a/src/com/android/launcher3/util/MultiValueAlpha.java b/src/com/android/launcher3/util/MultiValueAlpha.java
new file mode 100644
index 0000000..f810f48
--- /dev/null
+++ b/src/com/android/launcher3/util/MultiValueAlpha.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.launcher3.util;
+
+import android.util.Property;
+import android.view.View;
+
+/**
+ * Utility class to handle separating a single value as a factor of multiple values
+ */
+public class MultiValueAlpha {
+
+    public static final Property<AlphaProperty, Float> VALUE =
+            new Property<AlphaProperty, Float>(Float.TYPE, "value") {
+
+                @Override
+                public Float get(AlphaProperty alphaProperty) {
+                    return alphaProperty.mValue;
+                }
+
+                @Override
+                public void set(AlphaProperty object, Float value) {
+                    object.setValue(value);
+                }
+            };
+
+    private final View mView;
+    private final AlphaProperty[] mMyProperties;
+
+    private int mValidMask;
+
+    public MultiValueAlpha(View view, int size) {
+        mView = view;
+        mMyProperties = new AlphaProperty[size];
+
+        mValidMask = 0;
+        for (int i = 0; i < size; i++) {
+            int myMask = 1 << i;
+            mValidMask |= myMask;
+            mMyProperties[i] = new AlphaProperty(myMask);
+        }
+    }
+
+    public AlphaProperty getProperty(int index) {
+        return mMyProperties[index];
+    }
+
+    public class AlphaProperty {
+
+        private final int mMyMask;
+
+        private float mValue = 1;
+        // Factor of all other alpha channels, only valid if mMyMask is present in mValidMask.
+        private float mOthers = 1;
+
+        AlphaProperty(int myMask) {
+            mMyMask = myMask;
+        }
+
+        public void setValue(float value) {
+            if (mValue == value) {
+                return;
+            }
+
+            if ((mValidMask & mMyMask) == 0) {
+                // Our cache value is not correct, recompute it.
+                mOthers = 1;
+                for (AlphaProperty prop : mMyProperties) {
+                    if (prop != this) {
+                        mOthers *= prop.mValue;
+                    }
+                }
+            }
+
+            // Since we have changed our value, all other caches except our own need to be
+            // recomputed. Change mValidMask to indicate the new valid caches (only our own).
+            mValidMask = mMyMask;
+            mValue = value;
+
+            mView.setAlpha(mOthers * mValue);
+        }
+
+        public float getValue() {
+            return mValue;
+        }
+    }
+}
diff --git a/src/com/android/launcher3/util/SystemUiController.java b/src/com/android/launcher3/util/SystemUiController.java
index edbf05a..86995b7 100644
--- a/src/com/android/launcher3/util/SystemUiController.java
+++ b/src/com/android/launcher3/util/SystemUiController.java
@@ -16,11 +16,14 @@
 
 package com.android.launcher3.util;
 
+import android.text.TextUtils;
 import android.view.View;
 import android.view.Window;
 
 import com.android.launcher3.Utilities;
 
+import java.util.Arrays;
+
 /**
  * Utility class to manage various window flags to control system UI.
  */
@@ -31,6 +34,7 @@
     public static final int UI_STATE_ALL_APPS = 1;
     public static final int UI_STATE_WIDGET_BOTTOM_SHEET = 2;
     public static final int UI_STATE_ROOT_VIEW = 3;
+    public static final int UI_STATE_OVERVIEW = 4;
 
     public static final int FLAG_LIGHT_NAV = 1 << 0;
     public static final int FLAG_DARK_NAV = 1 << 1;
@@ -38,7 +42,7 @@
     public static final int FLAG_DARK_STATUS = 1 << 3;
 
     private final Window mWindow;
-    private final int[] mStates = new int[4];
+    private final int[] mStates = new int[5];
 
     public SystemUiController(Window window) {
         mWindow = window;
@@ -77,4 +81,9 @@
             mWindow.getDecorView().setSystemUiVisibility(newFlags);
         }
     }
+
+    @Override
+    public String toString() {
+        return "mStates=" + Arrays.toString(mStates);
+    }
 }
diff --git a/src/com/android/launcher3/views/AbstractSlideInView.java b/src/com/android/launcher3/views/AbstractSlideInView.java
index 7c4529d..c8d1457 100644
--- a/src/com/android/launcher3/views/AbstractSlideInView.java
+++ b/src/com/android/launcher3/views/AbstractSlideInView.java
@@ -81,6 +81,7 @@
             @Override
             public void onAnimationEnd(Animator animation) {
                 mSwipeDetector.finishedScrolling();
+                announceAccessibilityChanges();
             }
         });
     }
diff --git a/src/com/android/launcher3/views/BaseDragLayer.java b/src/com/android/launcher3/views/BaseDragLayer.java
index 149b38b..2f142ac 100644
--- a/src/com/android/launcher3/views/BaseDragLayer.java
+++ b/src/com/android/launcher3/views/BaseDragLayer.java
@@ -30,6 +30,8 @@
 import com.android.launcher3.BaseDraggingActivity;
 import com.android.launcher3.InsettableFrameLayout;
 import com.android.launcher3.Utilities;
+import com.android.launcher3.util.MultiValueAlpha;
+import com.android.launcher3.util.MultiValueAlpha.AlphaProperty;
 import com.android.launcher3.util.TouchController;
 
 import java.util.ArrayList;
@@ -45,17 +47,18 @@
     protected final Rect mHitRect = new Rect();
 
     protected final T mActivity;
+    private final MultiValueAlpha mMultiValueAlpha;
 
     protected TouchController[] mControllers;
     protected TouchController mActiveController;
     private TouchCompleteListener mTouchCompleteListener;
 
-    public BaseDragLayer(Context context, AttributeSet attrs) {
+    public BaseDragLayer(Context context, AttributeSet attrs, int alphaChannelCount) {
         super(context, attrs);
         mActivity = (T) BaseActivity.fromContext(context);
+        mMultiValueAlpha = new MultiValueAlpha(this, alphaChannelCount);
     }
 
-
     public boolean isEventOverView(View view, MotionEvent ev) {
         getDescendantRectRelativeToSelf(view, mHitRect);
         return mHitRect.contains((int) ev.getX(), (int) ev.getY());
@@ -114,12 +117,20 @@
         View topView = AbstractFloatingView.getTopOpenView(mActivity);
         if (topView != null) {
             // Only add the top view as a child for accessibility when it is open
-            childrenForAccessibility.add(topView);
+            addAccessibleChildToList(topView, childrenForAccessibility);
         } else {
             super.addChildrenForAccessibility(childrenForAccessibility);
         }
     }
 
+    protected void addAccessibleChildToList(View child, ArrayList<View> outList) {
+        if (child.isImportantForAccessibility()) {
+            outList.add(child);
+        } else {
+            child.addChildrenForAccessibility(outList);
+        }
+    }
+
     @Override
     public void onViewRemoved(View child) {
         super.onViewRemoved(child);
@@ -276,6 +287,10 @@
         return new LayoutParams(p);
     }
 
+    public AlphaProperty getAlphaProperty(int index) {
+        return mMultiValueAlpha.getProperty(index);
+    }
+
     public static class LayoutParams extends InsettableFrameLayout.LayoutParams {
         public int x, y;
         public boolean customPosition = false;
diff --git a/src/com/android/launcher3/views/LauncherDragIndicator.java b/src/com/android/launcher3/views/LauncherDragIndicator.java
deleted file mode 100644
index 986e4be..0000000
--- a/src/com/android/launcher3/views/LauncherDragIndicator.java
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.launcher3.views;
-
-import static com.android.launcher3.LauncherState.ALL_APPS;
-
-import android.content.Context;
-import android.graphics.Rect;
-import android.os.Bundle;
-import android.util.AttributeSet;
-import android.view.Gravity;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.view.accessibility.AccessibilityNodeInfo;
-import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
-import android.widget.FrameLayout;
-import android.widget.ImageView;
-
-import com.android.launcher3.DeviceProfile;
-import com.android.launcher3.Insettable;
-import com.android.launcher3.Launcher;
-import com.android.launcher3.R;
-import com.android.launcher3.Utilities;
-import com.android.launcher3.userevent.nano.LauncherLogProto.Action;
-import com.android.launcher3.userevent.nano.LauncherLogProto.ControlType;
-
-public class LauncherDragIndicator extends ImageView implements Insettable, OnClickListener {
-
-    private static final int WALLPAPERS = R.string.wallpaper_button_text;
-    private static final int WIDGETS = R.string.widget_button_text;
-    private static final int SETTINGS = R.string.settings_button_text;
-
-    protected final Launcher mLauncher;
-
-    public LauncherDragIndicator(Context context) {
-        this(context, null);
-    }
-
-    public LauncherDragIndicator(Context context, AttributeSet attrs) {
-        this(context, attrs, 0);
-    }
-
-    public LauncherDragIndicator(Context context, AttributeSet attrs, int defStyleAttr) {
-        super(context, attrs, defStyleAttr);
-        mLauncher = Launcher.getLauncher(context);
-        setOnClickListener(this);
-    }
-
-    @Override
-    public void setInsets(Rect insets) {
-        DeviceProfile grid = mLauncher.getDeviceProfile();
-        FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) getLayoutParams();
-
-        if (grid.isVerticalBarLayout()) {
-            if (grid.isSeascape()) {
-                lp.leftMargin = grid.hotseatBarSidePaddingPx;
-                lp.rightMargin = insets.right;
-                lp.gravity =  Gravity.RIGHT | Gravity.BOTTOM;
-            } else {
-                lp.leftMargin = insets.left;
-                lp.rightMargin = grid.hotseatBarSidePaddingPx;
-                lp.gravity = Gravity.LEFT | Gravity.BOTTOM;
-            }
-            lp.bottomMargin = grid.workspacePadding.bottom;
-            setImageResource(R.drawable.all_apps_handle_landscape);
-        } else {
-            lp.leftMargin = lp.rightMargin = 0;
-            lp.gravity = Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
-            lp.bottomMargin = getPortraitBottomMargin(grid, insets);
-            setImageResource(R.drawable.ic_drag_indicator);
-        }
-
-        lp.width = lp.height = grid.pageIndicatorSizePx;
-        setLayoutParams(lp);
-    }
-
-    protected int getPortraitBottomMargin(DeviceProfile grid, Rect insets) {
-        return grid.hotseatBarSizePx + insets.bottom - grid.pageIndicatorSizePx;
-    }
-
-    @Override
-    public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
-        super.onInitializeAccessibilityNodeInfo(info);
-        initCustomActions(info);
-    }
-
-    protected void initCustomActions(AccessibilityNodeInfo info) {
-        Context context = getContext();
-        if (Utilities.isWallpaperAllowed(context)) {
-            info.addAction(new AccessibilityAction(WALLPAPERS, context.getText(WALLPAPERS)));
-        }
-        info.addAction(new AccessibilityAction(WIDGETS, context.getText(WIDGETS)));
-        info.addAction(new AccessibilityAction(SETTINGS, context.getText(SETTINGS)));
-    }
-
-    @Override
-    public boolean performAccessibilityAction(int action, Bundle arguments) {
-        if (action == WALLPAPERS) {
-            return OptionsPopupView.startWallpaperPicker(this);
-        } else if (action == WIDGETS) {
-            return OptionsPopupView.onWidgetsClicked(this);
-        } else if (action == SETTINGS) {
-            return OptionsPopupView.startSettings(this);
-        }
-        return super.performAccessibilityAction(action, arguments);
-    }
-
-    @Override
-    public void onClick(View view) {
-        if (!mLauncher.isInState(ALL_APPS)) {
-            mLauncher.getUserEventDispatcher().logActionOnControl(
-                    Action.Touch.TAP, ControlType.ALL_APPS_BUTTON);
-            mLauncher.getStateManager().goToState(ALL_APPS);
-        }
-    }
-}
diff --git a/src/com/android/launcher3/views/OptionsPopupView.java b/src/com/android/launcher3/views/OptionsPopupView.java
index 56b92c7..c17857f 100644
--- a/src/com/android/launcher3/views/OptionsPopupView.java
+++ b/src/com/android/launcher3/views/OptionsPopupView.java
@@ -184,6 +184,7 @@
         Intent intent = new Intent(Intent.ACTION_SET_WALLPAPER)
                 .putExtra(EXTRA_WALLPAPER_OFFSET,
                         launcher.getWorkspace().getWallpaperOffsetForCenterPage());
+        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
 
         String pickerPackage = launcher.getString(R.string.wallpaper_picker_package);
         if (!TextUtils.isEmpty(pickerPackage)) {
diff --git a/src/com/android/launcher3/views/ScrimView.java b/src/com/android/launcher3/views/ScrimView.java
new file mode 100644
index 0000000..6bbce00
--- /dev/null
+++ b/src/com/android/launcher3/views/ScrimView.java
@@ -0,0 +1,404 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.launcher3.views;
+
+import static android.content.Context.ACCESSIBILITY_SERVICE;
+import static android.support.v4.graphics.ColorUtils.compositeColors;
+import static android.support.v4.graphics.ColorUtils.setAlphaComponent;
+import static android.view.MotionEvent.ACTION_DOWN;
+
+import static com.android.launcher3.LauncherState.ALL_APPS;
+import static com.android.launcher3.LauncherState.NORMAL;
+import static com.android.launcher3.anim.Interpolators.ACCEL;
+import static com.android.launcher3.anim.Interpolators.DEACCEL;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.Keyframe;
+import android.animation.ObjectAnimator;
+import android.animation.PropertyValuesHolder;
+import android.animation.RectEvaluator;
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Rect;
+import android.graphics.RectF;
+import android.graphics.drawable.Drawable;
+import android.os.Bundle;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.support.v4.view.ViewCompat;
+import android.support.v4.view.accessibility.AccessibilityNodeInfoCompat;
+import android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat;
+import android.support.v4.widget.ExploreByTouchHelper;
+import android.util.AttributeSet;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.accessibility.AccessibilityManager;
+import android.view.accessibility.AccessibilityManager.AccessibilityStateChangeListener;
+
+import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.Insettable;
+import com.android.launcher3.Launcher;
+import com.android.launcher3.LauncherState;
+import com.android.launcher3.LauncherStateManager;
+import com.android.launcher3.LauncherStateManager.StateListener;
+import com.android.launcher3.R;
+import com.android.launcher3.Utilities;
+import com.android.launcher3.uioverrides.WallpaperColorInfo;
+import com.android.launcher3.uioverrides.WallpaperColorInfo.OnChangeListener;
+import com.android.launcher3.userevent.nano.LauncherLogProto.Action;
+import com.android.launcher3.userevent.nano.LauncherLogProto.ControlType;
+import com.android.launcher3.util.Themes;
+
+import java.util.List;
+
+/**
+ * Simple scrim which draws a flat color
+ */
+public class ScrimView extends View implements Insettable, OnChangeListener,
+        AccessibilityStateChangeListener, StateListener {
+
+    private static final int WALLPAPERS = R.string.wallpaper_button_text;
+    private static final int WIDGETS = R.string.widget_button_text;
+    private static final int SETTINGS = R.string.settings_button_text;
+
+    private final Rect mTempRect = new Rect();
+    private final int[] mTempPos = new int[2];
+
+    protected final Launcher mLauncher;
+    private final WallpaperColorInfo mWallpaperColorInfo;
+    private final AccessibilityManager mAM;
+    protected final int mEndScrim;
+
+    protected float mMaxScrimAlpha;
+
+    protected float mProgress = 1;
+    protected int mScrimColor;
+
+    protected int mCurrentFlatColor;
+    protected int mEndFlatColor;
+    protected int mEndFlatColorAlpha;
+
+    protected final int mDragHandleSize;
+    private final Rect mDragHandleBounds;
+    private final RectF mHitRect = new RectF();
+
+    private final AccessibilityHelper mAccessibilityHelper;
+    @Nullable
+    protected Drawable mDragHandle;
+
+    public ScrimView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        mLauncher = Launcher.getLauncher(context);
+        mWallpaperColorInfo = WallpaperColorInfo.getInstance(context);
+        mEndScrim = Themes.getAttrColor(context, R.attr.allAppsScrimColor);
+
+        mMaxScrimAlpha = 0.7f;
+
+        mDragHandleSize = context.getResources()
+                .getDimensionPixelSize(R.dimen.vertical_drag_handle_size);
+        mDragHandleBounds = new Rect(0, 0, mDragHandleSize, mDragHandleSize);
+
+        mAccessibilityHelper = createAccessibilityHelper();
+        ViewCompat.setAccessibilityDelegate(this, mAccessibilityHelper);
+
+        mAM = (AccessibilityManager) context.getSystemService(ACCESSIBILITY_SERVICE);
+    }
+
+    @NonNull
+    protected AccessibilityHelper createAccessibilityHelper() {
+        return new AccessibilityHelper();
+    }
+
+    @Override
+    public void setInsets(Rect insets) {
+        updateDragHandleBounds();
+        updateDragHandleVisibility(null);
+    }
+
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+        updateDragHandleBounds();
+    }
+
+    @Override
+    protected void onAttachedToWindow() {
+        super.onAttachedToWindow();
+        mWallpaperColorInfo.addOnChangeListener(this);
+        onExtractedColorsChanged(mWallpaperColorInfo);
+
+        mAM.addAccessibilityStateChangeListener(this);
+        onAccessibilityStateChanged(mAM.isEnabled());
+    }
+
+    @Override
+    protected void onDetachedFromWindow() {
+        super.onDetachedFromWindow();
+        mWallpaperColorInfo.removeOnChangeListener(this);
+        mAM.removeAccessibilityStateChangeListener(this);
+    }
+
+    @Override
+    public boolean hasOverlappingRendering() {
+        return false;
+    }
+
+    @Override
+    public void onExtractedColorsChanged(WallpaperColorInfo wallpaperColorInfo) {
+        mScrimColor = wallpaperColorInfo.getMainColor();
+        mEndFlatColor = compositeColors(mEndScrim, setAlphaComponent(
+                mScrimColor, Math.round(mMaxScrimAlpha * 255)));
+        mEndFlatColorAlpha = Color.alpha(mEndFlatColor);
+        updateColors();
+        invalidate();
+    }
+
+    public void setProgress(float progress) {
+        if (mProgress != progress) {
+            mProgress = progress;
+            updateColors();
+            updateDragHandleAlpha();
+            invalidate();
+        }
+    }
+
+    public void reInitUi() { }
+
+    protected void updateColors() {
+        mCurrentFlatColor = mProgress >= 1 ? 0 : setAlphaComponent(
+                mEndFlatColor, Math.round((1 - mProgress) * mEndFlatColorAlpha));
+    }
+
+    protected void updateDragHandleAlpha() {
+        if (mDragHandle != null) {
+            mDragHandle.setAlpha(Math.round(255 * Utilities.boundToRange(mProgress, 0, 1)));
+        }
+    }
+
+    @Override
+    protected void onDraw(Canvas canvas) {
+        if (mCurrentFlatColor != 0) {
+            canvas.drawColor(mCurrentFlatColor);
+        }
+        if (mDragHandle != null) {
+            mDragHandle.draw(canvas);
+        }
+    }
+
+    @Override
+    public boolean onTouchEvent(MotionEvent event) {
+        boolean value = super.onTouchEvent(event);
+        if (!value && mDragHandle != null && event.getAction() == ACTION_DOWN
+                && mDragHandle.getAlpha() == 255
+                && mHitRect.contains(event.getX(), event.getY())) {
+
+            final Drawable drawable = mDragHandle;
+            mDragHandle = null;
+            drawable.setBounds(mDragHandleBounds);
+
+            Rect topBounds = new Rect(mDragHandleBounds);
+            topBounds.offset(0, -mDragHandleBounds.height() / 2);
+
+            Rect invalidateRegion = new Rect(mDragHandleBounds);
+            invalidateRegion.top = topBounds.top;
+
+            Keyframe frameTop = Keyframe.ofObject(0.6f, topBounds);
+            frameTop.setInterpolator(DEACCEL);
+            Keyframe frameBot = Keyframe.ofObject(1, mDragHandleBounds);
+            frameBot.setInterpolator(ACCEL);
+            PropertyValuesHolder holder = PropertyValuesHolder .ofKeyframe("bounds",
+                    Keyframe.ofObject(0, mDragHandleBounds), frameTop, frameBot);
+            holder.setEvaluator(new RectEvaluator());
+
+            ObjectAnimator anim = ObjectAnimator.ofPropertyValuesHolder(drawable, holder);
+            anim.addListener(new AnimatorListenerAdapter() {
+                @Override
+                public void onAnimationEnd(Animator animation) {
+                    getOverlay().remove(drawable);
+                    updateDragHandleVisibility(drawable);
+                }
+            });
+            anim.addUpdateListener((v) -> invalidate(invalidateRegion));
+            getOverlay().add(drawable);
+            anim.start();
+        }
+        return value;
+    }
+
+    protected void updateDragHandleBounds() {
+        DeviceProfile grid = mLauncher.getDeviceProfile();
+        final int left;
+        final int width = getMeasuredWidth();
+        final int top = getMeasuredHeight() - mDragHandleSize - grid.getInsets().bottom;
+        final int topMargin;
+
+        if (grid.isVerticalBarLayout()) {
+            topMargin = grid.workspacePadding.bottom;
+            if (grid.isSeascape()) {
+                left = width - grid.getInsets().right - mDragHandleSize;
+            } else {
+                left = mDragHandleSize + grid.getInsets().left;
+            }
+        } else {
+            left = (width - mDragHandleSize) / 2;
+            topMargin = grid.hotseatBarSizePx;
+        }
+        mDragHandleBounds.offsetTo(left, top - topMargin);
+        mHitRect.set(mDragHandleBounds);
+        float inset = -mDragHandleSize / 2;
+        mHitRect.inset(inset, inset);
+
+        if (mDragHandle != null) {
+            mDragHandle.setBounds(mDragHandleBounds);
+        }
+    }
+
+    @Override
+    public void onAccessibilityStateChanged(boolean enabled) {
+        LauncherStateManager stateManager = mLauncher.getStateManager();
+        stateManager.removeStateListener(this);
+
+        if (enabled) {
+            stateManager.addStateListener(this);
+            onStateSetImmediately(mLauncher.getStateManager().getState());
+        } else {
+            setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS);
+        }
+        updateDragHandleVisibility(null);
+    }
+
+    private void updateDragHandleVisibility(Drawable recycle) {
+        boolean visible = mLauncher.getDeviceProfile().isVerticalBarLayout() || mAM.isEnabled();
+        boolean wasVisible = mDragHandle != null;
+        if (visible != wasVisible) {
+            if (visible) {
+                mDragHandle = recycle != null ? recycle :
+                        mLauncher.getDrawable(R.drawable.drag_handle_indicator);
+                mDragHandle.setBounds(mDragHandleBounds);
+
+                updateDragHandleAlpha();
+            } else {
+                mDragHandle = null;
+            }
+            invalidate();
+        }
+    }
+
+    @Override
+    public boolean dispatchHoverEvent(MotionEvent event) {
+        return mAccessibilityHelper.dispatchHoverEvent(event) || super.dispatchHoverEvent(event);
+    }
+
+    @Override
+    public boolean dispatchKeyEvent(KeyEvent event) {
+        return mAccessibilityHelper.dispatchKeyEvent(event) || super.dispatchKeyEvent(event);
+    }
+
+    @Override
+    public void onFocusChanged(boolean gainFocus, int direction,
+            Rect previouslyFocusedRect) {
+        super.onFocusChanged(gainFocus, direction, previouslyFocusedRect);
+        mAccessibilityHelper.onFocusChanged(gainFocus, direction, previouslyFocusedRect);
+    }
+
+    @Override
+    public void onStateTransitionStart(LauncherState toState) {}
+
+    @Override
+    public void onStateTransitionComplete(LauncherState finalState) {
+        onStateSetImmediately(finalState);
+    }
+
+    @Override
+    public void onStateSetImmediately(LauncherState state) {
+        setImportantForAccessibility(state == ALL_APPS
+                ? IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS
+                : IMPORTANT_FOR_ACCESSIBILITY_AUTO);
+    }
+
+    protected class AccessibilityHelper extends ExploreByTouchHelper {
+
+        private static final int DRAG_HANDLE_ID = 1;
+
+        public AccessibilityHelper() {
+            super(ScrimView.this);
+        }
+
+        @Override
+        protected int getVirtualViewAt(float x, float y) {
+            return  mDragHandleBounds.contains((int) x, (int) y)
+                    ? DRAG_HANDLE_ID : INVALID_ID;
+        }
+
+        @Override
+        protected void getVisibleVirtualViews(List<Integer> virtualViewIds) {
+            virtualViewIds.add(DRAG_HANDLE_ID);
+        }
+
+        @Override
+        protected void onPopulateNodeForVirtualView(int virtualViewId,
+                AccessibilityNodeInfoCompat node) {
+            node.setContentDescription(getContext().getString(R.string.all_apps_button_label));
+            node.setBoundsInParent(mDragHandleBounds);
+
+            getLocationOnScreen(mTempPos);
+            mTempRect.set(mDragHandleBounds);
+            mTempRect.offset(mTempPos[0], mTempPos[1]);
+            node.setBoundsInScreen(mTempRect);
+
+            node.addAction(AccessibilityNodeInfoCompat.ACTION_CLICK);
+            node.setClickable(true);
+            node.setFocusable(true);
+
+            if (mLauncher.isInState(NORMAL)) {
+                Context context = getContext();
+                if (Utilities.isWallpaperAllowed(context)) {
+                    node.addAction(
+                            new AccessibilityActionCompat(WALLPAPERS, context.getText(WALLPAPERS)));
+                }
+                node.addAction(new AccessibilityActionCompat(WIDGETS, context.getText(WIDGETS)));
+                node.addAction(new AccessibilityActionCompat(SETTINGS, context.getText(SETTINGS)));
+            }
+        }
+
+        @Override
+        protected boolean onPerformActionForVirtualView(
+                int virtualViewId, int action, Bundle arguments) {
+            if (action == AccessibilityNodeInfoCompat.ACTION_CLICK) {
+                mLauncher.getUserEventDispatcher().logActionOnControl(
+                        Action.Touch.TAP, ControlType.ALL_APPS_BUTTON,
+                        mLauncher.getStateManager().getState().containerType);
+                mLauncher.getStateManager().goToState(ALL_APPS);
+                return true;
+            } else if (action == WALLPAPERS) {
+                return OptionsPopupView.startWallpaperPicker(ScrimView.this);
+            } else if (action == WIDGETS) {
+                return OptionsPopupView.onWidgetsClicked(ScrimView.this);
+            } else if (action == SETTINGS) {
+                return OptionsPopupView.startSettings(ScrimView.this);
+            }
+
+            return false;
+        }
+    }
+
+    public int getDragHandleSize() {
+        return mDragHandleSize;
+    }
+}
diff --git a/src/com/android/launcher3/widget/WidgetsBottomSheet.java b/src/com/android/launcher3/widget/WidgetsBottomSheet.java
index a258485..5ce7e04 100644
--- a/src/com/android/launcher3/widget/WidgetsBottomSheet.java
+++ b/src/com/android/launcher3/widget/WidgetsBottomSheet.java
@@ -20,6 +20,7 @@
 import android.content.Context;
 import android.graphics.Rect;
 import android.util.AttributeSet;
+import android.util.Pair;
 import android.view.Gravity;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -72,7 +73,7 @@
 
         mLauncher.getDragLayer().addView(this);
         mIsOpen = false;
-        open(true);
+        animateOpen();
     }
 
     @Override
@@ -129,20 +130,16 @@
         return widget;
     }
 
-    private void open(boolean animate) {
+    private void animateOpen() {
         if (mIsOpen || mOpenCloseAnimator.isRunning()) {
             return;
         }
         mIsOpen = true;
         setupNavBarColor();
-        if (animate) {
-            mOpenCloseAnimator.setValues(
-                    PropertyValuesHolder.ofFloat(TRANSLATION_SHIFT, TRANSLATION_SHIFT_OPENED));
-            mOpenCloseAnimator.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
-            mOpenCloseAnimator.start();
-        } else {
-            setTranslationShift(TRANSLATION_SHIFT_OPENED);
-        }
+        mOpenCloseAnimator.setValues(
+                PropertyValuesHolder.ofFloat(TRANSLATION_SHIFT, TRANSLATION_SHIFT_OPENED));
+        mOpenCloseAnimator.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
+        mOpenCloseAnimator.start();
     }
 
     @Override
@@ -170,4 +167,10 @@
     protected int getElementsRowCount() {
         return 1;
     }
+
+    @Override
+    protected Pair<View, String> getAccessibilityTarget() {
+        return Pair.create(findViewById(R.id.title),  getContext().getString(
+                mIsOpen ? R.string.widgets_list : R.string.widgets_list_closed));
+    }
 }
diff --git a/src/com/android/launcher3/widget/WidgetsFullSheet.java b/src/com/android/launcher3/widget/WidgetsFullSheet.java
index a622624..e94d81d 100644
--- a/src/com/android/launcher3/widget/WidgetsFullSheet.java
+++ b/src/com/android/launcher3/widget/WidgetsFullSheet.java
@@ -21,8 +21,10 @@
 import android.content.Context;
 import android.graphics.Rect;
 import android.util.AttributeSet;
+import android.util.Pair;
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
+import android.view.View;
 import android.view.animation.AnimationUtils;
 
 import com.android.launcher3.Insettable;
@@ -55,6 +57,7 @@
         mAdapter = new WidgetsListAdapter(context,
                 LayoutInflater.from(context), apps.getWidgetCache(), apps.getIconCache(),
                 this, this);
+
     }
 
     public WidgetsFullSheet(Context context, AttributeSet attrs) {
@@ -77,6 +80,12 @@
     }
 
     @Override
+    protected Pair<View, String> getAccessibilityTarget() {
+        return Pair.create(mRecyclerView, getContext().getString(
+                mIsOpen ? R.string.widgets_list : R.string.widgets_list_closed));
+    }
+
+    @Override
     protected void onAttachedToWindow() {
         super.onAttachedToWindow();
         mLauncher.getAppWidgetHost().addProviderChangeListener(this);
@@ -149,10 +158,6 @@
     }
 
     private void open(boolean animate) {
-        if (mIsOpen) {
-            return;
-        }
-        mIsOpen = true;
         if (animate) {
             if (mLauncher.getDragLayer().getInsets().bottom > 0) {
                 mContent.setAlpha(0);
@@ -180,6 +185,7 @@
         } else {
             setTranslationShift(TRANSLATION_SHIFT_OPENED);
             mAdapter.setApplyBitmapDeferred(false, mRecyclerView);
+            post(this::announceAccessibilityChanges);
         }
     }
 
@@ -212,6 +218,7 @@
     public static WidgetsFullSheet show(Launcher launcher, boolean animate) {
         WidgetsFullSheet sheet = (WidgetsFullSheet) launcher.getLayoutInflater()
                 .inflate(R.layout.widgets_full_sheet, launcher.getDragLayer(), false);
+        sheet.mIsOpen = true;
         launcher.getDragLayer().addView(sheet);
         sheet.open(animate);
         return sheet;
diff --git a/src/com/android/launcher3/widget/WidgetsRowViewHolder.java b/src/com/android/launcher3/widget/WidgetsRowViewHolder.java
index bc85db6..8f269a6 100644
--- a/src/com/android/launcher3/widget/WidgetsRowViewHolder.java
+++ b/src/com/android/launcher3/widget/WidgetsRowViewHolder.java
@@ -29,7 +29,8 @@
     public WidgetsRowViewHolder(ViewGroup v) {
         super(v);
 
-        cellContainer = (ViewGroup) v.findViewById(R.id.widgets_cell_list);
-        title = (BubbleTextView) v.findViewById(R.id.section);
+        cellContainer = v.findViewById(R.id.widgets_cell_list);
+        title = v.findViewById(R.id.section);
+        title.setAccessibilityDelegate(null);
     }
 }
diff --git a/src_ui_overrides/com/android/launcher3/uioverrides/AllAppsScrim.java b/src_ui_overrides/com/android/launcher3/uioverrides/AllAppsScrim.java
deleted file mode 100644
index e970c5b..0000000
--- a/src_ui_overrides/com/android/launcher3/uioverrides/AllAppsScrim.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.launcher3.uioverrides;
-
-import static com.android.launcher3.anim.Interpolators.ACCEL_1_5;
-
-import com.android.launcher3.R;
-import com.android.launcher3.allapps.AllAppsContainerView;
-import com.android.launcher3.graphics.ColorScrim;
-import com.android.launcher3.util.Themes;
-
-public class AllAppsScrim extends ColorScrim {
-
-    public AllAppsScrim(AllAppsContainerView view) {
-        super(view, Themes.getAttrColor(view.getContext(), R.attr.allAppsScrimColor), ACCEL_1_5);
-    }
-
-    public void reInitUi() {
-        // No op
-    }
-
-    public void onVerticalProgress(float progress) {
-        // No op
-    }
-}
diff --git a/src_ui_overrides/com/android/launcher3/uioverrides/AllAppsState.java b/src_ui_overrides/com/android/launcher3/uioverrides/AllAppsState.java
index 6366b2d..4a2f544 100644
--- a/src_ui_overrides/com/android/launcher3/uioverrides/AllAppsState.java
+++ b/src_ui_overrides/com/android/launcher3/uioverrides/AllAppsState.java
@@ -34,7 +34,7 @@
 
     private static final float PARALLAX_COEFFICIENT = .125f;
 
-    private static final int STATE_FLAGS = FLAG_DISABLE_ACCESSIBILITY | FLAG_ALL_APPS_SCRIM;
+    private static final int STATE_FLAGS = FLAG_DISABLE_ACCESSIBILITY;
 
     private static final PageAlphaProvider PAGE_ALPHA_PROVIDER = new PageAlphaProvider(DEACCEL_2) {
         @Override
diff --git a/src_ui_overrides/com/android/launcher3/uioverrides/AllAppsSwipeController.java b/src_ui_overrides/com/android/launcher3/uioverrides/AllAppsSwipeController.java
index 860be5f..e9dc800 100644
--- a/src_ui_overrides/com/android/launcher3/uioverrides/AllAppsSwipeController.java
+++ b/src_ui_overrides/com/android/launcher3/uioverrides/AllAppsSwipeController.java
@@ -8,6 +8,7 @@
 import com.android.launcher3.AbstractFloatingView;
 import com.android.launcher3.Launcher;
 import com.android.launcher3.LauncherState;
+import com.android.launcher3.LauncherStateManager.AnimationComponents;
 import com.android.launcher3.touch.AbstractStateChangeTouchController;
 import com.android.launcher3.touch.SwipeDetector;
 import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
@@ -57,16 +58,16 @@
 
     @Override
     protected int getLogContainerTypeForNormalState() {
-        return mLauncher.getDragLayer().isEventOverHotseat(mTouchDownEvent) ?
+        return mLauncher.getDragLayer().isEventOverView(mLauncher.getHotseat(), mTouchDownEvent) ?
                 ContainerType.HOTSEAT : ContainerType.WORKSPACE;
     }
 
     @Override
-    protected float initCurrentAnimation() {
+    protected float initCurrentAnimation(@AnimationComponents int animComponents) {
         float range = getShiftRange();
         long maxAccuracy = (long) (2 * range);
         mCurrentAnimation = mLauncher.getStateManager()
-                .createAnimationToNewWorkspace(mToState, maxAccuracy);
+                .createAnimationToNewWorkspace(mToState, maxAccuracy, animComponents);
         float startVerticalShift = mFromState.getVerticalProgress(mLauncher) * range;
         float endVerticalShift = mToState.getVerticalProgress(mLauncher) * range;
         float totalShift = endVerticalShift - startVerticalShift;
diff --git a/src_ui_overrides/com/android/launcher3/uioverrides/DisplayRotationListener.java b/src_ui_overrides/com/android/launcher3/uioverrides/DisplayRotationListener.java
new file mode 100644
index 0000000..b1a67e9
--- /dev/null
+++ b/src_ui_overrides/com/android/launcher3/uioverrides/DisplayRotationListener.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.launcher3.uioverrides;
+
+import android.content.Context;
+import android.view.OrientationEventListener;
+
+/**
+ * Utility class for listening for rotation changes
+ */
+public class DisplayRotationListener extends OrientationEventListener {
+
+    private final Runnable mCallback;
+
+    public DisplayRotationListener(Context context, Runnable callback) {
+        super(context);
+        mCallback = callback;
+    }
+
+    @Override
+    public void onOrientationChanged(int i) {
+        mCallback.run();
+    }
+}
diff --git a/src_ui_overrides/com/android/launcher3/uioverrides/UiFactory.java b/src_ui_overrides/com/android/launcher3/uioverrides/UiFactory.java
index b8cd035..db98f9a 100644
--- a/src_ui_overrides/com/android/launcher3/uioverrides/UiFactory.java
+++ b/src_ui_overrides/com/android/launcher3/uioverrides/UiFactory.java
@@ -16,12 +16,15 @@
 
 package com.android.launcher3.uioverrides;
 
+import android.app.Activity;
 import android.content.Context;
 
 import com.android.launcher3.Launcher;
 import com.android.launcher3.LauncherStateManager.StateHandler;
 import com.android.launcher3.util.TouchController;
 
+import java.io.PrintWriter;
+
 public class UiFactory {
 
     public static TouchController[] createTouchControllers(Launcher launcher) {
@@ -47,4 +50,12 @@
     public static void onLauncherStateOrResumeChanged(Launcher launcher) { }
 
     public static void onTrimMemory(Launcher launcher, int level) { }
+
+    public static boolean dumpActivity(Activity activity, PrintWriter writer) {
+        return false;
+    }
+
+    public static void prepareToShowOverview(Launcher launcher) { }
+
+    public static void setBackButtonAlpha(Launcher launcher, float alpha, boolean animate) { }
 }